diff options
Diffstat (limited to 'src')
160 files changed, 20052 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..aaa60fd --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,62 @@ +## Makefile.am for d3lphin + +SUBDIRS = pics servicemenus + +# this is the program that gets installed. it's name is used for all +# of the other Makefile.am variables +bin_PROGRAMS = d3lphin + +# set the include path for X, qt and KDE +INCLUDES = $(all_includes) + +# the library search path. +d3lphin_LDFLAGS = $(KDE_RPATH) $(all_libraries) + +# the libraries to link against. +d3lphin_LDADD = $(LIB_KFILE) $(LIB_KDEPRINT) -lkonq + +# which sources should be compiled for d3lphin +d3lphin_SOURCES = bookmarkselector.cpp bookmarkssettingspage.cpp \ + bookmarkssidebarpage.cpp detailsviewsettingspage.cpp dolphin.cpp dolphincontextmenu.cpp \ + dolphindetailsview.cpp dolphindetailsviewsettings.cpp dolphindirlister.cpp \ + dolphiniconsview.cpp dolphiniconsviewsettings.cpp dolphinsettings.cpp \ + dolphinsettingsbase.cpp dolphinsettingsdialog.cpp dolphinstatusbar.cpp dolphinview.cpp \ + editbookmarkdialog.cpp filterbar.cpp generalsettingspage.cpp iconsviewsettingspage.cpp \ + infosidebarpage.cpp itemeffectsmanager.cpp main.cpp pixmapviewer.cpp progressindicator.cpp \ + renamedialog.cpp settingspagebase.cpp sidebarpage.cpp sidebars.cpp sidebarssettings.cpp \ + statusbarmessagelabel.cpp statusbarspaceinfo.cpp undomanager.cpp urlbutton.cpp urlnavigator.cpp \ + urlnavigatorbutton.cpp viewproperties.cpp viewpropertiesdialog.cpp viewsettingspage.cpp + + +# these are the headers for your project +noinst_HEADERS = bookmarkselector.h bookmarkssettingspage.h \ + bookmarkssidebarpage.h detailsviewsettingspage.h dolphin.h dolphincontextmenu.h \ + dolphindetailsview.h dolphindetailsviewsettings.h dolphindirlister.h dolphiniconsview.h \ + dolphiniconsviewsettings.h dolphiniconsviewsettings.h iconsviewsettingspage.h dolphinsettings.h \ + dolphinsettingsbase.h dolphinsettingsdialog.h dolphinstatusbar.h dolphinview.h \ + editbookmarkdialog.h filterbar.h generalsettingspage.h iconsviewsettingspage.h \ + infosidebarpage.h itemeffectsmanager.h pixmapviewer.h renamedialog.h settingspagebase.h \ + sidebarpage.h sidebars.h statusbarmessagelabel.h statusbarspaceinfo.h undomanager.h \ + urlbutton.h urlnavigator.h urlnavigatorbutton.h viewproperties.h \ + viewpropertiesdialog.h viewsettingspage.h + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +messages: rc.cpp + $(EXTRACTRC) `find . -name \*.ui -o -name \*.rc` > rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/d3lphin.pot + + + +# this is where the kdelnk file will go +kdelnkdir = $(kde_appsdir)/System +xdg_apps_DATA = d3lphin.desktop + +# this is where the XML-GUI resource file goes +rcdir = $(kde_datadir)/d3lphin +rc_DATA = d3lphinui.rc + +KDE_ICON = AUTO +kde_icon_KDEICON = hi128-app-d3lphin.png hi16-app-d3lphin.png \ + hi22-app-d3lphin.png hi32-app-d3lphin.png hi48-app-d3lphin.png hi64-app-d3lphin.png diff --git a/src/README b/src/README new file mode 100644 index 0000000..f04a563 --- /dev/null +++ b/src/README @@ -0,0 +1,81 @@ +----------------------------------------------- +Kde application framework template quickstart +Author: Thomas Nagy +Date: 2004-03-22 +----------------------------------------------- + +This README file explains you basic things for starting with +this application template. + + +** Building and installing ** + +* Build the configure script by "make -f Makefile.cvs" + +* To clean, use "make clean", and to clean everything +(remove the makefiles, etc), use "make distclean" + +* To distribute your program, try "make dist". +This will make a compact tarball archive of your release with the +necessary scripts inside. + +* Modifying the auto-tools scripts +for automake scripts there is an excellent tutorial there : +http://developer.kde.org/documentation/other/makefile_am_howto.html + +* Simplify your life : install the project in your home directory for +testing purposes. +./configure --prefix=/home/user/dummyfolder/ +In the end when you finished the development you can +rm -rf /home/user/dummyfolder/ +without fear. + + +** Technologies ** + +* Build the menus of your application easily +kde applications now use an xml file (*ui.rc file) to build the menus. +This allow a great customization of the application. However, when +programming the menu is shown only after a "make install" + +For more details, consult : +http://devel-home.kde.org/~larrosa/tutorial/p9.html +http://developer.kde.org/documentation/tutorials/xmlui/preface.html + +* Use KConfig XT to create your configuration dialogs and make +them more maintainable. + +For more details, consult : +http://developer.kde.org/documentation/tutorials/kconfigxt/kconfigxt.html + +* With KParts, you can embed other kde components in your program, or make your program +embeddable in other apps. For example, the kmplayer kpart can be called to play videos +in your app. + +For more details, consult : +http://www-106.ibm.com/developerworks/library/l-kparts/ +http://developer.kde.org/documentation/tutorials/dot/writing-plugins.html +http://developer.kde.org/documentation/tutorials/developing-a-plugin-structure/index.html + +* With dcop, you can control your app from other applications +Make sure to include K_DCOP and a kdcop: section in your .h file +http://developer.kde.org/documentation/tutorials/dot/dcopiface/dcop-interface.html + + +** Documentation ** + +* For the translations : +1. Download a patched gettext which can be found at: + http://public.kde.planetmirror.com/pub/kde/devel/gettext-kde/ +2. Install that gettext in ~/bin/ +3. cd ~/yourproject, export PATH=~/bin:$PATH, export +KDEDIR=/where_your_KDE3_is +4. make -f admin/Makefile.common package-messages +5. make package-messages +6. Translate the po files (not the pot!!) with kbabel or xemacs + +* Do not forget to write the documentation for your kde app +edit the documentation template index.docbook in doc/ + + + diff --git a/src/bookmarkselector.cpp b/src/bookmarkselector.cpp new file mode 100644 index 0000000..9a0c3cd --- /dev/null +++ b/src/bookmarkselector.cpp @@ -0,0 +1,183 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + + +#include <assert.h> +#include <qpopupmenu.h> +#include <qpainter.h> +#include <qpixmap.h> + +#include <kiconloader.h> +#include <kglobalsettings.h> +#include <kbookmarkmanager.h> + +#include "bookmarkselector.h" +#include "dolphinsettings.h" +#include "dolphinview.h" +#include "dolphin.h" +#include "urlnavigator.h" + +BookmarkSelector::BookmarkSelector(URLNavigator* parent) : + URLButton(parent), + m_selectedIndex(0) +{ + setFocusPolicy(QWidget::NoFocus); + + m_bookmarksMenu = new QPopupMenu(this); + + KBookmarkManager* manager = DolphinSettings::instance().bookmarkManager(); + connect(manager, SIGNAL(changed(const QString&, const QString&)), + this, SLOT(updateBookmarks())); + + updateBookmarks(); + + connect(m_bookmarksMenu, SIGNAL(activated(int)), + this, SLOT(slotBookmarkActivated(int))); + + setPopup(m_bookmarksMenu); +} + +BookmarkSelector::~BookmarkSelector() +{ +} + +void BookmarkSelector::updateBookmarks() +{ + m_bookmarksMenu->clear(); + + KBookmarkGroup root = DolphinSettings::instance().bookmarkManager()->root(); + KBookmark bookmark = root.first(); + int i = 0; + while (!bookmark.isNull()) { + m_bookmarksMenu->insertItem(MainBarIcon(bookmark.icon()), + bookmark.text(), + i); + if (i == m_selectedIndex) { + QPixmap pixmap = SmallIcon(bookmark.icon()); + setPixmap(pixmap); + setMinimumWidth(pixmap.width() + 2); + } + bookmark = root.next(bookmark); + ++i; + } + +} + +void BookmarkSelector::updateSelection(const KURL& url) +{ + KBookmarkGroup root = DolphinSettings::instance().bookmarkManager()->root(); + KBookmark bookmark = root.first(); + + int maxLength = 0; + m_selectedIndex = -1; + + // Search the bookmark which is equal to the URL or at least is a parent URL. + // If there are more than one possible parent URL candidates, choose the bookmark + // which covers the bigger range of the URL. + int i = 0; + while (!bookmark.isNull()) { + const KURL bookmarkURL = bookmark.url(); + if (bookmarkURL.isParentOf(url)) { + const int length = bookmarkURL.prettyURL().length(); + if (length > maxLength) { + m_selectedIndex = i; + setPixmap(SmallIcon(bookmark.icon())); + maxLength = length; + } + } + bookmark = root.next(bookmark); + ++i; + } + + if (m_selectedIndex < 0) { + // No bookmark has been found which matches to the given URL. Show + // a generic folder icon as pixmap for indication: + setPixmap(SmallIcon("folder")); + } +} + +KBookmark BookmarkSelector::selectedBookmark() const +{ + return DolphinSettings::instance().bookmark(m_selectedIndex); +} + +void BookmarkSelector::drawButton(QPainter* painter) +{ + const int buttonWidth = width(); + const int buttonHeight = height(); + + QColor backgroundColor; + QColor foregroundColor; + const bool isHighlighted = isDisplayHintEnabled(EnteredHint) || + isDisplayHintEnabled(DraggedHint); + if (isHighlighted) { + backgroundColor = KGlobalSettings::highlightColor(); + foregroundColor = KGlobalSettings::highlightedTextColor(); + } + else { + backgroundColor = colorGroup().background(); + foregroundColor = KGlobalSettings::buttonTextColor(); + } + + // dimm the colors if the parent view does not have the focus + const DolphinView* parentView = urlNavigator()->dolphinView(); + const Dolphin& dolphin = Dolphin::mainWin(); + + const bool isActive = (dolphin.activeView() == parentView); + if (!isActive) { + QColor dimmColor(colorGroup().background()); + foregroundColor = mixColors(foregroundColor, dimmColor); + if (isHighlighted) { + backgroundColor = mixColors(backgroundColor, dimmColor); + } + } + + if (!(isDisplayHintEnabled(ActivatedHint) && isActive) && !isHighlighted) { + // dimm the foreground color by mixing it with the background + foregroundColor = mixColors(foregroundColor, backgroundColor); + painter->setPen(foregroundColor); + } + + // draw button backround + painter->setPen(NoPen); + painter->setBrush(backgroundColor); + painter->drawRect(0, 0, buttonWidth, buttonHeight); + + // draw icon + const QPixmap* icon = pixmap(); + if (icon != 0) { + const int x = (buttonWidth - icon->width()) / 2; + const int y = (buttonHeight - icon->height()) / 2; + painter->drawPixmap(x, y, *icon); + } +} + +void BookmarkSelector::slotBookmarkActivated(int index) +{ + m_selectedIndex = index; + + KBookmark bookmark = selectedBookmark(); + setPixmap(SmallIcon(bookmark.icon())); + + emit bookmarkActivated(index); +} + +#include "bookmarkselector.moc" + diff --git a/src/bookmarkselector.h b/src/bookmarkselector.h new file mode 100644 index 0000000..9bede96 --- /dev/null +++ b/src/bookmarkselector.h @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef BOOKMARKSELECTOR_H +#define BOOKMARKSELECTOR_H + +#include <kbookmark.h> +#include <urlbutton.h> + +class URLNavigator; +class QPopupMenu; +class KURL; + +/** + * @brief Allows to select a bookmark from a popup menu. + * + * The icon from the current selected bookmark is shown + * inside the bookmark selector. + * + * @see URLNavigator + * @author Peter Penz <peter.penz@gmx.at> + */ +class BookmarkSelector : public URLButton +{ + Q_OBJECT + +public: + /** + * @param parent Parent widget where the bookmark selector + * is embedded into. + */ + BookmarkSelector(URLNavigator* parent); + + virtual ~BookmarkSelector(); + + /** + * Updates the selection dependent from the given URL \a url. The + * URL must not match exactly to one of the available bookmarks: + * The bookmark which is equal to the URL or at least is a parent URL + * is selected. If there are more than one possible parent URL candidates, + * the bookmark which covers the bigger range of the URL is selected. + */ + void updateSelection(const KURL& url); + + /** + * Returns the index of the selected bookmark. To get + * the bookmark, use BookmarkSelector::selectedBookmark(). + */ + int selectedIndex() const { return m_selectedIndex; } + + /** Returns the selected bookmark. */ + KBookmark selectedBookmark() const; + +signals: + /** + * Is send when a bookmark has been activated by the user. + * @param index Index of the selected bookmark. + */ + void bookmarkActivated(int index); + +protected: + /** + * Draws the icon of the selected URL as content of the URL + * selector. + */ + virtual void drawButton(QPainter* painter); + +private slots: + /** + * Updates the selected index and the icon if a bookmark + * has been activated by the user. + */ + void slotBookmarkActivated(int index); + void updateBookmarks(); + +private: + int m_selectedIndex; + QPopupMenu* m_bookmarksMenu; +}; + +#endif diff --git a/src/bookmarkssettingspage.cpp b/src/bookmarkssettingspage.cpp new file mode 100644 index 0000000..5b615f8 --- /dev/null +++ b/src/bookmarkssettingspage.cpp @@ -0,0 +1,314 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "bookmarkssettingspage.h" + +#include <assert.h> + +#include <qlayout.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qvbox.h> + +#include <kbookmark.h> +#include <kbookmarkmanager.h> +#include <kdialog.h> +#include <klistview.h> +#include <klocale.h> +#include <kpushbutton.h> + +#include "dolphinsettings.h" +#include "editbookmarkdialog.h" + +BookmarksSettingsPage::BookmarksSettingsPage(QWidget*parent) : + SettingsPageBase(parent), + m_addButton(0), + m_removeButton(0), + m_moveUpButton(0), + m_moveDownButton(0) +{ + QVBoxLayout* topLayout = new QVBoxLayout(parent, 2, KDialog::spacingHint()); + + const int spacing = KDialog::spacingHint(); + + QHBox* hBox = new QHBox(parent); + hBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + hBox->setSpacing(spacing); + hBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored); + + m_listView = new KListView(hBox); + m_listView->addColumn(i18n("Icon")); + m_listView->addColumn(i18n("Name")); + m_listView->addColumn(i18n("Location")); + m_listView->setResizeMode(QListView::LastColumn); + m_listView->setColumnAlignment(0, Qt::AlignHCenter); + m_listView->setAllColumnsShowFocus(true); + m_listView->setSorting(-1); + connect(m_listView, SIGNAL(selectionChanged()), + this, SLOT(updateButtons())); + connect(m_listView, SIGNAL(pressed(QListViewItem*)), + this, SLOT(slotBookmarkPressed(QListViewItem*))); + connect(m_listView, SIGNAL(doubleClicked(QListViewItem*, const QPoint&, int)), + this, SLOT(slotBookmarkDoubleClicked(QListViewItem*, const QPoint&, int))); + + QVBox* buttonBox = new QVBox(hBox); + buttonBox->setSpacing(spacing); + + const QSizePolicy buttonSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); + + m_addButton = new KPushButton(i18n("Add..."), buttonBox); + connect(m_addButton, SIGNAL(clicked()), + this, SLOT(slotAddButtonClicked())); + m_addButton->setSizePolicy(buttonSizePolicy); + + m_editButton = new KPushButton(i18n("Edit..."), buttonBox); + connect(m_editButton, SIGNAL(clicked()), + this, SLOT(slotEditButtonClicked())); + m_editButton->setSizePolicy(buttonSizePolicy); + + m_removeButton = new KPushButton(i18n("Remove"), buttonBox); + connect(m_removeButton, SIGNAL(clicked()), + this, SLOT(slotRemoveButtonClicked())); + m_removeButton->setSizePolicy(buttonSizePolicy); + + m_moveUpButton = new KPushButton(i18n("Move Up"), buttonBox); + connect(m_moveUpButton, SIGNAL(clicked()), + this, SLOT(slotMoveUpButtonClicked())); + m_moveUpButton->setSizePolicy(buttonSizePolicy); + + m_moveDownButton = new KPushButton(i18n("Move Down"), buttonBox); + connect(m_moveDownButton, SIGNAL(clicked()), + this, SLOT(slotMoveDownButtonClicked())); + m_moveDownButton->setSizePolicy(buttonSizePolicy); + + // Add a dummy widget with no restriction regarding a vertical resizing. + // This assures that the spacing between the buttons is not increased. + new QWidget(buttonBox); + + topLayout->addWidget(hBox); + + // insert all editable bookmarks. + KBookmarkGroup root = DolphinSettings::instance().bookmarkManager()->root(); + KBookmark bookmark = root.first(); + + QListViewItem* prev = 0; + while (!bookmark.isNull()) { + QListViewItem* item = new QListViewItem(m_listView); + item->setPixmap(PixmapIdx, SmallIcon(bookmark.icon())); + item->setText(NameIdx, bookmark.text()); + item->setText(URLIdx, bookmark.url().prettyURL()); + + // add hidden column to be able to retrieve the icon name again + item->setText(IconIdx, bookmark.icon()); + + m_listView->insertItem(item); + if (prev != 0) { + item->moveItem(prev); + } + prev = item; + + bookmark = root.next(bookmark); + } + m_listView->setSelected(m_listView->firstChild(), true); + + updateButtons(); +} + + +BookmarksSettingsPage::~BookmarksSettingsPage() +{ +} + +void BookmarksSettingsPage::applySettings() +{ + // delete all bookmarks + KBookmarkManager* manager = DolphinSettings::instance().bookmarkManager(); + KBookmarkGroup root = manager->root(); + KBookmark bookmark = root.first(); + while (!bookmark.isNull()) { + root.deleteBookmark(bookmark); + bookmark = root.first(); + } + + // add all items as bookmarks + QListViewItem* item = m_listView->firstChild(); + while (item != 0) { + root.addBookmark(manager, + item->text(NameIdx), + KURL(item->text(URLIdx)), + item->text(IconIdx)); // hidden column + item = item->itemBelow(); + } + + manager->emitChanged(root); +} + +void BookmarksSettingsPage::updateButtons() +{ + const QListViewItem* selectedItem = m_listView->selectedItem(); + const bool hasSelection = (selectedItem != 0); + + m_editButton->setEnabled(hasSelection); + m_removeButton->setEnabled(hasSelection); + + const bool enableMoveUp = hasSelection && + (selectedItem != m_listView->firstChild()); + m_moveUpButton->setEnabled(enableMoveUp); + + const bool enableMoveDown = hasSelection && + (selectedItem != m_listView->lastChild()); + m_moveDownButton->setEnabled(enableMoveDown); +} + +void BookmarksSettingsPage::slotBookmarkDoubleClicked(QListViewItem*, + const QPoint&, + int) +{ + slotEditButtonClicked(); +} + +void BookmarksSettingsPage::slotBookmarkPressed(QListViewItem* item) +{ + if (item == 0) { + m_listView->setSelected(m_listView->currentItem(), true); + } +} + +void BookmarksSettingsPage::slotAddButtonClicked() +{ + KBookmark bookmark = EditBookmarkDialog::getBookmark(i18n("Add Bookmark"), + i18n("New bookmark"), + KURL(), + "bookmark"); + if (!bookmark.isNull()) { + // insert bookmark into listview + QListViewItem* item = new QListViewItem(m_listView); + item->setPixmap(PixmapIdx, SmallIcon(bookmark.icon())); + item->setText(NameIdx, bookmark.text()); + item->setText(URLIdx, bookmark.url().prettyURL()); + item->setText(IconIdx, bookmark.icon()); + m_listView->insertItem(item); + + QListViewItem* lastItem = m_listView->lastChild(); + if (lastItem != 0) { + item->moveItem(lastItem); + } + + m_listView->setSelected(item, true); + updateButtons(); + } +} + +void BookmarksSettingsPage::slotEditButtonClicked() +{ + QListViewItem* item = m_listView->selectedItem(); + assert(item != 0); // 'edit' may not get invoked when having no items + + KBookmark bookmark = EditBookmarkDialog::getBookmark(i18n("Edit Bookmark"), + item->text(NameIdx), + KURL(item->text(URLIdx)), + item->text(IconIdx)); + if (!bookmark.isNull()) { + item->setPixmap(PixmapIdx, SmallIcon(bookmark.icon())); + item->setText(NameIdx, bookmark.text()); + item->setText(URLIdx, bookmark.url().prettyURL()); + item->setText(IconIdx, bookmark.icon()); + } +} + +void BookmarksSettingsPage::slotRemoveButtonClicked() +{ + QListViewItem* selectedItem = m_listView->selectedItem(); + assert(selectedItem != 0); + QListViewItem* nextItem = selectedItem->itemBelow(); + if (nextItem == 0) { + nextItem = selectedItem->itemAbove(); + } + + m_listView->takeItem(selectedItem); + if (nextItem != 0) { + m_listView->setSelected(nextItem, true); + } +} + +void BookmarksSettingsPage::slotMoveUpButtonClicked() +{ + moveBookmark(-1); +} + +void BookmarksSettingsPage::slotMoveDownButtonClicked() +{ + moveBookmark(+1); +} + +int BookmarksSettingsPage::selectedBookmarkIndex() const +{ + int index = -1; + + QListViewItem* selectedItem = m_listView->selectedItem(); + if (selectedItem != 0) { + index = 0; + QListViewItem* item = m_listView->firstChild(); + while (item != selectedItem) { + item = item->nextSibling(); + ++index; + } + } + + return index; +} + +void BookmarksSettingsPage::moveBookmark(int direction) +{ + // this implementation currently only allows moving of bookmarks + // one step up or down + assert((direction >= -1) && (direction <= +1)); + + // swap bookmarks in listview + QListViewItem* selectedItem = m_listView->selectedItem(); + assert(selectedItem != 0); + QListViewItem* item = (direction < 0) ? selectedItem->itemAbove() : + selectedItem->itemBelow(); + assert(item != 0); + + QPixmap pixmap; + if (item->pixmap(0) != 0) { + pixmap = *(item->pixmap(0)); + } + QString name(item->text(NameIdx)); + QString url(item->text(URLIdx)); + QString icon(item->text(IconIdx)); + + if (selectedItem->pixmap(0) != 0) { + item->setPixmap(PixmapIdx, *(selectedItem->pixmap(0))); + } + item->setText(NameIdx, selectedItem->text(NameIdx)); + item->setText(URLIdx, selectedItem->text(URLIdx)); + item->setText(IconIdx, selectedItem->text(IconIdx)); + + selectedItem->setPixmap(PixmapIdx, pixmap); + selectedItem->setText(NameIdx, name); + selectedItem->setText(URLIdx, url); + selectedItem->setText(IconIdx, icon); + + m_listView->setSelected(item, true); +} + +#include "bookmarkssettingspage.moc" diff --git a/src/bookmarkssettingspage.h b/src/bookmarkssettingspage.h new file mode 100644 index 0000000..89f3752 --- /dev/null +++ b/src/bookmarkssettingspage.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef BOOKMARKSSETTINGSPAGE_H +#define BOOKMARKSSETTINGSPAGE_H + +#include <settingspagebase.h> +#include <qvaluelist.h> + +class KListView; +class KPushButton; +class QListViewItem; + +/** + * @brief Represents the page from the Dolphin Settings which allows + * to modify the bookmarks. + */ +class BookmarksSettingsPage : public SettingsPageBase +{ + Q_OBJECT + +public: + BookmarksSettingsPage(QWidget* parent); + + virtual ~BookmarksSettingsPage(); + + /** @see SettingsPageBase::applySettings */ + virtual void applySettings(); + +private slots: + void updateButtons(); + void slotBookmarkDoubleClicked(QListViewItem*, const QPoint&, int); + void slotAddButtonClicked(); + void slotEditButtonClicked(); + void slotRemoveButtonClicked(); + void slotMoveUpButtonClicked(); + void slotMoveDownButtonClicked(); + + /** + * Is connected with the signal QListView::pressed(QListViewItem* item) + * and assures that always one bookmarks stays selected although a + * click has been done on the viewport area. + * TODO: this is a workaround, possibly there is a more easy approach + * doing this... + */ + void slotBookmarkPressed(QListViewItem* item); + +private: + enum ColumnIndex { + PixmapIdx = 0, + NameIdx = 1, + URLIdx = 2, + IconIdx = 3 + }; + + KListView* m_listView; + KPushButton* m_addButton; + KPushButton* m_editButton; + KPushButton* m_removeButton; + KPushButton* m_moveUpButton; + KPushButton* m_moveDownButton; + + /** + * Returns the index of the selected bookmark + * inside the bookmarks listview. + */ + int selectedBookmarkIndex() const; + + /** + * Moves the currently selected bookmark up, if 'direction' + * is < 0, otherwise the bookmark is moved down. + */ + void moveBookmark(int direction); +}; + +#endif diff --git a/src/bookmarkssidebarpage.cpp b/src/bookmarkssidebarpage.cpp new file mode 100644 index 0000000..34eef5c --- /dev/null +++ b/src/bookmarkssidebarpage.cpp @@ -0,0 +1,331 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "bookmarkssidebarpage.h" + +#include <qlistbox.h> +#include <qlayout.h> +#include <qpainter.h> +#include <assert.h> +#include <qpopupmenu.h> + +#include <kbookmarkmanager.h> +#include <kmessagebox.h> +#include <klocale.h> +#include <kurldrag.h> + +#include "dolphinsettings.h" +#include "dolphin.h" +#include "dolphinview.h" +#include "editbookmarkdialog.h" + +BookmarksSidebarPage::BookmarksSidebarPage(QWidget* parent) : + SidebarPage(parent) +{ + QVBoxLayout* layout = new QVBoxLayout(this); + m_bookmarksList = new BookmarksListBox(this); + m_bookmarksList->setPaletteBackgroundColor(colorGroup().background()); + + layout->addWidget(m_bookmarksList); + connect(m_bookmarksList, SIGNAL(mouseButtonClicked(int, QListBoxItem*, const QPoint&)), + this, SLOT(slotMouseButtonClicked(int, QListBoxItem*))); + connect(m_bookmarksList, SIGNAL(contextMenuRequested(QListBoxItem*, const QPoint&)), + this, SLOT(slotContextMenuRequested(QListBoxItem*, const QPoint&))); + + KBookmarkManager* manager = DolphinSettings::instance().bookmarkManager(); + connect(manager, SIGNAL(changed(const QString&, const QString&)), + this, SLOT(updateBookmarks())); + + updateBookmarks(); +} + +BookmarksSidebarPage::~BookmarksSidebarPage() +{ +} + +void BookmarksSidebarPage::activeViewChanged() +{ + connectToActiveView(); +} + +void BookmarksSidebarPage::updateBookmarks() +{ + m_bookmarksList->clear(); + + KIconLoader iconLoader; + + KBookmarkGroup root = DolphinSettings::instance().bookmarkManager()->root(); + KBookmark bookmark = root.first(); + while (!bookmark.isNull()) { + m_bookmarksList->insertItem( BookmarkItem::fromKbookmark(bookmark, iconLoader) ); + + bookmark = root.next(bookmark); + } + + connectToActiveView(); +} + +void BookmarksSidebarPage::slotMouseButtonClicked(int button, QListBoxItem* item) +{ + if ((button != Qt::LeftButton) || (item == 0)) { + return; + } + + const int index = m_bookmarksList->index(item); + KBookmark bookmark = DolphinSettings::instance().bookmark(index); + Dolphin::mainWin().activeView()->setURL(bookmark.url()); +} + +void BookmarksSidebarPage::slotContextMenuRequested(QListBoxItem* item, + const QPoint& pos) +{ + const int insertID = 1; + const int editID = 2; + const int deleteID = 3; + const int addID = 4; + + QPopupMenu* popup = new QPopupMenu(); + if (item == 0) { + popup->insertItem(SmallIcon("filenew"), i18n("Add Bookmark..."), addID); + } + else { + popup->insertItem(SmallIcon("filenew"), i18n("Insert Bookmark..."), insertID); + popup->insertItem(SmallIcon("edit"), i18n("Edit..."), editID); + popup->insertItem(SmallIcon("editdelete"), i18n("Delete"), deleteID); + } + + KBookmarkManager* manager = DolphinSettings::instance().bookmarkManager(); + KBookmarkGroup root = manager->root(); + const int index = m_bookmarksList->index(m_bookmarksList->selectedItem()); + + const int result = popup->exec(pos); + switch (result) { + case insertID: { + KBookmark newBookmark = EditBookmarkDialog::getBookmark(i18n("Insert Bookmark"), + i18n("New bookmark"), + KURL(), + "bookmark"); + if (!newBookmark.isNull()) { + root.addBookmark(manager, newBookmark); + if (index > 0) { + KBookmark prevBookmark = DolphinSettings::instance().bookmark(index - 1); + root.moveItem(newBookmark, prevBookmark); + } + else { + // insert bookmark at first position (is a little bit tricky as KBookmarkGroup + // only allows to move items after existing items) + KBookmark firstBookmark = root.first(); + root.moveItem(newBookmark, firstBookmark); + root.moveItem(firstBookmark, newBookmark); + } + manager->emitChanged(root); + } + break; + } + + case editID: { + KBookmark oldBookmark = DolphinSettings::instance().bookmark(index); + KBookmark newBookmark = EditBookmarkDialog::getBookmark(i18n("Edit Bookmark"), + oldBookmark.text(), + oldBookmark.url(), + oldBookmark.icon()); + if (!newBookmark.isNull()) { + root.addBookmark(manager, newBookmark); + root.moveItem(newBookmark, oldBookmark); + root.deleteBookmark(oldBookmark); + manager->emitChanged(root); + } + break; + } + + case deleteID: { + KBookmark bookmark = DolphinSettings::instance().bookmark(index); + root.deleteBookmark(bookmark); + manager->emitChanged(root); + break; + } + + case addID: { + KBookmark bookmark = EditBookmarkDialog::getBookmark(i18n("Add Bookmark"), + "New bookmark", + KURL(), + "bookmark"); + if (!bookmark.isNull()) { + root.addBookmark(manager, bookmark); + manager->emitChanged(root); + } + } + + default: break; + } + + delete popup; + popup = 0; + + DolphinView* view = Dolphin::mainWin().activeView(); + adjustSelection(view->url()); +} + + +void BookmarksSidebarPage::adjustSelection(const KURL& url) +{ + // TODO (remarked in dolphin/TODO): the following code is quite equal + // to BookmarkSelector::updateSelection(). + + KBookmarkGroup root = DolphinSettings::instance().bookmarkManager()->root(); + KBookmark bookmark = root.first(); + + int maxLength = 0; + int selectedIndex = -1; + + // Search the bookmark which is equal to the URL or at least is a parent URL. + // If there are more than one possible parent URL candidates, choose the bookmark + // which covers the bigger range of the URL. + int i = 0; + while (!bookmark.isNull()) { + const KURL bookmarkURL = bookmark.url(); + if (bookmarkURL.isParentOf(url)) { + const int length = bookmarkURL.prettyURL().length(); + if (length > maxLength) { + selectedIndex = i; + maxLength = length; + } + } + bookmark = root.next(bookmark); + ++i; + } + + const bool block = m_bookmarksList->signalsBlocked(); + m_bookmarksList->blockSignals(true); + if (selectedIndex < 0) { + // no bookmark matches, hence deactivate any selection + const int currentIndex = m_bookmarksList->index(m_bookmarksList->selectedItem()); + m_bookmarksList->setSelected(currentIndex, false); + } + else { + // select the bookmark which is part of the current URL + m_bookmarksList->setSelected(selectedIndex, true); + } + m_bookmarksList->blockSignals(block); +} + +void BookmarksSidebarPage::slotURLChanged(const KURL& url) +{ + adjustSelection(url); +} + +void BookmarksSidebarPage::connectToActiveView() +{ + DolphinView* view = Dolphin::mainWin().activeView(); + adjustSelection(view->url()); + connect(view, SIGNAL(signalURLChanged(const KURL&)), + this, SLOT(slotURLChanged(const KURL&))); +} + +BookmarksListBox::BookmarksListBox(QWidget* parent) : + QListBox(parent) +{ + setAcceptDrops(true); +} +BookmarksListBox::~BookmarksListBox() +{ +} + +void BookmarksListBox::paintEvent(QPaintEvent* /* event */) +{ + // don't invoke QListBox::paintEvent(event) to prevent + // that any kind of frame is drawn +} + +void BookmarksListBox::contentsMousePressEvent(QMouseEvent *event) +{ + if (event->button() == LeftButton) + dragPos = event->pos(); + QListBox::contentsMousePressEvent(event); +} + +void BookmarksListBox::contentsMouseMoveEvent(QMouseEvent *event) +{ + if (event->state() & LeftButton) { + int distance = (event->pos() - dragPos).manhattanLength(); + if (distance > QApplication::startDragDistance()) + startDrag(); + } + QListBox::contentsMouseMoveEvent(event); +} + +void BookmarksListBox::startDrag() +{ + int currentItem = QListBox::currentItem(); + if (currentItem != -1) { + BookmarkItem* bookmark = (BookmarkItem*)item(currentItem); + if (bookmark!=0){ + KURL::List lst; + lst.append( bookmark->url() ); + KURLDrag *drag = new KURLDrag(lst, this); + drag->drag(); + } + } +} + +void BookmarksListBox::dragEnterEvent( QDragEnterEvent *event ) +{ + event->accept(KURLDrag::canDecode(event)); +} + +void BookmarksListBox::dropEvent( QDropEvent *event ) +{ + KURL::List urls; + if (KURLDrag::decode(event, urls) && !urls.isEmpty()) { + KBookmarkManager* manager = DolphinSettings::instance().bookmarkManager(); + KBookmarkGroup root = manager->root(); + + KURL::List::iterator it; + for(it=urls.begin(); it!=urls.end(); ++it) { + root.addBookmark(manager, (*it).fileName(), (*it), "", false); + } + manager->emitChanged(root); + } +} + +BookmarkItem::BookmarkItem(const QPixmap& pixmap, const QString& text, const KURL& url) : + QListBoxPixmap(pixmap, text), + m_url(url) +{ +} + +BookmarkItem::~BookmarkItem() +{ +} + +int BookmarkItem::height(const QListBox* listBox) const +{ + return QListBoxPixmap::height(listBox) + 8; +} + +const KURL& BookmarkItem::url() const +{ + return m_url; +} + +BookmarkItem* BookmarkItem::fromKbookmark(const KBookmark& bookmark, const KIconLoader& iconLoader) +{ + QPixmap icon(iconLoader.loadIcon(bookmark.icon(), KIcon::NoGroup, KIcon::SizeMedium)); + return new BookmarkItem(icon, bookmark.text(), bookmark.url()); +} diff --git a/src/bookmarkssidebarpage.h b/src/bookmarkssidebarpage.h new file mode 100644 index 0000000..7941fd6 --- /dev/null +++ b/src/bookmarkssidebarpage.h @@ -0,0 +1,139 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef _BOOKMARKSSIDEBARPAGE_H_ +#define _BOOKMARKSSIDEBARPAGE_H_ + +#include <sidebarpage.h> +#include <qlistbox.h> +#include <kurl.h> +#include <kbookmark.h> +#include <kiconloader.h> + +class BookmarksListBox; + +/** + * @brief Sidebar page for accessing bookmarks. + * + * It is possible to add, remove and edit bookmarks + * by a context menu. The selection of the bookmark + * is automatically adjusted to the URL given by + * the active view. + */ +class BookmarksSidebarPage : public SidebarPage +{ + Q_OBJECT + +public: + BookmarksSidebarPage(QWidget* parent); + virtual ~BookmarksSidebarPage(); + +protected: + /** @see SidebarPage::activeViewChanged() */ + virtual void activeViewChanged(); + +private slots: + /** Fills the listbox with the bookmarks stored in DolphinSettings. */ + void updateBookmarks(); + + /** + * Checks whether the left mouse button has been clicked above a bookmark. + * If this is the case, the URL for the currently active view is adjusted. + */ + void slotMouseButtonClicked(int button, QListBoxItem* item); + + /** @see QListBox::slotContextMenuRequested */ + void slotContextMenuRequested(QListBoxItem* item, const QPoint& pos); + + /** + * Is invoked whenever the URL of the active view has been changed. Adjusts + * the selection of the listbox to the bookmark which is part of the current URL. + */ + void slotURLChanged(const KURL& url); + +private: + /** + * Updates the selection dependent from the given URL \a url. The + * URL must not match exactly to one of the available bookmarks: + * The bookmark which is equal to the URL or at least is a parent URL + * is selected. If there are more than one possible parent URL candidates, + * the bookmark which covers the bigger range of the URL is selected. + */ + void adjustSelection(const KURL& url); + + /** + * Connects to signals from the currently active Dolphin view to get + * informed about URL and bookmark changes. + */ + void connectToActiveView(); + + BookmarksListBox* m_bookmarksList; +}; + +/** + * @brief Listbox which contains a list of bookmarks. + * + * Only QListBox::paintEvent() has been overwritten to prevent + * that a (not wanted) frameborder is drawn. + */ +class BookmarksListBox : public QListBox +{ + Q_OBJECT + +public: + BookmarksListBox(QWidget* parent); + virtual ~BookmarksListBox(); + +protected: + //drag + void contentsMousePressEvent(QMouseEvent *event); + void contentsMouseMoveEvent(QMouseEvent *event); + //drop + void dragEnterEvent( QDragEnterEvent *evt ); + void dropEvent( QDropEvent *evt ); +// void mousePressEvent( QMouseEvent *evt ); +// void mouseMoveEvent( QMouseEvent * ); + /** @see QWidget::paintEvent() */ + virtual void paintEvent(QPaintEvent* event); +private: + QPoint dragPos; + + void startDrag(); +}; + +/** + * @brief Item which can be added to a BookmarksListBox. + * + * Only QListBoxPixmap::height() has been overwritten to get + * a spacing between the items. + */ +class BookmarkItem : public QListBoxPixmap +{ +public: + BookmarkItem(const QPixmap& pixmap, const QString& text, const KURL& url); + virtual ~BookmarkItem(); + virtual int height(const QListBox* listBox) const; + const KURL& url() const; + + static BookmarkItem* fromKbookmark(const KBookmark& bookmark, const KIconLoader& iconLoader); + +private: + KURL m_url; +}; + +#endif // _BOOKMARKSSIDEBARPAGE_H_ diff --git a/src/d3lphin.desktop b/src/d3lphin.desktop new file mode 100644 index 0000000..9eae8ad --- /dev/null +++ b/src/d3lphin.desktop @@ -0,0 +1,65 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Dolphin +Name[pa]=ਡਾਲਫਿਨ +Name[sr]=Делфин +Name[sr@latin]=Делфин +Name[uk]=Дельфін +Name[ar]=الدولفين +Name[lv]= Dolphin +Name[ne]=डल्फिन +Name[pa]=ਡਾਲਫਿਨ +Exec=d3lphin %i -caption "%c" "%u" +Icon=d3lphin +Type=Application +DocPath=d3lphin/d3lphin.html +Categories=Qt;KDE;System;FileManager; +GenericName=File Manager +GenericName[ar]=مدير الملفات +GenericName[be]=Кіраўнік файлаў +GenericName[bg]=Файлов браузър +GenericName[ca]=Gestor de fitxers +GenericName[cs]=Správce souborů +GenericName[csb]=Menadżer lopków +GenericName[de]=Dateimanager +GenericName[el]=Διαχειριστής αρχείων +GenericName[eo]=Dosieradministrilo +GenericName[es]=Gestor de ficheros +GenericName[et]=Failihaldur +GenericName[eu]=Fitxategi kudeatzailea +GenericName[fa]=مدیر پرونده +GenericName[ga]=Bainisteoir Comhad +GenericName[he]=מנהל קבצים +GenericName[hu]=Fájlkezelő +GenericName[it]=Gestione file +GenericName[ja]=ファイルマネージャ +GenericName[kk]=Файл менеджері +GenericName[km]=កម្មវិធីគ្រប់គ្រងឯកសារ +GenericName[ko]=파일 관리자 +GenericName[lv]=Failu pārvaldnieks +GenericName[nb]=Filbehandler +GenericName[nds]=Dateipleger +GenericName[ne]=फाइल प्रबन्धक +GenericName[nl]=Bestandsbeheerder +GenericName[nn]=Filhandsamar +GenericName[oc]=Gestionari de fichièrs +GenericName[pa]=ਫਾਇਲ ਮੈਨੇਜਰ +GenericName[pl]=Menedżer plików +GenericName[pt]=Gestor de Ficheiros +GenericName[pt_BR]=Gerenciador de Arquivos +GenericName[ru]=Файловый менеджер +GenericName[sl]=Upravitelj datotek +GenericName[sr]=Менаџер фајлова +GenericName[sr@latin]=Menadžer fajlova +GenericName[sv]=Filhanterare +GenericName[tg]=Мудири файл +GenericName[th]=เครื่องมือจัดการแฟ้ม +GenericName[uk]=Менеджер файлів +GenericName[vi]=Bộ quản lý tập tin +GenericName[wa]=Manaedjeu di fitchîs +GenericName[x-test]=xxFile Managerxx +GenericName[zh_CN]=文件管理器 +GenericName[zh_TW]=檔案管理程式 +Terminal=false +MimeType=inode/directory; +InitialPreference=10 diff --git a/src/d3lphinui.rc b/src/d3lphinui.rc new file mode 100644 index 0000000..9280645 --- /dev/null +++ b/src/d3lphinui.rc @@ -0,0 +1,110 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui version="1" name="d3lphin" > + <MenuBar> + <Menu name="file" > + <Menu name="create_new" > + <text>Create New</text> + <Action name="create_folder" /> + <Separator/> + <ActionList name="create_file_group" /> + </Menu> + <Separator/> + <Action name="rename" /> + <Action name="move_to_trash" /> + <Action name="delete" /> + <Separator/> + <Action name="properties" /> + </Menu> + <Menu name="edit" > + <Action name="select_all" /> + <Action name="invert_selection" /> + </Menu> + <Menu name="view" > + <Menu name="view_mode" > + <text>View Mode</text> + <Action name="icons" /> + <Action name="details" /> + <Action name="previews" /> + </Menu> + <Menu name="sort" > + <text>Sort</text> + <Action name="by_name" /> + <Action name="by_size" /> + <Action name="by_date" /> + <Separator/> + <Action name="descending" /> + </Menu> + <Action name="show_hidden_files" /> + <Separator/> + <Action name="split_view" /> + <Action name="reload" /> + <Action name="stop" /> + <Separator/> + <Menu name="navigation_bar" > + <text>Navigation Bar</text> + <Action name="edit_location" /> + <Action name="browse" /> + </Menu> + <Action name="leftsidebar" /> + <Action name="rightsidebar" /> + <Action name="view_properties" /> + </Menu> + <Menu name="tools"> + <Action name="open_terminal" /> + <Action name="find_file" /> + <Action name="show_filter_bar" /> + <Action name="compare_files" /> + </Menu> +</MenuBar> +<State name="new_file" > + <disable> + <Action name="edit_undo" /> + <Action name="edit_redo" /> + <Action name="edit_cut" /> + <Action name="edit_copy" /> + <Action name="rename" /> + <Action name="move_to_trash" /> + <Action name="delete" /> + <Action name="invert_selection" /> + <Separator/> + <Action name="properties" /> + <Action name="go_back" /> + <Action name="go_forward" /> + </disable> + </State> + <State name="has_selection" > + <enable> + <Action name="edit_cut" /> + <Action name="edit_copy" /> + <Action name="move_to_trash" /> + <Action name="delete" /> + <Action name="properties" /> + <Action name="invert_selection" /> + </enable> + </State> + <State name="has_no_selection" > + <disable> + <Action name="edit_cut" /> + <Action name="edit_copy" /> + <Action name="rename" /> + <Action name="move_to_trash" /> + <Action name="delete" /> + <Action name="properties" /> + <Action name="invert_selection" /> + </disable> + </State> + <ToolBar noMerge="1" name="mainToolBar" > + <text>Main Toolbar</text> + <Action name="go_back" /> + <Action name="go_forward" /> + <Separator name="separator_1" /> + <Action name="icons" /> + <Action name="details" /> + <Action name="previews" /> + <Separator name="separator_0" /> + <Action name="split_view" /> + </ToolBar> + <ActionProperties> + <Action shortcut="Backspace;XF86Back" name="go_back" /> + </ActionProperties> +</kpartgui> diff --git a/src/detailsviewsettingspage.cpp b/src/detailsviewsettingspage.cpp new file mode 100644 index 0000000..b8c4d97 --- /dev/null +++ b/src/detailsviewsettingspage.cpp @@ -0,0 +1,155 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "detailsviewsettingspage.h" +#include <qcheckbox.h> +#include <klocale.h> +#include <kdialog.h> +#include <kfontcombo.h> +#include <qspinbox.h> +#include <qlabel.h> +#include <qgrid.h> +#include <assert.h> +#include <qbuttongroup.h> +#include <qradiobutton.h> +#include <qcombobox.h> +#include <qgroupbox.h> +#include <qgroupbox.h> +#include "dolphinsettings.h" +#include "dolphindetailsviewsettings.h" +#include "dolphindetailsview.h" + +DetailsViewSettingsPage::DetailsViewSettingsPage(QWidget *parent) : + QVBox(parent), + m_dateBox(0), + m_permissionsBox(0), + m_ownerBox(0), + m_groupBox(0), + m_smallIconSize(0), + m_mediumIconSize(0), + m_largeIconSize(0) +{ + const int spacing = KDialog::spacingHint(); + const int margin = KDialog::marginHint(); + const QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + setSpacing(spacing); + setMargin(margin); + + DolphinDetailsViewSettings* settings = DolphinSettings::instance().detailsView(); + assert(settings != 0); + + // create "Columns" properties + QGroupBox* columnsGroup = new QGroupBox(4, Qt::Vertical, i18n("Columns"), this); + columnsGroup->setSizePolicy(sizePolicy); + columnsGroup->setMargin(margin); + + QHBox* visibleColumnsLayout = new QHBox(columnsGroup); + m_dateBox = new QCheckBox(i18n("Date"), visibleColumnsLayout); + m_dateBox->setChecked(settings->isColumnEnabled(DolphinDetailsView::DateColumn)); + + m_permissionsBox = new QCheckBox(i18n("Permissions"), visibleColumnsLayout); + m_permissionsBox->setChecked(settings->isColumnEnabled(DolphinDetailsView::PermissionsColumn)); + + m_ownerBox = new QCheckBox(i18n("Owner"), visibleColumnsLayout); + m_ownerBox->setChecked(settings->isColumnEnabled(DolphinDetailsView::OwnerColumn)); + + m_groupBox = new QCheckBox(i18n("Group"), visibleColumnsLayout); + m_groupBox->setChecked(settings->isColumnEnabled(DolphinDetailsView::GroupColumn)); + + // Create "Icon" properties + QButtonGroup* iconSizeGroup = new QButtonGroup(3, Qt::Horizontal, i18n("Icon Size"), this); + iconSizeGroup->setSizePolicy(sizePolicy); + iconSizeGroup->setMargin(margin); + m_smallIconSize = new QRadioButton(i18n("Small"), iconSizeGroup); + m_mediumIconSize = new QRadioButton(i18n("Medium"), iconSizeGroup); + m_largeIconSize = new QRadioButton(i18n("Large"), iconSizeGroup); + switch (settings->iconSize()) { + case KIcon::SizeLarge: + m_largeIconSize->setChecked(true); + break; + + case KIcon::SizeMedium: + m_mediumIconSize->setChecked(true); + break; + + case KIcon::SizeSmall: + default: + m_smallIconSize->setChecked(true); + } + + //new QLabel(i18n("Icon size:"), iconGroup); + //m_iconSizeBox = new QComboBox(iconGroup); + //m_iconSizeBox->insertItem(i18n("Small")); + //m_iconSizeBox->insertItem(i18n("Medium")); + //m_iconSizeBox->insertItem(i18n("Large")); + + // create "Text" properties + QGroupBox* textGroup = new QGroupBox(2, Qt::Horizontal, i18n("Text"), this); + textGroup->setSizePolicy(sizePolicy); + textGroup->setMargin(margin); + + new QLabel(i18n("Font family:"), textGroup); + m_fontFamilyBox = new KFontCombo(textGroup); + m_fontFamilyBox->setCurrentFont(settings->fontFamily()); + + new QLabel(i18n("Font size:"), textGroup); + m_fontSizeBox = new QSpinBox(6, 99, 1, textGroup); + m_fontSizeBox->setValue(settings->fontSize()); + + // Add a dummy widget with no restriction regarding + // a vertical resizing. This assures that the dialog layout + // is not stretched vertically. + new QWidget(this); +} + + +DetailsViewSettingsPage::~DetailsViewSettingsPage() +{ +} + +void DetailsViewSettingsPage::applySettings() +{ + DolphinDetailsViewSettings* settings = DolphinSettings::instance().detailsView(); + assert(settings != 0); + + settings->setColumnEnabled(DolphinDetailsView::DateColumn, + m_dateBox->isChecked()); + settings->setColumnEnabled(DolphinDetailsView::PermissionsColumn, + m_permissionsBox->isChecked()); + settings->setColumnEnabled(DolphinDetailsView::OwnerColumn, + m_ownerBox->isChecked()); + settings->setColumnEnabled(DolphinDetailsView::GroupColumn, + m_groupBox->isChecked()); + + int iconSize = KIcon::SizeSmall; + if (m_mediumIconSize->isChecked()) { + iconSize = KIcon::SizeMedium; + } + else if (m_largeIconSize->isChecked()) { + iconSize = KIcon::SizeLarge; + } + settings->setIconSize(iconSize); + + settings->setFontFamily(m_fontFamilyBox->currentFont()); + settings->setFontSize(m_fontSizeBox->value()); +} + +#include "detailsviewsettingspage.moc" diff --git a/src/detailsviewsettingspage.h b/src/detailsviewsettingspage.h new file mode 100644 index 0000000..c9bde55 --- /dev/null +++ b/src/detailsviewsettingspage.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef DETAILSVIEWSETTINGSPAGE_H +#define DETAILSVIEWSETTINGSPAGE_H + +#include <qvbox.h> +class QCheckBox; +class KFontCombo; +class QSpinBox; +class QComboBox; +class QRadioButton; + +/** + * @brief Represents the page from the Dolphin Settings which allows + * to modify the settings for the details view. + * + * @author Peter Penz <peter.penz@gmx.at> + */ +class DetailsViewSettingsPage : public QVBox +{ + Q_OBJECT + +public: + DetailsViewSettingsPage(QWidget* parent); + virtual ~DetailsViewSettingsPage(); + + /** + * Applies the settings for the details view. + * The settings are persisted automatically when + * closing Dolphin. + */ + void applySettings(); + +private: + QCheckBox* m_dateBox; + QCheckBox* m_permissionsBox; + QCheckBox* m_ownerBox; + QCheckBox* m_groupBox; + QRadioButton* m_smallIconSize; + QRadioButton* m_mediumIconSize; + QRadioButton* m_largeIconSize; + + KFontCombo* m_fontFamilyBox; + QSpinBox* m_fontSizeBox; +}; + +#endif diff --git a/src/dolphin.cpp b/src/dolphin.cpp new file mode 100644 index 0000000..09eeeeb --- /dev/null +++ b/src/dolphin.cpp @@ -0,0 +1,1711 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> * + * Copyright (C) 2006 by Stefan Monov <logixoul@gmail.com> * + * Copyright (C) 2006 by Cvetoslav Ludmiloff <ludmiloff@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphin.h" + +#include <assert.h> + +#include <kbookmarkmanager.h> +#include <kglobal.h> +#include <kpropertiesdialog.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kdeversion.h> +#include <kstatusbar.h> +#include <kaccel.h> +#include <kio/netaccess.h> +#include <kfiledialog.h> +#include <kconfig.h> +#include <kurl.h> +#include <kurldrag.h> +#include <kstdaccel.h> +#include <kaction.h> +#include <kstdaction.h> +#include <kactionclasses.h> +#include <kpopupmenu.h> +#include <kio/renamedlg.h> +#include <kinputdialog.h> +#include <kshell.h> +#include <kdesktopfile.h> +#include <kstandarddirs.h> +#include <kprotocolinfo.h> +#include <kmessagebox.h> +#include <kservice.h> +#include <kstandarddirs.h> +#include <krun.h> + +#include <qclipboard.h> +#include <qdragobject.h> + +#include "urlnavigator.h" +#include "viewpropertiesdialog.h" +#include "viewproperties.h" +#include "dolphinsettings.h" +#include "dolphinsettingsdialog.h" +#include "dolphinstatusbar.h" +#include "undomanager.h" +#include "progressindicator.h" +#include "dolphinsettings.h" +#include "sidebars.h" +#include "sidebarssettings.h" + + +Dolphin& Dolphin::mainWin() +{ + static Dolphin* instance = 0; + if (instance == 0) { + instance = new Dolphin(); + instance->init(); + } + return *instance; +} + +Dolphin::~Dolphin() +{ +} + +void Dolphin::setActiveView(DolphinView* view) +{ + assert((view == m_view[PrimaryIdx]) || (view == m_view[SecondaryIdx])); + if (m_activeView == view) { + return; + } + + m_activeView = view; + + updateHistory(); + updateEditActions(); + updateViewActions(); + updateGoActions(); + + setCaption(m_activeView->url().fileName()); + + emit activeViewChanged(); +} + +void Dolphin::dropURLs(const KURL::List& urls, + const KURL& destination) +{ + const ButtonState keyboardState = KApplication::keyboardMouseState(); + const bool shiftPressed = (keyboardState & ShiftButton) > 0; + const bool controlPressed = (keyboardState & ControlButton) > 0; + + int selectedIndex = -1; + if (shiftPressed && controlPressed) { + // shortcut for 'Linke Here' is used + selectedIndex = 2; + } + else if (controlPressed) { + // shortcut for 'Copy Here' is used + selectedIndex = 1; + } + else if (shiftPressed) { + // shortcut for 'Move Here' is used + selectedIndex = 0; + } + else { + // no shortcut is used, hence open a popup menu + KPopupMenu popup(this); + + popup.insertItem(SmallIcon("goto"), i18n("&Move Here") + "\t" + KKey::modFlagLabel(KKey::SHIFT), 0); + popup.insertItem(SmallIcon("editcopy"), i18n( "&Copy Here" ) + "\t" + KKey::modFlagLabel(KKey::CTRL), 1); + popup.insertItem(i18n("&Link Here") + "\t" + KKey::modFlagLabel((KKey::ModFlag)(KKey::CTRL|KKey::SHIFT)), 2); + popup.insertSeparator(); + popup.insertItem(SmallIcon("stop"), i18n("Cancel"), 3); + popup.setAccel(i18n("Escape"), 3); + + selectedIndex = popup.exec(QCursor::pos()); + } + + if (selectedIndex < 0) { + return; + } + + switch (selectedIndex) { + case 0: { + // 'Move Here' has been selected + updateViewProperties(urls); + moveURLs(urls, destination); + break; + } + + case 1: { + // 'Copy Here' has been selected + updateViewProperties(urls); + copyURLs(urls, destination); + break; + } + + case 2: { + // 'Link Here' has been selected + KIO::Job* job = KIO::link(urls, destination); + addPendingUndoJob(job, DolphinCommand::Link, urls, destination); + break; + } + + default: + // 'Cancel' has been selected + break; + } +} + +void Dolphin::refreshViews() +{ + const bool split = DolphinSettings::instance().isViewSplit(); + const bool isPrimaryViewActive = (m_activeView == m_view[PrimaryIdx]); + DolphinSettings& settings = DolphinSettings::instance(); + KURL url; + for (int i = PrimaryIdx; i <= SecondaryIdx; ++i) { + if (m_view[i] != 0) { + url = m_view[i]->url(); + + // delete view instance... + m_view[i]->close(); + m_view[i]->deleteLater(); + m_view[i] = 0; + } + + if (split || (i == PrimaryIdx)) { + // ... and recreate it + ViewProperties props(url); + m_view[i] = new DolphinView(m_splitter, + url, + props.viewMode(), + props.isShowHiddenFilesEnabled()); + m_view[i]->show(); + } + + rightSidebarSettings* rightsidebarSettings = settings.rightsidebar(); + assert(rightsidebarSettings != 0); + if (rightsidebarSettings->isVisible()) { + m_splitter->moveToLast(m_rightsidebar); + } + } + + m_activeView = isPrimaryViewActive ? m_view[PrimaryIdx] : m_view[SecondaryIdx]; + assert(m_activeView != 0); + + updateViewActions(); + emit activeViewChanged(); +} + +void Dolphin::slotHistoryChanged() +{ + updateHistory(); +} + +void Dolphin::slotURLChanged(const KURL& url) +{ + updateEditActions(); + updateGoActions(); + setCaption(url.fileName()); +} + +void Dolphin::slotURLChangeRequest(const KURL& url) +{ + clearStatusBar(); + m_activeView->setURL(url); +} + +void Dolphin::slotViewModeChanged() +{ + updateViewActions(); +} + +void Dolphin::slotShowHiddenFilesChanged() +{ + KToggleAction* showHiddenFilesAction = + static_cast<KToggleAction*>(actionCollection()->action("show_hidden_files")); + showHiddenFilesAction->setChecked(m_activeView->isShowHiddenFilesEnabled()); +} + +void Dolphin::slotShowFilterBarChanged() +{ + KToggleAction* showFilterBarAction = + static_cast<KToggleAction*>(actionCollection()->action("show_filter_bar")); + showFilterBarAction->setChecked(m_activeView->isFilterBarVisible()); +} + +void Dolphin::slotSortingChanged(DolphinView::Sorting sorting) +{ + KAction* action = 0; + switch (sorting) { + case DolphinView::SortByName: + action = actionCollection()->action("by_name"); + break; + case DolphinView::SortBySize: + action = actionCollection()->action("by_size"); + break; + case DolphinView::SortByDate: + action = actionCollection()->action("by_date"); + break; + default: + break; + } + + if (action != 0) { + KToggleAction* toggleAction = static_cast<KToggleAction*>(action); + toggleAction->setChecked(true); + } +} + +void Dolphin::slotSortOrderChanged(Qt::SortOrder order) +{ + KToggleAction* descending = static_cast<KToggleAction*>(actionCollection()->action("descending")); + const bool sortDescending = (order == Qt::Descending); + descending->setChecked(sortDescending); +} + +void Dolphin::slotSelectionChanged() +{ + updateEditActions(); + + assert(m_view[PrimaryIdx] != 0); + int selectedURLsCount = m_view[PrimaryIdx]->selectedURLs().count(); + if (m_view[SecondaryIdx] != 0) { + selectedURLsCount += m_view[SecondaryIdx]->selectedURLs().count(); + } + + KAction* compareFilesAction = actionCollection()->action("compare_files"); + compareFilesAction->setEnabled(selectedURLsCount == 2); + + m_activeView->updateStatusBar(); + + emit selectionChanged(); +} + +void Dolphin::closeEvent(QCloseEvent* event) +{ + KConfig* config = kapp->config(); + config->setGroup("General"); + config->writeEntry("First Run", false); + + DolphinSettings& settings = DolphinSettings::instance(); + + leftSidebarSettings* leftsidebarSettings = settings.leftsidebar(); + const bool isleftSidebarVisible = (m_leftsidebar != 0); + leftsidebarSettings->setVisible(isleftSidebarVisible); + if (isleftSidebarVisible) { + leftsidebarSettings->setWidth(m_leftsidebar->width()); + } + + rightSidebarSettings* rightsidebarSettings = settings.rightsidebar(); + const bool isrightSidebarVisible = (m_rightsidebar != 0); + rightsidebarSettings->setVisible(isrightSidebarVisible); + if (isrightSidebarVisible) { + rightsidebarSettings->setWidth(m_rightsidebar->width()); + } + + settings.save(); + + config->sync(); + KMainWindow::closeEvent(event); +} + +void Dolphin::saveProperties(KConfig* config) +{ + config->setGroup("Primary view"); + config->writeEntry("URL", m_view[PrimaryIdx]->url().url()); + config->writeEntry("Editable URL", m_view[PrimaryIdx]->isURLEditable()); + if (m_view[SecondaryIdx] != 0) { + config->setGroup("Secondary view"); + config->writeEntry("URL", m_view[SecondaryIdx]->url().url()); + config->writeEntry("Editable URL", m_view[SecondaryIdx]->isURLEditable()); + } +} + +void Dolphin::readProperties(KConfig* config) +{ + config->setGroup("Primary view"); + m_view[PrimaryIdx]->setURL(config->readEntry("URL")); + m_view[PrimaryIdx]->setURLEditable(config->readBoolEntry("Editable URL")); + if (config->hasGroup("Secondary view")) { + config->setGroup("Secondary view"); + if (m_view[SecondaryIdx] == 0) { + toggleSplitView(); + } + m_view[SecondaryIdx]->setURL(config->readEntry("URL")); + m_view[SecondaryIdx]->setURLEditable(config->readBoolEntry("Editable URL")); + } + else if (m_view[SecondaryIdx] != 0) { + toggleSplitView(); + } +} + +void Dolphin::createFolder() +{ + // Parts of the following code have been taken + // from the class KonqPopupMenu located in + // libqonq/konq_popupmenu.h of Konqueror. + // (Copyright (C) 2000 David Faure <faure@kde.org>, + // Copyright (C) 2001 Holger Freyther <freyther@yahoo.com>) + + clearStatusBar(); + + DolphinStatusBar* statusBar = m_activeView->statusBar(); + const KURL baseURL(m_activeView->url()); + + QString name(i18n("New Folder")); + if (baseURL.isLocalFile() && QFileInfo(baseURL.path(+1) + name).exists()) { + name = KIO::RenameDlg::suggestName(baseURL, i18n("New Folder")); + } + + bool ok = false; + name = KInputDialog::getText(i18n("New Folder"), + i18n("Enter folder name:" ), + name, + &ok, + this); + + if (!ok) { + // the user has pressed 'Cancel' + return; + } + + assert(!name.isEmpty()); + + KURL url; + if ((name[0] == '/') || (name[0] == '~')) { + url.setPath(KShell::tildeExpand(name)); + } + else { + name = KIO::encodeFileName(name); + url = baseURL; + url.addPath(name); + } + ok = KIO::NetAccess::mkdir(url, this); + + // TODO: provide message type hint + if (ok) { + statusBar->setMessage(i18n("Created folder %1.").arg(url.path()), + DolphinStatusBar::OperationCompleted); + + DolphinCommand command(DolphinCommand::CreateFolder, KURL::List(), url); + UndoManager::instance().addCommand(command); + } + else { + // Creating of the folder has been failed. Check whether the creating + // has been failed because a folder with the same name exists... + if (KIO::NetAccess::exists(url, true, this)) { + statusBar->setMessage(i18n("A folder named %1 already exists.").arg(url.path()), + DolphinStatusBar::Error); + } + else { + statusBar->setMessage(i18n("Creating of folder %1 failed.").arg(url.path()), + DolphinStatusBar::Error); + } + + } +} + +void Dolphin::createFile() +{ + // Parts of the following code have been taken + // from the class KonqPopupMenu located in + // libqonq/konq_popupmenu.h of Konqueror. + // (Copyright (C) 2000 David Faure <faure@kde.org>, + // Copyright (C) 2001 Holger Freyther <freyther@yahoo.com>) + + clearStatusBar(); + + // TODO: const Entry& entry = m_createFileTemplates[QString(sender->name())]; + // should be enough. Anyway: the implemantation of [] does a linear search internally too. + KSortableValueList<CreateFileEntry, QString>::ConstIterator it = m_createFileTemplates.begin(); + KSortableValueList<CreateFileEntry, QString>::ConstIterator end = m_createFileTemplates.end(); + + const QString senderName(sender()->name()); + bool found = false; + CreateFileEntry entry; + while (!found && (it != end)) { + if ((*it).index() == senderName) { + entry = (*it).value(); + found = true; + } + else { + ++it; + } + } + + DolphinStatusBar* statusBar = m_activeView->statusBar(); + if (!found || !QFile::exists(entry.templatePath)) { + statusBar->setMessage(i18n("Could not create file."), DolphinStatusBar::Error); + return; + } + + // Get the source path of the template which should be copied. + // The source path is part of the URL entry of the desktop file. + const int pos = entry.templatePath.findRev('/'); + QString sourcePath(entry.templatePath.left(pos + 1)); + sourcePath += KDesktopFile(entry.templatePath, true).readPathEntry("URL"); + + QString name(i18n(entry.name)); + // Most entry names end with "..." (e. g. "HTML File..."), which is ok for + // menus but no good choice for a new file name -> remove the dots... + name.replace("...", QString::null); + + // add the file extension to the name + name.append(sourcePath.right(sourcePath.length() - sourcePath.findRev('.'))); + + // Check whether a file with the current name already exists. If yes suggest automatically + // a unique file name (e. g. "HTML File" will be replaced by "HTML File_1"). + const KURL viewURL(m_activeView->url()); + const bool fileExists = viewURL.isLocalFile() && + QFileInfo(viewURL.path(+1) + KIO::encodeFileName(name)).exists(); + if (fileExists) { + name = KIO::RenameDlg::suggestName(viewURL, name); + } + + // let the user change the suggested file name + bool ok = false; + name = KInputDialog::getText(entry.name, + entry.comment, + name, + &ok, + this); + if (!ok) { + // the user has pressed 'Cancel' + return; + } + + // before copying the template to the destination path check whether a file + // with the given name already exists + const QString destPath(viewURL.prettyURL() + "/" + KIO::encodeFileName(name)); + const KURL destURL(destPath); + if (KIO::NetAccess::exists(destURL, false, this)) { + statusBar->setMessage(i18n("A file named %1 already exists.").arg(name), + DolphinStatusBar::Error); + return; + } + + // copy the template to the destination path + const KURL sourceURL(sourcePath); + KIO::CopyJob* job = KIO::copyAs(sourceURL, destURL); + job->setDefaultPermissions(true); + if (KIO::NetAccess::synchronousRun(job, this)) { + statusBar->setMessage(i18n("Created file %1.").arg(name), + DolphinStatusBar::OperationCompleted); + + KURL::List list; + list.append(sourceURL); + DolphinCommand command(DolphinCommand::CreateFile, list, destURL); + UndoManager::instance().addCommand(command); + + } + else { + statusBar->setMessage(i18n("Creating of file %1 failed.").arg(name), + DolphinStatusBar::Error); + } +} + +void Dolphin::rename() +{ + clearStatusBar(); + m_activeView->renameSelectedItems(); +} + +void Dolphin::moveToTrash() +{ + clearStatusBar(); + KURL::List selectedURLs = m_activeView->selectedURLs(); + KIO::Job* job = KIO::trash(selectedURLs); + addPendingUndoJob(job, DolphinCommand::Trash, selectedURLs, m_activeView->url()); +} + +void Dolphin::deleteItems() +{ + clearStatusBar(); + + KURL::List list = m_activeView->selectedURLs(); + const uint itemCount = list.count(); + assert(itemCount >= 1); + + QString text; + if (itemCount > 1) { + text = i18n("Do you really want to delete the %1 selected items?").arg(itemCount); + } + else { + const KURL& url = list.first(); + text = i18n("Do you really want to delete '%1'?").arg(url.fileName()); + } + + const bool del = KMessageBox::warningContinueCancel(this, + text, + QString::null, + KGuiItem(i18n("Delete"), SmallIcon("editdelete")) + ) == KMessageBox::Continue; + if (del) { + KIO::Job* job = KIO::del(list); + connect(job, SIGNAL(result(KIO::Job*)), + this, SLOT(slotHandleJobError(KIO::Job*))); + connect(job, SIGNAL(result(KIO::Job*)), + this, SLOT(slotDeleteFileFinished(KIO::Job*))); + } +} + +void Dolphin::properties() +{ + const KFileItemList* sourceList = m_activeView->selectedItems(); + if (sourceList == 0) { + return; + } + + KFileItemList list; + KFileItemListIterator it(*sourceList); + KFileItem* item = 0; + while ((item = it.current()) != 0) { + list.append(item); + ++it; + } + + new KPropertiesDialog(list, this); +} + +void Dolphin::quit() +{ + close(); +} + +void Dolphin::slotHandleJobError(KIO::Job* job) +{ + if (job->error() != 0) { + m_activeView->statusBar()->setMessage(job->errorString(), + DolphinStatusBar::Error); + } +} + +void Dolphin::slotDeleteFileFinished(KIO::Job* job) +{ + if (job->error() == 0) { + m_activeView->statusBar()->setMessage(i18n("Delete operation completed."), + DolphinStatusBar::OperationCompleted); + + // TODO: In opposite to the 'Move to Trash' operation in the class KFileIconView + // no rearranging of the item position is done when a file has been deleted. + // This is bypassed by reloading the view, but it might be worth to investigate + // deeper for the root of this issue. + m_activeView->reload(); + } +} + +void Dolphin::slotUndoAvailable(bool available) +{ + KAction* undoAction = actionCollection()->action(KStdAction::stdName(KStdAction::Undo)); + if (undoAction != 0) { + undoAction->setEnabled(available); + } +} + +void Dolphin::slotUndoTextChanged(const QString& text) +{ + KAction* undoAction = actionCollection()->action(KStdAction::stdName(KStdAction::Undo)); + if (undoAction != 0) { + undoAction->setText(text); + } +} + +void Dolphin::slotRedoAvailable(bool available) +{ + KAction* redoAction = actionCollection()->action(KStdAction::stdName(KStdAction::Redo)); + if (redoAction != 0) { + redoAction->setEnabled(available); + } +} + +void Dolphin::slotRedoTextChanged(const QString& text) +{ + KAction* redoAction = actionCollection()->action(KStdAction::stdName(KStdAction::Redo)); + if (redoAction != 0) { + redoAction->setText(text); + } +} + +void Dolphin::cut() +{ + m_clipboardContainsCutData = true; + QDragObject* data = new KURLDrag(m_activeView->selectedURLs(), + widget()); + QApplication::clipboard()->setData(data); +} + +void Dolphin::copy() +{ + m_clipboardContainsCutData = false; + QDragObject* data = new KURLDrag(m_activeView->selectedURLs(), + widget()); + QApplication::clipboard()->setData(data); +} + +void Dolphin::paste() +{ + QClipboard* clipboard = QApplication::clipboard(); + QMimeSource* data = clipboard->data(); + if (!KURLDrag::canDecode(data)) { + return; + } + + clearStatusBar(); + + KURL::List sourceURLs; + KURLDrag::decode(data, sourceURLs); + + // per default the pasting is done into the current URL of the view + KURL destURL(m_activeView->url()); + + // check whether the pasting should be done into a selected directory + KURL::List selectedURLs = m_activeView->selectedURLs(); + if (selectedURLs.count() == 1) { + const KFileItem fileItem(S_IFDIR, + KFileItem::Unknown, + selectedURLs.first(), + true); + if (fileItem.isDir()) { + // only one item is selected which is a directory, hence paste + // into this directory + destURL = selectedURLs.first(); + } + } + + + updateViewProperties(sourceURLs); + if (m_clipboardContainsCutData) { + moveURLs(sourceURLs, destURL); + m_clipboardContainsCutData = false; + clipboard->clear(); + } + else { + copyURLs(sourceURLs, destURL); + } +} + +void Dolphin::updatePasteAction() +{ + KAction* pasteAction = actionCollection()->action(KStdAction::stdName(KStdAction::Paste)); + if (pasteAction == 0) { + return; + } + + QString text(i18n("Paste")); + QClipboard* clipboard = QApplication::clipboard(); + QMimeSource* data = clipboard->data(); + if (KURLDrag::canDecode(data)) { + pasteAction->setEnabled(true); + + KURL::List urls; + KURLDrag::decode(data, urls); + const int count = urls.count(); + if (count == 1) { + pasteAction->setText(i18n("Paste 1 File")); + } + else { + pasteAction->setText(i18n("Paste %1 Files").arg(count)); + } + } + else { + pasteAction->setEnabled(false); + pasteAction->setText(i18n("Paste")); + } + + if (pasteAction->isEnabled()) { + KURL::List urls = m_activeView->selectedURLs(); + const uint count = urls.count(); + if (count > 1) { + // pasting should not be allowed when more than one file + // is selected + pasteAction->setEnabled(false); + } + else if (count == 1) { + // Only one file is selected. Pasting is only allowed if this + // file is a directory. + const KFileItem fileItem(S_IFDIR, + KFileItem::Unknown, + urls.first(), + true); + pasteAction->setEnabled(fileItem.isDir()); + } + } +} + +void Dolphin::selectAll() +{ + clearStatusBar(); + m_activeView->selectAll(); +} + +void Dolphin::invertSelection() +{ + clearStatusBar(); + m_activeView->invertSelection(); +} +void Dolphin::setIconsView() +{ + m_activeView->setMode(DolphinView::IconsView); +} + +void Dolphin::setDetailsView() +{ + m_activeView->setMode(DolphinView::DetailsView); +} + +void Dolphin::setPreviewsView() +{ + m_activeView->setMode(DolphinView::PreviewsView); +} + +void Dolphin::sortByName() +{ + m_activeView->setSorting(DolphinView::SortByName); +} + +void Dolphin::sortBySize() +{ + m_activeView->setSorting(DolphinView::SortBySize); +} + +void Dolphin::sortByDate() +{ + m_activeView->setSorting(DolphinView::SortByDate); +} + +void Dolphin::toggleSortOrder() +{ + const Qt::SortOrder order = (m_activeView->sortOrder() == Qt::Ascending) ? + Qt::Descending : + Qt::Ascending; + m_activeView->setSortOrder(order); +} + +void Dolphin::toggleSplitView() +{ + if (m_view[SecondaryIdx] == 0) { + const int newWidth = (m_view[PrimaryIdx]->width() - m_splitter->handleWidth()) / 2; + + // create a secondary view + m_view[SecondaryIdx] = new DolphinView(m_splitter, + m_view[PrimaryIdx]->url(), + m_view[PrimaryIdx]->mode(), + m_view[PrimaryIdx]->isShowHiddenFilesEnabled()); + + QValueList<int> list = m_splitter->sizes(); + assert(!list.isEmpty()); + list.pop_back(); + list.append(newWidth); + list.append(newWidth); + m_splitter->setSizes(list); + m_view[SecondaryIdx]->show(); + if(m_rightsidebar != 0){ + closerightSidebar(); + openrightSidebar(); + } + } + else { + // remove secondary view + if (m_activeView == m_view[PrimaryIdx]) { + m_view[SecondaryIdx]->close(); + m_view[SecondaryIdx]->deleteLater(); + m_view[SecondaryIdx] = 0; + setActiveView(m_view[PrimaryIdx]); + } + else { + // The secondary view is active, hence from the users point of view + // the content of the secondary view should be moved to the primary view. + // From an implementation point of view it is more efficient to close + // the primary view and exchange the internal pointers afterwards. + m_view[PrimaryIdx]->close(); + m_view[PrimaryIdx]->deleteLater(); + m_view[PrimaryIdx] = m_view[SecondaryIdx]; + m_view[SecondaryIdx] = 0; + setActiveView(m_view[PrimaryIdx]); + } + } +} + +void Dolphin::reloadView() +{ + clearStatusBar(); + m_activeView->reload(); +} + +void Dolphin::stopLoading() +{ +} + +void Dolphin::showHiddenFiles() +{ + clearStatusBar(); + + const KToggleAction* showHiddenFilesAction = + static_cast<KToggleAction*>(actionCollection()->action("show_hidden_files")); + const bool show = showHiddenFilesAction->isChecked(); + m_activeView->setShowHiddenFilesEnabled(show); +} + +void Dolphin::showFilterBar() +{ + const KToggleAction* showFilterBarAction = + static_cast<KToggleAction*>(actionCollection()->action("show_filter_bar")); + const bool show = showFilterBarAction->isChecked(); + m_activeView->slotShowFilterBar(show); +} + +void Dolphin::zoomIn() +{ + m_activeView->zoomIn(); + updateViewActions(); +} + +void Dolphin::zoomOut() +{ + m_activeView->zoomOut(); + updateViewActions(); +} + +void Dolphin::editLocation() +{ + clearStatusBar(); + m_activeView->editURL(); +} + +void Dolphin::browse() +{ + clearStatusBar(); + m_activeView->setURLEditable(false); +} + +void Dolphin::adjustViewProperties() +{ + clearStatusBar(); + ViewPropertiesDialog dlg(m_activeView); + dlg.exec(); +} + +void Dolphin::goBack() +{ + clearStatusBar(); + m_activeView->goBack(); +} + +void Dolphin::goForward() +{ + clearStatusBar(); + m_activeView->goForward(); +} + +void Dolphin::goUp() +{ + clearStatusBar(); + m_activeView->goUp(); +} + +void Dolphin::goHome() +{ + clearStatusBar(); + m_activeView->goHome(); +} + +void Dolphin::openTerminal() +{ + QString command("konsole --workdir \""); + command.append(m_activeView->url().path()); + command.append('\"'); + + KRun::runCommand(command, "Konsole", "konsole"); +} + +void Dolphin::findFile() +{ + KRun::run("kfind", m_activeView->url()); +} + +void Dolphin::compareFiles() +{ + // The method is only invoked if exactly 2 files have + // been selected. The selected files may be: + // - both in the primary view + // - both in the secondary view + // - one in the primary view and the other in the secondary + // view + assert(m_view[PrimaryIdx] != 0); + + KURL urlA; + KURL urlB; + KURL::List urls = m_view[PrimaryIdx]->selectedURLs(); + + switch (urls.count()) { + case 0: { + assert(m_view[SecondaryIdx] != 0); + urls = m_view[SecondaryIdx]->selectedURLs(); + assert(urls.count() == 2); + urlA = urls[0]; + urlB = urls[1]; + break; + } + + case 1: { + urlA = urls[0]; + assert(m_view[SecondaryIdx] != 0); + urls = m_view[SecondaryIdx]->selectedURLs(); + assert(urls.count() == 1); + urlB = urls[0]; + break; + } + + case 2: { + urlA = urls[0]; + urlB = urls[1]; + break; + } + + default: { + // may not happen: compareFiles may only get invoked if 2 + // files are selected + assert(false); + } + } + + QString command("kompare -c \""); + command.append(urlA.prettyURL()); + command.append("\" \""); + command.append(urlB.prettyURL()); + command.append('\"'); + KRun::runCommand(command, "Kompare", "kompare"); + +} + +void Dolphin::editSettings() +{ + // TODO: make a static method for opening the settings dialog + DolphinSettingsDialog dlg; + dlg.exec(); +} + +void Dolphin::addUndoOperation(KIO::Job* job) +{ + if (job->error() != 0) { + slotHandleJobError(job); + } + else { + const int id = job->progressId(); + + // set iterator to the executed command with the current id... + QValueList<UndoInfo>::Iterator it = m_pendingUndoJobs.begin(); + const QValueList<UndoInfo>::Iterator end = m_pendingUndoJobs.end(); + bool found = false; + while (!found && (it != end)) { + if ((*it).id == id) { + found = true; + } + else { + ++it; + } + } + + if (found) { + DolphinCommand command = (*it).command; + if (command.type() == DolphinCommand::Trash) { + // To be able to perform an undo for the 'Move to Trash' operation + // all source URLs must be updated with the trash URL. E. g. when moving + // a file "test.txt" and a second file "test.txt" to the trash, + // then the filenames in the trash are "0-test.txt" and "1-test.txt". + QMap<QString, QString> metaData = job->metaData(); + KURL::List newSourceURLs; + + KURL::List sourceURLs = command.source(); + KURL::List::Iterator sourceIt = sourceURLs.begin(); + const KURL::List::Iterator sourceEnd = sourceURLs.end(); + + while (sourceIt != sourceEnd) { + QMap<QString, QString>::ConstIterator metaIt = metaData.find("trashURL-" + (*sourceIt).path()); + if (metaIt != metaData.end()) { + newSourceURLs.append(KURL(metaIt.data())); + } + ++sourceIt; + } + command.setSource(newSourceURLs); + } + + UndoManager::instance().addCommand(command); + m_pendingUndoJobs.erase(it); + + DolphinStatusBar* statusBar = m_activeView->statusBar(); + switch (command.type()) { + case DolphinCommand::Copy: + statusBar->setMessage(i18n("Copy operation completed."), + DolphinStatusBar::OperationCompleted); + break; + case DolphinCommand::Move: + statusBar->setMessage(i18n("Move operation completed."), + DolphinStatusBar::OperationCompleted); + break; + case DolphinCommand::Trash: + statusBar->setMessage(i18n("Move to trash operation completed."), + DolphinStatusBar::OperationCompleted); + break; + default: + break; + } + } + } +} + +Dolphin::Dolphin() : + KMainWindow(0, "D3lphin"), + m_splitter(0), + m_leftsidebar(0), + m_rightsidebar(0), + m_activeView(0), + m_clipboardContainsCutData(false) +{ + m_view[PrimaryIdx] = 0; + m_view[SecondaryIdx] = 0; + + m_fileGroupActions.setAutoDelete(true); + + // TODO: the following members are not used yet. See documentation + // of Dolphin::linkGroupActions() and Dolphin::linkToDeviceActions() + // in the header file for details. + //m_linkGroupActions.setAutoDelete(true); + //m_linkToDeviceActions.setAutoDelete(true); +} + +void Dolphin::init() +{ + // Check whether Dolphin runs the first time. If yes then + // a proper default window size is given at the end of Dolphin::init(). + KConfig* config = kapp->config(); + config->setGroup("General"); + const bool firstRun = config->readBoolEntry("First Run", true); + + setAcceptDrops(true); + + m_splitter = new QSplitter(this); + + DolphinSettings& settings = DolphinSettings::instance(); + + KBookmarkManager* manager = settings.bookmarkManager(); + assert(manager != 0); + KBookmarkGroup root = manager->root(); + if (root.first().isNull()) { + root.addBookmark(manager, i18n("Home"), settings.homeURL(), "folder_home"); + root.addBookmark(manager, i18n("System"), KURL("system:/"), "system"); + root.addBookmark(manager, i18n("Storage Media"), KURL("system:/media"), "blockdevice"); + root.addBookmark(manager, i18n("Network"), KURL("remote:/"), "network_local"); + root.addBookmark(manager, i18n("Users' Folders"), KURL("system:/users"), "folder_home2"); + root.addBookmark(manager, i18n("Root"), KURL("/"), "folder_red"); + root.addBookmark(manager, i18n("Trash"), KURL("trash:/"), "trashcan_full"); + } + + const KURL& homeURL = root.first().url(); + setCaption(homeURL.fileName()); + ViewProperties props(homeURL); + m_view[PrimaryIdx] = new DolphinView(m_splitter, + homeURL, + props.viewMode(), + props.isShowHiddenFilesEnabled()); + + m_activeView = m_view[PrimaryIdx]; + + setCentralWidget(m_splitter); + + // open sidebars + leftSidebarSettings* leftsidebarSettings = settings.leftsidebar(); + assert(leftsidebarSettings != 0); + if (leftsidebarSettings->isVisible()) { + openleftSidebar(); + } + + rightSidebarSettings* rightsidebarSettings = settings.rightsidebar(); + assert(rightsidebarSettings != 0); + if (rightsidebarSettings->isVisible()) { + openrightSidebar(); + } + + setupActions(); + setupGUI(Keys|Save|Create|ToolBar); + createGUI(0, false); + + stateChanged("new_file"); + setAutoSaveSettings(); + + QClipboard* clipboard = QApplication::clipboard(); + connect(clipboard, SIGNAL(dataChanged()), + this, SLOT(updatePasteAction())); + updatePasteAction(); + updateGoActions(); + + setupCreateNewMenuActions(); + + loadSettings(); + + if (firstRun) { + // assure a proper default size if Dolphin runs the first time + resize(640, 480); + } +} + +void Dolphin::loadSettings() +{ + DolphinSettings& settings = DolphinSettings::instance(); + + KToggleAction* splitAction = static_cast<KToggleAction*>(actionCollection()->action("split_view")); + if (settings.isViewSplit()) { + splitAction->setChecked(true); + toggleSplitView(); + } + + updateViewActions(); +} + +void Dolphin::setupActions() +{ + // setup 'File' menu + KAction* createFolder = new KAction(i18n("Folder..."), "Ctrl+N", + this, SLOT(createFolder()), + actionCollection(), "create_folder"); + createFolder->setIcon("folder"); + + new KAction(i18n("Rename"), KKey(Key_F2), + this, SLOT(rename()), + actionCollection(), "rename"); + + KAction* moveToTrashAction = new KAction(i18n("Move to Trash"), KKey(Key_Delete), + this, SLOT(moveToTrash()), + actionCollection(), "move_to_trash"); + moveToTrashAction->setIcon("edittrash"); + + KAction* deleteAction = new KAction(i18n("Delete"), "Shift+Delete", + this, SLOT(deleteItems()), + actionCollection(), "delete"); + deleteAction->setIcon("editdelete"); + + new KAction(i18n("Propert&ies"), "Alt+Return", + this, SLOT(properties()), + actionCollection(), "properties"); + + KStdAction::quit(this, SLOT(quit()), actionCollection()); + + // setup 'Edit' menu + UndoManager& undoManager = UndoManager::instance(); + KStdAction::undo(&undoManager, + SLOT(undo()), + actionCollection()); + connect(&undoManager, SIGNAL(undoAvailable(bool)), + this, SLOT(slotUndoAvailable(bool))); + connect(&undoManager, SIGNAL(undoTextChanged(const QString&)), + this, SLOT(slotUndoTextChanged(const QString&))); + + KStdAction::redo(&undoManager, + SLOT(redo()), + actionCollection()); + connect(&undoManager, SIGNAL(redoAvailable(bool)), + this, SLOT(slotRedoAvailable(bool))); + connect(&undoManager, SIGNAL(redoTextChanged(const QString&)), + this, SLOT(slotRedoTextChanged(const QString&))); + + KStdAction::cut(this, SLOT(cut()), actionCollection()); + KStdAction::copy(this, SLOT(copy()), actionCollection()); + KStdAction::paste(this, SLOT(paste()), actionCollection()); + + new KAction(i18n("Select All"), "Ctrl+A", + this, SLOT(selectAll()), + actionCollection(), "select_all"); + + new KAction(i18n("Invert Selection"), "Ctrl+Shift+A", + this, SLOT(invertSelection()), + actionCollection(), "invert_selection"); + + // setup 'View' menu + KStdAction::zoomIn(this, + SLOT(zoomIn()), + actionCollection()); + + KStdAction::zoomOut(this, + SLOT(zoomOut()), + actionCollection()); + + KRadioAction* iconsView = new KRadioAction(i18n("Icons"), "Ctrl+1", + this, SLOT(setIconsView()), + actionCollection(), "icons"); + iconsView->setExclusiveGroup("view_mode"); + iconsView->setIcon("view_icon"); + + KRadioAction* detailsView = new KRadioAction(i18n("Details"), "Ctrl+2", + this, SLOT(setDetailsView()), + actionCollection(), "details"); + detailsView->setExclusiveGroup("view_mode"); + detailsView->setIcon("view_text"); + + KRadioAction* previewsView = new KRadioAction(i18n("Previews"), "Ctrl+3", + this, SLOT(setPreviewsView()), + actionCollection(), "previews"); + previewsView->setExclusiveGroup("view_mode"); + previewsView->setIcon("gvdirpart"); + + KRadioAction* sortByName = new KRadioAction(i18n("By Name"), 0, + this, SLOT(sortByName()), + actionCollection(), "by_name"); + sortByName->setExclusiveGroup("sort"); + + KRadioAction* sortBySize = new KRadioAction(i18n("By Size"), 0, + this, SLOT(sortBySize()), + actionCollection(), "by_size"); + sortBySize->setExclusiveGroup("sort"); + + KRadioAction* sortByDate = new KRadioAction(i18n("By Date"), 0, + this, SLOT(sortByDate()), + actionCollection(), "by_date"); + sortByDate->setExclusiveGroup("sort"); + + new KToggleAction(i18n("Descending"), 0, this, SLOT(toggleSortOrder()), + actionCollection(), "descending"); + + new KToggleAction(i18n("Show Hidden Files"), "Alt+.", + this, SLOT(showHiddenFiles()), + actionCollection(), "show_hidden_files"); + + KToggleAction* splitAction = new KToggleAction(i18n("Split View"), "F10", + this, SLOT(toggleSplitView()), + actionCollection(), "split_view"); + splitAction->setIcon("view_left_right"); + + KAction* reloadAction = new KAction(i18n("Reload"), "F5", + this, SLOT(reloadView()), + actionCollection(), "reload"); + reloadAction->setIcon("reload"); + + KAction* stopAction = new KAction(i18n("Stop"), 0, + this, SLOT(stopLoading()), + actionCollection(), "stop"); + stopAction->setIcon("stop"); + + new KAction(i18n("Edit Location"), "Ctrl+L", + this, SLOT(editLocation()), + actionCollection(), "edit_location"); + + new KAction(i18n("Browse"), "Ctrl+B", + this, SLOT(browse()), + actionCollection(), "browse"); + + new KToggleAction(i18n("Left Sidebar"), "F8", + this, SLOT(toggleleftSidebar()), + actionCollection(), "leftsidebar"); + + new KToggleAction(i18n("Right Sidebar"), "F9", + this, SLOT(togglerightSidebar()), + actionCollection(), "rightsidebar"); + + new KAction(i18n("Adjust View Properties..."), 0, + this, SLOT(adjustViewProperties()), + actionCollection(), "view_properties"); + + // setup 'Go' menu + KStdAction::back(this, SLOT(goBack()), actionCollection()); + KStdAction::forward(this, SLOT(goForward()), actionCollection()); + KStdAction::up(this, SLOT(goUp()), actionCollection()); + KStdAction::home(this, SLOT(goHome()), actionCollection()); + + // setup 'Tools' menu + KAction* openTerminalAction = new KAction(i18n("Open Terminal"), "F4", + this, SLOT(openTerminal()), + actionCollection(), "open_terminal"); + openTerminalAction->setIcon("konsole"); + + KAction* findFileAction = new KAction(i18n("Find File..."), "Ctrl+F", + this, SLOT(findFile()), + actionCollection(), "find_file"); + findFileAction->setIcon("filefind"); + + new KToggleAction(i18n("Show Filter Bar"), "filter", "/", + this, SLOT(showFilterBar()), + actionCollection(), "show_filter_bar"); + + KAction* compareFilesAction = new KAction(i18n("Compare Files"), 0, + this, SLOT(compareFiles()), + actionCollection(), "compare_files"); + compareFilesAction->setIcon("kompare"); + compareFilesAction->setEnabled(false); + + // setup 'Settings' menu + KStdAction::preferences(this, SLOT(editSettings()), actionCollection()); +} + +void Dolphin::setupCreateNewMenuActions() +{ + // Parts of the following code have been taken + // from the class KNewMenu located in + // libqonq/knewmenu.h of Konqueror. + // Copyright (C) 1998, 1999 David Faure <faure@kde.org> + // 2003 Sven Leiber <s.leiber@web.de> + + QStringList files = actionCollection()->instance()->dirs()->findAllResources("templates"); + for (QStringList::Iterator it = files.begin() ; it != files.end(); ++it) { + if ((*it)[0] != '.' ) { + KSimpleConfig config(*it, true); + config.setDesktopGroup(); + + // tricky solution to ensure that TextFile is at the beginning + // because this filetype is the most used (according kde-core discussion) + const QString name(config.readEntry("Name")); + QString key(name); + + const QString path(config.readPathEntry("URL")); + if (!path.endsWith("emptydir")) { + if (path.endsWith("TextFile.txt")) { + key = "1" + key; + } + else if (!KDesktopFile::isDesktopFile(path)) { + key = "2" + key; + } + else if (path.endsWith("URL.desktop")){ + key = "3" + key; + } + else if (path.endsWith("Program.desktop")){ + key = "4" + key; + } + else { + key = "5"; + } + + const QString icon(config.readEntry("Icon")); + const QString comment(config.readEntry("Comment")); + const QString type(config.readEntry("Type")); + + const QString filePath(*it); + + + if (type == "Link") { + CreateFileEntry entry; + entry.name = name; + entry.icon = icon; + entry.comment = comment; + entry.templatePath = filePath; + m_createFileTemplates.insert(key, entry); + } + } + } + } + m_createFileTemplates.sort(); + + unplugActionList("create_actions"); + KSortableValueList<CreateFileEntry, QString>::ConstIterator it = m_createFileTemplates.begin(); + KSortableValueList<CreateFileEntry, QString>::ConstIterator end = m_createFileTemplates.end(); + while (it != end) { + CreateFileEntry entry = (*it).value(); + KAction* action = new KAction(entry.name); + action->setIcon(entry.icon); + action->setName((*it).index()); + connect(action, SIGNAL(activated()), + this, SLOT(createFile())); + + const QChar section = ((*it).index()[0]); + switch (section) { + case '1': + case '2': { + m_fileGroupActions.append(action); + break; + } + + case '3': + case '4': { + // TODO: not used yet. See documentation of Dolphin::linkGroupActions() + // and Dolphin::linkToDeviceActions() in the header file for details. + //m_linkGroupActions.append(action); + break; + } + + case '5': { + // TODO: not used yet. See documentation of Dolphin::linkGroupActions() + // and Dolphin::linkToDeviceActions() in the header file for details. + //m_linkToDeviceActions.append(action); + break; + } + default: + break; + } + ++it; + } + + plugActionList("create_file_group", m_fileGroupActions); + //plugActionList("create_link_group", m_linkGroupActions); + //plugActionList("link_to_device", m_linkToDeviceActions); +} + +void Dolphin::updateHistory() +{ + int index = 0; + const QValueList<URLNavigator::HistoryElem> list = m_activeView->urlHistory(index); + + KAction* backAction = actionCollection()->action("go_back"); + if (backAction != 0) { + backAction->setEnabled(index < static_cast<int>(list.count()) - 1); + } + + KAction* forwardAction = actionCollection()->action("go_forward"); + if (forwardAction != 0) { + forwardAction->setEnabled(index > 0); + } +} + +void Dolphin::updateEditActions() +{ + const KFileItemList* list = m_activeView->selectedItems(); + if ((list == 0) || (*list).isEmpty()) { + stateChanged("has_no_selection"); + } + else { + stateChanged("has_selection"); + + KAction* renameAction = actionCollection()->action("rename"); + if (renameAction != 0) { + renameAction->setEnabled(list->count() >= 1); + } + + bool enableMoveToTrash = true; + + KFileItemListIterator it(*list); + KFileItem* item = 0; + while ((item = it.current()) != 0) { + const KURL& url = item->url(); + // only enable the 'Move to Trash' action for local files + if (!url.isLocalFile()) { + enableMoveToTrash = false; + } + ++it; + } + + KAction* moveToTrashAction = actionCollection()->action("move_to_trash"); + moveToTrashAction->setEnabled(enableMoveToTrash); + } + updatePasteAction(); +} + +void Dolphin::updateViewActions() +{ + KAction* zoomInAction = actionCollection()->action(KStdAction::stdName(KStdAction::ZoomIn)); + if (zoomInAction != 0) { + zoomInAction->setEnabled(m_activeView->isZoomInPossible()); + } + + KAction* zoomOutAction = actionCollection()->action(KStdAction::stdName(KStdAction::ZoomOut)); + if (zoomOutAction != 0) { + zoomOutAction->setEnabled(m_activeView->isZoomOutPossible()); + } + + KAction* action = 0; + switch (m_activeView->mode()) { + case DolphinView::IconsView: + action = actionCollection()->action("icons"); + break; + case DolphinView::DetailsView: + action = actionCollection()->action("details"); + break; + case DolphinView::PreviewsView: + action = actionCollection()->action("previews"); + break; + default: + break; + } + + if (action != 0) { + KToggleAction* toggleAction = static_cast<KToggleAction*>(action); + toggleAction->setChecked(true); + } + + slotSortingChanged(m_activeView->sorting()); + slotSortOrderChanged(m_activeView->sortOrder()); + + KToggleAction* showFilterBarAction = + static_cast<KToggleAction*>(actionCollection()->action("show_filter_bar")); + showFilterBarAction->setChecked(m_activeView->isFilterBarVisible()); + + KToggleAction* showHiddenFilesAction = + static_cast<KToggleAction*>(actionCollection()->action("show_hidden_files")); + showHiddenFilesAction->setChecked(m_activeView->isShowHiddenFilesEnabled()); + + KToggleAction* splitAction = static_cast<KToggleAction*>(actionCollection()->action("split_view")); + splitAction->setChecked(m_view[SecondaryIdx] != 0); + + KToggleAction* leftsidebarAction = static_cast<KToggleAction*>(actionCollection()->action("leftsidebar")); + leftsidebarAction->setChecked(m_leftsidebar != 0); + + KToggleAction* rightsidebarAction = static_cast<KToggleAction*>(actionCollection()->action("rightsidebar")); + rightsidebarAction->setChecked(m_rightsidebar != 0); +} + +void Dolphin::updateGoActions() +{ + KAction* goUpAction = actionCollection()->action(KStdAction::stdName(KStdAction::Up)); + const KURL& currentURL = m_activeView->url(); + goUpAction->setEnabled(currentURL.upURL() != currentURL); +} + +void Dolphin::updateViewProperties(const KURL::List& urls) +{ + if (urls.isEmpty()) { + return; + } + + // Updating the view properties might take up to several seconds + // when dragging several thousand URLs. Writing a KIO slave for this + // use case is not worth the effort, but at least the main widget + // must be disabled and a progress should be shown. + ProgressIndicator progressIndicator(i18n("Updating view properties..."), + QString::null, + urls.count()); + + KURL::List::ConstIterator end = urls.end(); + for(KURL::List::ConstIterator it = urls.begin(); it != end; ++it) { + progressIndicator.execOperation(); + + ViewProperties props(*it); + props.save(); + } +} + +void Dolphin::copyURLs(const KURL::List& source, const KURL& dest) +{ + KIO::Job* job = KIO::copy(source, dest); + addPendingUndoJob(job, DolphinCommand::Copy, source, dest); +} + +void Dolphin::moveURLs(const KURL::List& source, const KURL& dest) +{ + KIO::Job* job = KIO::move(source, dest); + addPendingUndoJob(job, DolphinCommand::Move, source, dest); +} + +void Dolphin::addPendingUndoJob(KIO::Job* job, + DolphinCommand::Type commandType, + const KURL::List& source, + const KURL& dest) +{ + connect(job, SIGNAL(result(KIO::Job*)), + this, SLOT(addUndoOperation(KIO::Job*))); + + UndoInfo undoInfo; + undoInfo.id = job->progressId(); + undoInfo.command = DolphinCommand(commandType, source, dest); + m_pendingUndoJobs.append(undoInfo); +} + +void Dolphin::clearStatusBar() +{ + m_activeView->statusBar()->clear(); +} + +void Dolphin::openleftSidebar() +{ + if (m_leftsidebar != 0) { + // the sidebar is already open + return; + } + + m_leftsidebar = new leftSidebar(m_splitter); + m_leftsidebar->show(); + + connect(m_leftsidebar, SIGNAL(urlChanged(const KURL&)), + this, SLOT(slotURLChangeRequest(const KURL&))); + m_splitter->setCollapsible(m_leftsidebar, false); + m_splitter->setResizeMode(m_leftsidebar, QSplitter::KeepSize); + m_splitter->moveToFirst(m_leftsidebar); + + leftSidebarSettings* settings = DolphinSettings::instance().leftsidebar(); + settings->setVisible(true); +} + +void Dolphin::openrightSidebar() +{ + if (m_rightsidebar != 0) { + // the sidebar is already open + return; + } + + m_rightsidebar = new rightSidebar(m_splitter); + m_rightsidebar->show(); + + connect(m_rightsidebar, SIGNAL(urlChanged(const KURL&)), + this, SLOT(slotURLChangeRequest(const KURL&))); + m_splitter->setCollapsible(m_rightsidebar, false); + m_splitter->setResizeMode(m_rightsidebar, QSplitter::KeepSize); + m_splitter->moveToLast(m_rightsidebar); + + rightSidebarSettings* settings = DolphinSettings::instance().rightsidebar(); + settings->setVisible(true); +} + +void Dolphin::closeleftSidebar() +{ + if (m_leftsidebar == 0) { + // the sidebar has already been closed + return; + } + + // store width of sidebar and remember that the sidebar has been closed + leftSidebarSettings* settings = DolphinSettings::instance().leftsidebar(); + settings->setVisible(false); + settings->setWidth(m_leftsidebar->width()); + + m_leftsidebar->deleteLater(); + m_leftsidebar = 0; +} + +void Dolphin::closerightSidebar() +{ + if (m_rightsidebar == 0) { + // the sidebar has already been closed + return; + } + + // store width of sidebar and remember that the sidebar has been closed + rightSidebarSettings* settings = DolphinSettings::instance().rightsidebar(); + settings->setVisible(false); + settings->setWidth(m_rightsidebar->width()); + + m_rightsidebar->deleteLater(); + m_rightsidebar = 0; +} + +void Dolphin::toggleleftSidebar() +{ + if (m_leftsidebar == 0) { + openleftSidebar(); + } + else { + closeleftSidebar(); + } + + KToggleAction* leftsidebarAction = static_cast<KToggleAction*>(actionCollection()->action("leftsidebar")); + leftsidebarAction->setChecked(m_leftsidebar != 0); +} + +void Dolphin::togglerightSidebar() +{ + if (m_rightsidebar == 0) { + openrightSidebar(); + } + else { + closerightSidebar(); + } + + KToggleAction* rightsidebarAction = static_cast<KToggleAction*>(actionCollection()->action("rightsidebar")); + rightsidebarAction->setChecked(m_rightsidebar != 0); +} + +#include "dolphin.moc" diff --git a/src/dolphin.h b/src/dolphin.h new file mode 100644 index 0000000..bccfbba --- /dev/null +++ b/src/dolphin.h @@ -0,0 +1,456 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> * + * Copyright (C) 2006 by Stefan Monov <logixoul@gmail.com> * + * Copyright (C) 2006 by Cvetoslav Ludmiloff <ludmiloff@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef _DOLPHIN_H_ +#define _DOLPHIN_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <kapplication.h> +#include <kmainwindow.h> +#include <qvaluelist.h> +#include <qptrlist.h> +#include <qstring.h> +#include <ksortablevaluelist.h> + +#include "dolphinview.h" +#include "undomanager.h" + +class KPrinter; +class KURL; +class QLineEdit; +class KFileIconView; +class QHBox; +class QIconViewItem; +class QSplitter; +class KAction; +class URLNavigator; +class leftSidebar; +class rightSidebar; + +/** + * @short Main window for Dolphin. + * + * Handles the menus, toolbars and Dolphin views. + * + * @author Peter Penz <peter.penz@gmx.at> +*/ +class Dolphin : public KMainWindow +{ + Q_OBJECT + +public: + /** + * Returns the instance for the Dolphin main window. + */ + // KXMLGUIClient::instance() already in use :-( + static Dolphin& mainWin(); + + virtual ~Dolphin(); + + /** + * Activates the given view, which means that + * all menu actions are applied to this view. When + * having a split view setup the nonactive view + * is usually shown in darker colors. + */ + void setActiveView(DolphinView* view); + + /** + * Returns the currently active view. See + * Dolphin::setActiveView() for more details. + */ + DolphinView* activeView() const { return m_activeView; } + + /** + * Handles the dropping of URLs to the given + * destination. A context menu with the options + * 'Move Here', 'Copy Here', 'Link Here' and + * 'Cancel' is offered to the user. + * @param urls List of URLs which have been + * dropped. + * @param destination Destination URL, where the + * list or URLs should be moved, + * copied or linked to. + */ + void dropURLs(const KURL::List& urls, + const KURL& destination); + + /** + * Returns 'true', if the clipboard contains data + * which has been cutted by the Cut action (Ctrl + X). + */ + bool clipboardContainsCutData() const { return m_clipboardContainsCutData; } + + /** + * Returns the list of actions which are part of the file group + * of the 'Create New...' sub menu. Usually the list contains actions + * for creating folders, text files, HTML files etc. + */ + const QPtrList<KAction>& fileGroupActions() const { return m_fileGroupActions; } + //const QPtrList<KAction>& linkGroupActions() const { return m_linkGroupActions; } + //const QPtrList<KAction>& linkToDeviceActions() const { return m_linkToDeviceActions; } + + /** + * Refreshs the views of the main window by recreating them dependent from + * the given Dolphin settings. + */ + void refreshViews(); + +signals: + /** + * Is send if the active view has been changed in + * the split view mode. + */ + void activeViewChanged(); + + /** + * Is send if the selection of the currently active view has + * been changed. + */ + void selectionChanged(); + +public slots: + /** + * Updates the state of the 'Back' and 'Forward' menu + * actions corresponding the the current history. + */ + void slotHistoryChanged(); + + /** + * Updates the caption of the main window and the state + * of all menu actions which depend from a changed URL. + */ + void slotURLChanged(const KURL& url); + + /** + * Go to the given URL. + */ + void slotURLChangeRequest(const KURL& url); + + /** Updates the state of all 'View' menu actions. */ + void slotViewModeChanged(); + + /** Updates the state of the 'Show hidden files' menu action. */ + void slotShowHiddenFilesChanged(); + + /** Updates the state of the 'Show filter bar' menu action. */ + void slotShowFilterBarChanged(); + + /** Updates the state of the 'Sort by' actions. */ + void slotSortingChanged(DolphinView::Sorting sorting); + + /** Updates the state of the 'Sort Ascending/Descending' action. */ + void slotSortOrderChanged(Qt::SortOrder order); + + /** Updates the state of the 'Edit' menu actions. */ + void slotSelectionChanged(); + +protected: + /** @see QMainWindow::closeEvent */ + virtual void closeEvent(QCloseEvent* event); + + /** + * This method is called when it is time for the app to save its + * properties for session management purposes. + */ + void saveProperties(KConfig*); + + /** + * This method is called when this app is restored. The KConfig + * object points to the session management config file that was saved + * with @ref saveProperties + */ + void readProperties(KConfig*); + +private slots: + /** Opens an input dialog for creating a new folder. */ + void createFolder(); + + /** Creates a file with the MIME type given by the sender. */ + void createFile(); + + /** Renames the selected item of the active view. */ + void rename(); + + /** Moves the selected items of the active view to the trash. */ + void moveToTrash(); + + /** Deletes the selected items of the active view. */ + void deleteItems(); + + /** + * Opens the properties window for the selected items of the + * active view. The properties windows shows informations + * like name, size and permissions. + */ + void properties(); + + /** Stores all settings and quits Dolphin. */ + void quit(); + + /** + * Shows the error information of the job \a job + * in the status bar. + */ + void slotHandleJobError(KIO::Job* job); + + /** + * Indicates in the status bar that the delete operation + * of the job \a job has been finished. + */ + void slotDeleteFileFinished(KIO::Job* job); + + /** + * Updates the state of the 'Undo' menu action dependent + * from the parameter \a available. + */ + void slotUndoAvailable(bool available); + + /** Sets the text of the 'Undo' menu action to \a text. */ + void slotUndoTextChanged(const QString& text); + + /** + * Updates the state of the 'Redo' menu action dependent + * from the parameter \a available. + */ + void slotRedoAvailable(bool available); + + /** Sets the text of the 'Redo' menu action to \a text. */ + void slotRedoTextChanged(const QString& text); + + /** + * Copies all selected items to the clipboard and marks + * the items as cutted. + */ + void cut(); + + /** Copies all selected items to the clipboard. */ + void copy(); + + /** Pastes the clipboard data to the active view. */ + void paste(); + + /** + * Updates the text of the paste action dependent from + * the number of items which are in the clipboard. + */ + void updatePasteAction(); + + /** Selects all items from the active view. */ + void selectAll(); + + /** + * Inverts the selection of all items of the active view: + * Selected items get nonselected and nonselected items get + * selected. + */ + void invertSelection(); + + /** The current active view is switched to the icons mode. */ + void setIconsView(); + + /** The current active view is switched to the details mode. */ + void setDetailsView(); + + /** The current active view is switched to the previews mode. */ + void setPreviewsView(); + + /** The sorting of the current view should be done by the name. */ + void sortByName(); + + /** The sorting of the current view should be done by the size. */ + void sortBySize(); + + /** The sorting of the current view should be done by the date. */ + void sortByDate(); + + /** Switches between an ascending and descending sorting order. */ + void toggleSortOrder(); + + /** + * Switches between one and two views: + * If one view is visible, it will get split into two views. + * If already two views are visible, the nonactivated view gets closed. + */ + void toggleSplitView(); + + /** Reloads the current active view. */ + void reloadView(); + + /** Stops the loading process for the current active view. */ + void stopLoading(); + + /** + * Switches between showing and hiding of hidden marked files dependent + * from the current state of the 'Show Hidden Files' menu toggle action. + */ + void showHiddenFiles(); + + /** + * Switches between showing and hiding of the filter bar dependent + * from the current state of the 'Show Filter Bar' menu toggle action. + */ + void showFilterBar(); + + /** Increases the size of the current set view mode. */ + void zoomIn(); + + /** Decreases the size of the current set view mode. */ + void zoomOut(); + + /** + * Switches to the edit mode of the navigation bar. If the edit mode is + * already active, it is assured that the navigation bar get focused. + */ + void editLocation(); + + /** Switches to the browse mode of the navigation bar. */ + void browse(); + + /** + * Opens the view properties dialog, which allows to modify the properties + * of the currently active view. + */ + void adjustViewProperties(); + + /** Goes back on step of the URL history. */ + void goBack(); + + /** Goes forward one step of the URL history. */ + void goForward(); + + /** Goes up one hierarchy of the current URL. */ + void goUp(); + + /** Goes to the home URL. */ + void goHome(); + + /** Opens a terminal for the current shown directory. */ + void openTerminal(); + + /** Opens KFind for the current shown directory. */ + void findFile(); + + /** Opens Kompare for 2 selected files. */ + void compareFiles(); + + /** Opens the settings dialog for Dolphin. */ + void editSettings(); + + /** + * Adds the undo operation given by \a job + * to the UndoManager. + */ + void addUndoOperation(KIO::Job* job); + + + void toggleleftSidebar(); + void togglerightSidebar(); + + /** + * Stores the current sidebar width and closes + * the sidebar. + */ + void closeleftSidebar(); + void closerightSidebar(); + +private: + Dolphin(); + void init(); + void loadSettings(); + + void setupAccel(); + void setupActions(); + void setupCreateNewMenuActions(); + void updateHistory(); + void updateEditActions(); + void updateViewActions(); + void updateGoActions(); + void updateViewProperties(const KURL::List& urls); + void copyURLs(const KURL::List& source, const KURL& dest); + void moveURLs(const KURL::List& source, const KURL& dest); + void addPendingUndoJob(KIO::Job* job, + DolphinCommand::Type commandType, + const KURL::List& source, + const KURL& dest); + void clearStatusBar(); + void openleftSidebar(); + void openrightSidebar(); + + QSplitter* m_splitter; + leftSidebar* m_leftsidebar; + rightSidebar* m_rightsidebar; + DolphinView* m_activeView; + + /** + * Dolphin supports only one or two views, which + * are handled internally as primary and secondary view. + */ + enum ViewIndex + { + PrimaryIdx = 0, + SecondaryIdx = 1 + }; + DolphinView* m_view[SecondaryIdx + 1]; + + /// If set to true, the clipboard contains data which should be cutted after pasting. + bool m_clipboardContainsCutData; + + /** + * Asynchronous operations like 'Move' and 'Copy' may only be added as undo + * operation after they have been finished successfully. When an asynchronous + * operation is started, it is added to a pending undo jobs list in the meantime. + * As soon as the job has been finished, the operation is added to the undo mangager. + * @see UndoManager + * @see Dolphin::addPendingUndoJob + * @see Dolphin::addUndoOperation + */ + struct UndoInfo + { + int id; + DolphinCommand command; + }; + QValueList<UndoInfo> m_pendingUndoJobs; + + /** Contains meta information for creating files. */ + struct CreateFileEntry + { + QString name; + QString filePath; + QString templatePath; + QString icon; + QString comment; + }; + + QPtrList<KAction> m_fileGroupActions; + KSortableValueList<CreateFileEntry,QString> m_createFileTemplates; + + // TODO: not used yet. See documentation of Dolphin::linkGroupActions() + // and Dolphin::linkToDeviceActions() in for details. + //QPtrList<KAction> m_linkGroupActions; + //QPtrList<KAction> m_linkToDeviceActions; +}; + +#endif // _DOLPHIN_H_ + diff --git a/src/dolphin.lsm b/src/dolphin.lsm new file mode 100644 index 0000000..6733258 --- /dev/null +++ b/src/dolphin.lsm @@ -0,0 +1,16 @@ +Begin3 +Title: Dolphin -- Some description +Version: 0.1 +Entered-date: +Description: +Keywords: KDE Qt +Author: Peter Penz <peter.penz@gmx.at> +Maintained-by: Peter Penz <peter.penz@gmx.at> +Home-page: +Alternate-site: +Primary-site: ftp://ftp.kde.org/pub/kde/unstable/apps/utils + xxxxxx dolphin-0.1.tar.gz + xxx dolphin-0.1.lsm +Platform: Linux. Needs KDE +Copying-policy: GPL +End diff --git a/src/dolphincontextmenu.cpp b/src/dolphincontextmenu.cpp new file mode 100644 index 0000000..7ac2a56 --- /dev/null +++ b/src/dolphincontextmenu.cpp @@ -0,0 +1,494 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) and * + * Cvetoslav Ludmiloff * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphincontextmenu.h" + +#include <kactioncollection.h> +#include <kbookmarkmanager.h> +#include <kbookmark.h> +#include <ktrader.h> +#include <klocale.h> +#include <krun.h> +#include <qdir.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include <kiconloader.h> +#include <kaction.h> +#include <kpropertiesdialog.h> +#include <kdesktopfile.h> +#include <assert.h> +#include <ksortablevaluelist.h> +#include <kio/netaccess.h> +#include <konq_operations.h> + +#include "dolphin.h" +#include "dolphinview.h" +#include "editbookmarkdialog.h" +#include "dolphinsettings.h" + + +DolphinContextMenu::DolphinContextMenu(DolphinView* parent, + KFileItem* fileInfo, + const QPoint& pos) : + m_dolphinView(parent), + m_fileInfo(fileInfo), + m_pos(pos) +{ +} + +void DolphinContextMenu::open() +{ + if (m_fileInfo == 0) { + openViewportContextMenu(); + } + else { + openItemContextMenu(); + } +} + +DolphinContextMenu::~DolphinContextMenu() +{ +} + +void DolphinContextMenu::openViewportContextMenu() +{ + // Parts of the following code have been taken + // from the class KonqOperations located in + // libqonq/konq_operations.h of Konqueror. + // (Copyright (C) 2000 David Faure <faure@kde.org>) + + assert(m_fileInfo == 0); + const int propertiesID = 100; + const int bookmarkID = 101; + + KPopupMenu* popup = new KPopupMenu(m_dolphinView); + Dolphin& dolphin = Dolphin::mainWin(); + + // setup 'Create New' menu + KPopupMenu* createNewMenu = new KPopupMenu(); + + KAction* createFolderAction = dolphin.actionCollection()->action("create_folder"); + if (createFolderAction != 0) { + createFolderAction->plug(createNewMenu); + } + + createNewMenu->insertSeparator(); + + KAction* action = 0; + + QPtrListIterator<KAction> fileGrouptIt(dolphin.fileGroupActions()); + while ((action = fileGrouptIt.current()) != 0) { + action->plug(createNewMenu); + ++fileGrouptIt; + } + + // TODO: not used yet. See documentation of Dolphin::linkGroupActions() + // and Dolphin::linkToDeviceActions() in the header file for details. + // + //createNewMenu->insertSeparator(); + // + //QPtrListIterator<KAction> linkGroupIt(dolphin.linkGroupActions()); + //while ((action = linkGroupIt.current()) != 0) { + // action->plug(createNewMenu); + // ++linkGroupIt; + //} + // + //KPopupMenu* linkToDeviceMenu = new KPopupMenu(); + //QPtrListIterator<KAction> linkToDeviceIt(dolphin.linkToDeviceActions()); + //while ((action = linkToDeviceIt.current()) != 0) { + // action->plug(linkToDeviceMenu); + // ++linkToDeviceIt; + //} + // + //createNewMenu->insertItem(i18n("Link to Device"), linkToDeviceMenu); + + const KURL& url = dolphin.activeView()->url(); + if (url.protocol() == "trash") + { + popup->insertItem(i18n("Empty Deleted Items Folder"), emptyID); + } + else + { + popup->insertItem(SmallIcon("filenew"), i18n("Create New"), createNewMenu); + } + popup->insertSeparator(); + + KAction* pasteAction = dolphin.actionCollection()->action(KStdAction::stdName(KStdAction::Paste)); + pasteAction->plug(popup); + + // setup 'View Mode' menu + KPopupMenu* viewModeMenu = new KPopupMenu(); + + KAction* iconsMode = dolphin.actionCollection()->action("icons"); + iconsMode->plug(viewModeMenu); + + KAction* detailsMode = dolphin.actionCollection()->action("details"); + detailsMode->plug(viewModeMenu); + + KAction* previewsMode = dolphin.actionCollection()->action("previews"); + previewsMode->plug(viewModeMenu); + + popup->insertItem(i18n("View Mode"), viewModeMenu); + popup->insertSeparator(); + + popup->insertItem(i18n("Bookmark this folder"), bookmarkID); + popup->insertSeparator(); + + popup->insertItem(i18n("Properties..."), propertiesID); + + int id = popup->exec(m_pos); + if (id == emptyID) { + KonqOperations::emptyTrash(); + } + else if (id == propertiesID) { + new KPropertiesDialog(dolphin.activeView()->url()); + } + else if (id == bookmarkID) { + const KURL& url = dolphin.activeView()->url(); + KBookmark bookmark = EditBookmarkDialog::getBookmark(i18n("Add folder as bookmark"), + url.filename(), + url, + "bookmark"); + if (!bookmark.isNull()) { + KBookmarkManager* manager = DolphinSettings::instance().bookmarkManager(); + KBookmarkGroup root = manager->root(); + root.addBookmark(manager, bookmark); + manager->emitChanged(root); + } + } + + popup->deleteLater(); +} + +void DolphinContextMenu::openItemContextMenu() +{ + // Parts of the following code have been taken + // from the class KonqOperations located in + // libqonq/konq_operations.h of Konqueror. + // (Copyright (C) 2000 David Faure <faure@kde.org>) + + assert(m_fileInfo != 0); + + KPopupMenu* popup = new KPopupMenu(m_dolphinView); + Dolphin& dolphin = Dolphin::mainWin(); + const KURL::List urls = m_dolphinView->selectedURLs(); + + const KURL& url = dolphin.activeView()->url(); + if (url.protocol() == "trash") + { + popup->insertItem(i18n("&Restore"), restoreID); + } + + // insert 'Cut', 'Copy' and 'Paste' + const KStdAction::StdAction actionNames[] = { KStdAction::Cut, KStdAction::Copy, KStdAction::Paste }; + const int count = sizeof(actionNames) / sizeof(KStdAction::StdAction); + for (int i = 0; i < count; ++i) { + KAction* action = dolphin.actionCollection()->action(KStdAction::stdName(actionNames[i])); + if (action != 0) { + action->plug(popup); + } + } + popup->insertSeparator(); + + // insert 'Rename' + KAction* renameAction = dolphin.actionCollection()->action("rename"); + renameAction->plug(popup); + + // insert 'Move to Trash' for local URLs, otherwise insert 'Delete' + if (url.isLocalFile()) { + KAction* moveToTrashAction = dolphin.actionCollection()->action("move_to_trash"); + moveToTrashAction->plug(popup); + } + else { + KAction* deleteAction = dolphin.actionCollection()->action("delete"); + deleteAction->plug(popup); + } + + // insert 'Bookmark this folder...' entry + // urls is a list of selected items, so insert boolmark menu if + // urls contains only one item, i.e. no multiple selection made + if (m_fileInfo->isDir() && (urls.count() == 1)) { + popup->insertItem(i18n("Bookmark this folder"), bookmarkID); + } + + popup->insertSeparator(); + + // Insert 'Open With...' sub menu + QValueVector<KService::Ptr> openWithVector; + const int openWithID = insertOpenWithItems(popup, openWithVector); + + // Insert 'Actions' sub menu + QValueVector<KDEDesktopMimeType::Service> actionsVector; + insertActionItems(popup, actionsVector); + + // insert 'Properties...' entry + popup->insertSeparator(); + KAction* propertiesAction = dolphin.actionCollection()->action("properties"); + propertiesAction->plug(popup); + + int id = popup->exec(m_pos); + + if (id == restoreID ) { + KonqOperations::restoreTrashedItems(urls); + } + else if (id == bookmarkID) { + const KURL selectedURL(m_fileInfo->url()); + KBookmark bookmark = EditBookmarkDialog::getBookmark(i18n("Add folder as bookmark"), + selectedURL.filename(), + selectedURL, + "bookmark"); + if (!bookmark.isNull()) { + KBookmarkManager* manager = DolphinSettings::instance().bookmarkManager(); + KBookmarkGroup root = manager->root(); + root.addBookmark(manager, bookmark); + manager->emitChanged(root); + } + } + else if (id >= actionsIDStart) { + // one of the 'Actions' items has been selected + KDEDesktopMimeType::executeService(urls, actionsVector[id - actionsIDStart]); + } + else if (id >= openWithIDStart) { + // one of the 'Open With' items has been selected + if (id == openWithID) { + // the item 'Other...' has been selected + KRun::displayOpenWithDialog(urls); + } + else { + KService::Ptr servicePtr = openWithVector[id - openWithIDStart]; + KRun::run(*servicePtr, urls); + } + } + + openWithVector.clear(); + actionsVector.clear(); + popup->deleteLater(); +} + +int DolphinContextMenu::insertOpenWithItems(KPopupMenu* popup, + QValueVector<KService::Ptr>& openWithVector) +{ + // Prepare 'Open With' sub menu. Usually a sub menu is created, where all applications + // are listed which are registered to open the item. As last entry "Other..." will be + // attached which allows to select a custom application. If no applications are registered + // no sub menu is created at all, only "Open With..." will be offered. + const KFileItemList* list = m_dolphinView->selectedItems(); + assert(list != 0); + + bool insertOpenWithItems = true; + const QString contextMimeType(m_fileInfo->mimetype()); + KFileItemListIterator mimeIt(*list); + KFileItem* item = 0; + while (insertOpenWithItems && ((item = mimeIt.current()) != 0)) { + insertOpenWithItems = (contextMimeType == item->mimetype()); + ++mimeIt; + } + + int openWithID = -1; + + if (insertOpenWithItems) { + // fill the 'Open with' sub menu with application types + const KMimeType::Ptr mimePtr = KMimeType::findByURL(m_fileInfo->url()); + KTrader::OfferList offers = KTrader::self()->query(mimePtr->name(), + "Type == 'Application'"); + int index = openWithIDStart; + if (offers.count() > 0) { + KTrader::OfferList::Iterator it; + KPopupMenu* openWithMenu = new KPopupMenu(); + for(it = offers.begin(); it != offers.end(); ++it) { + // The offer list from the KTrader returns duplicate + // application entries. Although this seems to be a configuration + // problem outside the scope of Dolphin, duplicated entries just + // will be skipped here. + const QString appName((*it)->name()); + if (!containsEntry(openWithMenu, appName)) { + openWithMenu->insertItem((*it)->pixmap(KIcon::Small), + appName, index); + openWithVector.append(*it); + ++index; + } + } + + openWithMenu->insertSeparator(); + openWithMenu->insertItem(i18n("&Other..."), index); + popup->insertItem(i18n("Open With"), openWithMenu); + } + else { + // No applications are registered, hence just offer + // a "Open With..." item instead of a sub menu containing + // only one entry. + popup->insertItem(i18n("Open With..."), openWithIDStart); + } + openWithID = index; + } + else { + // At least one of the selected items has a different MIME type. In this case + // just show a disabled "Open With..." entry. + popup->insertItem(i18n("Open With..."), openWithIDStart); + popup->setItemEnabled(openWithIDStart, false); + } + + popup->setItemEnabled(openWithID, insertOpenWithItems); + + return openWithID; +} + +void DolphinContextMenu::insertActionItems(KPopupMenu* popup, + QValueVector<KDEDesktopMimeType::Service>& actionsVector) +{ + KPopupMenu* actionsMenu = new KPopupMenu(); + + int actionsIndex = 0; + + QStringList dirs = KGlobal::dirs()->findDirs("data", "d3lphin/servicemenus/"); + + KPopupMenu* menu = 0; + for (QStringList::ConstIterator dirIt = dirs.begin(); dirIt != dirs.end(); ++dirIt) { + QDir dir(*dirIt); + QStringList entries = dir.entryList("*.desktop", QDir::Files); + + for (QStringList::ConstIterator entryIt = entries.begin(); entryIt != entries.end(); ++entryIt) { + KSimpleConfig cfg(*dirIt + *entryIt, true); + cfg.setDesktopGroup(); + if ((cfg.hasKey("Actions") || cfg.hasKey("X-KDE-GetActionMenu")) && cfg.hasKey("ServiceTypes")) { + const QStringList types = cfg.readListEntry("ServiceTypes"); + for (QStringList::ConstIterator it = types.begin(); it != types.end(); ++it) { + // check whether the mime type is equal or whether the + // mimegroup (e. g. image/*) is supported + + bool insert = false; + if ((*it) == "all/allfiles") { + // The service type is valid for all files, but not for directories. + // Check whether the selected items only consist of files... + const KFileItemList* list = m_dolphinView->selectedItems(); + assert(list != 0); + + KFileItemListIterator mimeIt(*list); + KFileItem* item = 0; + insert = true; + while (insert && ((item = mimeIt.current()) != 0)) { + insert = !item->isDir(); + ++mimeIt; + } + } + + if (!insert) { + // Check whether the MIME types of all selected files match + // to the mimetype of the service action. As soon as one MIME + // type does not match, no service menu is shown at all. + const KFileItemList* list = m_dolphinView->selectedItems(); + assert(list != 0); + + KFileItemListIterator mimeIt(*list); + KFileItem* item = 0; + insert = true; + while (insert && ((item = mimeIt.current()) != 0)) { + const QString mimeType((*mimeIt)->mimetype()); + const QString mimeGroup(mimeType.left(mimeType.find('/'))); + + insert = (*it == mimeType) || + ((*it).right(1) == "*") && + ((*it).left((*it).find('/')) == mimeGroup); + ++mimeIt; + } + } + + if (insert) { + menu = actionsMenu; + + const QString submenuName = cfg.readEntry( "X-KDE-Submenu" ); + if (!submenuName.isEmpty()) { + menu = new KPopupMenu(); + actionsMenu->insertItem(submenuName, menu, submenuID); + } + + QValueList<KDEDesktopMimeType::Service> userServices = + KDEDesktopMimeType::userDefinedServices(*dirIt + *entryIt, true); + + QValueList<KDEDesktopMimeType::Service>::Iterator serviceIt; + for (serviceIt = userServices.begin(); serviceIt != userServices.end(); ++serviceIt) { + KDEDesktopMimeType::Service service = (*serviceIt); + if (!service.m_strIcon.isEmpty()) { + menu->insertItem(SmallIcon(service.m_strIcon), + service.m_strName, + actionsIDStart + actionsIndex); + } + else { + menu->insertItem(service.m_strName, + actionsIDStart + actionsIndex); + } + actionsVector.append(service); + ++actionsIndex; + } + } + } + } + } + } + + const int itemsCount = actionsMenu->count(); + if (itemsCount == 0) { + // no actions are available at all, hence show the "Actions" + // submenu disabled + actionsMenu->setEnabled(false); + } + + if (itemsCount == 1) { + // Exactly one item is available. Instead of showing a sub menu with + // only one item, show the item directly in the root menu. + if (menu == actionsMenu) { + // The item is an action, hence show the action in the root menu. + const int id = actionsMenu->idAt(0); + const QString text(actionsMenu->text(id)); + const QIconSet* iconSet = actionsMenu->iconSet(id); + if (iconSet == 0) { + popup->insertItem(text, id); + } + else { + popup->insertItem(*iconSet, text, id); + } + } + else { + // The item is a sub menu, hence show the sub menu in the root menu. + popup->insertItem(actionsMenu->text(submenuID), menu); + } + actionsMenu->deleteLater(); + actionsMenu = 0; + } + else { + popup->insertItem(i18n("Actions"), actionsMenu); + } +} + +bool DolphinContextMenu::containsEntry(const KPopupMenu* menu, + const QString& entryName) const +{ + assert(menu != 0); + + const uint count = menu->count(); + for (uint i = 0; i < count; ++i) { + const int id = menu->idAt(i); + if (menu->text(id) == entryName) { + return true; + } + } + + return false; +} diff --git a/src/dolphincontextmenu.h b/src/dolphincontextmenu.h new file mode 100644 index 0000000..f14419e --- /dev/null +++ b/src/dolphincontextmenu.h @@ -0,0 +1,130 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef DOLPHINCONTEXTMENU_H +#define DOLPHINCONTEXTMENU_H + +#include <kpopupmenu.h> +#include <qpoint.h> +#include <qstring.h> +#include <qvaluelist.h> +#include <kmountpoint.h> +#include <qvaluevector.h> +#include <kservice.h> +#include <kpropertiesdialog.h> + +class KPopupMenu; +class KFileItem; +class QPoint; +class QWidget; +class DolphinView; + +/** + * @brief Represents the context menu which appears when doing a right + * click on an item or the viewport of the file manager. + * + * Beside static menu entries (e. g. 'Paste' or 'Properties') two + * dynamic sub menus are shown when opening a context menu above + * an item: + * - 'Open With': Contains all applications which are registered to + * open items of the given MIME type. + * - 'Actions': Contains all actions which can be applied to the + * given item. + * + * @author Peter Penz <peter.penz@gmx.at> + */ +class DolphinContextMenu +{ +public: + /** + * @parent Pointer to the dolphin view the context menu + * belongs to. + * @fileInfo Pointer to the file item the context menu + * is applied. If 0 is passed, the context menu + * is above the viewport. + * @pos Position of the upper left edge of the context menu. + */ + DolphinContextMenu(DolphinView* parent, + KFileItem* fileInfo, + const QPoint& pos); + + virtual ~DolphinContextMenu(); + + /** Opens the context menu modal. */ + void open(); + +private: + void openViewportContextMenu(); + void openItemContextMenu(); + + /** + * Inserts the 'Open With...' submenu to \a popup. + * @param popup Menu where the 'Open With...' sub menu should + * be added. + * @param openWithVector Output parameter which contains all 'Open with...' + * services. + * @return Identifier of the first 'Open With...' entry. + * All succeeding identifiers have an increased value of 1 + * to the predecessor. + */ + int insertOpenWithItems(KPopupMenu* popup, + QValueVector<KService::Ptr>& openWithVector); + + /** + * Inserts the 'Actions...' submenu to \a popup. + * @param popup Menu where the 'Actions...' sub menu should + * be added. + * @param openWithVector Output parameter which contains all 'Actions...' + * services. + */ + void insertActionItems(KPopupMenu* popup, + QValueVector<KDEDesktopMimeType::Service>& actionsVector); + + /** + * Returns true, if 'menu' contains already + * an entry with the name 'entryName'. + */ + bool containsEntry(const KPopupMenu* menu, + const QString& entryName) const; + + enum { + restoreID = 80, + emptyID = 85, + submenuID = 90, + bookmarkID = 91, + openWithIDStart = 100, + actionsIDStart = 1000, + }; + + DolphinView* m_dolphinView; + KFileItem* m_fileInfo; + QPoint m_pos; + + struct Entry { + int type; + QString name; + QString filePath; // empty for separator + QString templatePath; // same as filePath for template + QString icon; + QString comment; + }; +}; + +#endif diff --git a/src/dolphindetailsview.cpp b/src/dolphindetailsview.cpp new file mode 100644 index 0000000..66d524e --- /dev/null +++ b/src/dolphindetailsview.cpp @@ -0,0 +1,789 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphindetailsview.h" + +#include <kurldrag.h> +#include <qpainter.h> +#include <qobjectlist.h> +#include <qheader.h> +#include <qclipboard.h> +#include <qpainter.h> +#include <klocale.h> +#include <kglobalsettings.h> +#include <qscrollbar.h> +#include <qcursor.h> +#include <qstyle.h> +#include <assert.h> + +#include "dolphinview.h" +#include "viewproperties.h" +#include "dolphin.h" +#include "kiconeffect.h" +#include "dolphinsettings.h" +#include "dolphinstatusbar.h" +#include "dolphindetailsviewsettings.h" + +DolphinDetailsView::DolphinDetailsView(DolphinView* parent) : + KFileDetailView(parent, 0), + m_dolphinView(parent), + m_resizeTimer(0), + m_scrollTimer(0), + m_rubber(0) +{ + m_resizeTimer = new QTimer(this); + connect(m_resizeTimer, SIGNAL(timeout()), + this, SLOT(updateColumnsWidth())); + + setAcceptDrops(true); + setSelectionMode(KFile::Extended); + setHScrollBarMode(QScrollView::AlwaysOff); + + setColumnAlignment(SizeColumn, Qt::AlignRight); + for (int i = DateColumn; i <= GroupColumn; ++i) { + setColumnAlignment(i, Qt::AlignHCenter); + } + + Dolphin& dolphin = Dolphin::mainWin(); + + connect(this, SIGNAL(onItem(QListViewItem*)), + this, SLOT(slotOnItem(QListViewItem*))); + connect(this, SIGNAL(onViewport()), + this, SLOT(slotOnViewport())); + connect(this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)), + this, SLOT(slotContextMenuRequested(QListViewItem*, const QPoint&, int))); + connect(this, SIGNAL(selectionChanged()), + &dolphin, SLOT(slotSelectionChanged())); + connect(&dolphin, SIGNAL(activeViewChanged()), + this, SLOT(slotActivationUpdate())); + connect(this, SIGNAL(itemRenamed(QListViewItem*, const QString&, int)), + this, SLOT(slotItemRenamed(QListViewItem*, const QString&, int))); + connect(this, SIGNAL(dropped(QDropEvent*, const KURL::List&, const KURL&)), + parent, SLOT(slotURLListDropped(QDropEvent*, const KURL::List&, const KURL&))); + + QClipboard* clipboard = QApplication::clipboard(); + connect(clipboard, SIGNAL(dataChanged()), + this, SLOT(slotUpdateDisabledItems())); + + QHeader* viewHeader = header(); + viewHeader->setResizeEnabled(false); + viewHeader->setMovingEnabled(false); + connect(viewHeader, SIGNAL(clicked(int)), + this, SLOT(slotHeaderClicked(int))); + + setMouseTracking(true); + setDefaultRenameAction(QListView::Accept); + + refreshSettings(); +} + +DolphinDetailsView::~DolphinDetailsView() +{ + delete m_rubber; + m_rubber = 0; +} + +void DolphinDetailsView::beginItemUpdates() +{ +} + +void DolphinDetailsView::endItemUpdates() +{ + updateDisabledItems(); + + // Restore the current item. Use the information stored in the history if + // available. Otherwise use the first item as current item. + + const KFileListViewItem* item = static_cast<const KFileListViewItem*>(firstChild()); + if (item != 0) { + setCurrentItem(item->fileInfo()); + } + + int index = 0; + const QValueList<URLNavigator::HistoryElem> history = m_dolphinView->urlHistory(index); + if (!history.isEmpty()) { + KFileView* fileView = static_cast<KFileView*>(this); + fileView->setCurrentItem(history[index].currentFileName()); + setContentsPos(history[index].contentsX(), history[index].contentsY()); + } + + updateColumnsWidth(); +} + +void DolphinDetailsView::insertItem(KFileItem* fileItem) +{ + KFileView::insertItem(fileItem); + + DolphinListViewItem* item = new DolphinListViewItem(static_cast<QListView*>(this), fileItem); + + QDir::SortSpec spec = KFileView::sorting(); + if (spec & QDir::Time) { + item->setKey(sortingKey(fileItem->time(KIO::UDS_MODIFICATION_TIME), + fileItem->isDir(), + spec)); + } + else if (spec & QDir::Size) { + item->setKey(sortingKey(fileItem->size(), fileItem->isDir(), spec)); + } + else { + item->setKey(sortingKey(fileItem->text(), fileItem->isDir(), spec)); + } + + fileItem->setExtraData(this, item); +} + +bool DolphinDetailsView::isOnFilename(const QListViewItem* item, const QPoint& pos) const +{ + const QPoint absPos(mapToGlobal(QPoint(0, 0))); + return (pos.x() - absPos.x()) <= filenameWidth(item); +} + +void DolphinDetailsView::refreshSettings() +{ + const DolphinDetailsViewSettings* settings = DolphinSettings::instance().detailsView(); + assert(settings != 0); + + for (int i = DolphinDetailsView::GroupColumn; i >= DolphinDetailsView::NameColumn; --i) { + if (!settings->isColumnEnabled(i)) { + removeColumn(i); + } + } + + QFont adjustedFont(font()); + adjustedFont.setFamily(settings->fontFamily()); + adjustedFont.setPointSize(settings->fontSize()); + setFont(adjustedFont); + + updateView(true); +} + +void DolphinDetailsView::zoomIn() +{ + if (isZoomInPossible()) { + DolphinDetailsViewSettings* settings = DolphinSettings::instance().detailsView(); + switch (settings->iconSize()) { + case KIcon::SizeSmall: settings->setIconSize(KIcon::SizeMedium); break; + case KIcon::SizeMedium: settings->setIconSize(KIcon::SizeLarge); break; + default: assert(false); break; + } + ItemEffectsManager::zoomIn(); + } +} + +void DolphinDetailsView::zoomOut() +{ + if (isZoomOutPossible()) { + DolphinDetailsViewSettings* settings = DolphinSettings::instance().detailsView(); + switch (settings->iconSize()) { + case KIcon::SizeLarge: settings->setIconSize(KIcon::SizeMedium); break; + case KIcon::SizeMedium: settings->setIconSize(KIcon::SizeSmall); break; + default: assert(false); break; + } + ItemEffectsManager::zoomOut(); + } +} + +bool DolphinDetailsView::isZoomInPossible() const +{ + DolphinDetailsViewSettings* settings = DolphinSettings::instance().detailsView(); + return settings->iconSize() < KIcon::SizeLarge; +} + +bool DolphinDetailsView::isZoomOutPossible() const +{ + DolphinDetailsViewSettings* settings = DolphinSettings::instance().detailsView(); + return settings->iconSize() > KIcon::SizeSmall; +} + +void DolphinDetailsView::resizeContents(int width, int height) +{ + KFileDetailView::resizeContents(width, height); + + // When loading several 1000 items a punch of resize events + // drops in. As updating the column width is a quite expensive + // operation, this operation will be postponed until there is + // no resize event for at least 50 milliseconds. + m_resizeTimer->stop(); + m_resizeTimer->start(50, true); +} + +void DolphinDetailsView::slotOnItem(QListViewItem* item) +{ + if (isOnFilename(item, QCursor::pos())) { + activateItem(item); + KFileItem* fileItem = static_cast<KFileListViewItem*>(item)->fileInfo(); + m_dolphinView->requestItemInfo(fileItem->url()); + } + else { + resetActivatedItem(); + } +} + +void DolphinDetailsView::slotOnViewport() +{ + resetActivatedItem(); + m_dolphinView->requestItemInfo(KURL()); +} + +void DolphinDetailsView::setContextPixmap(void* context, + const QPixmap& pixmap) +{ + reinterpret_cast<KFileListViewItem*>(context)->setPixmap(0, pixmap); +} + +const QPixmap* DolphinDetailsView::contextPixmap(void* context) +{ + return reinterpret_cast<KFileListViewItem*>(context)->pixmap(0); +} + +void* DolphinDetailsView::firstContext() +{ + return reinterpret_cast<void*>(firstChild()); +} + +void* DolphinDetailsView::nextContext(void* context) +{ + KFileListViewItem* listViewItem = reinterpret_cast<KFileListViewItem*>(context); + return reinterpret_cast<void*>(listViewItem->nextSibling()); +} + +KFileItem* DolphinDetailsView::contextFileInfo(void* context) +{ + return reinterpret_cast<KFileListViewItem*>(context)->fileInfo(); +} + + +void DolphinDetailsView::contentsDragMoveEvent(QDragMoveEvent* event) +{ + KFileDetailView::contentsDragMoveEvent(event); + + // If a dragging is done above a directory, show the icon as 'active' for + // a visual feedback + KFileListViewItem* item = static_cast<KFileListViewItem*>(itemAt(event->pos())); + + bool showActive = false; + if (item != 0) { + const KFileItem* fileInfo = item->fileInfo(); + showActive = (fileInfo != 0) && fileInfo->isDir(); + } + + if (showActive) { + slotOnItem(item); + } + else { + slotOnViewport(); + } +} + +void DolphinDetailsView::resizeEvent(QResizeEvent* event) +{ + KFileDetailView::resizeEvent(event); + + // When loading several 1000 items a punch of resize events + // drops in. As updating the column width is a quite expensive + // operation, this operation will be postponed until there is + // no resize event for at least 50 milliseconds. + m_resizeTimer->stop(); + m_resizeTimer->start(50, true); +} + +bool DolphinDetailsView::acceptDrag(QDropEvent* event) const +{ + bool accept = KURLDrag::canDecode(event) && + (event->action() == QDropEvent::Copy || + event->action() == QDropEvent::Move || + event->action() == QDropEvent::Link); + if (accept) { + if (static_cast<const QWidget*>(event->source()) == this) { + KFileListViewItem* item = static_cast<KFileListViewItem*>(itemAt(event->pos())); + accept = (item != 0); + if (accept) { + KFileItem* fileItem = item->fileInfo(); + accept = fileItem->isDir(); + } + } + } + + return accept; +} + +void DolphinDetailsView::contentsDropEvent(QDropEvent* event) +{ + // KFileDetailView::contentsDropEvent does not care whether the mouse + // cursor is above a filename or not, the destination URL is always + // the URL of the item. This is fixed here in a way that the destination + // URL is only the URL of the item if the cursor is above the filename. + const QPoint pos(QCursor::pos()); + const QPoint viewportPos(viewport()->mapToGlobal(QPoint(0, 0))); + QListViewItem* item = itemAt(QPoint(pos.x() - viewportPos.x(), pos.y() - viewportPos.y())); + if ((item == 0) || ((item != 0) && isOnFilename(item, pos))) { + // dropping is done on the viewport or directly above a filename + KFileDetailView::contentsDropEvent(event); + return; + } + + // Dropping is done above an item, but the mouse cursor is not above the file name. + // In this case the signals of the base implementation will be blocked and send + // in a corrected manner afterwards. + assert(item != 0); + const bool block = signalsBlocked(); + blockSignals(true); + KFileDetailView::contentsDropEvent(event); + blockSignals(block); + + if (!acceptDrag(event)) { + return; + } + + emit dropped(event, 0); + KURL::List urls; + if (KURLDrag::decode(event, urls) && !urls.isEmpty()) { + emit dropped(event, urls, KURL()); + sig->dropURLs(0, event, urls); + } +} + +void DolphinDetailsView::contentsMousePressEvent(QMouseEvent* event) +{ + if (m_rubber != 0) { + drawRubber(); + delete m_rubber; + m_rubber = 0; + } + + // Swallow the base implementation of the mouse press event + // if the mouse cursor is not above the filename. This prevents + // that the item gets selected and simulates an equal usability + // like in the icon view. + const QPoint pos(QCursor::pos()); + const QPoint viewportPos(viewport()->mapToGlobal(QPoint(0, 0))); + QListViewItem* item = itemAt(QPoint(pos.x() - viewportPos.x(), pos.y() - viewportPos.y())); + if ((item != 0) && isOnFilename(item, pos)) { + KFileDetailView::contentsMousePressEvent(event); + } + else if (event->button() == Qt::LeftButton) { + const ButtonState keyboardState = KApplication::keyboardMouseState(); + const bool isSelectionActive = (keyboardState & ShiftButton) || + (keyboardState & ControlButton); + if (!isSelectionActive) { + clearSelection(); + } + + assert(m_rubber == 0); + m_rubber = new QRect(event->x(), event->y(), 0, 0); + } + + resetActivatedItem(); + emit signalRequestActivation(); + + m_dolphinView->statusBar()->clear(); +} + +void DolphinDetailsView::contentsMouseMoveEvent(QMouseEvent* event) +{ + if (m_rubber != 0) { + slotAutoScroll(); + return; + } + + KFileDetailView::contentsMouseMoveEvent(event); + + const QPoint& pos = event->globalPos(); + const QPoint viewportPos = viewport()->mapToGlobal(QPoint(0, 0)); + QListViewItem* item = itemAt(QPoint(pos.x() - viewportPos.x(), pos.y() - viewportPos.y())); + if ((item != 0) && isOnFilename(item, pos)) { + activateItem(item); + } + else { + resetActivatedItem(); + } +} + +void DolphinDetailsView::contentsMouseReleaseEvent(QMouseEvent* event) +{ + if (m_rubber != 0) { + drawRubber(); + delete m_rubber; + m_rubber = 0; + } + + if (m_scrollTimer != 0) { + disconnect(m_scrollTimer, SIGNAL(timeout()), + this, SLOT(slotAutoScroll())); + m_scrollTimer->stop(); + delete m_scrollTimer; + m_scrollTimer = 0; + } + + KFileDetailView::contentsMouseReleaseEvent(event); +} + +void DolphinDetailsView::paintEmptyArea(QPainter* painter, const QRect& rect) +{ + if (m_dolphinView->isActive()) { + KFileDetailView::paintEmptyArea(painter, rect); + } + else { + const QBrush brush(colorGroup().background()); + painter->fillRect(rect, brush); + } +} + +void DolphinDetailsView::drawRubber() +{ + // Parts of the following code have been taken + // from the class KonqBaseListViewWidget located in + // konqueror/listview/konq_listviewwidget.h of Konqueror. + // (Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> + // 2001, 2002, 2004 Michael Brade <brade@kde.org>) + if (m_rubber == 0) { + return; + } + + QPainter p; + p.begin(viewport()); + p.setRasterOp(NotROP); + p.setPen(QPen(color0, 1)); + p.setBrush(NoBrush); + + QPoint point(m_rubber->x(), m_rubber->y()); + point = contentsToViewport(point); + style().drawPrimitive(QStyle::PE_FocusRect, &p, + QRect(point.x(), point.y(), m_rubber->width(), m_rubber->height()), + colorGroup(), QStyle::Style_Default, colorGroup().base()); + p.end(); +} + +void DolphinDetailsView::viewportPaintEvent(QPaintEvent* paintEvent) +{ + drawRubber(); + KFileDetailView::viewportPaintEvent(paintEvent); + drawRubber(); +} + +void DolphinDetailsView::leaveEvent(QEvent* event) +{ + KFileDetailView::leaveEvent(event); + slotOnViewport(); +} + +void DolphinDetailsView::slotActivationUpdate() +{ + update(); + + // TODO: there must be a simpler way to say + // "update all children" + const QObjectList* list = children(); + if (list == 0) { + return; + } + + QObjectListIterator it(*list); + QObject* object = 0; + while ((object = it.current()) != 0) { + if (object->inherits("QWidget")) { + QWidget* widget = static_cast<QWidget*>(object); + widget->update(); + } + ++it; + } +} + +void DolphinDetailsView::slotContextMenuRequested(QListViewItem* item, + const QPoint& pos, + int /* col */) +{ + KFileItem* fileInfo = 0; + if ((item != 0) && isOnFilename(item, pos)) { + fileInfo = static_cast<KFileListViewItem*>(item)->fileInfo(); + } + m_dolphinView->openContextMenu(fileInfo, pos); + +} + +void DolphinDetailsView::slotUpdateDisabledItems() +{ + updateDisabledItems(); +} + +void DolphinDetailsView::slotAutoScroll() +{ + // Parts of the following code have been taken + // from the class KonqBaseListViewWidget located in + // konqueror/listview/konq_listviewwidget.h of Konqueror. + // (Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> + // 2001, 2002, 2004 Michael Brade <brade@kde.org>) + + const QPoint pos(viewport()->mapFromGlobal(QCursor::pos())); + const QPoint vc(viewportToContents(pos)); + + if (vc == m_rubber->bottomRight()) { + return; + } + + drawRubber(); + + m_rubber->setBottomRight(vc); + + QListViewItem* item = itemAt(QPoint(0,0)); + + const bool block = signalsBlocked(); + blockSignals(true); + + const QRect rubber(m_rubber->normalize()); + const int bottom = contentsY() + visibleHeight() - 1; + + // select all items which intersect with the rubber, deselect all others + bool bottomReached = false; + while ((item != 0) && !bottomReached) { + QRect rect(itemRect(item)); + rect.setWidth(filenameWidth(item)); + rect = QRect(viewportToContents(rect.topLeft()), + viewportToContents(rect.bottomRight())); + if (rect.isValid() && (rect.top() <= bottom)) { + const KFileItem* fileItem = static_cast<KFileListViewItem*>(item)->fileInfo(); + setSelected(fileItem, rect.intersects(rubber)); + item = item->itemBelow(); + } + else { + bottomReached = true; + } + } + + blockSignals(block); + emit selectionChanged(); + + drawRubber(); + + // scroll the viewport if the top or bottom margin is reached + const int scrollMargin = 40; + ensureVisible(vc.x(), vc.y(), scrollMargin, scrollMargin); + const bool scroll = !QRect(scrollMargin, + scrollMargin, + viewport()->width() - 2 * scrollMargin, + viewport()->height() - 2 * scrollMargin).contains(pos); + if (scroll) { + if (m_scrollTimer == 0) { + m_scrollTimer = new QTimer( this ); + connect(m_scrollTimer, SIGNAL(timeout()), + this, SLOT(slotAutoScroll())); + m_scrollTimer->start(100, false); + } + } + else if (m_scrollTimer != 0) { + disconnect(m_scrollTimer, SIGNAL(timeout()), + this, SLOT(slotAutoScroll())); + m_scrollTimer->stop(); + delete m_scrollTimer; + m_scrollTimer = 0; + } +} + +void DolphinDetailsView::updateColumnsWidth() +{ + const int columnCount = columns(); + int requiredWidth = 0; + for (int i = 1; i < columnCount; ++i) { + // When a directory contains no items, a minimum width for + // the column must be available, so that the header is readable. + // TODO: use header data instead of the hardcoded 64 value... + int columnWidth = 64; + QFontMetrics fontMetrics(font()); + for (QListViewItem* item = firstChild(); item != 0; item = item->nextSibling()) { + const int width = item->width(fontMetrics, this, i); + if (width > columnWidth) { + columnWidth = width; + } + } + columnWidth += 16; // add custom margin + setColumnWidth(i, columnWidth); + requiredWidth += columnWidth; + } + + // resize the first column in a way that the + // whole available width is used + int firstColumnWidth = visibleWidth() - requiredWidth; + if (firstColumnWidth < 128) { + firstColumnWidth = 128; + } + setColumnWidth(0, firstColumnWidth); +} + +void DolphinDetailsView::slotItemRenamed(QListViewItem* item, + const QString& name, + int /* column */) +{ + KFileItem* fileInfo = static_cast<KFileListViewItem*>(item)->fileInfo(); + m_dolphinView->rename(KURL(fileInfo->url()), name); +} + +void DolphinDetailsView::slotHeaderClicked(int /* section */) +{ + // The sorting has already been changed in QListView if this slot is + // invoked, but Dolphin was not informed about this (no signal is available + // which indicates a change of the sorting). This is bypassed by changing + // the sorting and sort order to a temporary other value and readjust it again. + const int column = sortColumn(); + if (column <= DateColumn) { + DolphinView::Sorting sorting = DolphinView::SortByName; + switch (column) { + case SizeColumn: sorting = DolphinView::SortBySize; break; + case DateColumn: sorting = DolphinView::SortByDate; break; + case NameColumn: + default: break; + } + + const Qt::SortOrder currSortOrder = sortOrder(); + + // temporary adjust the sorting and sort order to different values... + const DolphinView::Sorting tempSorting = (sorting == DolphinView::SortByName) ? + DolphinView::SortBySize : + DolphinView::SortByName; + m_dolphinView->setSorting(tempSorting); + const Qt::SortOrder tempSortOrder = (currSortOrder == Qt::Ascending) ? + Qt::Descending : Qt::Ascending; + m_dolphinView->setSortOrder(tempSortOrder); + + // ... so that setting them again results in storing the new setting. + m_dolphinView->setSorting(sorting); + m_dolphinView->setSortOrder(currSortOrder); + } +} + +DolphinDetailsView::DolphinListViewItem::DolphinListViewItem(QListView* parent, + KFileItem* fileItem) : + KFileListViewItem(parent, fileItem) +{ + const int iconSize = DolphinSettings::instance().detailsView()->iconSize(); + KFileItem* info = fileInfo(); + setPixmap(DolphinDetailsView::NameColumn, info->pixmap(iconSize)); + + // The base class KFileListViewItem represents the column 'Size' only as byte values. + // Adjust those values in a way that a mapping to GBytes, MBytes, KBytes and Bytes + // is done. As the file size for directories is useless (only the size of the directory i-node + // is given), it is removed completely. + if (fileItem->isDir()) { + setText(SizeColumn, " - "); + } + else { + QString sizeText(KIO::convertSize(fileItem->size())); + sizeText.append(" "); + setText(SizeColumn, sizeText); + } + + // Dolphin allows to remove specific columns, but the base class KFileListViewItem + // is not aware about this (or at least the class KFileDetailView does not react on + // QListView::remove()). Therefore the columns are rearranged here. + const DolphinDetailsViewSettings* settings = DolphinSettings::instance().detailsView(); + assert(settings != 0); + + int column_idx = DateColumn; // the columns for 'name' and 'size' cannot get removed + for (int i = DolphinDetailsView::DateColumn; i <= DolphinDetailsView::GroupColumn; ++i) { + if (column_idx < i) { + setText(column_idx, text(i)); + } + if (settings->isColumnEnabled(i)) { + ++column_idx; + } + } +} + +DolphinDetailsView::DolphinListViewItem::~DolphinListViewItem() +{ +} + +void DolphinDetailsView::DolphinListViewItem::paintCell(QPainter* painter, + const QColorGroup& colorGroup, + int column, + int cellWidth, + int alignment) +{ + const QListView* view = listView(); + const bool isActive = view->parent() == Dolphin::mainWin().activeView(); + if (isSelected()) { + // Per default the selection is drawn above the whole width of the item. As a consistent + // behavior with the icon view is wanted, only the the column containing the file name + // should be shown as selected. + QColorGroup defaultColorGroup(colorGroup); + const QColor highlightColor(isActive ? backgroundColor(column) : view->colorGroup().background()); + defaultColorGroup.setColor(QColorGroup::Highlight , highlightColor); + defaultColorGroup.setColor(QColorGroup::HighlightedText, colorGroup.color(QColorGroup::Text)); + KFileListViewItem::paintCell(painter, defaultColorGroup, column, cellWidth, alignment); + + if (column == 0) { + // draw the selection only on the first column + QListView* parent = listView(); + const int itemWidth = width(parent->fontMetrics(), parent, 0); + if (isActive) { + KFileListViewItem::paintCell(painter, colorGroup, column, itemWidth, alignment); + } + else { + QListViewItem::paintCell(painter, colorGroup, column, itemWidth, alignment); + } + } + } + else { + if (isActive) { + KFileListViewItem::paintCell(painter, colorGroup, column, cellWidth, alignment); + } + else { + QListViewItem::paintCell(painter, colorGroup, column, cellWidth, alignment); + } + } + + if (column < listView()->columns() - 1) { + // draw a separator between columns + painter->setPen(KGlobalSettings::buttonBackground()); + painter->drawLine(cellWidth - 1, 0, cellWidth - 1, height() - 1); + } +} + +void DolphinDetailsView::DolphinListViewItem::paintFocus(QPainter* painter, + const QColorGroup& colorGroup, + const QRect& rect) +{ + // draw the focus consistently with the selection (see implementation notes + // in DolphinListViewItem::paintCell) + QListView* parent = listView(); + int visibleWidth = width(parent->fontMetrics(), parent, 0); + const int colWidth = parent->columnWidth(0); + if (visibleWidth > colWidth) { + visibleWidth = colWidth; + } + + QRect focusRect(rect); + focusRect.setWidth(visibleWidth); + + KFileListViewItem::paintFocus(painter, colorGroup, focusRect); +} + +int DolphinDetailsView::filenameWidth(const QListViewItem* item) const +{ + assert(item != 0); + + int visibleWidth = item->width(fontMetrics(), this, 0); + const int colWidth = columnWidth(0); + if (visibleWidth > colWidth) { + visibleWidth = colWidth; + } + + return visibleWidth; +} +#include "dolphindetailsview.moc" diff --git a/src/dolphindetailsview.h b/src/dolphindetailsview.h new file mode 100644 index 0000000..e1ee95f --- /dev/null +++ b/src/dolphindetailsview.h @@ -0,0 +1,216 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef DOLPHINDETAILSVIEW_H +#define DOLPHINDETAILSVIEW_H + +#include <kfiledetailview.h> +#include <itemeffectsmanager.h> + +class QRect; +class QTimer; +class DolphinView; + +/** + * @brief Represents the details view which shows the name, size, + * date, permissions, owner and group of an item. + * + * The width of the columns are automatically adjusted in a way + * that full available width of the view is used by stretching the width + * of the name column. + * + * @author Peter Penz + */ +class DolphinDetailsView : public KFileDetailView, public ItemEffectsManager +{ + Q_OBJECT + +public: + /** + * Maps the column indices of KFileDetailView to a + * descriptive column name. + */ + enum ColumnName { + NameColumn = 0, + SizeColumn = 1, + DateColumn = 2, + PermissionsColumn = 3, + OwnerColumn = 4, + GroupColumn = 5 + }; + + DolphinDetailsView(DolphinView* parent); + + virtual ~DolphinDetailsView(); + + /** @see ItemEffectsManager::updateItems */ + virtual void beginItemUpdates(); + + /** @see ItemEffectsManager::updateItems */ + virtual void endItemUpdates(); + + /** @see KFileView::insertItem */ + virtual void insertItem(KFileItem* fileItem); + + /** + * @return True, if the position \a pos is above the name of + * item \a item. + */ + bool isOnFilename(const QListViewItem* item, const QPoint& pos) const; + + /** + * Reads out the dolphin settings for the details view and refreshs + * the details view. + */ + // TODO: Other view implementations use a similar interface. When using + // Interview in Qt4 this method should be moved to a base class (currently + // not possible due to having different base classes for the views). + void refreshSettings(); + + /** @see ItemEffectsManager::zoomIn() */ + virtual void zoomIn(); + + /** @see ItemEffectsManager::zoomOut() */ + virtual void zoomOut(); + + /** @see ItemEffectsManager::isZoomInPossible() */ + virtual bool isZoomInPossible() const; + + /** @see ItemEffectsManager::isZoomOutPossible() */ + virtual bool isZoomOutPossible() const; + +signals: + /** + * Is send, if the details view should be activated. Usually an activation + * is triggered by a mouse click. + */ + void signalRequestActivation(); + +public slots: + /** @see KFileDetailView::resizeContents */ + virtual void resizeContents(int width, int height); + + /** Is connected to the onItem-signal from KFileDetailView. */ + void slotOnItem(QListViewItem* item); + + /** Is connected to the onViewport-signal from KFileDetailView. */ + void slotOnViewport(); + +protected: + /** @see ItemEffectsManager::setContextPixmap() */ + virtual void setContextPixmap(void* context, + const QPixmap& pixmap); + + /** @see ItemEffectsManager::setContextPixmap() */ + virtual const QPixmap* contextPixmap(void* context); + + /** @see ItemEffectsManager::setContextPixmap() */ + virtual void* firstContext(); + + /** @see ItemEffectsManager::setContextPixmap() */ + virtual void* nextContext(void* context); + + /** @see ItemEffectsManager::setContextPixmap() */ + virtual KFileItem* contextFileInfo(void* context); + + /** @see KFileDetailView::contentsDragMoveEvent() */ + virtual void contentsDragMoveEvent(QDragMoveEvent* event); + + /** @see KFileDetailView::resizeEvent() */ + virtual void resizeEvent(QResizeEvent* event); + + /** @see KFileDetailView::acceptDrag() */ + virtual bool acceptDrag (QDropEvent* event) const; + + /** @see KFileDetailView::contentsDropEvent() */ + virtual void contentsDropEvent(QDropEvent* event); + + /** @see KFileDetailView::contentsMousePressEvent() */ + virtual void contentsMousePressEvent(QMouseEvent* event); + + /** @see KFileDetailView::contentsMouseMoveEvent() */ + virtual void contentsMouseMoveEvent(QMouseEvent* event); + + /** @see KFileDetailView::contentsMouseReleaseEvent() */ + virtual void contentsMouseReleaseEvent(QMouseEvent* event); + + /** @see QListView::paintEmptyArea() */ + virtual void paintEmptyArea(QPainter* painter, const QRect& rect); + + /** Draws the selection rubber. */ + void drawRubber(); + + /** @see QListView::viewportPaintEvent() */ + virtual void viewportPaintEvent(QPaintEvent* paintEvent); + + /** @see QWidget::leaveEvent() */ + virtual void leaveEvent(QEvent* event); + +private slots: + void slotActivationUpdate(); + void slotContextMenuRequested(QListViewItem* item, + const QPoint& pos, + int col); + void slotUpdateDisabledItems(); + void slotAutoScroll(); + void updateColumnsWidth(); + void slotItemRenamed(QListViewItem* item, + const QString& name, + int column); + + /** + * Is invoked when a section from the header has + * been clicked and stores the sort column and sort + * order. + */ + void slotHeaderClicked(int section); + +private: + class DolphinListViewItem : public KFileListViewItem { + public: + DolphinListViewItem(QListView* parent, + KFileItem* fileItem); + virtual ~DolphinListViewItem(); + virtual void paintCell(QPainter* painter, + const QColorGroup& colorGroup, + int column, + int cellWidth, + int alignment); + + virtual void paintFocus(QPainter* painter, + const QColorGroup& colorGroup, + const QRect& rect); + }; + + DolphinView* m_dolphinView; + QTimer* m_resizeTimer; + QTimer* m_scrollTimer; + QRect* m_rubber; + + /** + * Returns the width of the filename in pixels including + * the icon. It is assured that the returned width is + * <= the width of the filename column. + */ + int filenameWidth(const QListViewItem* item) const; + +}; + +#endif diff --git a/src/dolphindetailsviewsettings.cpp b/src/dolphindetailsviewsettings.cpp new file mode 100644 index 0000000..005ebf0 --- /dev/null +++ b/src/dolphindetailsviewsettings.cpp @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphindetailsviewsettings.h" +#include "dolphindetailsview.h" +#include <kglobalsettings.h> +#include <kapplication.h> + +DolphinDetailsViewSettings::DolphinDetailsViewSettings() : + m_columnEnabled(0), + m_iconSize(0), + m_fontSize(0) +{ + KConfig* config = kapp->config(); + config->setGroup("Details Mode"); + + // read which columns should be shown + const bool showName = config->readBoolEntry("Show Name", true); + const bool showSize = config->readBoolEntry("Show Size", true); + const bool showDate = config->readBoolEntry("Show Date", true); + const bool showPermissions = config->readBoolEntry("Show Permissions", false); + const bool showOwner = config->readBoolEntry("Show Owner", false); + const bool showGroup = config->readBoolEntry("Show Group", false); + + setColumnEnabled(DolphinDetailsView::NameColumn, showName); + setColumnEnabled(DolphinDetailsView::SizeColumn, showSize); + setColumnEnabled(DolphinDetailsView::DateColumn, showDate); + setColumnEnabled(DolphinDetailsView::PermissionsColumn, showPermissions); + setColumnEnabled(DolphinDetailsView::OwnerColumn, showOwner); + setColumnEnabled(DolphinDetailsView::GroupColumn, showGroup); + + // read icon size + m_iconSize = config->readNumEntry("Icon Size", KIcon::SizeSmall); + + // read font size and font family + m_fontSize = config->readNumEntry("Font Size", -1); + m_fontFamily = config->readEntry("Font Family"); + + const QFont font(KGlobalSettings::generalFont()); + if (m_fontSize < 0) { + m_fontSize = font.pointSize(); + } + + if (m_fontFamily.isEmpty()) { + m_fontFamily = font.family(); + } +} + +DolphinDetailsViewSettings::~DolphinDetailsViewSettings() +{ + m_columnEnabled = 0; + m_fontSize = 0; +} + +void DolphinDetailsViewSettings::setColumnEnabled(int column, + bool enable) +{ + if (enable) { + m_columnEnabled = m_columnEnabled | (1 << column); + } + else { + m_columnEnabled = m_columnEnabled & ~(1 << column); + } +} + +bool DolphinDetailsViewSettings::isColumnEnabled(int column) const +{ + return (m_columnEnabled & (1 << column)) > 0; +} + +void DolphinDetailsViewSettings::save() +{ + KConfig* config = kapp->config(); + config->setGroup("Details Mode"); + + config->writeEntry("Show Name", + isColumnEnabled(DolphinDetailsView::NameColumn)); + config->writeEntry("Show Size", + isColumnEnabled(DolphinDetailsView::SizeColumn)); + config->writeEntry("Show Date", + isColumnEnabled(DolphinDetailsView::DateColumn)); + config->writeEntry("Show Permissions", + isColumnEnabled(DolphinDetailsView::PermissionsColumn)); + config->writeEntry("Show Owner", + isColumnEnabled(DolphinDetailsView::OwnerColumn)); + config->writeEntry("Show Group", + isColumnEnabled(DolphinDetailsView::GroupColumn)); + config->writeEntry("Icon Size", m_iconSize); + config->writeEntry("Font Size", m_fontSize); + config->writeEntry("Font Family", m_fontFamily); +} diff --git a/src/dolphindetailsviewsettings.h b/src/dolphindetailsviewsettings.h new file mode 100644 index 0000000..d296f96 --- /dev/null +++ b/src/dolphindetailsviewsettings.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef DOLPHINDETAILSVIEWSETTINGS_H +#define DOLPHINDETAILSVIEWSETTINGS_H + +#include <qstring.h> +#include <qnamespace.h> +#include <dolphinsettingsbase.h> + +/** + * @brief Contains the settings for the details view. + * + * The following properties are stored: + * - enabled columns + * - sorted column + * - sort order for the sorted column + * - icon size + * - font family + * - font size + * + * @see DolphinDetailsView + * @author Peter Penz <peter.penz@gmx.at> + */ +class DolphinDetailsViewSettings : public DolphinSettingsBase +{ +public: + DolphinDetailsViewSettings(); + + virtual ~DolphinDetailsViewSettings(); + + void setColumnEnabled(int column, bool enable); + bool isColumnEnabled(int column) const; + + void setIconSize(int size) { m_iconSize = size; } + int iconSize() const { return m_iconSize; } + + void setFontFamily(const QString& family) { m_fontFamily = family; } + const QString& fontFamily() const { return m_fontFamily; } + + void setFontSize(int size) { m_fontSize = size; } + int fontSize() const { return m_fontSize; } + + /** @see DolphinSettingsBase::save() */ + virtual void save(); + +private: + int m_columnEnabled; + int m_iconSize; + int m_fontSize; + QString m_fontFamily; +}; + +#endif diff --git a/src/dolphindirlister.cpp b/src/dolphindirlister.cpp new file mode 100644 index 0000000..897b4b4 --- /dev/null +++ b/src/dolphindirlister.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphindirlister.h" +#include <kio/jobclasses.h> + +// TODO: +#include <stdio.h> + +DolphinDirLister::DolphinDirLister() : + KDirLister(true) +{ +} + +DolphinDirLister::~DolphinDirLister() +{ +} + +void DolphinDirLister::handleError(KIO::Job* job) +{ + // TODO: some error texts should be adjusted manually + emit errorMessage(job->errorString()); +} + +#include "dolphindirlister.moc" diff --git a/src/dolphindirlister.h b/src/dolphindirlister.h new file mode 100644 index 0000000..8d49d98 --- /dev/null +++ b/src/dolphindirlister.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef DOLPHINDIRLISTER_H +#define DOLPHINDIRLISTER_H + +#include <kdirlister.h> + +/** + * @brief Extends the class KDirLister by emitting an error + * signal containing text. + * + * @author Peter Penz + */ +class DolphinDirLister : public KDirLister +{ + Q_OBJECT + +public: + DolphinDirLister(); + virtual ~DolphinDirLister(); + +signals: + /** Is emitted whenever an error occured. */ + void errorMessage(const QString& msg); + +protected: + virtual void handleError(KIO::Job* job); +}; + +#endif diff --git a/src/dolphiniconsview.cpp b/src/dolphiniconsview.cpp new file mode 100644 index 0000000..7a2489b --- /dev/null +++ b/src/dolphiniconsview.cpp @@ -0,0 +1,500 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphiniconsview.h" +#include <qpainter.h> +#include <kiconeffect.h> +#include <kapplication.h> +#include <qobjectlist.h> +#include <kglobalsettings.h> +#include <kurldrag.h> +#include <qclipboard.h> +#include <assert.h> +#include <kaction.h> +#include <kstdaction.h> +#include <kfileitem.h> + +#include "dolphinview.h" +#include "viewproperties.h" +#include "dolphin.h" +#include "dolphinstatusbar.h" +#include "dolphinsettings.h" +#include "dolphiniconsviewsettings.h" + +DolphinIconsView::DolphinIconsView(DolphinView* parent, LayoutMode layoutMode) : + KFileIconView(parent, 0), + m_previewIconSize(-1), + m_layoutMode(layoutMode), + m_dolphinView(parent) +{ + setAcceptDrops(true); + setMode(KIconView::Execute); + setSelectionMode(KFile::Extended); + Dolphin& dolphin = Dolphin::mainWin(); + + connect(this, SIGNAL(onItem(QIconViewItem*)), + this, SLOT(slotOnItem(QIconViewItem*))); + connect(this, SIGNAL(onViewport()), + this, SLOT(slotOnViewport())); + connect(this, SIGNAL(contextMenuRequested(QIconViewItem*, const QPoint&)), + this, SLOT(slotContextMenuRequested(QIconViewItem*, const QPoint&))); + connect(this, SIGNAL(selectionChanged()), + &dolphin, SLOT(slotSelectionChanged())); + connect(&dolphin, SIGNAL(activeViewChanged()), + this, SLOT(slotActivationUpdate())); + connect(this, SIGNAL(itemRenamed(QIconViewItem*, const QString&)), + this, SLOT(slotItemRenamed(QIconViewItem*, const QString&))); + connect(this, SIGNAL(dropped(QDropEvent*, const KURL::List&, const KURL&)), + parent, SLOT(slotURLListDropped(QDropEvent*, const KURL::List&, const KURL&))); + + QClipboard* clipboard = QApplication::clipboard(); + connect(clipboard, SIGNAL(dataChanged()), + this, SLOT(slotUpdateDisabledItems())); + + // KFileIconView creates two actions for zooming, which are directly connected to the + // slots KFileIconView::zoomIn() and KFileIconView::zoomOut(). As this behavior is not + // wanted and the slots are not virtual, the actions are disabled here. + KAction* zoomInAction = actionCollection()->action("zoomIn"); + assert(zoomInAction != 0); + zoomInAction->setEnabled(false); + + KAction* zoomOutAction = actionCollection()->action("zoomOut"); + assert(zoomOutAction != 0); + zoomOutAction->setEnabled(false); + + setItemsMovable(true); + setWordWrapIconText(true); + if (m_layoutMode == Previews) { + showPreviews(); + } + refreshSettings(); +} + +DolphinIconsView::~DolphinIconsView() +{ +} + +void DolphinIconsView::setLayoutMode(LayoutMode mode) +{ + if (m_layoutMode != mode) { + m_layoutMode = mode; + refreshSettings(); + } +} + +void DolphinIconsView::beginItemUpdates() +{ +} + +void DolphinIconsView::endItemUpdates() +{ + arrangeItemsInGrid(); + + // TODO: KFileIconView does not emit any signal when the preview + // has been finished. Using a delay of 300 ms is a temporary workaround + // until the DolphinIconsView will implement the previews by it's own in + // future releases. + QTimer::singleShot(300, this, SLOT(slotUpdateDisabledItems())); + + const KFileIconViewItem* item = static_cast<const KFileIconViewItem*>(firstItem()); + if (item != 0) { + setCurrentItem(item->fileInfo()); + } + + int index = 0; + const QValueList<URLNavigator::HistoryElem> history = m_dolphinView->urlHistory(index); + if (!history.isEmpty()) { + KFileView* fileView = static_cast<KFileView*>(this); + fileView->setCurrentItem(history[index].currentFileName()); + setContentsPos(history[index].contentsX(), history[index].contentsY()); + } +} + +void DolphinIconsView::refreshSettings() +{ + const DolphinIconsViewSettings* settings = DolphinSettings::instance().iconsView(m_layoutMode); + assert(settings != 0); + + setIconSize(settings->iconSize()); + + const QIconView::Arrangement arrangement = settings->arrangement(); + const QIconView::ItemTextPos textPos = (arrangement == QIconView::LeftToRight) ? + QIconView::Bottom : + QIconView::Right; + setArrangement(arrangement); + setItemTextPos(textPos); + + setGridX(settings->gridWidth()); + setGridY(settings->gridHeight()); + setSpacing(settings->gridSpacing()); + + QFont adjustedFont(font()); + adjustedFont.setFamily(settings->fontFamily()); + adjustedFont.setPointSize(settings->fontSize()); + setFont(adjustedFont); + setIconTextHeight(settings->textlinesCount()); + + if (m_layoutMode == Previews) { + // There is no getter method for the current size in KFileIconView. To + // prevent a flickering the current size is stored in m_previewIconSize and + // setPreviewSize is only invoked if the size really has changed. + showPreviews(); + + const int size = settings->previewSize(); + if (size != m_previewIconSize) { + m_previewIconSize = size; + setPreviewSize(size); + } + } +} + +void DolphinIconsView::zoomIn() +{ + if (isZoomInPossible()) { + DolphinIconsViewSettings* settings = DolphinSettings::instance().iconsView(m_layoutMode); + const int textWidthHint = settings->textWidthHint(); + + const int iconSize = increasedIconSize(settings->iconSize()); + settings->setIconSize(iconSize); + + if (m_layoutMode == Previews) { + const int previewSize = increasedIconSize(settings->previewSize()); + settings->setPreviewSize(previewSize); + } + + settings->calculateGridSize(textWidthHint); + ItemEffectsManager::zoomIn(); + } +} + +void DolphinIconsView::zoomOut() +{ + if (isZoomOutPossible()) { + DolphinIconsViewSettings* settings = DolphinSettings::instance().iconsView(m_layoutMode); + const int textWidthHint = settings->textWidthHint(); + + const int iconSize = decreasedIconSize(settings->iconSize()); + settings->setIconSize(iconSize); + + if (m_layoutMode == Previews) { + const int previewSize = decreasedIconSize(settings->previewSize()); + settings->setPreviewSize(previewSize); + } + + settings->calculateGridSize(textWidthHint); + ItemEffectsManager::zoomOut(); + } +} + +bool DolphinIconsView::isZoomInPossible() const +{ + DolphinIconsViewSettings* settings = DolphinSettings::instance().iconsView(m_layoutMode); + const int size = (m_layoutMode == Icons) ? settings->iconSize() : settings->previewSize(); + return size < KIcon::SizeEnormous; +} + +bool DolphinIconsView::isZoomOutPossible() const +{ + DolphinIconsViewSettings* settings = DolphinSettings::instance().iconsView(m_layoutMode); + return settings->iconSize() > KIcon::SizeSmall; +} + +void DolphinIconsView::arrangeItemsInGrid( bool updated ) +{ + + KFileIconView::arrangeItemsInGrid(updated); + + if (m_layoutMode == Previews) { + // The class KFileIconView has a bug when the size of the previews differs from the size + // of the icons: For specific MIME types the y-position and the height is calculated in + // a wrong manner. The following code bypasses this issue. No bugreport has been submitted + // as this functionality is not used by any KDE3 application and the core developers are + // busy enough for KDE4 now :-) + + KFileIconViewItem* item = static_cast<KFileIconViewItem*>(QIconView::firstItem()); + QString mimetype; + while (item != 0) { + mimetype = item->fileInfo()->mimetype(); + const bool fixSize = mimetype.contains("text") || + mimetype.contains("application/x-"); + if (fixSize) { + item->setPixmapSize(QSize(m_previewIconSize, m_previewIconSize)); + } + item = static_cast<KFileIconViewItem *>(item->nextItem()); + } + } +} + +void DolphinIconsView::setContextPixmap(void* context, + const QPixmap& pixmap) +{ + reinterpret_cast<KFileIconViewItem*>(context)->setPixmap(pixmap); +} + +const QPixmap* DolphinIconsView::contextPixmap(void* context) +{ + return reinterpret_cast<KFileIconViewItem*>(context)->pixmap(); +} + +void* DolphinIconsView::firstContext() +{ + return reinterpret_cast<void*>(firstItem()); +} + +void* DolphinIconsView::nextContext(void* context) +{ + KFileIconViewItem* iconViewItem = reinterpret_cast<KFileIconViewItem*>(context); + return reinterpret_cast<void*>(iconViewItem->nextItem()); +} + +KFileItem* DolphinIconsView::contextFileInfo(void* context) +{ + return reinterpret_cast<KFileIconViewItem*>(context)->fileInfo(); +} + +void DolphinIconsView::contentsMousePressEvent(QMouseEvent* event) +{ + KFileIconView::contentsMousePressEvent(event); + resetActivatedItem(); + emit signalRequestActivation(); + m_dolphinView->statusBar()->clear(); +} + +void DolphinIconsView::contentsMouseReleaseEvent(QMouseEvent* event) +{ + KFileIconView::contentsMouseReleaseEvent(event); + + // The KFileIconView does not send any selectionChanged signal if + // a selection is done by using the "select-during-button-pressed" feature. + // Hence inform Dolphin about the selection change manually: + Dolphin::mainWin().slotSelectionChanged(); +} + +void DolphinIconsView::drawBackground(QPainter* painter, const QRect& rect) +{ + if (m_dolphinView->isActive()) { + KFileIconView::drawBackground(painter, rect); + } + else { + const QBrush brush(colorGroup().background()); + painter->fillRect(0, 0, width(), height(), brush); + } +} + +QDragObject* DolphinIconsView::dragObject() +{ + KURL::List urls; + KFileItemListIterator it(*KFileView::selectedItems()); + while (it.current() != 0) { + urls.append((*it)->url()); + ++it; + } + + QPixmap pixmap; + if(urls.count() > 1) { + pixmap = DesktopIcon("kmultiple", iconSize()); + } + else { + KFileIconViewItem* item = static_cast<KFileIconViewItem*>(currentItem()); + if ((item != 0) && (item->pixmap() != 0)) { + pixmap = *(item->pixmap()); + } + } + + if (pixmap.isNull()) { + pixmap = currentFileItem()->pixmap(iconSize()); + } + + QDragObject* dragObj = new KURLDrag(urls, widget()); + dragObj->setPixmap(pixmap); + return dragObj; +} + +void DolphinIconsView::contentsDragEnterEvent(QDragEnterEvent* event) +{ + // TODO: The method KFileIconView::contentsDragEnterEvent() does + // not allow drag and drop inside itself, which prevents the possability + // to move a file into a directory. As the method KFileIconView::acceptDrag() + // is not virtual, we must overwrite the method + // KFileIconView::contentsDragEnterEvent() and do some cut/copy/paste for this + // usecase. Corresponding to the documentation the method KFileIconView::acceptDrag() + // will get virtual in KDE 4, which will simplify the code. + + if (event->source() != this) { + KFileIconView::contentsDragEnterEvent(event); + return; + } + + const bool accept = KURLDrag::canDecode(event) && + (event->action() == QDropEvent::Copy || + event->action() == QDropEvent::Move || + event->action() == QDropEvent::Link ); + if (accept) { + event->acceptAction(); + } + else { + event->ignore(); + } +} + +void DolphinIconsView::contentsDragMoveEvent(QDragMoveEvent* event) +{ + KFileIconView::contentsDragMoveEvent(event); + + // If a dragging is done above a directory, show the icon as 'active' for + // a visual feedback + KFileIconViewItem* item = static_cast<KFileIconViewItem*>(findItem(contentsToViewport(event->pos()))); + + bool showActive = false; + if (item != 0) { + const KFileItem* fileInfo = item->fileInfo(); + showActive = (fileInfo != 0) && fileInfo->isDir(); + } + + if (showActive) { + slotOnItem(item); + } + else { + slotOnViewport(); + } +} + +void DolphinIconsView::contentsDropEvent(QDropEvent* event) +{ + // TODO: Most of the following code is a copy of + // KFileIconView::contentsDropEvent. See comment in + // DolphinIconsView::contentsDragEnterEvent for details. + + if (event->source() != this) { + KFileIconView::contentsDropEvent(event); + return; + } + + KFileIconViewItem* item = static_cast<KFileIconViewItem*>(findItem(contentsToViewport(event->pos()))); + const bool accept = KURLDrag::canDecode(event) && + (event->action() == QDropEvent::Copy || + event->action() == QDropEvent::Move || + event->action() == QDropEvent::Link ) && + (item != 0); + if (!accept) { + return; + } + + KFileItem* fileItem = item->fileInfo(); + if (!fileItem->isDir()) { + // the file is not a directory, hence don't accept any drop + return; + } + emit dropped(event, fileItem); + KURL::List urls; + if (KURLDrag::decode(event, urls) && !urls.isEmpty()) { + emit dropped(event, urls, fileItem != 0 ? fileItem->url() : KURL()); + sig->dropURLs(fileItem, event, urls); + } +} + +void DolphinIconsView::slotOnItem(QIconViewItem* item) +{ + assert(item != 0); + activateItem(reinterpret_cast<void*>(item)); + + KFileItem* fileItem = static_cast<KFileIconViewItem*>(item)->fileInfo(); + m_dolphinView->requestItemInfo(fileItem->url()); +} + +void DolphinIconsView::slotOnViewport() +{ + resetActivatedItem(); + m_dolphinView->requestItemInfo(KURL()); +} + +void DolphinIconsView::slotContextMenuRequested(QIconViewItem* item, + const QPoint& pos) +{ + KFileItem* fileInfo = 0; + if (item != 0) { + fileInfo = static_cast<KFileIconViewItem*>(item)->fileInfo(); + } + m_dolphinView->openContextMenu(fileInfo, pos); +} + +void DolphinIconsView::slotItemRenamed(QIconViewItem* item, + const QString& name) +{ + KFileItem* fileInfo = static_cast<KFileIconViewItem*>(item)->fileInfo(); + m_dolphinView->rename(KURL(fileInfo->url()), name); +} + +void DolphinIconsView::slotActivationUpdate() +{ + update(); + + // TODO: there must be a simpler way to say + // "update all children" + const QObjectList* list = children(); + if (list == 0) { + return; + } + + QObjectListIterator it(*list); + QObject* object = 0; + while ((object = it.current()) != 0) { + if (object->inherits("QWidget")) { + QWidget* widget = static_cast<QWidget*>(object); + widget->update(); + } + ++it; + } +} + +void DolphinIconsView::slotUpdateDisabledItems() +{ + updateDisabledItems(); +} + +int DolphinIconsView::increasedIconSize(int size) const +{ + int incSize = 0; + switch (size) { + case KIcon::SizeSmall: incSize = KIcon::SizeSmallMedium; break; + case KIcon::SizeSmallMedium: incSize = KIcon::SizeMedium; break; + case KIcon::SizeMedium: incSize = KIcon::SizeLarge; break; + case KIcon::SizeLarge: incSize = KIcon::SizeHuge; break; + case KIcon::SizeHuge: incSize = KIcon::SizeEnormous; break; + default: assert(false); break; + } + return incSize; +} + +int DolphinIconsView::decreasedIconSize(int size) const +{ + int decSize = 0; + switch (size) { + case KIcon::SizeSmallMedium: decSize = KIcon::SizeSmall; break; + case KIcon::SizeMedium: decSize = KIcon::SizeSmallMedium; break; + case KIcon::SizeLarge: decSize = KIcon::SizeMedium; break; + case KIcon::SizeHuge: decSize = KIcon::SizeLarge; break; + case KIcon::SizeEnormous: decSize = KIcon::SizeHuge; break; + default: assert(false); break; + } + return decSize; +} + +#include "dolphiniconsview.moc" diff --git a/src/dolphiniconsview.h b/src/dolphiniconsview.h new file mode 100644 index 0000000..9be2102 --- /dev/null +++ b/src/dolphiniconsview.h @@ -0,0 +1,168 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef DOLPHINICONSVIEW_H +#define DOLPHINICONSVIEW_H + +#include <kfileiconview.h> +#include <qpixmap.h> +#include <kurl.h> +#include <itemeffectsmanager.h> + +class DolphinView; + +/** + * @brief Represents the view, where each item is shown as an icon. + * + * It is also possible that instead of the icon a preview of the item + * content is shown. + * + * @author Peter Penz + */ +class DolphinIconsView : public KFileIconView, public ItemEffectsManager +{ + Q_OBJECT + +public: + enum LayoutMode { + Icons, + Previews + }; + + DolphinIconsView(DolphinView *parent, LayoutMode layoutMode); + + virtual ~DolphinIconsView(); + + void setLayoutMode(LayoutMode mode); + LayoutMode layoutMode() const { return m_layoutMode; } + + /** @see ItemEffectsManager::updateItems */ + virtual void beginItemUpdates(); + + /** @see ItemEffectsManager::updateItems */ + virtual void endItemUpdates(); + + /** + * Reads out the dolphin settings for the icons view and refreshs + * the details view. + */ + // TODO: Other view implementations use a similar interface. When using + // Interview in Qt4 this method should be moved to a base class (currently + // not possible due to having different base classes for the views). + void refreshSettings(); + + /** @see ItemEffectsManager::zoomIn() */ + virtual void zoomIn(); + + /** @see ItemEffectsManager::zoomOut() */ + virtual void zoomOut(); + + /** @see ItemEffectsManager::isZoomInPossible() */ + virtual bool isZoomInPossible() const; + + /** @see ItemEffectsManager::isZoomOutPossible() */ + virtual bool isZoomOutPossible() const; + +public slots: + /** + * Bypass a layout issue in KFileIconView in combination with previews. + * @see KFileIconView::arrangeItemsInGrid + */ + virtual void arrangeItemsInGrid(bool updated = true); + +signals: + /** + * Is send, if the details view should be activated. Usually an activation + * is triggered by a mouse click. + */ + void signalRequestActivation(); + +protected: + /** @see ItemEffectsManager::setContextPixmap */ + virtual void setContextPixmap(void* context, + const QPixmap& pixmap); + + /** @see ItemEffectsManager::contextPixmap */ + virtual const QPixmap* contextPixmap(void* context); + + /** @see ItemEffectsManager::firstContext */ + virtual void* firstContext(); + + /** @see ItemEffectsManager::nextContext */ + virtual void* nextContext(void* context); + + /** @see ItemEffectsManager::contextFileInfo */ + virtual KFileItem* contextFileInfo(void* context); + + /** @see KFileIconView::contentsMousePressEvent */ + virtual void contentsMousePressEvent(QMouseEvent* event); + + /** @see KFileIconView::contentsMouseReleaseEvent */ + virtual void contentsMouseReleaseEvent(QMouseEvent* event); + + /** @see KFileIconView::drawBackground */ + virtual void drawBackground(QPainter* painter, const QRect& rect); + + /** @see KFileIconView::dragObject */ + virtual QDragObject* dragObject(); + + /** @see KFileIconView::contentsDragEnterEvent */ + virtual void contentsDragEnterEvent(QDragEnterEvent* event); + + /** @see KFileIconView::contentsDragMoveEvent */ + virtual void contentsDragMoveEvent(QDragMoveEvent* event); + + /** @see KFileIconView::contentsDropEvent */ + virtual void contentsDropEvent(QDropEvent* event); + +private slots: + /** Is connected to the onItem-signal from KFileIconView. */ + void slotOnItem(QIconViewItem* item); + + /** Is connected to the onViewport-signal from KFileIconView. */ + void slotOnViewport(); + + /** + * Opens the context menu for the item \a item on the given + * position \a pos. + */ + void slotContextMenuRequested(QIconViewItem* item, + const QPoint& pos); + + /** Renames the item \a item to the name \a name. */ + void slotItemRenamed(QIconViewItem* item, + const QString& name); + + void slotActivationUpdate(); + void slotUpdateDisabledItems(); + +private: + int m_previewIconSize; + LayoutMode m_layoutMode; + DolphinView* m_dolphinView; + + /** Returns the increased icon size for the size \a size. */ + int increasedIconSize(int size) const; + + /** Returns the decreased icon size for the size \a size. */ + int decreasedIconSize(int size) const; +}; + +#endif diff --git a/src/dolphiniconsviewsettings.cpp b/src/dolphiniconsviewsettings.cpp new file mode 100644 index 0000000..d47f0f7 --- /dev/null +++ b/src/dolphiniconsviewsettings.cpp @@ -0,0 +1,199 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphiniconsviewsettings.h" +#include <kicontheme.h> +#include <kglobalsettings.h> +#include <kapplication.h> +#include <assert.h> + +DolphinIconsViewSettings::DolphinIconsViewSettings(DolphinIconsView::LayoutMode mode) : + m_arrangement(QIconView::LeftToRight), + m_layoutMode(mode), + m_iconSize(KIcon::SizeMedium), + m_previewSize(KIcon::SizeMedium), + m_gridWidth(0), + m_gridHeight(KIcon::SizeMedium), + m_gridSpacing(8), + m_fontSize(0), + m_textlinesCount(2) +{ + KConfig* config = kapp->config(); + setConfigGroup(config); + + // read icon size + m_iconSize = config->readNumEntry("Icon Size", -1); + if (m_iconSize < 0) { + m_iconSize = KIcon::SizeMedium; + } + + // read arrangement + const QString arrangement(config->readEntry("Arrangement")); + if (arrangement == "Left to Right") { + m_arrangement = QIconView::LeftToRight; + } + else if (arrangement == "Top to Bottom") { + m_arrangement = QIconView::TopToBottom; + } + + // read preview size, grid width and grid height + m_previewSize = config->readNumEntry("Preview Size", -1); + m_gridWidth = config->readNumEntry("Grid Width", -1); + m_gridHeight = config->readNumEntry("Grid Height", -1); + m_gridSpacing = config->readNumEntry("Grid Spacing", -1); + + if (mode == DolphinIconsView::Previews) { + if (m_previewSize < 0) { + m_previewSize = KIcon::SizeEnormous; + } + if (m_gridWidth < 0) { + m_gridWidth = m_previewSize + (m_previewSize / 2); + } + } + else if (m_gridWidth < 0) { + m_gridWidth = m_iconSize + (m_iconSize / 2) + (KIcon::SizeLarge * 2); + } + + if (m_gridHeight < 0) { + m_gridHeight = m_iconSize * 2; + } + + // read font size and font family + m_fontSize = config->readNumEntry("Font Size", -1); + m_fontFamily = config->readEntry("Font Family"); + + const QFont font(KGlobalSettings::generalFont()); + if (m_fontSize < 0) { + m_fontSize = font.pointSize(); + } + + if (m_fontFamily.isEmpty()) { + m_fontFamily = font.family(); + } + + // read textlines count + m_textlinesCount = config->readNumEntry("Number of Textlines", 2); +} + + +DolphinIconsViewSettings::~DolphinIconsViewSettings() +{ +} + +void DolphinIconsViewSettings::setIconSize(int size) +{ + // TODO: add boundaries check + m_iconSize = size; +} + +void DolphinIconsViewSettings::setPreviewSize(int size) +{ + // TODO: add boundaries check + m_previewSize = size; +} + +void DolphinIconsViewSettings::setGridSpacing(int spacing) +{ + // TODO: add boundaries check + m_gridSpacing = spacing; +} + +void DolphinIconsViewSettings::save() +{ + KConfig* config = kapp->config(); + setConfigGroup(config); + + config->writeEntry("Icon Size", m_iconSize); + if (m_arrangement == QIconView::LeftToRight) { + config->writeEntry("Arrangement", "Left to Right"); + } + else { + config->writeEntry("Arrangement", "Top to Bottom"); + } + + config->writeEntry("Preview Size", m_previewSize); + config->writeEntry("Grid Width", m_gridWidth); + config->writeEntry("Grid Height", m_gridHeight); + config->writeEntry("Grid Spacing", m_gridSpacing); + config->writeEntry("Font Size", m_fontSize); + config->writeEntry("Font Family", m_fontFamily); + config->writeEntry("Number of Textlines", m_textlinesCount); +} + +void DolphinIconsViewSettings::calculateGridSize(int hint) +{ + const int maxSize = (m_previewSize > m_iconSize) ? m_previewSize : m_iconSize; + if (m_arrangement == QIconView::LeftToRight) { + int widthUnit = maxSize + (maxSize / 2); + if (widthUnit < KIcon::SizeLarge) { + widthUnit = KIcon::SizeLarge; + } + //m_gridWidth = widthUnit + hint * KIcon::SizeLarge; + m_gridWidth = widthUnit + hint * KIcon::SizeLarge; + + m_gridHeight = m_iconSize; + if (m_gridHeight <= KIcon::SizeMedium) { + m_gridHeight = m_gridHeight * 2; + } + else { + m_gridHeight += maxSize / 2; + } + } + else { + assert(m_arrangement == QIconView::TopToBottom); + m_gridWidth = maxSize + (hint + 1) * (8 * m_fontSize); + + // The height-setting is ignored yet by KFileIconView if the TopToBottom + // arrangement is active. Anyway write the setting to have a defined value. + m_gridHeight = maxSize; + } +} + +int DolphinIconsViewSettings::textWidthHint() const +{ + const int maxSize = (m_previewSize > m_iconSize) ? m_previewSize : m_iconSize; + int hint = 0; + if (m_arrangement == QIconView::LeftToRight) { + int widthUnit = maxSize + (maxSize / 2); + if (widthUnit < KIcon::SizeLarge) { + widthUnit = KIcon::SizeLarge; + } + hint = (m_gridWidth - widthUnit) / KIcon::SizeLarge; + } + else { + assert(m_arrangement == QIconView::TopToBottom); + hint = (m_gridWidth - maxSize) / (8 * m_fontSize) - 1; + if (hint > 2) { + hint = 2; + } + } + return hint; +} + +void DolphinIconsViewSettings::setConfigGroup(KConfig* config) +{ + if (m_layoutMode == DolphinIconsView::Previews) { + config->setGroup("Previews Mode"); + } + else { + config->setGroup("Icons Mode"); + } +} + diff --git a/src/dolphiniconsviewsettings.h b/src/dolphiniconsviewsettings.h new file mode 100644 index 0000000..ec63677 --- /dev/null +++ b/src/dolphiniconsviewsettings.h @@ -0,0 +1,126 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef DOLPHINICONSVIEWSETTINGS_H +#define DOLPHINICONSVIEWSETTINGS_H + +#include <qstring.h> +#include <qiconview.h> +#include <dolphinview.h> +#include <dolphiniconsview.h> +#include <dolphinsettingsbase.h> + +/** + * @brief Contains the settings for the icons view. + * + * The following properties are stored: + * - layout mode (icons or previews) + * - icon size + * - preview size + * - grid width, height and spacing + * - arrangement (left to right or top to bottom) + * - font family + * - font size + * - number of text lines + * + * @see DolphinIconsView + * @author Peter Penz <peter.penz@gmx.at> + */ +class DolphinIconsViewSettings : public DolphinSettingsBase +{ +public: + DolphinIconsViewSettings(DolphinIconsView::LayoutMode mode); + virtual ~DolphinIconsViewSettings(); + + void setIconSize(int size); + int iconSize() const { return m_iconSize; } + + void setPreviewSize(int size); + int previewSize() const { return m_previewSize; } + + /** + * Returns the width of the grid. For setting the width + * DolphinIconsviewSettings::calculateGridSize() must be used. + */ + int gridWidth() const { return m_gridWidth; } + + /** + * Returns the height of the grid. For setting the height + * DolphinIconsviewSettings::calculateGridSize() must be used. + */ + int gridHeight() const { return m_gridHeight; } + + void setGridSpacing(int spacing); + int gridSpacing() const { return m_gridSpacing; } + + void setArrangement(QIconView::Arrangement arrangement) { m_arrangement = arrangement; } + QIconView::Arrangement arrangement() const { return m_arrangement; } + + void setFontFamily(const QString& family) { m_fontFamily = family; } + const QString& fontFamily() const { return m_fontFamily; } + + void setFontSize(int size) { m_fontSize = size; } + int fontSize() const { return m_fontSize; } + + void setTextlinesCount(int count) { m_textlinesCount = count; } + int textlinesCount() const { return m_textlinesCount; } + + /** @see DolphinSettingsBase::save */ + virtual void save(); + + /** + * Calculates the width and the height of the grid dependant from \a hint and + * the current settings. The hint gives information about the wanted text + * width, where a lower value indicates a smaller text width. Currently + * in Dolphin the values 0, 1 and 2 are used. See also + * DolhinIconsViewSettings::textWidthHint. + * + * The calculation of the grid width and grid height is a little bit tricky, + * as the user model does not fit to the implementation model of QIconView. The user model + * allows to specify icon-, preview- and text width sizes, whereas the implementation + * model expects only a grid width and height. The nasty thing is that the specified + * width and height varies dependant from the arrangement (e. g. the height is totally + * ignored for the top-to-bottom arrangement inside QIconView). + */ + void calculateGridSize(int hint); + + /** + * Returns the text width hint dependant from the given settings. + * A lower value indicates a smaller text width. Currently + * in Dolphin the values 0, 1 and 2 are used. The text width hint can + * be used later for DolphinIconsViewSettings::calculateGridSize(). + */ + int textWidthHint() const; + +private: + QIconView::Arrangement m_arrangement; + DolphinIconsView::LayoutMode m_layoutMode; + int m_iconSize; + int m_previewSize; + int m_gridWidth; + int m_gridHeight; + int m_gridSpacing; + int m_fontSize; + int m_textlinesCount; + QString m_fontFamily; + + void setConfigGroup(KConfig* config); +}; + +#endif diff --git a/src/dolphinsettings.cpp b/src/dolphinsettings.cpp new file mode 100644 index 0000000..01ef80e --- /dev/null +++ b/src/dolphinsettings.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at), * + * Cvetoslav Ludmiloff and Patrice Tremblay * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphinsettings.h" +#include <qdir.h> + +#include <kapplication.h> +#include <kbookmark.h> +#include <kbookmarkmanager.h> +#include <kicontheme.h> +#include <klocale.h> +#include <kstandarddirs.h> + +#include "dolphin.h" +#include "dolphiniconsviewsettings.h" +#include "dolphindetailsviewsettings.h" +#include "sidebarssettings.h" + +DolphinSettings& DolphinSettings::instance() +{ + static DolphinSettings* instance = 0; + if (instance == 0) { + instance = new DolphinSettings(); + } + return *instance; +} + +void DolphinSettings::setHomeURL(const KURL& url) +{ + m_homeURL = url; + // TODO: update home bookmark? +} + +DolphinSettings::DolphinSettings() : + m_defaultMode(DolphinView::IconsView), + m_isViewSplit(false), + m_isURLEditable(false) +{ + KConfig* config = kapp->config(); + config->setGroup("General"); + m_homeURL = KURL(config->readEntry("Home URL", QDir::homeDirPath())); + m_defaultMode = static_cast<DolphinView::Mode>(config->readNumEntry("Default View Mode", DolphinView::IconsView)); + m_isViewSplit = config->readBoolEntry("Split View", false); + m_isSaveView = config->readBoolEntry("Save View", false); + m_isURLEditable = config->readBoolEntry("Editable URL", false); + + m_iconsView = new DolphinIconsViewSettings(DolphinIconsView::Icons); + m_previewsView = new DolphinIconsViewSettings(DolphinIconsView::Previews); + m_detailsView = new DolphinDetailsViewSettings(); + m_leftsidebar = new leftSidebarSettings(); + m_rightsidebar = new rightSidebarSettings(); +} + +DolphinSettings::~DolphinSettings() +{ + delete m_iconsView; + m_iconsView = 0; + + delete m_previewsView; + m_previewsView = 0; + + delete m_detailsView; + m_detailsView = 0; + + delete m_leftsidebar; + m_leftsidebar = 0; + + delete m_rightsidebar; + m_rightsidebar = 0; +} + +KBookmark DolphinSettings::bookmark(int index) const +{ + int i = 0; + KBookmarkGroup root = bookmarkManager()->root(); + KBookmark bookmark = root.first(); + while (!bookmark.isNull()) { + if (i == index) { + return bookmark; + } + ++i; + bookmark = root.next(bookmark); + } + + return KBookmark(); +} + +DolphinIconsViewSettings* DolphinSettings::iconsView(DolphinIconsView::LayoutMode mode) const +{ + return (mode == DolphinIconsView::Icons) ? m_iconsView : m_previewsView; +} + +KBookmarkManager* DolphinSettings::bookmarkManager() const +{ + QString basePath = KGlobal::instance()->instanceName(); + basePath.append("/bookmarks.xml"); + const QString file = locateLocal("data", basePath); + + return KBookmarkManager::managerForFile(file, false); +} + +void DolphinSettings::save() +{ + KConfig* config = kapp->config(); + config->setGroup("General"); + config->writeEntry("Version", 1); // internal version + config->writeEntry("Home URL", m_homeURL.prettyURL()); + config->writeEntry("Default View Mode", m_defaultMode); + config->writeEntry("Split View", m_isViewSplit); + config->writeEntry("Save View", m_isSaveView); + config->writeEntry("Editable URL", m_isURLEditable); + + m_iconsView->save(); + m_previewsView->save(); + m_detailsView->save(); + m_leftsidebar->save(); + m_rightsidebar->save(); + + QString basePath = KGlobal::instance()->instanceName(); + basePath.append("/bookmarks.xml"); + const QString file = locateLocal( "data", basePath); + + KBookmarkManager* manager = KBookmarkManager::managerForFile(file, false); + manager->save(false); +} diff --git a/src/dolphinsettings.h b/src/dolphinsettings.h new file mode 100644 index 0000000..3e70fd4 --- /dev/null +++ b/src/dolphinsettings.h @@ -0,0 +1,110 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef DOLPHINSETTINGS_H +#define DOLPHINSETTINGS_H + +#include <qvaluelist.h> + +#include <dolphiniconsview.h> +#include <dolphinview.h> +#include <dolphinsettingsbase.h> +#include <kurl.h> + +class KBookmark; +class KBookmarkManager; +class DolphinIconsViewSettings; +class DolphinDetailsViewSettings; +class leftSidebarSettings; +class rightSidebarSettings; + +/** + * @brief Manages and stores all settings from Dolphin. + * + * The following properties are stored: + * - home URL + * - default view mode + * - URL navigator state (editable or not) + * - split view + * - bookmarks + * - properties for icons and details view + */ +class DolphinSettings : DolphinSettingsBase { +public: + static DolphinSettings& instance(); + + void setHomeURL(const KURL& url); + const KURL& homeURL() const { return m_homeURL; } + + void setDefaultViewMode(DolphinView::Mode mode) { m_defaultMode = mode; } + DolphinView::Mode defaultViewMode() const { return m_defaultMode; } + + void setURLEditable(bool editable) { m_isURLEditable = editable; } + bool isURLEditable() const { return m_isURLEditable; } + + void setViewSplit(bool split) { m_isViewSplit = split; } + bool isViewSplit() const { return m_isViewSplit; } + + void setSaveView(bool yes) { m_isSaveView = yes; } + bool isSaveView() const { return m_isSaveView; } + + + DolphinIconsViewSettings* iconsView(DolphinIconsView::LayoutMode mode) const; + + DolphinDetailsViewSettings* detailsView() const { return m_detailsView; } + + leftSidebarSettings* leftsidebar() const { return m_leftsidebar; } + rightSidebarSettings* rightsidebar() const { return m_rightsidebar; } + + KBookmarkManager* bookmarkManager() const; + + // TODO: should this really belong here or get moved to a derived KBookmarkManager? + // Dolphin uses some lists where an index is given and the corresponding bookmark + // should get retrieved... + KBookmark bookmark(int index) const; + + /** @see DolphinSettingsBase::save */ + virtual void save(); + +protected: + DolphinSettings(); + virtual ~DolphinSettings(); + +private: + enum BookmarkHint { + Home = 0, + Media = 1, + Network = 2, + Root = 3 + }; + + DolphinView::Mode m_defaultMode; + bool m_isViewSplit; + bool m_isURLEditable; + bool m_isSaveView; + KURL m_homeURL; + DolphinIconsViewSettings* m_iconsView; + DolphinIconsViewSettings* m_previewsView; + DolphinDetailsViewSettings* m_detailsView; + leftSidebarSettings* m_leftsidebar; + rightSidebarSettings* m_rightsidebar; +}; + +#endif diff --git a/src/dolphinsettingsbase.cpp b/src/dolphinsettingsbase.cpp new file mode 100644 index 0000000..c65297c --- /dev/null +++ b/src/dolphinsettingsbase.cpp @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphinsettingsbase.h" + +DolphinSettingsBase::DolphinSettingsBase() +{ +} + +DolphinSettingsBase::~DolphinSettingsBase() +{ +} + + diff --git a/src/dolphinsettingsbase.h b/src/dolphinsettingsbase.h new file mode 100644 index 0000000..2c2482e --- /dev/null +++ b/src/dolphinsettingsbase.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef DOLPHINSETTINGSBASE_H +#define DOLPHINSETTINGSBASE_H + +/** + * @brief Base class for all Dolphin settings. + * + * Derived classes must implement the method + * DolphinSettingsBase::save(). + * + * @author Peter Penz <peter.penz@gmx.at> + */ +// TODO: design this base class as Composite pattern, +// as settings might contain other settings +class DolphinSettingsBase +{ +public: + DolphinSettingsBase(); + + virtual ~DolphinSettingsBase(); + + virtual void save() = 0; +}; + +#endif diff --git a/src/dolphinsettingsdialog.cpp b/src/dolphinsettingsdialog.cpp new file mode 100644 index 0000000..4bed70b --- /dev/null +++ b/src/dolphinsettingsdialog.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphinsettingsdialog.h" +#include <klocale.h> +#include <kiconloader.h> +#include "generalsettingspage.h" +#include "viewsettingspage.h" +#include "bookmarkssettingspage.h" +#include "dolphin.h" + +DolphinSettingsDialog::DolphinSettingsDialog() : + KDialogBase(IconList, i18n("D3lphin Preferences"), + Ok|Apply|Cancel, Ok) +{ + KIconLoader iconLoader; + QFrame* generalSettingsFrame = addPage(i18n("General"), 0, + iconLoader.loadIcon("exec", + KIcon::NoGroup, + KIcon::SizeMedium)); + m_generalSettingsPage = new GeneralSettingsPage(generalSettingsFrame); + + QFrame* viewSettingsFrame = addPage(i18n("View Modes"), 0, + iconLoader.loadIcon("view_choose", + KIcon::NoGroup, + KIcon::SizeMedium)); + m_viewSettingsPage = new ViewSettingsPage(viewSettingsFrame); + + QFrame* bookmarksSettingsFrame = addPage(i18n("Bookmarks"), 0, + iconLoader.loadIcon("bookmark", + KIcon::NoGroup, + KIcon::SizeMedium)); + m_bookmarksSettingsPage = new BookmarksSettingsPage(bookmarksSettingsFrame); +} + +DolphinSettingsDialog::~DolphinSettingsDialog() +{ +} + +void DolphinSettingsDialog::slotOk() +{ + applySettings(); + KDialogBase::slotOk(); +} + +void DolphinSettingsDialog::slotApply() +{ + applySettings(); + KDialogBase::slotApply(); +} + +void DolphinSettingsDialog::applySettings() +{ + m_generalSettingsPage->applySettings(); + m_viewSettingsPage->applySettings(); + m_bookmarksSettingsPage->applySettings(); + Dolphin::mainWin().refreshViews(); +} + +#include "dolphinsettingsdialog.moc" diff --git a/src/dolphinsettingsdialog.h b/src/dolphinsettingsdialog.h new file mode 100644 index 0000000..7b8023d --- /dev/null +++ b/src/dolphinsettingsdialog.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef DOLPHINSETTINGSDIALOG_H +#define DOLPHINSETTINGSDIALOG_H + +#include <kdialogbase.h> +class GeneralSettingsPage; +class ViewSettingsPage; +class BookmarksSettingsPage; + +/** + * @brief Settings dialog for Dolphin. + * + * Contains the pages for general settings, view settings and + * bookmark settings. + * + * @author Peter Penz <peter.penz@gmx.at> + */ +class DolphinSettingsDialog : public KDialogBase { + Q_OBJECT + +public: + DolphinSettingsDialog(); + virtual ~DolphinSettingsDialog(); + +protected slots: + virtual void slotOk(); + virtual void slotApply(); + +private: + GeneralSettingsPage* m_generalSettingsPage; + ViewSettingsPage* m_viewSettingsPage; + BookmarksSettingsPage* m_bookmarksSettingsPage; + + void applySettings(); +}; + +#endif diff --git a/src/dolphinstatusbar.cpp b/src/dolphinstatusbar.cpp new file mode 100644 index 0000000..cfa5fb4 --- /dev/null +++ b/src/dolphinstatusbar.cpp @@ -0,0 +1,166 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphinstatusbar.h" +#include <kprogress.h> +#include <qlabel.h> +#include <qtimer.h> +#include <kiconloader.h> + +#include "dolphinview.h" +#include "statusbarmessagelabel.h" +#include "statusbarspaceinfo.h" + +DolphinStatusBar::DolphinStatusBar(DolphinView* parent) : + QHBox(parent), + m_messageLabel(0), + m_spaceInfo(0), + m_progressBar(0), + m_progress(100) +{ + m_messageLabel = new StatusBarMessageLabel(this); + m_messageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + + m_spaceInfo = new StatusBarSpaceInfo(this); + m_spaceInfo->setURL(parent->url()); + + m_progressText = new QLabel(this); + m_progressText->hide(); + + m_progressBar = new KProgress(this); + m_progressBar->hide(); + + m_progressTimer = new QTimer(this); + connect(m_progressTimer, SIGNAL(timeout()), + this, SLOT(slotProgressTimer())); + + const QSize size(m_progressBar->sizeHint()); + m_progressBar->setMaximumWidth(size.width()); + setMinimumHeight(size.height()); + m_messageLabel->setMinimumTextHeight(size.height()); + + connect(parent, SIGNAL(signalURLChanged(const KURL&)), + this, SLOT(slotURLChanged(const KURL&))); +} + + +DolphinStatusBar::~DolphinStatusBar() +{ +} + +void DolphinStatusBar::setMessage(const QString& msg, + Type type) +{ + m_messageLabel->setText(msg); + if (msg.isEmpty() || (msg == m_defaultText)) { + type = Default; + } + m_messageLabel->setType(type); + + if ((type == Error) && (m_progress < 100)) { + // If an error message is shown during a progress is ongoing, + // the (never finishing) progress information should be hidden immediately + // (invoking 'setProgress(100)' only leads to a delayed hiding). + m_progressBar->hide(); + m_progressText->hide(); + setProgress(100); + } +} + +DolphinStatusBar::Type DolphinStatusBar::type() const +{ + return m_messageLabel->type(); +} + +QString DolphinStatusBar::message() const +{ + return m_messageLabel->text(); +} + +void DolphinStatusBar::setProgressText(const QString& text) +{ + m_progressText->setText(text); +} + +QString DolphinStatusBar::progressText() const +{ + return m_progressText->text(); +} + +void DolphinStatusBar::setProgress(int percent) +{ + if (percent < 0) { + percent = 0; + } + else if (percent > 100) { + percent = 100; + } + + m_progress = percent; + m_progressBar->setProgress(m_progress); + m_progressTimer->start(300, true); + + const QString msg(m_messageLabel->text()); + if (msg.isEmpty() || (msg == m_defaultText)) { + if (percent == 0) { + m_messageLabel->setText(QString::null); + m_messageLabel->setType(Default); + } + else if (percent == 100) { + m_messageLabel->setText(m_defaultText); + } + } +} + +void DolphinStatusBar::clear() +{ + // TODO: check for timeout, so that it's prevented that + // a message is cleared too early. + m_messageLabel->setText(m_defaultText); + m_messageLabel->setType(Default); +} + +void DolphinStatusBar::setDefaultText(const QString& text) +{ + m_defaultText = text; +} + +void DolphinStatusBar::slotProgressTimer() +{ + if (m_progress < 100) { + // progress should be shown + m_progressBar->show(); + m_progressText->show(); + m_spaceInfo->hide(); + } + else { + // progress should not be shown anymore + m_progressBar->hide(); + m_progressText->hide(); + m_spaceInfo->show(); + } +} + +void DolphinStatusBar::slotURLChanged(const KURL& url) +{ + m_spaceInfo->setURL(url); +} + +#include "dolphinstatusbar.moc" diff --git a/src/dolphinstatusbar.h b/src/dolphinstatusbar.h new file mode 100644 index 0000000..e4e3e8d --- /dev/null +++ b/src/dolphinstatusbar.h @@ -0,0 +1,133 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef DOLPHINSTATUSBAR_H +#define DOLPHINSTATUSBAR_H + +#include <qhbox.h> +class KProgress; +class QLabel; +class QTimer; +class StatusBarMessageLabel; +class StatusBarSpaceInfo; +class DolphinView; +class KURL; + +/** + * @brief Represents the statusbar of a Dolphin view. + * + * The statusbar allows to show messages and progress + * information. + * + * @author Peter Penz + */ +class DolphinStatusBar : public QHBox { + Q_OBJECT + +public: + /** + * Describes the type of the message text. Dependent + * from the type a corresponding icon and color is + * used for the message text. + */ + enum Type { + Default, + OperationCompleted, + Information, + Error + }; + + DolphinStatusBar(DolphinView* parent = 0); + virtual ~DolphinStatusBar(); + + /** + * Sets the message text to \a msg. Dependant + * from the given type \a type an icon is shown and + * the color of the text is adjusted. The height of + * the statusbar is automatically adjusted in a way, + * that the full text fits into the available width. + * + * If a progress is ongoing and a message + * with the type Type::Error is set, the progress + * is cleared automatically. + */ + void setMessage(const QString& msg, Type type); + + QString message() const; + Type type() const; + + /** + * Sets the text for the progress information. + * The text is shown with a delay of 300 milliseconds: + * if the progress set by DolphinStatusBar::setProgress() + * does reach 100 % within 300 milliseconds, + * the progress text is not shown at all. This assures that + * no flickering occurs for showing a progress of fast + * operations. + */ + void setProgressText(const QString& text); + QString progressText() const; + + /** + * Sets the progress in percent (0 - 100). The + * progress is shown with a delay of 300 milliseconds: + * if the progress does reach 100 % within 300 milliseconds, + * the progress is not shown at all. This assures that + * no flickering occurs for showing a progress of fast + * operations. + */ + void setProgress(int percent); + int progress() const { return m_progress; } + + /** + * Clears the message text of the status bar by replacing + * the message with the default text, which can be set + * by DolphinStatusBar::setDefaultText(). The progress + * information is not cleared. + */ + void clear(); + + /** + * Sets the default text, which is shown if the status bar + * is cleared by DolphinStatusBar::clear(). + */ + void setDefaultText(const QString& text); + const QString& defaultText() const { return m_defaultText; } + +private slots: + void slotProgressTimer(); + + /** + * Is invoked, when the URL of the DolphinView, where the + * statusbar belongs too, has been changed. + */ + void slotURLChanged(const KURL& url); + +private: + StatusBarMessageLabel* m_messageLabel; + StatusBarSpaceInfo* m_spaceInfo; + QLabel* m_progressText; + KProgress* m_progressBar; + QTimer* m_progressTimer; + int m_progress; + QString m_defaultText; +}; + +#endif diff --git a/src/dolphinview.cpp b/src/dolphinview.cpp new file mode 100644 index 0000000..7bf57f0 --- /dev/null +++ b/src/dolphinview.cpp @@ -0,0 +1,1065 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> * + * Copyright (C) 2006 by Gregor Kališnik <gregor@podnapisi.net> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphinview.h" + +#include <qlayout.h> +#include <kurl.h> +#include <klocale.h> +#include <kio/netaccess.h> +#include <kio/renamedlg.h> +#include <assert.h> + +#include "urlnavigator.h" +#include "dolphinstatusbar.h" +#include "dolphin.h" +#include "dolphindirlister.h" +#include "viewproperties.h" +#include "dolphindetailsview.h" +#include "dolphiniconsview.h" +#include "dolphincontextmenu.h" +#include "undomanager.h" +#include "renamedialog.h" +#include "progressindicator.h" + +#include "filterbar.h" + +DolphinView::DolphinView(QWidget *parent, + const KURL& url, + Mode mode, + bool showHiddenFiles) : + QWidget(parent), + m_refreshing(false), + m_showProgress(false), + m_mode(mode), + m_iconsView(0), + m_detailsView(0), + m_statusBar(0), + m_iconSize(0), + m_folderCount(0), + m_fileCount(0), + m_filterBar(0) +{ + setFocusPolicy(QWidget::StrongFocus); + m_topLayout = new QVBoxLayout(this); + + Dolphin& dolphin = Dolphin::mainWin(); + + connect(this, SIGNAL(signalModeChanged()), + &dolphin, SLOT(slotViewModeChanged())); + connect(this, SIGNAL(signalShowHiddenFilesChanged()), + &dolphin, SLOT(slotShowHiddenFilesChanged())); + connect(this, SIGNAL(signalSortingChanged(DolphinView::Sorting)), + &dolphin, SLOT(slotSortingChanged(DolphinView::Sorting))); + connect(this, SIGNAL(signalSortOrderChanged(Qt::SortOrder)), + &dolphin, SLOT(slotSortOrderChanged(Qt::SortOrder))); + + m_urlNavigator = new URLNavigator(url, this); + connect(m_urlNavigator, SIGNAL(urlChanged(const KURL&)), + this, SLOT(slotURLChanged(const KURL&))); + connect(m_urlNavigator, SIGNAL(urlChanged(const KURL&)), + &dolphin, SLOT(slotURLChanged(const KURL&))); + connect(m_urlNavigator, SIGNAL(historyChanged()), + &dolphin, SLOT(slotHistoryChanged())); + + m_statusBar = new DolphinStatusBar(this); + + m_dirLister = new DolphinDirLister(); + m_dirLister->setAutoUpdate(true); + m_dirLister->setMainWindow(this); + m_dirLister->setShowingDotFiles(showHiddenFiles); + connect(m_dirLister, SIGNAL(clear()), + this, SLOT(slotClear())); + connect(m_dirLister, SIGNAL(percent(int)), + this, SLOT(slotPercent(int))); + connect(m_dirLister, SIGNAL(deleteItem(KFileItem*)), + this, SLOT(slotDeleteItem(KFileItem*))); + connect(m_dirLister, SIGNAL(completed()), + this, SLOT(slotCompleted())); + connect(m_dirLister, SIGNAL(infoMessage(const QString&)), + this, SLOT(slotInfoMessage(const QString&))); + connect(m_dirLister, SIGNAL(errorMessage(const QString&)), + this, SLOT(slotErrorMessage(const QString&))); + connect(m_dirLister, SIGNAL(refreshItems (const KFileItemList&)), + this, SLOT(slotRefreshItems(const KFileItemList&))); + connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)), + this, SLOT(slotAddItems(const KFileItemList&))); + + m_iconSize = KIcon::SizeMedium; + + m_topLayout->addWidget(m_urlNavigator); + createView(); + + m_filterBar = new FilterBar(this); + m_filterBar->hide(); + m_topLayout->addWidget(m_filterBar); + connect(m_filterBar, SIGNAL(signalFilterChanged(const QString&)), + this, SLOT(slotChangeNameFilter(const QString&))); + + m_topLayout->addWidget(m_statusBar); +} + +DolphinView::~DolphinView() +{ + delete m_dirLister; + m_dirLister = 0; +} + +void DolphinView::setURL(const KURL& url) +{ + m_urlNavigator->setURL(url); +} + +const KURL& DolphinView::url() const +{ + return m_urlNavigator->url(); +} + +void DolphinView::requestActivation() +{ + Dolphin::mainWin().setActiveView(this); +} + +bool DolphinView::isActive() const +{ + return (Dolphin::mainWin().activeView() == this); +} + +void DolphinView::setMode(Mode mode) +{ + if (mode == m_mode) { + return; // the wished mode is already set + } + + QWidget* view = (m_iconsView != 0) ? static_cast<QWidget*>(m_iconsView) : + static_cast<QWidget*>(m_detailsView); + if (view != 0) { + m_topLayout->remove(view); + view->close(); + view->deleteLater(); + m_iconsView = 0; + m_detailsView = 0; + } + + m_mode = mode; + + createView(); + + ViewProperties props(m_urlNavigator->url()); + props.setViewMode(m_mode); + + emit signalModeChanged(); +} + +DolphinView::Mode DolphinView::mode() const +{ + return m_mode; +} + +void DolphinView::setShowHiddenFilesEnabled(bool show) +{ + if (m_dirLister->showingDotFiles() == show) { + return; + } + + ViewProperties props(m_urlNavigator->url()); + props.setShowHiddenFilesEnabled(show); + props.save(); + + m_dirLister->setShowingDotFiles(show); + + emit signalShowHiddenFilesChanged(); + + reload(); +} + +bool DolphinView::isShowHiddenFilesEnabled() const +{ + return m_dirLister->showingDotFiles(); +} + +void DolphinView::setViewProperties(const ViewProperties& props) +{ + setMode(props.viewMode()); + setSorting(props.sorting()); + setSortOrder(props.sortOrder()); + setShowHiddenFilesEnabled(props.isShowHiddenFilesEnabled()); +} + +void DolphinView::renameSelectedItems() +{ + const KURL::List urls = selectedURLs(); + if (urls.count() > 1) { + // More than one item has been selected for renaming. Open + // a rename dialog and rename all items afterwards. + RenameDialog dialog(urls); + if (dialog.exec() == QDialog::Rejected) { + return; + } + + DolphinView* view = Dolphin::mainWin().activeView(); + const QString& newName = dialog.newName(); + if (newName.isEmpty()) { + view->statusBar()->setMessage(i18n("The new item name is invalid."), + DolphinStatusBar::Error); + } + else { + UndoManager& undoMan = UndoManager::instance(); + undoMan.beginMacro(); + + assert(newName.contains('#')); + + const int urlsCount = urls.count(); + ProgressIndicator* progressIndicator = + new ProgressIndicator(i18n("Renaming items..."), + i18n("Renaming finished."), + urlsCount); + + // iterate through all selected items and rename them... + const int replaceIndex = newName.find('#'); + assert(replaceIndex >= 0); + for (int i = 0; i < urlsCount; ++i) { + const KURL& source = urls[i]; + QString name(newName); + name.replace(replaceIndex, 1, renameIndexPresentation(i + 1, urlsCount)); + + if (source.fileName() != name) { + KURL dest(source.upURL()); + dest.addPath(name); + + const bool destExists = KIO::NetAccess::exists(dest, false, view); + if (destExists) { + delete progressIndicator; + progressIndicator = 0; + view->statusBar()->setMessage(i18n("Renaming failed (item '%1' already exists).").arg(name), + DolphinStatusBar::Error); + break; + } + else if (KIO::NetAccess::file_move(source, dest)) { + // TODO: From the users point of view he executed one 'rename n files' operation, + // but internally we store it as n 'rename 1 file' operations for the undo mechanism. + DolphinCommand command(DolphinCommand::Rename, source, dest); + undoMan.addCommand(command); + } + } + + progressIndicator->execOperation(); + } + delete progressIndicator; + progressIndicator = 0; + + undoMan.endMacro(); + } + } + else { + // Only one item has been selected for renaming. Use the custom + // renaming mechanism from the views. + assert(urls.count() == 1); + if (m_mode == DetailsView) { + QListViewItem* item = m_detailsView->firstChild(); + while (item != 0) { + if (item->isSelected()) { + m_detailsView->rename(item, DolphinDetailsView::NameColumn); + break; + } + item = item->nextSibling(); + } + } + else { + KFileIconViewItem* item = static_cast<KFileIconViewItem*>(m_iconsView->firstItem()); + while (item != 0) { + if (item->isSelected()) { + item->rename(); + break; + } + item = static_cast<KFileIconViewItem*>(item->nextItem()); + } + } + } +} + +void DolphinView::selectAll() +{ + fileView()->selectAll(); +} + +void DolphinView::invertSelection() +{ + fileView()->invertSelection(); +} + +DolphinStatusBar* DolphinView::statusBar() const +{ + return m_statusBar; +} + +int DolphinView::contentsX() const +{ + return scrollView()->contentsX(); +} + +int DolphinView::contentsY() const +{ + return scrollView()->contentsY(); +} + +void DolphinView::refreshSettings() +{ + if (m_iconsView != 0) { + m_iconsView->refreshSettings(); + } + + if (m_detailsView != 0) { + // TODO: There is no usable interface in QListView/KFileDetailView + // to hide/show columns. The easiest approach is to delete + // the current instance and recreate a new one, which automatically + // refreshs the settings. If a proper interface is available in Qt4 + // m_detailsView->refreshSettings() would be enough. + m_topLayout->remove(m_detailsView); + m_detailsView->close(); + m_detailsView->deleteLater(); + m_detailsView = 0; + + createView(); + } +} + +void DolphinView::updateStatusBar() +{ + // As the item count information is less important + // in comparison with other messages, it should only + // be shown if: + // - the status bar is empty or + // - shows already the item count information or + // - shows only a not very important information + // - if any progress is given don't show the item count info at all + const QString msg(m_statusBar->message()); + const bool updateStatusBarMsg = (msg.isEmpty() || + (msg == m_statusBar->defaultText()) || + (m_statusBar->type() == DolphinStatusBar::Information)) && + (m_statusBar->progress() == 100); + + const QString text(hasSelection() ? selectionStatusBarText() : defaultStatusBarText()); + m_statusBar->setDefaultText(text); + + if (updateStatusBarMsg) { + m_statusBar->setMessage(text, DolphinStatusBar::Default); + } +} + +void DolphinView::requestItemInfo(const KURL& url) +{ + emit signalRequestItemInfo(url); +} + +bool DolphinView::isURLEditable() const +{ + return m_urlNavigator->isURLEditable(); +} + +void DolphinView::zoomIn() +{ + itemEffectsManager()->zoomIn(); +} + +void DolphinView::zoomOut() +{ + itemEffectsManager()->zoomOut(); +} + +bool DolphinView::isZoomInPossible() const +{ + return itemEffectsManager()->isZoomInPossible(); +} + +bool DolphinView::isZoomOutPossible() const +{ + return itemEffectsManager()->isZoomOutPossible(); +} + +void DolphinView::setSorting(Sorting sorting) +{ + if (sorting != this->sorting()) { + KFileView* view = fileView(); + int spec = view->sorting() & ~QDir::Name & ~QDir::Size & ~QDir::Time & ~QDir::Unsorted; + + switch (sorting) { + case SortByName: spec = spec | QDir::Name; break; + case SortBySize: spec = spec | QDir::Size; break; + case SortByDate: spec = spec | QDir::Time; break; + default: break; + } + + ViewProperties props(url()); + props.setSorting(sorting); + + view->setSorting(static_cast<QDir::SortSpec>(spec)); + + emit signalSortingChanged(sorting); + } +} + +DolphinView::Sorting DolphinView::sorting() const +{ + const QDir::SortSpec spec = fileView()->sorting(); + + if (spec & QDir::Time) { + return SortByDate; + } + + if (spec & QDir::Size) { + return SortBySize; + } + + return SortByName; +} + +void DolphinView::setSortOrder(Qt::SortOrder order) +{ + if (sortOrder() != order) { + KFileView* view = fileView(); + int sorting = view->sorting(); + sorting = (order == Qt::Ascending) ? (sorting & ~QDir::Reversed) : + (sorting | QDir::Reversed); + + ViewProperties props(url()); + props.setSortOrder(order); + + view->setSorting(static_cast<QDir::SortSpec>(sorting)); + + emit signalSortOrderChanged(order); + } +} + +Qt::SortOrder DolphinView::sortOrder() const +{ + return fileView()->isReversed() ? Qt::Descending : Qt::Ascending; +} + +void DolphinView::goBack() +{ + m_urlNavigator->goBack(); +} + +void DolphinView::goForward() +{ + m_urlNavigator->goForward(); +} + +void DolphinView::goUp() +{ + m_urlNavigator->goUp(); +} + +void DolphinView::goHome() +{ + m_urlNavigator->goHome(); +} + +void DolphinView::setURLEditable(bool editable) +{ + m_urlNavigator->setURLEditable(editable); +} + +void DolphinView::editURL() +{ + m_urlNavigator->editURL(); +} + +const QValueList<URLNavigator::HistoryElem> DolphinView::urlHistory(int& index) const +{ + return m_urlNavigator->history(index); +} + +bool DolphinView::hasSelection() const +{ + const KFileItemList* list = selectedItems(); + return (list != 0) && !list->isEmpty(); +} + +const KFileItemList* DolphinView::selectedItems() const +{ + return fileView()->selectedItems(); +} + +KURL::List DolphinView::selectedURLs() const +{ + KURL::List urls; + + const KFileItemList* list = fileView()->selectedItems(); + if (list != 0) { + KFileItemListIterator it(*list); + KFileItem* item = 0; + while ((item = it.current()) != 0) { + urls.append(item->url()); + ++it; + } + } + + return urls; +} + +const KFileItem* DolphinView::currentFileItem() const +{ + return fileView()->currentFileItem(); +} + +void DolphinView::openContextMenu(KFileItem* fileInfo, const QPoint& pos) +{ + DolphinContextMenu contextMenu(this, fileInfo, pos); + contextMenu.open(); +} + +void DolphinView::rename(const KURL& source, const QString& newName) +{ + bool ok = false; + + if (newName.isEmpty() || (source.fileName() == newName)) { + return; + } + + KURL dest(source.upURL()); + dest.addPath(newName); + + const bool destExists = KIO::NetAccess::exists(dest, + false, + Dolphin::mainWin().activeView()); + if (destExists) { + // the destination already exists, hence ask the user + // how to proceed... + KIO::RenameDlg renameDialog(this, + i18n("File Already Exists"), + source.path(), + dest.path(), + KIO::M_OVERWRITE); + switch (renameDialog.exec()) { + case KIO::R_OVERWRITE: + // the destination should be overwritten + ok = KIO::NetAccess::file_move(source, dest, -1, true); + break; + + case KIO::R_RENAME: { + // a new name for the destination has been used + KURL newDest(renameDialog.newDestURL()); + ok = KIO::NetAccess::file_move(source, newDest); + break; + } + + default: + // the renaming operation has been canceled + reload(); + return; + } + } + else { + // no destination exists, hence just move the file to + // do the renaming + ok = KIO::NetAccess::file_move(source, dest); + } + + if (ok) { + m_statusBar->setMessage(i18n("Renamed file '%1' to '%2'.").arg(source.fileName(), dest.fileName()), + DolphinStatusBar::OperationCompleted); + + DolphinCommand command(DolphinCommand::Rename, source, dest); + UndoManager::instance().addCommand(command); + } + else { + m_statusBar->setMessage(i18n("Renaming of file '%1' to '%2' failed.").arg(source.fileName(), dest.fileName()), + DolphinStatusBar::Error); + reload(); + } +} + +void DolphinView::reload() +{ + startDirLister(m_urlNavigator->url(), true); +} + +void DolphinView::slotURLListDropped(QDropEvent* /* event */, + const KURL::List& urls, + const KURL& url) +{ + KURL destination(url); + if (destination.isEmpty()) { + destination = m_urlNavigator->url(); + } + else { + // Check whether the destination URL is a directory. If this is not the + // case, use the navigator URL as destination (otherwise the destination, + // which represents a file, would be replaced by a copy- or move-operation). + KFileItem fileItem(KFileItem::Unknown, KFileItem::Unknown, destination); + if (!fileItem.isDir()) { + destination = m_urlNavigator->url(); + } + } + + Dolphin::mainWin().dropURLs(urls, destination); +} + +void DolphinView::mouseReleaseEvent(QMouseEvent* event) +{ + QWidget::mouseReleaseEvent(event); + Dolphin::mainWin().setActiveView(this); +} + +void DolphinView::slotURLChanged(const KURL& url) +{ + const ViewProperties props(url); + setMode(props.viewMode()); + + const bool showHiddenFiles = props.isShowHiddenFilesEnabled(); + setShowHiddenFilesEnabled(showHiddenFiles); + m_dirLister->setShowingDotFiles(showHiddenFiles); + + setSorting(props.sorting()); + setSortOrder(props.sortOrder()); + + startDirLister(url); + + // The selectionChanged signal is not emitted when a new view object is + // created. The application does not care whether a view is represented by a + // different instance, hence inform the application that the selection might have + // changed so that it can update it's actions. + Dolphin::mainWin().slotSelectionChanged(); + + emit signalURLChanged(url); +} + +void DolphinView::triggerIconsViewItem(QIconViewItem* item) +{ + const ButtonState keyboardState = KApplication::keyboardMouseState(); + const bool isSelectionActive = ((keyboardState & ShiftButton) > 0) || + ((keyboardState & ControlButton) > 0); + if ((item != 0) && !isSelectionActive) { + // Updating the URL must be done outside the scope of this slot, + // as iconview items will get deleted. + QTimer::singleShot(0, this, SLOT(updateURL())); + Dolphin::mainWin().setActiveView(this); + } +} + +void DolphinView::triggerDetailsViewItem(QListViewItem* item, + const QPoint& pos, + int /* column */) +{ + if (item == 0) { + return; + } + + if (m_detailsView->isOnFilename(item, pos)) { + // Updating the URL must be done outside the scope of this slot, + // as listview items will get deleted. + QTimer::singleShot(0, this, SLOT(updateURL())); + Dolphin::mainWin().setActiveView(this); + } + else { + m_detailsView->clearSelection(); + } +} + +void DolphinView::triggerDetailsViewItem(QListViewItem* item) +{ + const QPoint pos(0, item->itemPos()); + triggerDetailsViewItem(item, pos, 0); +} + +void DolphinView::updateURL() +{ + KFileView* fileView = (m_iconsView != 0) ? static_cast<KFileView*>(m_iconsView) : + static_cast<KFileView*>(m_detailsView); + + KFileItem* fileItem = fileView->currentFileItem(); + if (fileItem == 0) { + return; + } + + if (fileItem->isDir()) { + // Prefer the local path over the URL. This assures that the + // volume space information is correct. Assuming that the URL is media:/sda1, + // and the local path is /windows/C: For the URL the space info is related + // to the root partition (and hence wrong) and for the local path the space + // info is related to the windows partition (-> correct). + const QString localPath(fileItem->localPath()); + if (localPath.isEmpty()) { + setURL(fileItem->url()); + } + else { + setURL(KURL(localPath)); + } + } + else if (fileItem->isFile()) { + // allow to browse through ZIP and tar files + KMimeType::Ptr mime = fileItem->mimeTypePtr(); + if (mime->is("application/x-zip")) { + KURL url = fileItem->url(); + url.setProtocol("zip"); + setURL(url); + } + else if (mime->is("application/x-tar") || + mime->is("application/x-tarz") || + mime->is("application/x-tbz") || + mime->is("application/x-tgz") || + mime->is("application/x-tzo")) { + KURL url = fileItem->url(); + url.setProtocol("tar"); + setURL(url); + } + else { + fileItem->run(); + } + } + else { + fileItem->run(); + } +} + +void DolphinView::slotPercent(int percent) +{ + if (m_showProgress) { + m_statusBar->setProgress(percent); + } +} + +void DolphinView::slotClear() +{ + fileView()->clearView(); + updateStatusBar(); +} + +void DolphinView::slotDeleteItem(KFileItem* item) +{ + fileView()->removeItem(item); + updateStatusBar(); +} + +void DolphinView::slotCompleted() +{ + m_refreshing = true; + + KFileView* view = fileView(); + view->clearView(); + + // TODO: in Qt4 the code should get a lot + // simpler and nicer due to Interview... + if (m_iconsView != 0) { + m_iconsView->beginItemUpdates(); + } + if (m_detailsView != 0) { + m_detailsView->beginItemUpdates(); + } + + if (m_showProgress) { + m_statusBar->setProgressText(QString::null); + m_statusBar->setProgress(100); + m_showProgress = false; + } + + KFileItemList items(m_dirLister->items()); + KFileItemListIterator it(items); + + m_fileCount = 0; + m_folderCount = 0; + + KFileItem* item = 0; + while ((item = it.current()) != 0) { + view->insertItem(item); + if (item->isDir()) { + ++m_folderCount; + } + else { + ++m_fileCount; + } + ++it; + } + + updateStatusBar(); + + if (m_iconsView != 0) { + // Prevent a flickering of the icon view widget by giving a small + // timeslot to swallow asynchronous update events. + m_iconsView->setUpdatesEnabled(false); + QTimer::singleShot(10, this, SLOT(slotDelayedUpdate())); + } + + if (m_detailsView != 0) { + m_detailsView->endItemUpdates(); + m_refreshing = false; + } +} + +void DolphinView::slotDelayedUpdate() +{ + if (m_iconsView != 0) { + m_iconsView->setUpdatesEnabled(true); + m_iconsView->endItemUpdates(); + } + m_refreshing = false; +} + +void DolphinView::slotInfoMessage(const QString& msg) +{ + m_statusBar->setMessage(msg, DolphinStatusBar::Information); +} + +void DolphinView::slotErrorMessage(const QString& msg) +{ + m_statusBar->setMessage(msg, DolphinStatusBar::Error); +} + +void DolphinView::slotRefreshItems(const KFileItemList& /* list */) +{ + QTimer::singleShot(0, this, SLOT(reload())); +} + +void DolphinView::slotAddItems(const KFileItemList& list) +{ + fileView()->addItemList(list); + fileView()->updateView(); +} + +void DolphinView::slotGrabActivation() +{ + Dolphin::mainWin().setActiveView(this); +} + +void DolphinView::slotContentsMoving(int x, int y) +{ + if (!m_refreshing) { + // Only emit a 'contents moved' signal if the user + // moved the content by adjusting the sliders. Adjustments + // resulted by refreshing a directory should not be respected. + emit contentsMoved(x, y); + } +} + +void DolphinView::createView() +{ + assert(m_iconsView == 0); + assert(m_detailsView == 0); + + switch (m_mode) { + case IconsView: + case PreviewsView: { + const DolphinIconsView::LayoutMode layoutMode = (m_mode == IconsView) ? + DolphinIconsView::Icons : + DolphinIconsView::Previews; + m_iconsView = new DolphinIconsView(this, layoutMode); + m_topLayout->insertWidget(1, m_iconsView); + setFocusProxy(m_iconsView); + + connect(m_iconsView, SIGNAL(executed(QIconViewItem*)), + this, SLOT(triggerIconsViewItem(QIconViewItem*))); + connect(m_iconsView, SIGNAL(returnPressed(QIconViewItem*)), + this, SLOT(triggerIconsViewItem(QIconViewItem*))); + connect(m_iconsView, SIGNAL(signalRequestActivation()), + this, SLOT(slotGrabActivation())); + + m_iconsView->endItemUpdates(); + m_iconsView->show(); + m_iconsView->setFocus(); + break; + } + + case DetailsView: { + m_detailsView = new DolphinDetailsView(this); + m_topLayout->insertWidget(1, m_detailsView); + setFocusProxy(m_detailsView); + + connect(m_detailsView, SIGNAL(executed(QListViewItem*, const QPoint&, int)), + this, SLOT(triggerDetailsViewItem(QListViewItem*, const QPoint&, int))); + connect(m_detailsView, SIGNAL(returnPressed(QListViewItem*)), + this, SLOT(triggerDetailsViewItem(QListViewItem*))); + connect(m_detailsView, SIGNAL(signalRequestActivation()), + this, SLOT(slotGrabActivation())); + m_detailsView->show(); + m_detailsView->setFocus(); + break; + } + + default: + break; + } + + connect(scrollView(), SIGNAL(contentsMoving(int, int)), + this, SLOT(slotContentsMoving(int, int))); + + startDirLister(m_urlNavigator->url()); +} + +KFileView* DolphinView::fileView() const +{ + return (m_mode == DetailsView) ? static_cast<KFileView*>(m_detailsView) : + static_cast<KFileView*>(m_iconsView); +} + +QScrollView* DolphinView::scrollView() const +{ + return (m_mode == DetailsView) ? static_cast<QScrollView*>(m_detailsView) : + static_cast<QScrollView*>(m_iconsView); +} + +ItemEffectsManager* DolphinView::itemEffectsManager() const +{ + return (m_mode == DetailsView) ? static_cast<ItemEffectsManager*>(m_detailsView) : + static_cast<ItemEffectsManager*>(m_iconsView); +} + +void DolphinView::startDirLister(const KURL& url, bool reload) +{ + if (!url.isValid()) { + const QString location(url.prettyURL()); + if (location.isEmpty()) { + m_statusBar->setMessage(i18n("The location is empty."), DolphinStatusBar::Error); + } + else { + m_statusBar->setMessage(i18n("The location '%1' is invalid.").arg(location), + DolphinStatusBar::Error); + } + return; + } + + // Only show the directory loading progress if the status bar does + // not contain another progress information. This means that + // the directory loading progress information has the lowest priority. + const QString progressText(m_statusBar->progressText()); + m_showProgress = progressText.isEmpty() || + (progressText == i18n("Loading directory...")); + if (m_showProgress) { + m_statusBar->setProgressText(i18n("Loading directory...")); + m_statusBar->setProgress(0); + } + + m_refreshing = true; + m_dirLister->stop(); + m_dirLister->openURL(url, false, reload); +} + +QString DolphinView::defaultStatusBarText() const +{ + const int itemCount = m_folderCount + m_fileCount; + + QString text = i18n( "1 Item", "%n Items", itemCount ); + text += i18n(" (1 Folder, ", " (%n Folders, ", m_folderCount ); + text += i18n("1 File)", "%n Files)", m_fileCount); + + return text; +} + +QString DolphinView::selectionStatusBarText() const +{ + QString text; + const KFileItemList* list = selectedItems(); + assert((list != 0) && !list->isEmpty()); + + int fileCount = 0; + int folderCount = 0; + KIO::filesize_t byteSize = 0; + for (KFileItemListIterator it(*list); it.current() != 0; ++it) { + KFileItem* item = it.current(); + if (item->isDir()) { + ++folderCount; + } + else { + ++fileCount; + byteSize += item->size(); + } + } + + if (folderCount>0) { + text = i18n("1 Folder selected","%n Folders selected", folderCount); + } + + if ((fileCount > 0) && (folderCount > 0)) { + text += ", "; + } + + if (fileCount > 0) { + const QString sizeText(KIO::convertSize(byteSize)); + text += i18n("1 File selected (%1)", "%n Files selected (%1)", fileCount).arg(sizeText); + } + + return text; +} + +QString DolphinView::renameIndexPresentation(int index, int itemCount) const +{ + // assure that the string reprentation for all indicess have the same + // number of characters based on the given number of items + QString str(QString::number(index)); + int chrCount = 1; + while (itemCount >= 10) { + ++chrCount; + itemCount /= 10; + } + str.reserve(chrCount); + + const int insertCount = chrCount - str.length(); + for (int i = 0; i < insertCount; ++i) { + str.insert(0, '0'); + } + return str; +} + +void DolphinView::slotShowFilterBar(bool show) +{ + assert(m_filterBar != 0); + if (show) { + m_filterBar->show(); + } + else { + m_filterBar->hide(); + } +} + +void DolphinView::slotChangeNameFilter(const QString& nameFilter) +{ + // The name filter of KDirLister does a 'hard' filtering, which + // means that only the items are shown where the names match + // exactly the filter. This is non-transparent for the user, which + // just wants to have a 'soft' filtering: does the name contain + // the filter string? + QString adjustedFilter(nameFilter); + adjustedFilter.insert(0, '*'); + adjustedFilter.append('*'); + + m_dirLister->setNameFilter(adjustedFilter); + m_dirLister->emitChanges(); + + // TODO: this is a workaround for QIconView: the item position + // stay as they are by filtering, only an inserting of an item + // results to an automatic adjusting of the item position. In Qt4/KDE4 + // this workaround should get obsolete due to Interview. + KFileView* view = fileView(); + if (view == m_iconsView) { + KFileItem* first = view->firstFileItem(); + if (first != 0) { + view->removeItem(first); + view->insertItem(first); + } + } +} + +bool DolphinView::isFilterBarVisible() const +{ + return m_filterBar->isVisible(); +} + +#include "dolphinview.moc" diff --git a/src/dolphinview.h b/src/dolphinview.h new file mode 100644 index 0000000..d0ad891 --- /dev/null +++ b/src/dolphinview.h @@ -0,0 +1,452 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> * + * Copyright (C) 2006 by Gregor Kališnik <gregor@podnapisi.net> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + + +#ifndef _DOLPHINVIEW_H_ +#define _DOLPHINVIEW_H_ + +#include <qwidget.h> +#include <kparts/part.h> +#include <kfileitem.h> +#include <kfileiconview.h> +#include <kio/job.h> +#include <urlnavigator.h> + +class QPainter; +class KURL; +class QLineEdit; +class URLNavigator; +class QTimer; +class QIconViewItem; +class QListViewItem; +class QVBoxLayout; +class KFileView; +class Dolphin; +class DolphinDirLister; +class DolphinStatusBar; +class DolphinIconsView; +class DolphinDetailsView; +class ViewProperties; +class QScrollView; +class KProgress; +class ItemEffectsManager; +class FilterBar; +/** + * @short Represents a view for the directory content + * including the navigation bar and status bar. + * + * View modes for icons, details and previews are supported. Currently + * Dolphin allows to have up to two views inside the main window. + * + * @see DolphinIconsView + * @see DolphinDetailsView + * @see URLNavigator + * @see DolphinStatusBar + * + * @author Peter Penz <peter.penz@gmx.at> + */ +class DolphinView : public QWidget +{ + Q_OBJECT + +public: + /** + * Defines the view mode for a directory. The view mode + * can be defined when constructing a DolphinView. The + * view mode is automatically updated if the directory itself + * defines a view mode (see class ViewProperties for details). + */ + enum Mode + { + /** + * The directory items are shown as icons including an + * icon name. */ + IconsView = 0, + + /** + * The icon, the name and at least the size of the directory + * items are shown in a table. It is possible to add columns + * for date, group and permissions. + */ + DetailsView = 1, + + /** + * The directory items are shown as preview if possible. As + * fallback the items are shown as icons. + */ + PreviewsView = 2 + }; + + /** Defines the sort order for the items of a directory. */ + enum Sorting + { + SortByName = 0, + SortBySize = 1, + SortByDate = 2 + }; + + DolphinView(QWidget* parent, + const KURL& url, + Mode mode = IconsView, + bool showHiddenFiles = false); + + virtual ~DolphinView(); + + /** + * Sets the current active URL. + * The signals URLNavigator::urlChanged and URLNavigator::historyChanged + * are submitted. + */ + void setURL(const KURL& url); + + /** Returns the current active URL. */ + const KURL& url() const; + + void requestActivation(); + bool isActive() const; + + void setMode(Mode mode); + Mode mode() const; + void setShowHiddenFilesEnabled(bool show); + bool isShowHiddenFilesEnabled() const; + + void setViewProperties(const ViewProperties& props); + + /** + * Triggers the renaming of the currently selected items, where + * the user must input a new name for the items. + */ + void renameSelectedItems(); + + /** + * Selects all items. + * @see DolphinView::selectedItems() + */ + void selectAll(); + + /** + * Inverts the current selection: selected items get unselected, + * unselected items get selected. + * @see DolphinView::selectedItems() + */ + void invertSelection(); + + /** + * Goes back one step in the URL history. The signals + * URLNavigator::urlChanged and URLNavigator::historyChanged + * are submitted. + */ + void goBack(); + + /** + * Goes forward one step in the URL history. The signals + * URLNavigator::urlChanged and URLNavigator::historyChanged + * are submitted. + */ + void goForward(); + + /** + * Goes up one step of the URL path. The signals + * URLNavigator::urlChanged and URLNavigator::historyChanged + * are submitted. + */ + void goUp(); + + /** + * Goes to the home URL. The signals URLNavigator::urlChanged + * and URLNavigator::historyChanged are submitted. + */ + void goHome(); + + /** + * Sets the URL of the navigation bar to an editable state + * if \a editable is true. If \a editable is false, each part of + * the location is presented by a button for a fast navigation. + */ + void setURLEditable(bool editable); + + /** + * Allows to edit the URL of the navigation bar and assures that + * the focus is assigned to the URL editor. + */ + void editURL(); + + /** + * Returns the complete URL history. The index 0 indicates the oldest + * history element. + * @param index Output parameter which indicates the current + * index of the location. + */ + const QValueList<URLNavigator::HistoryElem> urlHistory(int& index) const; + + /** + * Returns true, if at least one item is selected. + */ + bool hasSelection() const; + + /** + * Returns the selected items. 0 is returned, if no item + * is selected. + * @see DolphinView::selectedURLs() + */ + const KFileItemList* selectedItems() const; + + /** + * Returns a list of URLs for all selected items. An empty list + * is returned, if no item is selected. + * @see DolphinView::selectedItems() + */ + KURL::List selectedURLs() const; + + /** + * Returns the current item, where the cursor is. 0 is returned, if there is no + * current item (e. g. if the view is empty). Note that the current item must + * not be a selected item. + * @see DolphinView::selectedItems() + */ + const KFileItem* currentFileItem() const; + + /** + * Opens the context menu for the item indicated by \a fileInfo + * on the position \a pos. If 0 is passed for the file info, a context + * menu for the viewport is opened. + */ + void openContextMenu(KFileItem* fileInfo, const QPoint& pos); + + /** + * Renames the filename of the source URL by the new file name. + * If the new file name already exists, a dialog is opened which + * asks the user to enter a new name. + */ + void rename(const KURL& source, const QString& newName); + + /** Returns the status bar of the view. */ + DolphinStatusBar* statusBar() const; + + /** + * Returns the x-position of the view content. + * The content of the view might be larger than the visible area + * and hence a scrolling must be done. + */ + int contentsX() const; + + /** + * Returns the y-position of the view content. + * The content of the view might be larger than the visible area + * and hence a scrolling must be done. + */ + int contentsY() const; + + /** + * Returns true, if the URL shown by the navigation bar is editable. + * @see URLNavigator + */ + bool isURLEditable() const; + + /** Increases the size of the current set view mode. */ + void zoomIn(); + + /** Decreases the size of the current set view mode. */ + void zoomOut(); + + /** + * Returns true, if zooming in is possible. If false is returned, + * the minimal zoom size is possible. + */ + bool isZoomInPossible() const; + + /** + * Returns true, if zooming out is possible. If false is returned, + * the maximum zoom size is possible. + */ + bool isZoomOutPossible() const; + + /** Sets the sort order of the items inside a directory (see DolphinView::Sorting). */ + void setSorting(Sorting sorting); + + /** Returns the sort order of the items inside a directory (see DolphinView::Sorting). */ + Sorting sorting() const; + + /** Sets the sort order (Qt::Ascending or Qt::Descending) for the items. */ + void setSortOrder(Qt::SortOrder order); + + /** Returns the current used sort order (Qt::Ascending or Qt::Descending). */ + Qt::SortOrder sortOrder() const; + + /** Refreshs the view settings by reading out the stored settings. */ + void refreshSettings(); + + /** + * Updates the number of items (= number of files + number of + * directories) in the statusbar. If files are selected, the number + * of selected files and the sum of the filesize is shown. + */ + void updateStatusBar(); + + /** Returns the URLNavigator of the view for read access. */ + const URLNavigator* urlNavigator() const { return m_urlNavigator; } + + /** + * Triggers to request user information for the item given + * by the URL \a url. The signal signalRequestItemInfo is emitted, + * which provides a way for widgets to get an indication to update + * the item information. + */ + void requestItemInfo(const KURL& url); + + /** + * Checks if the filter bar is visible. + * + * @return @c true Filter bar is visible. + * @return @c false Filter bar is not visible. + */ + bool isFilterBarVisible() const; + +public slots: + void reload(); + void slotURLListDropped(QDropEvent* event, + const KURL::List& urls, + const KURL& url); + + /** + * Slot that popups the filter bar like FireFox popups his Search bar. + */ + void slotShowFilterBar(bool show); + +signals: + /** Is emitted if URL of the view has been changed to \a url. */ + void signalURLChanged(const KURL& url); + + /** + * Is emitted if the view mode (IconsView, DetailsView, + * PreviewsView) has been changed. + */ + void signalModeChanged(); + + /** Is emitted if the 'show hidden files' property has been changed. */ + void signalShowHiddenFilesChanged(); + + /** Is emitted if the sorting by name, size or date has been changed. */ + void signalSortingChanged(DolphinView::Sorting sorting); + + /** Is emitted if the sort order (ascending or descending) has been changed. */ + void signalSortOrderChanged(Qt::SortOrder order); + + /** + * Is emitted if information of an item is requested to be shown e. g. in the sidebar. + * It the URL is empty, no item information request is pending. + */ + void signalRequestItemInfo(const KURL& url); + + /** Is emitted if the contents has been moved to \a x, \a y. */ + void contentsMoved(int x, int y); + + /** + * Is emitted whenever the selection has been changed. The current selection can + * be retrieved by Dolphin::mainWin().activeView()->selectedItems() or by + * Dolphin::mainWin().activeView()->selectedURLs(). + */ + void signalSelectionChanged(); + +protected: + /** @see QWidget::mouseReleaseEvent */ + virtual void mouseReleaseEvent(QMouseEvent* event); + +private slots: + void slotURLChanged(const KURL& kurl); + void triggerIconsViewItem(QIconViewItem *item); + void triggerDetailsViewItem(QListViewItem* item, + const QPoint& pos, + int column); + void triggerDetailsViewItem(QListViewItem* item); + void updateURL(); + + void slotPercent(int percent); + void slotClear(); + void slotDeleteItem(KFileItem* item); + void slotCompleted(); + void slotDelayedUpdate(); + void slotInfoMessage(const QString& msg); + void slotErrorMessage(const QString& msg); + void slotRefreshItems(const KFileItemList& list); + void slotAddItems(const KFileItemList& list); + + void slotGrabActivation(); + + /** + * Is invoked shortly before the contents of a view implementation + * has been moved and emits the signal contentsMoved. Note that no + * signal is emitted when the contents moving is only temporary by + * e. g. reloading a directory. + */ + void slotContentsMoving(int x, int y); + + /** + * Filters the currently shown items by \a nameFilter. All items + * which contain the given filter string will be shown. + */ + void slotChangeNameFilter(const QString& nameFilter); + +private: + void createView(); + KFileView* fileView() const; + QScrollView* scrollView() const; + ItemEffectsManager* itemEffectsManager() const; + void startDirLister(const KURL& url, bool reload = false); + + /** + * Returns the default text of the status bar, if no item is + * selected. + */ + QString defaultStatusBarText() const; + + /** + * Returns the text for the status bar, if at least one item + * is selected. + */ + QString selectionStatusBarText() const; + + /** + * Returns the string representation for the index \a index + * for renaming \itemCount items. + */ + QString renameIndexPresentation(int index, int itemCount) const; + + bool m_refreshing; + bool m_showProgress; + Mode m_mode; + + QVBoxLayout* m_topLayout; + URLNavigator* m_urlNavigator; + + DolphinIconsView* m_iconsView; + DolphinDetailsView* m_detailsView; + DolphinStatusBar* m_statusBar; + + int m_iconSize; + int m_folderCount; + int m_fileCount; + + DolphinDirLister* m_dirLister; + + FilterBar *m_filterBar; +}; + +#endif // _DOLPHINVIEW_H_ diff --git a/src/editbookmarkdialog.cpp b/src/editbookmarkdialog.cpp new file mode 100644 index 0000000..3d25ce3 --- /dev/null +++ b/src/editbookmarkdialog.cpp @@ -0,0 +1,120 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "editbookmarkdialog.h" +#include <qgrid.h> +#include <klocale.h> +#include <qlineedit.h> +#include <qlabel.h> +#include <qlayout.h> +#include <kiconloader.h> +#include <qpushbutton.h> +#include <kurl.h> +#include <kfiledialog.h> +#include <kicondialog.h> +#include <qhbox.h> + +EditBookmarkDialog::~EditBookmarkDialog() +{ +} + +KBookmark EditBookmarkDialog::getBookmark(const QString& title, + const QString& name, + const KURL& url, + const QString& icon) +{ + EditBookmarkDialog dialog(title, name, url, icon); + dialog.exec(); + return dialog.m_bookmark; +} + +void EditBookmarkDialog::slotOk() +{ + m_bookmark = KBookmark::standaloneBookmark(m_name->text(), + KURL(m_location->text()), + m_iconName); + + KDialogBase::slotOk(); +} + +EditBookmarkDialog::EditBookmarkDialog(const QString& title, + const QString& name, + const KURL& url, + const QString& icon) : + KDialogBase(Plain, title, Ok|Cancel, Ok), + m_iconButton(0), + m_name(0), + m_location(0) +{ + QVBoxLayout* topLayout = new QVBoxLayout(plainPage(), 0, spacingHint()); + + QGrid* grid = new QGrid(2, Qt::Horizontal, plainPage()); + grid->setSpacing(spacingHint()); + + // create icon widgets + new QLabel(i18n("Icon:"), grid); + m_iconName = icon; + m_iconButton = new QPushButton(SmallIcon(m_iconName), QString::null, grid); + m_iconButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + connect(m_iconButton, SIGNAL(clicked()), + this, SLOT(selectIcon())); + + // create name widgets + new QLabel(i18n("Name:"), grid); + m_name = new QLineEdit(name, grid); + m_name->selectAll(); + m_name->setFocus(); + + // create location widgets + new QLabel(i18n("Location:"), grid); + + QHBox* locationBox = new QHBox(grid); + locationBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + locationBox->setSpacing(spacingHint()); + m_location = new QLineEdit(url.prettyURL(), locationBox); + m_location->setMinimumWidth(320); + + QPushButton* selectLocationButton = new QPushButton(SmallIcon("folder"), QString::null, locationBox); + selectLocationButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + connect(selectLocationButton, SIGNAL(clicked()), + this, SLOT(selectLocation())); + + topLayout->addWidget(grid); +} + +void EditBookmarkDialog::selectIcon() +{ + const QString iconName(KIconDialog::getIcon(KIcon::Small, KIcon::FileSystem)); + if (!iconName.isEmpty()) { + m_iconName = iconName; + m_iconButton->setIconSet(SmallIcon(iconName)); + } +} + +void EditBookmarkDialog::selectLocation() +{ + const QString location(m_location->text()); + KURL url(KFileDialog::getExistingURL(location)); + if (!url.isEmpty()) { + m_location->setText(url.prettyURL()); + } +} + +#include "editbookmarkdialog.moc" diff --git a/src/editbookmarkdialog.h b/src/editbookmarkdialog.h new file mode 100644 index 0000000..2156aae --- /dev/null +++ b/src/editbookmarkdialog.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef EDITBOOKMARKDIALOG_H +#define EDITBOOKMARKDIALOG_H + +#include <kbookmark.h> +#include <kdialogbase.h> + +class Bookmark; +class QLineEdit; +class QPushButton; + +/** + * @brief Allows to edit the icon, URL and name of a bookmark. + * + * The default usage is like this: + * \code + * KBookmark bookmark = EditBookmarkDialog::getBookmark(i18n("Add Bookmark"), + * i18n("New bookmark"), + * KURL(), + * "bookmark"); + * if (!bookmark.isNull()) { + * // ... + * } + * \endcode + */ +class EditBookmarkDialog : public KDialogBase +{ + Q_OBJECT + +public: + virtual ~EditBookmarkDialog(); + + /** + * Opens a dialog where the current icon, URL and name of + * an URL are editable. The title of the dialog is set to \a title. + * @return A valid bookmark, if the user has pressed OK. Otherwise + * a null bookmark is returned (see Bookmark::isNull()). + */ + static KBookmark getBookmark(const QString& title, + const QString& name, + const KURL& url, + const QString& icon); + +protected slots: + virtual void slotOk(); + +protected: + EditBookmarkDialog(const QString& title, + const QString& name, + const KURL& url, + const QString& icon); + +private slots: + void selectIcon(); + void selectLocation(); + +private: + QString m_iconName; + QPushButton* m_iconButton; + QLineEdit* m_name; + QLineEdit* m_location; + KBookmark m_bookmark; +}; +#endif diff --git a/src/filterbar.cpp b/src/filterbar.cpp new file mode 100644 index 0000000..83cc784 --- /dev/null +++ b/src/filterbar.cpp @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> * + * Copyright (C) 2006 by Gregor Kališnik <gregor@podnapisi.net> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include "filterbar.h" + +#include <qlabel.h> +#include <qlayout.h> + +#include <kdialog.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <klineedit.h> +#include <kiconloader.h> + +#include "dolphin.h" + +FilterBar::FilterBar(QWidget *parent, const char *name) : + QWidget(parent, name) +{ + const int gap = 3; + + QVBoxLayout* foo = new QVBoxLayout(this); + foo->addSpacing(gap); + + QHBoxLayout* layout = new QHBoxLayout(foo); + layout->addSpacing(gap); + + m_filter = new QLabel(i18n("Filter:"), this); + layout->addWidget(m_filter); + layout->addSpacing(KDialog::spacingHint()); + + m_filterInput = new KLineEdit(this); + layout->addWidget(m_filterInput); + + m_close = new KPushButton(this); + m_close->setIconSet(SmallIcon("fileclose")); + m_close->setFlat(true); + layout->addWidget(m_close); + layout->addSpacing(gap); + + connect(m_filterInput, SIGNAL(textChanged(const QString&)), + this, SIGNAL(signalFilterChanged(const QString&))); + connect(m_close, SIGNAL(clicked()), this, SLOT(hide())); + connect(m_close, SIGNAL(clicked()), + &Dolphin::mainWin(), SLOT(slotShowFilterBarChanged())); +} + +FilterBar::~FilterBar() +{ +} + +void FilterBar::hide() +{ + m_filterInput->clear(); + m_filterInput->clearFocus(); + QWidget::hide(); +} + +void FilterBar::show() +{ + m_filterInput->setFocus(); + QWidget::show(); +} + +void FilterBar::keyReleaseEvent(QKeyEvent* event) +{ + QWidget::keyReleaseEvent(event); + if ((event->key() == Qt::Key_Escape)) { + hide(); + Dolphin::mainWin().slotShowFilterBarChanged(); + } +} + +#include "filterbar.moc" diff --git a/src/filterbar.h b/src/filterbar.h new file mode 100644 index 0000000..7f9c8b8 --- /dev/null +++ b/src/filterbar.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> * + * Copyright (C) 2006 by Gregor Kališnik <gregor@podnapisi.net> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef FILTERBAR_H +#define FILTERBAR_H + +#include <qwidget.h> + +class QLabel; +class KLineEdit; +class KPushButton; + +/** + * @brief Provides an input field for filtering the currently shown items. + * + * @author Gregor Kališnik <gregor@podnapisi.net> + */ +class FilterBar : public QWidget +{ + Q_OBJECT + +public: + FilterBar(QWidget *parent = 0, const char *name = 0); + virtual ~FilterBar(); + +signals: + /** + * Signal that reports the name filter has been + * changed to \a nameFilter. + */ + void signalFilterChanged(const QString& nameFilter); + +public slots: + /** @see QWidget::hide() */ + virtual void hide(); + + /** @see QWidget::show() */ + virtual void show(); + +protected: + virtual void keyReleaseEvent(QKeyEvent* event); + +private: + QLabel* m_filter; + KLineEdit* m_filterInput; + KPushButton* m_close; +}; + +#endif diff --git a/src/generalsettingspage.cpp b/src/generalsettingspage.cpp new file mode 100644 index 0000000..0a97574 --- /dev/null +++ b/src/generalsettingspage.cpp @@ -0,0 +1,171 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) and * + * and Patrice Tremblay * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "generalsettingspage.h" + +#include <qlayout.h> +#include <kdialog.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qvbox.h> +#include <qgrid.h> +#include <qgroupbox.h> +#include <klocale.h> +#include <qcheckbox.h> +#include <qbuttongroup.h> +#include <qpushbutton.h> +#include <kfiledialog.h> +#include <qradiobutton.h> + +#include "dolphinsettings.h" +#include "dolphin.h" +#include "dolphinview.h" + +GeneralSettingsPage::GeneralSettingsPage(QWidget* parent) : + SettingsPageBase(parent), + m_homeURL(0), + m_startSplit(0), + m_startEditable(0) +{ + QVBoxLayout* topLayout = new QVBoxLayout(parent, 2, KDialog::spacingHint()); + + const int spacing = KDialog::spacingHint(); + const int margin = KDialog::marginHint(); + const QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + DolphinSettings& settings = DolphinSettings::instance(); + + QVBox* vBox = new QVBox(parent); + vBox->setSizePolicy(sizePolicy); + vBox->setSpacing(spacing); + vBox->setMargin(margin); + vBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored); + + // create 'Home URL' editor + QGroupBox* homeGroup = new QGroupBox(1, Qt::Horizontal, i18n("Home URL"), vBox); + homeGroup->setSizePolicy(sizePolicy); + homeGroup->setMargin(margin); + + QHBox* homeURLBox = new QHBox(homeGroup); + homeURLBox->setSizePolicy(sizePolicy); + homeURLBox->setSpacing(spacing); + + new QLabel(i18n("Location:"), homeURLBox); + m_homeURL = new QLineEdit(settings.homeURL().prettyURL(), homeURLBox); + + QPushButton* selectHomeURLButton = new QPushButton(SmallIcon("folder"), QString::null, homeURLBox); + connect(selectHomeURLButton, SIGNAL(clicked()), + this, SLOT(selectHomeURL())); + + QHBox* buttonBox = new QHBox(homeGroup); + buttonBox->setSizePolicy(sizePolicy); + buttonBox->setSpacing(spacing); + QPushButton* useCurrentButton = new QPushButton(i18n("Use current location"), buttonBox); + connect(useCurrentButton, SIGNAL(clicked()), + this, SLOT(useCurrentLocation())); + QPushButton* useDefaultButton = new QPushButton(i18n("Use default location"), buttonBox); + connect(useDefaultButton, SIGNAL(clicked()), + this, SLOT(useDefaulLocation())); + + // create 'Default View Mode' group + QButtonGroup* buttonGroup = new QButtonGroup(3, Qt::Vertical, i18n("Default View Mode"), vBox); + buttonGroup->setSizePolicy(sizePolicy); + buttonGroup->setMargin(margin); + + m_iconsView = new QRadioButton(i18n("Icons"), buttonGroup); + m_detailsView = new QRadioButton(i18n("Details"), buttonGroup); + m_previewsView = new QRadioButton(i18n("Previews"), buttonGroup); + + switch (settings.defaultViewMode()) { + case DolphinView::IconsView: m_iconsView->setChecked(true); break; + case DolphinView::DetailsView: m_detailsView->setChecked(true); break; + case DolphinView::PreviewsView: m_previewsView->setChecked(true); break; + } + + // create 'Start with split view' checkbox + m_startSplit = new QCheckBox(i18n("Start with split view"), vBox); + m_startSplit->setChecked(settings.isViewSplit()); + + // create 'Start with editable navigation bar' checkbox + m_startEditable = new QCheckBox(i18n("Start with editable navigation bar"), vBox); + m_startEditable->setChecked(settings.isURLEditable()); + + // create 'Save view properties for each folder' checkbox + m_saveView = new QCheckBox(i18n("Save view properties for each folder"), vBox); + m_saveView->setChecked(settings.isSaveView()); + + // Add a dummy widget with no restriction regarding + // a vertical resizing. This assures that the dialog layout + // is not stretched vertically. + new QWidget(vBox); + + topLayout->addWidget(vBox); +} + + +GeneralSettingsPage::~GeneralSettingsPage() +{ +} + +void GeneralSettingsPage::applySettings() +{ + DolphinSettings& settings = DolphinSettings::instance(); + + const KURL url(m_homeURL->text()); + KFileItem fileItem(S_IFDIR, KFileItem::Unknown, url); + if (url.isValid() && fileItem.isDir()) { + settings.setHomeURL(url); + } + + DolphinView::Mode viewMode = DolphinView::IconsView; + if (m_detailsView->isChecked()) { + viewMode = DolphinView::DetailsView; + } + else if (m_previewsView->isChecked()) { + viewMode = DolphinView::PreviewsView; + } + settings.setDefaultViewMode(viewMode); + + settings.setViewSplit(m_startSplit->isChecked()); + settings.setSaveView(m_saveView->isChecked()); + settings.setURLEditable(m_startEditable->isChecked()); +} + +void GeneralSettingsPage::selectHomeURL() +{ + const QString homeURL(m_homeURL->text()); + KURL url(KFileDialog::getExistingURL(homeURL)); + if (!url.isEmpty()) { + m_homeURL->setText(url.prettyURL()); + } +} + +void GeneralSettingsPage::useCurrentLocation() +{ + const DolphinView* view = Dolphin::mainWin().activeView(); + m_homeURL->setText(view->url().prettyURL()); +} + +void GeneralSettingsPage::useDefaulLocation() +{ + m_homeURL->setText("file://" + QDir::homeDirPath()); +} + +#include "generalsettingspage.moc" diff --git a/src/generalsettingspage.h b/src/generalsettingspage.h new file mode 100644 index 0000000..1d68fde --- /dev/null +++ b/src/generalsettingspage.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef GENERALSETTINGSPAGE_H +#define GENERALSETTINGSPAGE_H + +#include <settingspagebase.h> +class QLineEdit; +class QRadioButton; +class QCheckBox; + +/** + * @brief Page for the 'General' settings of the Dolphin settings dialog. + * + * The general settings allow to set the home URL, the default view mode + * and the split view mode. + * + * @author Peter Penz <peter.penz@gmx.at> + */ +class GeneralSettingsPage : public SettingsPageBase +{ + Q_OBJECT + +public: + GeneralSettingsPage(QWidget* parent); + + virtual ~GeneralSettingsPage(); + + /** @see SettingsPageBase::applySettings */ + virtual void applySettings(); + +private slots: + void selectHomeURL(); + void useCurrentLocation(); + void useDefaulLocation(); + +private: + QLineEdit* m_homeURL; + QRadioButton* m_iconsView; + QRadioButton* m_detailsView; + QRadioButton* m_previewsView; + QCheckBox* m_startSplit; + QCheckBox* m_startEditable; + QCheckBox* m_saveView; +}; + +#endif diff --git a/src/hi128-app-d3lphin.png b/src/hi128-app-d3lphin.png Binary files differnew file mode 100644 index 0000000..651128a --- /dev/null +++ b/src/hi128-app-d3lphin.png diff --git a/src/hi16-app-d3lphin.png b/src/hi16-app-d3lphin.png Binary files differnew file mode 100644 index 0000000..5788fc7 --- /dev/null +++ b/src/hi16-app-d3lphin.png diff --git a/src/hi22-app-d3lphin.png b/src/hi22-app-d3lphin.png Binary files differnew file mode 100644 index 0000000..335c07d --- /dev/null +++ b/src/hi22-app-d3lphin.png diff --git a/src/hi32-app-d3lphin.png b/src/hi32-app-d3lphin.png Binary files differnew file mode 100644 index 0000000..5bd4a2d --- /dev/null +++ b/src/hi32-app-d3lphin.png diff --git a/src/hi48-app-d3lphin.png b/src/hi48-app-d3lphin.png Binary files differnew file mode 100644 index 0000000..0c9574f --- /dev/null +++ b/src/hi48-app-d3lphin.png diff --git a/src/hi64-app-d3lphin.png b/src/hi64-app-d3lphin.png Binary files differnew file mode 100644 index 0000000..613c612 --- /dev/null +++ b/src/hi64-app-d3lphin.png diff --git a/src/iconsviewsettingspage.cpp b/src/iconsviewsettingspage.cpp new file mode 100644 index 0000000..f23e185 --- /dev/null +++ b/src/iconsviewsettingspage.cpp @@ -0,0 +1,262 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "iconsviewsettingspage.h" + +#include <qlabel.h> +#include <qslider.h> +#include <qbuttongroup.h> +#include <qradiobutton.h> +#include <qspinbox.h> +#include <kiconloader.h> +#include <kfontcombo.h> +#include <kdialog.h> +#include <klocale.h> +#include <assert.h> + +#include "dolphiniconsviewsettings.h" +#include "dolphinsettings.h" +#include "pixmapviewer.h" + +#define GRID_SPACING_BASE 8 +#define GRID_SPACING_INC 12 + +IconsViewSettingsPage::IconsViewSettingsPage(DolphinIconsView::LayoutMode mode, + QWidget* parent) : + QVBox(parent), + m_mode(mode), + m_iconSizeSlider(0), + m_previewSizeSlider(0), + m_textWidthBox(0), + m_gridSpacingBox(0), + m_fontFamilyBox(0), + m_fontSizeBox(0), + m_textlinesCountBox(0), + m_arrangementBox(0) +{ + const int spacing = KDialog::spacingHint(); + const int margin = KDialog::marginHint(); + const QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + setSpacing(spacing); + setMargin(margin); + + DolphinIconsViewSettings* settings = DolphinSettings::instance().iconsView(m_mode); + assert(settings != 0); + + QHBox* sizesLayout = new QHBox(this); + sizesLayout->setSpacing(spacing); + sizesLayout->setSizePolicy(sizePolicy); + + // create 'Icon Size' group including slider and preview + QGroupBox* iconSizeGroup = new QGroupBox(2, Qt::Vertical, i18n("Icon Size"), sizesLayout); + iconSizeGroup->setSizePolicy(sizePolicy); + iconSizeGroup->setMargin(margin); + + const QColor iconBackgroundColor(KGlobalSettings::baseColor()); + + QHBox* iconSizeVBox = new QHBox(iconSizeGroup); + iconSizeVBox->setSpacing(spacing); + new QLabel(i18n("Small"), iconSizeVBox); + m_iconSizeSlider = new QSlider(0, 5, 1, 0, Qt::Horizontal, iconSizeVBox); + m_iconSizeSlider->setValue(sliderValue(settings->iconSize())); + m_iconSizeSlider->setTickmarks(QSlider::Below); + connect(m_iconSizeSlider, SIGNAL(valueChanged(int)), + this, SLOT(slotIconSizeChanged(int))); + new QLabel(i18n("Large"), iconSizeVBox); + + m_iconSizeViewer = new PixmapViewer(iconSizeGroup); + m_iconSizeViewer->setMinimumWidth(KIcon::SizeEnormous); + m_iconSizeViewer->setFixedHeight(KIcon::SizeEnormous); + m_iconSizeViewer->setEraseColor(iconBackgroundColor); + slotIconSizeChanged(m_iconSizeSlider->value()); + + if (m_mode == DolphinIconsView::Previews) { + // create 'Preview Size' group including slider and preview + QGroupBox* previewSizeGroup = new QGroupBox(2, Qt::Vertical, i18n("Preview Size"), sizesLayout); + previewSizeGroup->setSizePolicy(sizePolicy); + previewSizeGroup->setMargin(margin); + + QHBox* previewSizeVBox = new QHBox(previewSizeGroup); + previewSizeVBox->setSpacing(spacing); + new QLabel(i18n("Small"), previewSizeVBox); + m_previewSizeSlider = new QSlider(0, 5, 1, 0, Qt::Horizontal, previewSizeVBox); + m_previewSizeSlider->setValue(sliderValue(settings->previewSize())); + m_previewSizeSlider->setTickmarks(QSlider::Below); + connect(m_previewSizeSlider, SIGNAL(valueChanged(int)), + this, SLOT(slotPreviewSizeChanged(int))); + new QLabel(i18n("Large"), previewSizeVBox); + + m_previewSizeViewer = new PixmapViewer(previewSizeGroup); + m_previewSizeViewer->setMinimumWidth(KIcon::SizeEnormous); + m_previewSizeViewer->setFixedHeight(KIcon::SizeEnormous); + m_previewSizeViewer->setEraseColor(iconBackgroundColor); + + slotPreviewSizeChanged(m_previewSizeSlider->value()); + } + + QGroupBox* textGroup = new QGroupBox(2, Qt::Horizontal, i18n("Text"), this); + textGroup->setSizePolicy(sizePolicy); + textGroup->setMargin(margin); + + new QLabel(i18n("Font family:"), textGroup); + m_fontFamilyBox = new KFontCombo(textGroup); + m_fontFamilyBox->setCurrentFont(settings->fontFamily()); + + new QLabel(i18n("Font size:"), textGroup); + m_fontSizeBox = new QSpinBox(6, 99, 1, textGroup); + m_fontSizeBox->setValue(settings->fontSize()); + + new QLabel(i18n("Number of lines:"), textGroup); + m_textlinesCountBox = new QSpinBox(1, 5, 1, textGroup); + m_textlinesCountBox->setValue(settings->textlinesCount()); + + new QLabel(i18n("Text width:"), textGroup); + m_textWidthBox = new QComboBox(textGroup); + m_textWidthBox->insertItem(i18n("Small")); + m_textWidthBox->insertItem(i18n("Medium")); + m_textWidthBox->insertItem(i18n("Large")); + + QGroupBox* gridGroup = new QGroupBox(2, Qt::Horizontal, i18n("Grid"), this); + gridGroup->setSizePolicy(sizePolicy); + gridGroup->setMargin(margin); + + const bool leftToRightArrangement = (settings->arrangement() == QIconView::LeftToRight); + new QLabel(i18n("Arrangement:"), gridGroup); + m_arrangementBox = new QComboBox(gridGroup); + m_arrangementBox->insertItem(i18n("Left to right")); + m_arrangementBox->insertItem(i18n("Top to bottom")); + m_arrangementBox->setCurrentItem(leftToRightArrangement ? 0 : 1); + + new QLabel(i18n("Grid spacing:"), gridGroup); + m_gridSpacingBox = new QComboBox(gridGroup); + m_gridSpacingBox->insertItem(i18n("Small")); + m_gridSpacingBox->insertItem(i18n("Medium")); + m_gridSpacingBox->insertItem(i18n("Large")); + m_gridSpacingBox->setCurrentItem((settings->gridSpacing() - GRID_SPACING_BASE) / GRID_SPACING_INC); + + // Add a dummy widget with no restriction regarding + // a vertical resizing. This assures that the dialog layout + // is not stretched vertically. + new QWidget(this); + + adjustTextWidthSelection(); +} + +IconsViewSettingsPage::~IconsViewSettingsPage() +{ +} + +void IconsViewSettingsPage::applySettings() +{ + DolphinIconsViewSettings* settings = DolphinSettings::instance().iconsView(m_mode); + assert(settings != 0); + + const int defaultSize = iconSize(m_iconSizeSlider->value()); + settings->setIconSize(defaultSize); + + int previewSize = (m_mode == DolphinIconsView::Previews) ? + iconSize(m_previewSizeSlider->value()) : + defaultSize; + if (previewSize < defaultSize) { + // assure that the preview size is never smaller than the icon size + previewSize = defaultSize; + } + settings->setPreviewSize(previewSize); + + const int fontSize = m_fontSizeBox->value(); + + QIconView::Arrangement arrangement = (m_arrangementBox->currentItem() == 0) ? + QIconView::LeftToRight : + QIconView::TopToBottom; + settings->setArrangement(arrangement); + settings->calculateGridSize(m_textWidthBox->currentItem()); + + settings->setFontFamily(m_fontFamilyBox->currentFont()); + settings->setFontSize(fontSize); + settings->setTextlinesCount(m_textlinesCountBox->value()); + + settings->setGridSpacing(GRID_SPACING_BASE + + m_gridSpacingBox->currentItem() * GRID_SPACING_INC); +} + +void IconsViewSettingsPage::slotIconSizeChanged(int value) +{ + KIconLoader iconLoader; + m_iconSizeViewer->setPixmap(iconLoader.loadIcon("folder", KIcon::Desktop, iconSize(value))); + + if (m_previewSizeSlider != 0) { + int previewSizeValue = m_previewSizeSlider->value(); + if (previewSizeValue < value) { + // assure that the preview size is never smaller than the icon size + previewSizeValue = value; + } + slotPreviewSizeChanged(previewSizeValue); + } +} + +void IconsViewSettingsPage::slotPreviewSizeChanged(int value) +{ + KIconLoader iconLoader; + const int iconSizeValue = m_iconSizeSlider->value(); + if (value < iconSizeValue) { + // assure that the preview size is never smaller than the icon size + value = iconSizeValue; + } + m_previewSizeViewer->setPixmap(iconLoader.loadIcon("preview", KIcon::Desktop, iconSize(value))); +} + +int IconsViewSettingsPage::iconSize(int sliderValue) const +{ + int size = KIcon::SizeMedium; + switch (sliderValue) { + case 0: size = KIcon::SizeSmall; break; + case 1: size = KIcon::SizeSmallMedium; break; + case 2: size = KIcon::SizeMedium; break; + case 3: size = KIcon::SizeLarge; break; + case 4: size = KIcon::SizeHuge; break; + case 5: size = KIcon::SizeEnormous; break; + } + return size; +} + +int IconsViewSettingsPage::sliderValue(int iconSize) const +{ + int value = 0; + switch (iconSize) { + case KIcon::SizeSmall: value = 0; break; + case KIcon::SizeSmallMedium: value = 1; break; + case KIcon::SizeMedium: value = 2; break; + case KIcon::SizeLarge: value = 3; break; + case KIcon::SizeHuge: value = 4; break; + case KIcon::SizeEnormous: value = 5; break; + default: break; + } + return value; +} + +void IconsViewSettingsPage::adjustTextWidthSelection() +{ + DolphinIconsViewSettings* settings = DolphinSettings::instance().iconsView(m_mode); + assert(settings != 0); + m_textWidthBox->setCurrentItem(settings->textWidthHint()); +} + +#include "iconsviewsettingspage.moc" diff --git a/src/iconsviewsettingspage.h b/src/iconsviewsettingspage.h new file mode 100644 index 0000000..ce7ce55 --- /dev/null +++ b/src/iconsviewsettingspage.h @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef ICONSVIEWSETTINGSPAGE_H +#define ICONSVIEWSETTINGSPAGE_H + +#include <qvbox.h> +#include <dolphiniconsview.h> + +class QSlider; +class QComboBox; +class QCheckBox; +class QPushButton; +class QSpinBox; +class KFontCombo; +class PixmapViewer; + +/** + * @brief Tab page for the 'Icons Mode' and 'Previews Mode' settings + * of the Dolphin settings dialog. + * + * Allows to set: + * - icon size + * - preview size + * - text width + * - grid spacing + * - font family + * - font size + * - number of text lines + * - arrangement + * + * @see DolphinIconsViewSettings + * @author Peter Penz <peter.penz@gmx.at> + */ +class IconsViewSettingsPage : public QVBox +{ + Q_OBJECT + +public: + IconsViewSettingsPage(DolphinIconsView::LayoutMode mode, + QWidget* parent); + virtual ~IconsViewSettingsPage(); + + /** + * Applies the settings for the icons view. + * The settings are persisted automatically when + * closing Dolphin. + */ + void applySettings(); + +private slots: + void slotIconSizeChanged(int value); + void slotPreviewSizeChanged(int value); + +private: + DolphinIconsView::LayoutMode m_mode; + + QSlider* m_iconSizeSlider; + PixmapViewer* m_iconSizeViewer; + QSlider* m_previewSizeSlider; + PixmapViewer* m_previewSizeViewer; + QComboBox* m_textWidthBox; + QComboBox* m_gridSpacingBox; + KFontCombo* m_fontFamilyBox; + QSpinBox* m_fontSizeBox; + QSpinBox* m_textlinesCountBox; + QComboBox* m_arrangementBox; + + /** Returns the icon size for the given slider value. */ + int iconSize(int sliderValue) const; + + /** Returns the slider value for the given icon size. */ + int sliderValue(int iconSize) const; + + /** + * Adjusts the selection of the text width combo box dependant + * from the grid width and grid height settings. + */ + void adjustTextWidthSelection(); +}; + +#endif diff --git a/src/infosidebarpage.cpp b/src/infosidebarpage.cpp new file mode 100644 index 0000000..7cfe346 --- /dev/null +++ b/src/infosidebarpage.cpp @@ -0,0 +1,630 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "infosidebarpage.h" +#include <assert.h> + +#include <qlayout.h> +#include <qpixmap.h> +#include <qlabel.h> +#include <qtimer.h> +#include <qpushbutton.h> +#include <qvbox.h> +#include <qvgroupbox.h> +#include <qpopupmenu.h> +#include <qpainter.h> +#include <qfontmetrics.h> +#include <qgrid.h> +#include <qhgroupbox.h> + +#include <kbookmarkmanager.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kio/previewjob.h> +#include <kfileitem.h> +#include <kdialog.h> +#include <kglobalsettings.h> +#include <kfilemetainfo.h> + +#include "dolphin.h" +#include "pixmapviewer.h" +#include "dolphinsettings.h" + +InfoSidebarPage::InfoSidebarPage(QWidget* parent) : + SidebarPage(parent), + m_multipleSelection(false), + m_pendingPreview(false), + m_timer(0), + m_preview(0), + m_name(0), + m_currInfoLineIdx(0), + m_infoGrid(0), + m_actionBox(0) +{ + const int spacing = KDialog::spacingHint(); + + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), + this, SLOT(slotTimeout())); + + QVBoxLayout* layout = new QVBoxLayout(this); + layout->setSpacing(spacing); + + // preview + m_preview = new PixmapViewer(this); + m_preview->setMinimumWidth(KIcon::SizeEnormous); + m_preview->setFixedHeight(KIcon::SizeEnormous); + + // name + m_name = new QLabel(this); + m_name->setTextFormat(Qt::RichText); + m_name->setAlignment(m_name->alignment() | Qt::AlignHCenter); + QFontMetrics fontMetrics(m_name->font()); + m_name->setMinimumHeight(fontMetrics.height() * 3); + m_name->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum); + + QWidget* sep1 = new QHGroupBox(this); // TODO: check whether default widget exist for this? + sep1->setFixedHeight(1); + + // general information + m_infoGrid = new QGrid(2, this); + m_infoGrid->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + QWidget* sep2 = new QHGroupBox(this); // TODO: check whether default widget exist for this? + sep2->setFixedHeight(1); + + // actions + m_actionBox = new QVBox(this); + m_actionBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + // Add a dummy widget with no restriction regarding a vertical resizing. + // This assures that information is always top aligned. + QWidget* dummy = new QWidget(this); + + layout->addItem(new QSpacerItem(spacing, spacing, QSizePolicy::Preferred, QSizePolicy::Fixed)); + layout->addWidget(m_preview); + layout->addWidget(m_name); + layout->addWidget(sep1); + layout->addWidget(m_infoGrid); + layout->addWidget(sep2); + layout->addWidget(m_actionBox); + layout->addWidget(dummy); + + connect(&Dolphin::mainWin(), SIGNAL(selectionChanged()), + this, SLOT(showItemInfo())); + + connectToActiveView(); +} + +InfoSidebarPage::~InfoSidebarPage() +{ +} + +void InfoSidebarPage::activeViewChanged() +{ + connectToActiveView(); +} + +void InfoSidebarPage::requestDelayedItemInfo(const KURL& url) +{ + cancelRequest(); + + if (!url.isEmpty() && !m_multipleSelection) { + m_urlCandidate = url; + m_timer->start(300, true); + } +} + +void InfoSidebarPage::requestItemInfo(const KURL& url) +{ + cancelRequest(); + + if (!url.isEmpty() && !m_multipleSelection) { + m_shownURL = url; + showItemInfo(); + } +} + +void InfoSidebarPage::showItemInfo() +{ + cancelRequest(); + + m_multipleSelection = false; + + // show the preview... + DolphinView* view = Dolphin::mainWin().activeView(); + const KFileItemList* selectedItems = view->selectedItems(); + if ((selectedItems != 0) && selectedItems->count() > 1) { + m_multipleSelection = true; + } + + if (m_multipleSelection) { + KIconLoader iconLoader; + QPixmap icon = iconLoader.loadIcon("exec", + KIcon::NoGroup, + KIcon::SizeEnormous); + m_preview->setPixmap(icon); + m_name->setText(i18n("%n items selected", "%n items selected", selectedItems->count())); + } + else if (!applyBookmark()) { + // try to get a preview pixmap from the item... + KURL::List list; + list.append(m_shownURL); + + m_pendingPreview = true; + m_preview->setPixmap(QPixmap()); + + KIO::PreviewJob* job = KIO::filePreview(list, + m_preview->width(), + KIcon::SizeEnormous); + connect(job, SIGNAL(gotPreview(const KFileItem*, const QPixmap&)), + this, SLOT(gotPreview(const KFileItem*, const QPixmap&))); + connect(job, SIGNAL(failed(const KFileItem*)), + this, SLOT(slotPreviewFailed(const KFileItem*))); + + QString text("<b>"); + text.append(m_shownURL.fileName()); + text.append("</b>"); + m_name->setText(text); + } + + createMetaInfo(); + insertActions(); +} + +void InfoSidebarPage::slotTimeout() +{ + m_shownURL = m_urlCandidate; + showItemInfo(); +} + +void InfoSidebarPage::slotPreviewFailed(const KFileItem* item) +{ + m_pendingPreview = false; + if (!applyBookmark()) { + m_preview->setPixmap(item->pixmap(KIcon::SizeEnormous)); + } +} + +void InfoSidebarPage::gotPreview(const KFileItem* /* item */, + const QPixmap& pixmap) +{ + if (m_pendingPreview) { + m_preview->setPixmap(pixmap); + m_pendingPreview = false; + } +} + +void InfoSidebarPage::startService(int index) +{ + DolphinView* view = Dolphin::mainWin().activeView(); + if (view->hasSelection()) { + KURL::List selectedURLs = view->selectedURLs(); + KDEDesktopMimeType::executeService(selectedURLs, m_actionsVector[index]); + } + else { + KDEDesktopMimeType::executeService(m_shownURL, m_actionsVector[index]); + } +} + +void InfoSidebarPage::connectToActiveView() +{ + cancelRequest(); + + DolphinView* view = Dolphin::mainWin().activeView(); + connect(view, SIGNAL(signalRequestItemInfo(const KURL&)), + this, SLOT(requestDelayedItemInfo(const KURL&))); + connect(view, SIGNAL(signalURLChanged(const KURL&)), + this, SLOT(requestItemInfo(const KURL&))); + + m_shownURL = view->url(); + showItemInfo(); +} + +bool InfoSidebarPage::applyBookmark() +{ + KBookmarkGroup root = DolphinSettings::instance().bookmarkManager()->root(); + KBookmark bookmark = root.first(); + while (!bookmark.isNull()) { + if (m_shownURL.equals(bookmark.url(), true)) { + QString text("<b>"); + text.append(bookmark.text()); + text.append("</b>"); + m_name->setText(text); + + KIconLoader iconLoader; + QPixmap icon = iconLoader.loadIcon(bookmark.icon(), + KIcon::NoGroup, + KIcon::SizeEnormous); + m_preview->setPixmap(icon); + return true; + } + bookmark = root.next(bookmark); + } + + return false; +} + +void InfoSidebarPage::cancelRequest() +{ + m_timer->stop(); + m_pendingPreview = false; +} + +void InfoSidebarPage::createMetaInfo() +{ + // To prevent a flickering it's important to reuse available + // labels instead of deleting them and recreate them afterwards. + // The methods beginInfoLines(), addInfoLine() and endInfoLines() + // take care of this. + beginInfoLines(); + DolphinView* view = Dolphin::mainWin().activeView(); + if (!view->hasSelection()) { + KFileItem fileItem(S_IFDIR, KFileItem::Unknown, m_shownURL); + fileItem.refresh(); + + if (fileItem.isDir()) { + addInfoLine(i18n("Type:"), i18n("Directory")); + } + else { + addInfoLine(i18n("Type:"), fileItem.mimeComment()); + + QString sizeText(KIO::convertSize(fileItem.size())); + addInfoLine(i18n("Size:"), sizeText); + addInfoLine(i18n("Modified:"), fileItem.timeString()); + + const KFileMetaInfo& metaInfo = fileItem.metaInfo(); + if (metaInfo.isValid()) { + QStringList keys = metaInfo.supportedKeys(); + for (QStringList::Iterator it = keys.begin(); it != keys.end(); ++it) { + if (showMetaInfo(*it)) { + KFileMetaInfoItem metaInfoItem = metaInfo.item(*it); + addInfoLine(*it, metaInfoItem.string()); + } + } + } + } + } + endInfoLines(); +} + +void InfoSidebarPage::beginInfoLines() +{ + m_currInfoLineIdx = 0; +} + +void InfoSidebarPage::endInfoLines() +{ + if (m_currInfoLineIdx <= 0) { + return; + } + + // remove labels which have not been used + if (m_currInfoLineIdx < static_cast<int>(m_infoWidgets.count())) { + QPtrListIterator<QLabel> deleteIter(m_infoWidgets); + deleteIter += m_currInfoLineIdx; + + QWidget* widget = 0; + int removeCount = 0; + while ((widget = deleteIter.current()) != 0) { + widget->close(); + widget->deleteLater(); + ++deleteIter; + ++removeCount; + } + for (int i = 0; i < removeCount; ++i) { + m_infoWidgets.removeLast(); + } + } +} + +bool InfoSidebarPage::showMetaInfo(const QString& key) const +{ + // sorted list of keys, where it's data should be shown + static const char* keys[] = { + "Album", + "Artist", + "Author", + "Bitrate", + "Date", + "Dimensions", + "Genre", + "Length", + "Lines", + "Pages", + "Title", + "Words" + }; + + // do a binary search for the key... + int top = 0; + int bottom = sizeof(keys) / sizeof(char*) - 1; + while (top < bottom) { + const int middle = (top + bottom) / 2; + const int result = key.compare(keys[middle]); + if (result < 0) { + bottom = middle - 1; + } + else if (result > 0) { + top = middle + 1; + } + else { + return true; + } + } + + return false; +} + +void InfoSidebarPage::addInfoLine(const QString& labelText, const QString& infoText) +{ + QString labelStr("<b>"); + labelStr.append(labelText); + labelStr.append("</b> "); + + const int count = m_infoWidgets.count(); + if (m_currInfoLineIdx < count - 1) { + // reuse available labels + m_infoWidgets.at(m_currInfoLineIdx++)->setText(labelStr); + m_infoWidgets.at(m_currInfoLineIdx++)->setText(infoText); + } + else { + // no labels are available anymore, hence create 2 new ones + QLabel* label = new QLabel(labelStr, m_infoGrid); + label->setTextFormat(Qt::RichText); + label->setAlignment(Qt::AlignRight | + Qt::AlignTop); + label->show(); + m_infoWidgets.append(label); + + QLabel* info = new QLabel(infoText, m_infoGrid); + info->setTextFormat(Qt::RichText); + info->setAlignment(Qt::AlignTop | Qt::WordBreak); + info->show(); + m_infoWidgets.append(info); + + m_currInfoLineIdx += 2; + } +} + +void InfoSidebarPage::insertActions() +{ + // delete all existing action widgets + // TODO: just use children() from QObject... + QPtrListIterator<QWidget> deleteIter(m_actionWidgets); + QWidget* widget = 0; + while ((widget = deleteIter.current()) != 0) { + widget->close(); + widget->deleteLater(); + ++deleteIter; + } + + m_actionWidgets.clear(); + m_actionsVector.clear(); + + int actionsIndex = 0; + + // The algorithm for searching the available actions works on a list + // of KFileItems. If no selection is given, a temporary KFileItem + // by the given URL 'url' is created and added to the list. + KFileItem fileItem(S_IFDIR, KFileItem::Unknown, m_shownURL); + KFileItemList localList; + const KFileItemList* itemList = Dolphin::mainWin().activeView()->selectedItems(); + if ((itemList == 0) || itemList->isEmpty()) { + fileItem.refresh(); + localList.append(&fileItem); + itemList = &localList; + } + + // 'itemList' contains now all KFileItems, where an item information should be shown. + // TODO: the following algorithm is quite equal to DolphinContextMenu::insertActionItems(). + // It's open yet whether they should be merged or whether they have to work slightly different. + QStringList dirs = KGlobal::dirs()->findDirs("data", "d3lphin/servicemenus/"); + for (QStringList::ConstIterator dirIt = dirs.begin(); dirIt != dirs.end(); ++dirIt) { + QDir dir(*dirIt); + QStringList entries = dir.entryList("*.desktop", QDir::Files); + + for (QStringList::ConstIterator entryIt = entries.begin(); entryIt != entries.end(); ++entryIt) { + KSimpleConfig cfg(*dirIt + *entryIt, true); + cfg.setDesktopGroup(); + if ((cfg.hasKey("Actions") || cfg.hasKey("X-KDE-GetActionMenu")) && cfg.hasKey("ServiceTypes")) { + const QStringList types = cfg.readListEntry("ServiceTypes"); + for (QStringList::ConstIterator it = types.begin(); it != types.end(); ++it) { + // check whether the mime type is equal or whether the + // mimegroup (e. g. image/*) is supported + + bool insert = false; + if ((*it) == "all/allfiles") { + // The service type is valid for all files, but not for directories. + // Check whether the selected items only consist of files... + KFileItemListIterator mimeIt(*itemList); + KFileItem* item = 0; + insert = true; + while (insert && ((item = mimeIt.current()) != 0)) { + insert = !item->isDir(); + ++mimeIt; + } + } + + if (!insert) { + // Check whether the MIME types of all selected files match + // to the mimetype of the service action. As soon as one MIME + // type does not match, no service menu is shown at all. + KFileItemListIterator mimeIt(*itemList); + KFileItem* item = 0; + insert = true; + while (insert && ((item = mimeIt.current()) != 0)) { + const QString mimeType((*mimeIt)->mimetype()); + const QString mimeGroup(mimeType.left(mimeType.find('/'))); + + insert = (*it == mimeType) || + ((*it).right(1) == "*") && + ((*it).left((*it).find('/')) == mimeGroup); + ++mimeIt; + } + } + + if (insert) { + const QString submenuName = cfg.readEntry( "X-KDE-Submenu" ); + QPopupMenu* popup = 0; + if (!submenuName.isEmpty()) { + // create a sub menu containing all actions + popup = new QPopupMenu(); + connect(popup, SIGNAL(activated(int)), + this, SLOT(startService(int))); + + QPushButton* button = new QPushButton(submenuName, m_actionBox); + button->setFlat(true); + button->setPopup(popup); + button->show(); + m_actionWidgets.append(button); + } + + QValueList<KDEDesktopMimeType::Service> userServices = + KDEDesktopMimeType::userDefinedServices(*dirIt + *entryIt, true); + + // iterate through all actions and add them to a widget + QValueList<KDEDesktopMimeType::Service>::Iterator serviceIt; + for (serviceIt = userServices.begin(); serviceIt != userServices.end(); ++serviceIt) { + KDEDesktopMimeType::Service service = (*serviceIt); + if (popup == 0) { + ServiceButton* button = new ServiceButton(SmallIcon(service.m_strIcon), + service.m_strName, + m_actionBox, + actionsIndex); + connect(button, SIGNAL(requestServiceStart(int)), + this, SLOT(startService(int))); + m_actionWidgets.append(button); + button->show(); + } + else { + popup->insertItem(SmallIcon(service.m_strIcon), service.m_strName, actionsIndex); + } + + m_actionsVector.append(service); + ++actionsIndex; + } + } + } + } + } + } +} + +ServiceButton::ServiceButton(const QIconSet& icon, + const QString& text, + QWidget* parent, + int index) : + QPushButton(icon, text, parent), + m_hover(false), + m_index(index) +{ + setEraseColor(colorGroup().background()); + setFocusPolicy(QWidget::NoFocus); + connect(this, SIGNAL(released()), + this, SLOT(slotReleased())); +} + +ServiceButton::~ServiceButton() +{ +} + +void ServiceButton::drawButton(QPainter* painter) +{ + const int buttonWidth = width(); + const int buttonHeight = height(); + + QColor backgroundColor; + QColor foregroundColor; + if (m_hover) { + backgroundColor = KGlobalSettings::highlightColor(); + foregroundColor = KGlobalSettings::highlightedTextColor(); + } + else { + backgroundColor = colorGroup().background(); + foregroundColor = KGlobalSettings::buttonTextColor(); + } + + // draw button background + painter->setPen(NoPen); + painter->setBrush(backgroundColor); + painter->drawRect(0, 0, buttonWidth, buttonHeight); + + const int spacing = KDialog::spacingHint(); + + // draw icon + int x = spacing; + const int y = (buttonHeight - KIcon::SizeSmall) / 2; + const QIconSet* set = iconSet(); + if (set != 0) { + painter->drawPixmap(x, y, set->pixmap(QIconSet::Small, QIconSet::Normal)); + } + x += KIcon::SizeSmall + spacing; + + // draw text + painter->setPen(foregroundColor); + + const int textWidth = buttonWidth - x; + QFontMetrics fontMetrics(font()); + const bool clipped = fontMetrics.width(text()) >= textWidth; + //const int align = clipped ? Qt::AlignVCenter : Qt::AlignCenter; + painter->drawText(QRect(x, 0, textWidth, buttonHeight), Qt::AlignVCenter, text()); + + if (clipped) { + // Blend the right area of the text with the background, as the + // text is clipped. + // TODO #1: use alpha blending in Qt4 instead of drawing the text that often + // TODO #2: same code as in URLNavigatorButton::drawButton() -> provide helper class? + const int blendSteps = 16; + + QColor blendColor(backgroundColor); + const int redInc = (foregroundColor.red() - backgroundColor.red()) / blendSteps; + const int greenInc = (foregroundColor.green() - backgroundColor.green()) / blendSteps; + const int blueInc = (foregroundColor.blue() - backgroundColor.blue()) / blendSteps; + for (int i = 0; i < blendSteps; ++i) { + painter->setClipRect(QRect(x + textWidth - i, 0, 1, buttonHeight)); + painter->setPen(blendColor); + painter->drawText(QRect(x, 0, textWidth, buttonHeight), Qt::AlignVCenter, text()); + + blendColor.setRgb(blendColor.red() + redInc, + blendColor.green() + greenInc, + blendColor.blue() + blueInc); + } + } +} + +void ServiceButton::enterEvent(QEvent* event) +{ + QPushButton::enterEvent(event); + m_hover = true; + update(); +} + +void ServiceButton::leaveEvent(QEvent* event) +{ + QPushButton::leaveEvent(event); + m_hover = false; + update(); +} + +void ServiceButton::slotReleased() +{ + emit requestServiceStart(m_index); +} + diff --git a/src/infosidebarpage.h b/src/infosidebarpage.h new file mode 100644 index 0000000..48e3dd4 --- /dev/null +++ b/src/infosidebarpage.h @@ -0,0 +1,194 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef _INFOSIDEBARPAGE_H_ +#define _INFOSIDEBARPAGE_H_ + +#include <sidebarpage.h> + +#include <qvaluevector.h> +#include <qpushbutton.h> + +#include <kurl.h> +#include <ksortablevaluelist.h> +#include <kmimetype.h> + +namespace KIO { + class Job; +}; + +class QPixmap; +class QIconSet; +class QString; +class QPainter; +class KFileItem; +class QLabel; +class QVBox; +class QGrid; +class PixmapViewer; + +/** + * @brief Prototype for a information sidebar. + * + * Will be exchanged in future releases by pluggable sidebar pages... + */ +class InfoSidebarPage : public SidebarPage +{ + Q_OBJECT + +public: + InfoSidebarPage(QWidget* parent); + virtual ~InfoSidebarPage(); + +protected: + /** @see SidebarPage::activeViewChanged() */ + virtual void activeViewChanged(); + +private slots: + /** + * Does a delayed request of information for the item of the given URL and + * provides default actions. + * + * @see InfoSidebarPage::showItemInfo() + */ + void requestDelayedItemInfo(const KURL& url); + + /** + * Does a request of information for the item of the given URL and + * provides default actions. + * + * @see InfoSidebarPage::showItemInfo() + */ + void requestItemInfo(const KURL& url); + + /** + * Shows the information for the item of the URL which has been provided by + * InfoSidebarPage::requestItemInfo() and provides default actions. + */ + void showItemInfo(); + + /** + * Triggered if the request for item information has timed out. + * @see InfoSidebarPage::requestDelayedItemInfo() + */ + void slotTimeout(); + + /** + * Is invoked if no preview is available for the item. In this + * case the icon will be shown. + */ + void slotPreviewFailed(const KFileItem* item); + + /** + * Is invoked if a preview is available for the item. The preview + * \a pixmap is shown inside the info page. + */ + void gotPreview(const KFileItem* item, const QPixmap& pixmap); + + /** + * Starts the service of m_actionsVector with the index \index on + * the shown URL (or the selected items if available). + */ + void startService(int index); + +private: + /** + * Connects to signals from the currently active Dolphin view to get + * informed about highlighting changes. + */ + void connectToActiveView(); + + /** + * Checks whether the current URL is repesented by a bookmark. If yes, + * then the bookmark icon and name are shown instead of a preview. + * @return True, if the URL represents exactly a bookmark. + */ + bool applyBookmark(); + + /** Assures that any pending item information request is cancelled. */ + void cancelRequest(); + + // TODO: the following methods are just a prototypes for meta + // info generation... + void createMetaInfo(); + void addInfoLine(const QString& labelText, + const QString& infoText); + void beginInfoLines(); + void endInfoLines(); + + /** + * Returns true, if the string \a key represents a meta information + * that should be shown. + */ + bool showMetaInfo(const QString& key) const; + + /** + * Inserts the available actions to the info page for the given item. + */ + void insertActions(); + + bool m_multipleSelection; + bool m_pendingPreview; + QTimer* m_timer; + KURL m_shownURL; + KURL m_urlCandidate; + + PixmapViewer* m_preview; + QLabel* m_name; + + int m_currInfoLineIdx; + QGrid* m_infoGrid; + QPtrList<QLabel> m_infoWidgets; // TODO: use children() from QObject instead + + QVBox* m_actionBox; + QPtrList<QWidget> m_actionWidgets; // TODO: use children() from QObject instead + QValueVector<KDEDesktopMimeType::Service> m_actionsVector; +}; + +// TODO #1: move to SidebarPage? +// TODO #2: quite same button from the optical point of view as URLNavigatorButton +// -> provide helper class or common base class +class ServiceButton : public QPushButton +{ + Q_OBJECT + +public: + ServiceButton(const QIconSet& icon, + const QString& text, + QWidget* parent, + int index); + virtual ~ServiceButton(); + +signals: + void requestServiceStart(int index); + +protected: + virtual void drawButton(QPainter* painter); + virtual void enterEvent(QEvent* event); + virtual void leaveEvent(QEvent* event); + +private slots: + void slotReleased(); + +private: + bool m_hover; + int m_index; +}; + +#endif // _INFOSIDEBARPAGE_H_ diff --git a/src/itemeffectsmanager.cpp b/src/itemeffectsmanager.cpp new file mode 100644 index 0000000..1d1d199 --- /dev/null +++ b/src/itemeffectsmanager.cpp @@ -0,0 +1,189 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "itemeffectsmanager.h" +#include <kiconeffect.h> +#include <kapplication.h> +#include <qobjectlist.h> +#include <kglobalsettings.h> +#include <qclipboard.h> +#include <kurldrag.h> +#include <klocale.h> + +#include "dolphin.h" +#include "dolphinstatusbar.h" + +ItemEffectsManager::ItemEffectsManager() +{ + m_pixmapCopy = new QPixmap(); +} + +ItemEffectsManager::~ItemEffectsManager() +{ + delete m_pixmapCopy; + m_pixmapCopy = 0; + + m_highlightedURL = 0; +} + +void ItemEffectsManager::zoomIn() +{ + Dolphin::mainWin().refreshViews(); +} + +void ItemEffectsManager::zoomOut() +{ + Dolphin::mainWin().refreshViews(); +} + +void ItemEffectsManager::activateItem(void* context) +{ + KFileItem* fileInfo = contextFileInfo(context); + const KURL itemURL(fileInfo->url()); + if (m_highlightedURL == itemURL) { + // the item is already highlighted + return; + } + + resetActivatedItem(); + + const QPixmap* itemPixmap = contextPixmap(context); + if (itemPixmap != 0) { + // remember the pixmap and item to be able to + // restore it to the old state later + *m_pixmapCopy = *itemPixmap; + m_highlightedURL = itemURL; + + // apply an icon effect to the item below the mouse pointer + KIconEffect iconEffect; + QPixmap pixmap = iconEffect.apply(*itemPixmap, + KIcon::Desktop, + KIcon::ActiveState); + setContextPixmap(context, pixmap); + } + + if (!Dolphin::mainWin().activeView()->hasSelection()) { + DolphinStatusBar* statusBar = Dolphin::mainWin().activeView()->statusBar(); + statusBar->setMessage(statusBarText(fileInfo), DolphinStatusBar::Default); + } +} + +void ItemEffectsManager::resetActivatedItem() +{ + if (m_highlightedURL.isEmpty()) { + return; + } + + for (void* context = firstContext(); context != 0; context = nextContext(context)) { + KURL itemURL(contextFileInfo(context)->url()); + if (itemURL == m_highlightedURL) { + // the highlighted item has been found and is restored to the default state + KIconEffect iconEffect; + QPixmap pixmap = iconEffect.apply(*m_pixmapCopy, + KIcon::Desktop, + KIcon::DefaultState); + + // TODO: KFileIconView does not emit any signal when the preview has been finished. + // Hence check the size to prevent that a preview is hidden by restoring a + // non-preview pixmap. + const QPixmap* highlightedPixmap = contextPixmap(context); + const bool restore = (pixmap.width() == highlightedPixmap->width()) && + (pixmap.height() == highlightedPixmap->height()); + if (restore) { + setContextPixmap(context, pixmap); + } + break; + } + } + + m_highlightedURL = 0; + + DolphinStatusBar* statusBar = Dolphin::mainWin().activeView()->statusBar(); + statusBar->clear(); +} + +void ItemEffectsManager::updateDisabledItems() +{ + if (!m_disabledItems.isEmpty()) { + // restore all disabled items with their original pixmap + for (void* context = firstContext(); context != 0; context = nextContext(context)) { + const KFileItem* fileInfo = contextFileInfo(context); + const KURL& fileURL = fileInfo->url(); + QValueListIterator<DisabledItem> it = m_disabledItems.begin(); + while (it != m_disabledItems.end()) { + if (fileURL == (*it).url) { + setContextPixmap(context, (*it).pixmap); + } + ++it; + } + } + m_disabledItems.clear(); + } + + if (!Dolphin::mainWin().clipboardContainsCutData()) { + return; + } + + QClipboard* clipboard = QApplication::clipboard(); + QMimeSource* data = clipboard->data(); + if (!KURLDrag::canDecode(data)) { + return; + } + + // The clipboard contains items, which have been cutted. Change the pixmaps of all those + // items to the disabled state. + KURL::List urls; + KURLDrag::decode(data, urls); + for (void* context = firstContext(); context != 0; context = nextContext(context)) { + const KFileItem* fileInfo = contextFileInfo(context); + const KURL& fileURL = fileInfo->url(); + for(KURL::List::ConstIterator it = urls.begin(); it != urls.end(); ++it) { + if (fileURL == (*it)) { + const QPixmap* itemPixmap = contextPixmap(context); + if (itemPixmap != 0) { + // remember old pixmap + DisabledItem disabledItem; + disabledItem.url = fileURL; + disabledItem.pixmap = *itemPixmap; + m_disabledItems.append(disabledItem); + + KIconEffect iconEffect; + QPixmap disabledPixmap = iconEffect.apply(*itemPixmap, + KIcon::Desktop, + KIcon::DisabledState); + setContextPixmap(context, disabledPixmap); + } + break; + } + } + } +} + +QString ItemEffectsManager::statusBarText(KFileItem* fileInfo) const +{ + if (fileInfo->isDir()) { + // KFileItem::getStatusBar() returns "MyDocuments/ Folder" as + // status bar text for a folder 'MyDocuments'. This is adjusted + // to "MyDocuments (Folder)" in Dolphin. + return i18n("%1 (Folder)").arg(fileInfo->name()); + } + + return fileInfo->getStatusBarInfo(); +} diff --git a/src/itemeffectsmanager.h b/src/itemeffectsmanager.h new file mode 100644 index 0000000..eb2921d --- /dev/null +++ b/src/itemeffectsmanager.h @@ -0,0 +1,120 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef ITEMEFFECTSMANAGER_H +#define ITEMEFFECTSMANAGER_H + +#include <qobject.h> +#include <qpixmap.h> +#include <kurl.h> +#include <qvaluelist.h> +class KFileItem; + +/** + * @brief Abstract class to implement item effects for a Dolphin view. + * + * Derived classes must implement the following pure virtual methods: + * - ItemEffectsManager::setContextPixmap() + * - ItemEffectsManager::contextPixmap() + * - ItemEffectsManager::firstContext() + * - ItemEffectsManager::nextContext() + * - ItemEffectsManager::contextFileInfo() + * + * The item effects manager highlights currently active items and also + * respects cutted items. A 'context' is defined as abstract data type, + * which usually is represented by a KFileListViewItem or + * a KFileIconViewItem. + * + * In Qt4 the item effects manager should get integrated as part of Interview + * and hence no abstract context handling should be necessary anymore. The main + * purpose of the current interface is to prevent code duplication as there is + * no common model shared by QListView and QIconView of Qt3. + * + * @see DolphinIconsView + * @see DolphinDetailsView + * @author Peter Penz <peter.penz@gmx.at> + */ +class ItemEffectsManager +{ +public: + ItemEffectsManager(); + virtual ~ItemEffectsManager(); + + /** Is invoked before the items get updated. */ + virtual void beginItemUpdates() = 0; + + /** Is invoked after the items have been updated. */ + virtual void endItemUpdates() = 0; + + /** + * Increases the size of the current set view mode and refreshes + * all views. Derived implementations must invoke the base implementation + * if zooming in had been done. + */ + virtual void zoomIn(); + + /** + * Decreases the size of the current set view mode and refreshes + * all views. Derived implementations must invoke the base implementation + * if zooming out had been done. + */ + virtual void zoomOut(); + + /** + * Returns true, if zooming in is possible. If false is returned, + * the minimal zoom size is possible. + */ + virtual bool isZoomInPossible() const = 0; + + /** + * Returns true, if zooming in is possible. If false is returned, + * the minimal zoom size is possible. + */ + virtual bool isZoomOutPossible() const = 0; + +protected: + virtual void setContextPixmap(void* context, + const QPixmap& pixmap) = 0; + virtual const QPixmap* contextPixmap(void* context) = 0; + virtual void* firstContext() = 0; + virtual void* nextContext(void* context) = 0; + virtual KFileItem* contextFileInfo(void* context) = 0; + + void activateItem(void* context); + void resetActivatedItem(); + void updateDisabledItems(); + +private: + struct DisabledItem { + KURL url; + QPixmap pixmap; + }; + + QPixmap* m_pixmapCopy; + KURL m_highlightedURL; + + // contains all items which have been disabled by a 'cut' operation + QValueList<DisabledItem> m_disabledItems; + + /** Returns the text for the statusbar for an activated item. */ + QString statusBarText(KFileItem* fileInfo) const; +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..73c5b11 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright (C) 2007 by Marcel Juhnke <marrat@marrat.homelinux.org> * + * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> * + * Copyright (C) 2006 by Stefan Monov <logixoul@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "dolphin.h" +#include <kapplication.h> +#include <dcopclient.h> +#include <kaboutdata.h> +#include <kcmdlineargs.h> +#include <klocale.h> +#include <krun.h> + +static KCmdLineOptions options[] = +{ + { "+[URL]", I18N_NOOP( "Document to open" ), 0 }, + KCmdLineLastOption +}; + +int main(int argc, char **argv) +{ + KAboutData about("d3lphin", + I18N_NOOP("Dolphin"), + "0.9.2", + I18N_NOOP("File Manager"), + KAboutData::License_GPL, + "(C) 2007 Marcel Juhnke"); + about.setHomepage("https://marrat.homelinux.org/D3lphin"); + about.setBugAddress("marrat@marrat.homelinux.org"); + about.addAuthor("Marcel Juhnke", I18N_NOOP("Maintainer and developer"), "marrat@marrat.homelinux.org"); + about.addAuthor("Michael Austin", I18N_NOOP("Documentation"), "tuxedup@users.sourceforge.net"); + about.addAuthor("Orville Bennett", I18N_NOOP("Documentation"), "obennett@hartford.edu"); + about.addCredit("Peter Penz", I18N_NOOP("... for the great original Dolphin")); + about.addCredit("Cvetoslav Ludmiloff, Stefan Monov", I18N_NOOP("... for their development on the original Dolphin")); + about.addCredit("Aaron J. Seigo", I18N_NOOP("... for the great support and the amazing patches for the orignal Dolphin")); + about.addCredit("Patrice Tremblay, Gregor Kalisnik, Filip Brcic, Igor Stepin and Jan Mette", I18N_NOOP("... for their patches")); + about.addCredit("Ain, Itai, Ivan, Jannick, Stephane, Patrice, Piotr, Stefano and Power On", + I18N_NOOP("... for their translations")); + + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions(options); + + KApplication app; + Dolphin& mainWin = Dolphin::mainWin(); + mainWin.show(); + + if (app.isRestored()) { + int n = 1; + while (KMainWindow::canBeRestored(n)){ + Dolphin::mainWin().restore(n); + ++n; + } + } else { + KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); + if (args->count() > 0) { + mainWin.activeView()->setURL(args->url(0)); + + for (int i = 1; i < args->count(); ++i) { + KRun::run("d3lphin", args->url(i)); + } + } + args->clear(); + } + + return app.exec(); +} diff --git a/src/pics/128x128/Makefile.am b/src/pics/128x128/Makefile.am new file mode 100644 index 0000000..5c6f8a9 --- /dev/null +++ b/src/pics/128x128/Makefile.am @@ -0,0 +1,3 @@ +iconsdir = $(kde_datadir)/d3lphin/icons/hicolor/128x128/actions +icons_DATA = preview.png + diff --git a/src/pics/128x128/preview.png b/src/pics/128x128/preview.png Binary files differnew file mode 100644 index 0000000..f55dbfd --- /dev/null +++ b/src/pics/128x128/preview.png diff --git a/src/pics/16x16/Makefile.am b/src/pics/16x16/Makefile.am new file mode 100644 index 0000000..1fa272b --- /dev/null +++ b/src/pics/16x16/Makefile.am @@ -0,0 +1,3 @@ +iconsdir = $(kde_datadir)/d3lphin/icons/hicolor/16x16/actions +icons_DATA = preview.png editurl.png + diff --git a/src/pics/16x16/editurl.png b/src/pics/16x16/editurl.png Binary files differnew file mode 100644 index 0000000..1c4d2a6 --- /dev/null +++ b/src/pics/16x16/editurl.png diff --git a/src/pics/16x16/preview.png b/src/pics/16x16/preview.png Binary files differnew file mode 100644 index 0000000..d9010c8 --- /dev/null +++ b/src/pics/16x16/preview.png diff --git a/src/pics/22x22/Makefile.am b/src/pics/22x22/Makefile.am new file mode 100644 index 0000000..245df4b --- /dev/null +++ b/src/pics/22x22/Makefile.am @@ -0,0 +1,3 @@ +iconsdir = $(kde_datadir)/d3lphin/icons/hicolor/22x22/actions +icons_DATA = preview.png + diff --git a/src/pics/22x22/preview.png b/src/pics/22x22/preview.png Binary files differnew file mode 100644 index 0000000..b42a438 --- /dev/null +++ b/src/pics/22x22/preview.png diff --git a/src/pics/32x32/Makefile.am b/src/pics/32x32/Makefile.am new file mode 100644 index 0000000..0d7f9f3 --- /dev/null +++ b/src/pics/32x32/Makefile.am @@ -0,0 +1,3 @@ +iconsdir = $(kde_datadir)/d3lphin/icons/hicolor/32x32/actions +icons_DATA = preview.png + diff --git a/src/pics/32x32/preview.png b/src/pics/32x32/preview.png Binary files differnew file mode 100644 index 0000000..f84bb90 --- /dev/null +++ b/src/pics/32x32/preview.png diff --git a/src/pics/48x48/Makefile.am b/src/pics/48x48/Makefile.am new file mode 100644 index 0000000..103382b --- /dev/null +++ b/src/pics/48x48/Makefile.am @@ -0,0 +1,3 @@ +iconsdir = $(kde_datadir)/d3lphin/icons/hicolor/48x48/actions +icons_DATA = preview.png + diff --git a/src/pics/48x48/preview.png b/src/pics/48x48/preview.png Binary files differnew file mode 100644 index 0000000..7ab3b53 --- /dev/null +++ b/src/pics/48x48/preview.png diff --git a/src/pics/64x64/Makefile.am b/src/pics/64x64/Makefile.am new file mode 100644 index 0000000..c705496 --- /dev/null +++ b/src/pics/64x64/Makefile.am @@ -0,0 +1,3 @@ +iconsdir = $(kde_datadir)/d3lphin/icons/hicolor/64x64/actions +icons_DATA = preview.png + diff --git a/src/pics/64x64/preview.png b/src/pics/64x64/preview.png Binary files differnew file mode 100644 index 0000000..96e53fe --- /dev/null +++ b/src/pics/64x64/preview.png diff --git a/src/pics/Makefile.am b/src/pics/Makefile.am new file mode 100644 index 0000000..c26c4f5 --- /dev/null +++ b/src/pics/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = 128x128 64x64 48x48 32x32 22x22 16x16 diff --git a/src/pixmapviewer.cpp b/src/pixmapviewer.cpp new file mode 100644 index 0000000..565b16c --- /dev/null +++ b/src/pixmapviewer.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "pixmapviewer.h" + +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <qpainter.h> + +PixmapViewer::PixmapViewer(QWidget* parent) : + QWidget(parent) +{ + setMinimumWidth(KIcon::SizeEnormous); + setMinimumWidth(KIcon::SizeEnormous); +} + +PixmapViewer::~PixmapViewer() +{ +} + +void PixmapViewer::setPixmap(const QPixmap& pixmap) +{ + m_pixmap = pixmap; + update(); +} + +void PixmapViewer::paintEvent(QPaintEvent* event) +{ + QWidget::paintEvent(event); + + QPainter painter; + painter.begin(this); + const int x = (width() - m_pixmap.width()) / 2; + const int y = (height() - m_pixmap.height()) / 2; + painter.drawPixmap(x, y, m_pixmap); + painter.end(); +} + +#include "pixmapviewer.moc" diff --git a/src/pixmapviewer.h b/src/pixmapviewer.h new file mode 100644 index 0000000..6c24974 --- /dev/null +++ b/src/pixmapviewer.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef PIXMAPVIEWER_H +#define PIXMAPVIEWER_H + +#include <qwidget.h> +#include <qpixmap.h> + +/** + * @brief Widget which shows a pixmap centered inside the boundaries. + * + * @see IconsViewSettingsPage + * @author Peter Penz <peter.penz@gmx.at> + */ +class PixmapViewer : public QWidget +{ + Q_OBJECT +public: + PixmapViewer(QWidget* parent); + virtual ~PixmapViewer(); + void setPixmap(const QPixmap& pixmap); + const QPixmap& pixmap() const { return m_pixmap; } + +protected: + virtual void paintEvent(QPaintEvent* event); + +private: + QPixmap m_pixmap; +}; + + +#endif diff --git a/src/progressindicator.cpp b/src/progressindicator.cpp new file mode 100644 index 0000000..6509150 --- /dev/null +++ b/src/progressindicator.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "progressindicator.h" +#include "dolphin.h" +#include "dolphinstatusbar.h" + +ProgressIndicator::ProgressIndicator(const QString& progressText, + const QString& finishedText, + int operationsCount) + : m_showProgress(false), + m_operationsCount(operationsCount), + m_operationsIndex(0), + m_startTime(QTime::currentTime()), + m_finishedText(finishedText) +{ + DolphinStatusBar* statusBar = Dolphin::mainWin().activeView()->statusBar(); + statusBar->clear(); + statusBar->setProgressText(progressText); + statusBar->setProgress(0); +} + + +ProgressIndicator::~ProgressIndicator() +{ + DolphinStatusBar* statusBar = Dolphin::mainWin().activeView()->statusBar(); + statusBar->setProgressText(QString::null); + statusBar->setProgress(100); + statusBar->setMessage(m_finishedText, DolphinStatusBar::OperationCompleted); + + if (m_showProgress) { + Dolphin::mainWin().setEnabled(true); + } +} + +void ProgressIndicator::execOperation() +{ + ++m_operationsIndex; + + if (!m_showProgress) { + const int elapsed = m_startTime.msecsTo(QTime::currentTime()); + if (elapsed > 500) { + // the operations took already more than 500 milliseconds, + // therefore show a progress indication + Dolphin::mainWin().setEnabled(false); + m_showProgress = true; + } + } + + if (m_showProgress) { + const QTime currentTime = QTime::currentTime(); + if (m_startTime.msecsTo(currentTime) > 100) { + m_startTime = currentTime; + + DolphinStatusBar* statusBar = Dolphin::mainWin().activeView()->statusBar(); + statusBar->setProgress((m_operationsIndex * 100) / m_operationsCount); + kapp->processEvents(); + statusBar->repaint(); + } + } +} + + diff --git a/src/progressindicator.h b/src/progressindicator.h new file mode 100644 index 0000000..7889607 --- /dev/null +++ b/src/progressindicator.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef PROGRESSINDICATOR_H +#define PROGRESSINDICATOR_H + +#include <qdatetime.h> + +/** + * Allows to show a progress of synchronous operations. Sample code: + * \code + * const int operationsCount = 100; + * ProgressIndicator progressIndicator(i18n("Loading..."), + * i18n("Loading finished."), + * operationsCount); + * for (int i = 0; i < operationsCount; ++i) { + * progressIndicator.execOperation(); + * // do synchronous operation... + * } + * \endcode + * The progress indicator takes care to show the progress bar only after + * a delay of around 500 milliseconds. This means if all operations are + * executing within 500 milliseconds, no progress bar is shown at all. + * As soon as the progress bar is shown, the application still may process + * events, but the the Dolphin main widget is disabled. + * + * @author Peter Penz <peter.penz@gmx.at> + */ +class ProgressIndicator +{ +public: + /** + * @param progressText Text for the progress bar (e. g. "Loading..."). + * @param finishedText Text which is displayed after the operations have been finished + * (e. g. "Loading finished."). + * @param operationsCount Number of operations. + */ + ProgressIndicator(const QString& progressText, + const QString& finishedText, + int operationsCount); + + /** + * Sets the progress to 100 % and displays the 'finishedText' property + * in the status bar. + */ + ~ProgressIndicator(); + + /** + * Increases the progress and should be invoked + * before each operation. + */ + void execOperation(); + +private: + bool m_showProgress; + int m_operationsCount; + int m_operationsIndex; + QTime m_startTime; + QString m_finishedText; +}; + +#endif diff --git a/src/renamedialog.cpp b/src/renamedialog.cpp new file mode 100644 index 0000000..7ec8681 --- /dev/null +++ b/src/renamedialog.cpp @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "renamedialog.h" +#include <klocale.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qvbox.h> +#include <assert.h> +#include <klineedit.h> + +RenameDialog::RenameDialog(const KURL::List& items) : + KDialogBase(Plain, i18n("Rename Items"), + Ok|Cancel, Ok) +{ + setButtonOK(KGuiItem(i18n("Rename"), "apply")); + + QVBoxLayout* topLayout = new QVBoxLayout(plainPage(), 0, spacingHint()); + topLayout->setMargin(KDialog::marginHint()); + + const int itemCount = items.count(); + QLabel* editLabel = new QLabel(i18n("Rename the %n selected items to:", "Rename the %n selected items to:", itemCount), + plainPage()); + + m_lineEdit = new KLineEdit(plainPage()); + m_newName = i18n("New name #"); + assert(itemCount > 1); + QString postfix(items[0].prettyURL().section('.',1)); + if (postfix.length() > 0) { + // The first item seems to have a postfix (e. g. 'jpg' or 'txt'). Now + // check whether all other items have the same postfix. If this is the + // case, add this postfix to the name suggestion. + postfix.insert(0, '.'); + for (int i = 1; i < itemCount; ++i) { + if (!items[i].prettyURL().contains(postfix)) { + // at least one item does not have the same postfix + postfix.truncate(0); + break; + } + } + } + + const int selectionLength = m_newName.length(); + if (postfix.length() > 0) { + m_newName.append(postfix); + } + m_lineEdit->setText(m_newName); + m_lineEdit->setSelection(0, selectionLength - 1); + m_lineEdit->setFocus(); + + QLabel* infoLabel = new QLabel(i18n("(# will be replaced by ascending numbers)"), plainPage()); + + topLayout->addWidget(editLabel); + topLayout->addWidget(m_lineEdit); + topLayout->addWidget(infoLabel); +} + +RenameDialog::~RenameDialog() +{ +} + +void RenameDialog::slotOk() +{ + m_newName = m_lineEdit->text(); + if (m_newName.contains('#') != 1) { + m_newName.truncate(0); + } + + KDialogBase::slotOk(); +} + +#include "renamedialog.moc" diff --git a/src/renamedialog.h b/src/renamedialog.h new file mode 100644 index 0000000..fb743db --- /dev/null +++ b/src/renamedialog.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef RENAMEDIALOG_H +#define RENAMEDIALOG_H + +#include <kdialogbase.h> +#include <kurl.h> +#include <qstring.h> + +class KLineEdit; + +/** + * @brief Dialog for renaming a variable number of files. + * + * The renaming is not done by the dialog, the invoker + * must do this itself: + * \code + * RenameDialog dialog(...); + * if (dialog.exec() == QDialog::Accepted) { + * const QString& newName = dialog.newName(); + * // ... rename items corresponding to the new name + * } + * \endcode + * @author Peter Penz + */ +class RenameDialog : public KDialogBase +{ + Q_OBJECT + +public: + RenameDialog(const KURL::List& items); + virtual ~RenameDialog(); + + /** + * Returns the new name of the items. If the returned string is not empty, + * then it is assured that the string contains exactly one character #, + * which should be replaced by ascending numbers. An empty string indicates + * that the user has removed the # character. + */ + const QString& newName() const { return m_newName; } + +protected slots: + virtual void slotOk(); + +private: + KLineEdit* m_lineEdit; + QString m_newName; +}; + +#endif diff --git a/src/servicemenus/Makefile.am b/src/servicemenus/Makefile.am new file mode 100644 index 0000000..45d121f --- /dev/null +++ b/src/servicemenus/Makefile.am @@ -0,0 +1,18 @@ +servicemenusdir = $(kde_datadir)/d3lphin/servicemenus +servicemenus_DATA = compress.desktop amarok_addaspodcast.desktop amarok_append.desktop \ + amarok_play_audiocd.desktop ark_compress.desktop ark_extract.desktop ark_extract_subdir.desktop \ + d3lphin_su.desktop edit_as_root.desktop encryptfile.desktop encryptfolder.desktop \ + floppy_format.desktop imageconverter.desktop installfont.desktop jpegorient.desktop \ + k3b_audiocd_rip.desktop k3b_cd_copy.desktop k3b_create_audio_cd.desktop \ + k3b_create_video_cd.desktop k3b_dvd_copy.desktop k3b_handle_empty_cd.desktop \ + k3b_handle_empty_dvd.desktop k3b_videodvd_rip.desktop k3b_write_bin_image.desktop \ + k3b_write_iso_image.desktop kdesktopSetAsBackground.desktop konqgwenview.desktop \ + konsolehere.desktop mail_as_attachment.desktop media_eject.desktop media_mount.desktop \ + media_realfolder.desktop media_safelyremove.desktop media_unmount.desktop \ + open_in_digikam.desktop run_as_root.desktop smb2rdc.desktop text-ada-print.desktop \ + text-c++-print.desktop text-c++h-print.desktop text-ch-print.desktop text-css-print.desktop \ + text-diff-print.desktop text-html-print.desktop text-java-print.desktop text-log-print.desktop \ + text-makefile-print.desktop text-pas-print.desktop text-perl-print.desktop text-print.desktop \ + text-python-print.desktop text-tcl-print.desktop text-tex-print.desktop text-xml-print.desktop \ + text-xslt-print.desktop + diff --git a/src/servicemenus/Makefile.am.new b/src/servicemenus/Makefile.am.new new file mode 100644 index 0000000..45d121f --- /dev/null +++ b/src/servicemenus/Makefile.am.new @@ -0,0 +1,18 @@ +servicemenusdir = $(kde_datadir)/d3lphin/servicemenus +servicemenus_DATA = compress.desktop amarok_addaspodcast.desktop amarok_append.desktop \ + amarok_play_audiocd.desktop ark_compress.desktop ark_extract.desktop ark_extract_subdir.desktop \ + d3lphin_su.desktop edit_as_root.desktop encryptfile.desktop encryptfolder.desktop \ + floppy_format.desktop imageconverter.desktop installfont.desktop jpegorient.desktop \ + k3b_audiocd_rip.desktop k3b_cd_copy.desktop k3b_create_audio_cd.desktop \ + k3b_create_video_cd.desktop k3b_dvd_copy.desktop k3b_handle_empty_cd.desktop \ + k3b_handle_empty_dvd.desktop k3b_videodvd_rip.desktop k3b_write_bin_image.desktop \ + k3b_write_iso_image.desktop kdesktopSetAsBackground.desktop konqgwenview.desktop \ + konsolehere.desktop mail_as_attachment.desktop media_eject.desktop media_mount.desktop \ + media_realfolder.desktop media_safelyremove.desktop media_unmount.desktop \ + open_in_digikam.desktop run_as_root.desktop smb2rdc.desktop text-ada-print.desktop \ + text-c++-print.desktop text-c++h-print.desktop text-ch-print.desktop text-css-print.desktop \ + text-diff-print.desktop text-html-print.desktop text-java-print.desktop text-log-print.desktop \ + text-makefile-print.desktop text-pas-print.desktop text-perl-print.desktop text-print.desktop \ + text-python-print.desktop text-tcl-print.desktop text-tex-print.desktop text-xml-print.desktop \ + text-xslt-print.desktop + diff --git a/src/servicemenus/amarok_addaspodcast.desktop b/src/servicemenus/amarok_addaspodcast.desktop new file mode 100644 index 0000000..7c61588 --- /dev/null +++ b/src/servicemenus/amarok_addaspodcast.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +ServiceTypes=text/html,text/xml,application/xml,text/rss +Actions=addAsPodcast +[Desktop Action addAsPodcast] +Name=Add as podcast to amaroK +Name[de]=Als Podcast zu amaroK hinzufügen +Icon=amarok +Exec=dcop amarok playlistbrowser addPodcast %u diff --git a/src/servicemenus/amarok_append.desktop b/src/servicemenus/amarok_append.desktop new file mode 100644 index 0000000..acf3cb0 --- /dev/null +++ b/src/servicemenus/amarok_append.desktop @@ -0,0 +1,96 @@ +[Desktop Entry] +ServiceTypes=application/asx,audio/* +Actions=appendToPlaylist;appendAndPlay;queueTrack; +X-KDE-Submenu=Amarok +X-KDE-Submenu[bn]=আমারক +X-KDE-Submenu[pa]=ਅਮਰੋਕ +X-KDE-Submenu[xx]=xxAmarokxx + +[Desktop Action appendToPlaylist] +Name=Append to Playlist +Name[bg]=Добавяне към списъка с песни +Name[bn]=সঙ্গীত-তালিকাতে সংযোজন করো +Name[br]=Ouzhpennañ d'ar roll tonioù +Name[cs]=Přidat do seznamu skladeb +Name[da]=Tilføj til spilleliste +Name[de]=An Amarok-Wiedergabeliste anhängen +Name[el]=Προσθήκη στη λίστα αναπαραγωγής +Name[et]=Lisa lugude nimekirja +Name[fi]=Lisää soittolistaan +Name[fr]=Ajouter à la liste de lecture +Name[ga]=Iarcheangail le Seinmliosta +Name[it]=Aggiungi alla playlist +Name[ja]=プレイリストに追加 +Name[km]=បន្ថែមទៅខាងចុងបញ្ជីចាក់ +Name[nl]=Toevoegen aanafspeellijst +Name[pa]=ਸੰਗੀਤ-ਸੂਚੀ 'ਚ ਸ਼ਾਮਲ +Name[pl]=Dołącz do listy odtwarzania +Name[pt]=Adicionar à Lista do Amarok +Name[pt_BR]=Anexar à Lista de Músicas +Name[ru]=Добавить в список +Name[sv]=Lägg till i spellistan +Name[uk]=Додати до списку композицій +Name[uz]=Қўшиқ рўйхатига қўшиш +Name[xx]=xxAppend to Playlistxx +Name[zh_CN]=追加到播放列表 +Icon=amarok +Exec=amarok -e %U + +[Desktop Action appendAndPlay] +Name=Append & Play +Name[bg]=Добавяне и възпроизвеждане +Name[bn]=সংযোজন করো এবং বাজাও +Name[br]=Ouzhpennañ ha seniñ +Name[cs]=Připojit a hrát +Name[da]=Tilføj og spil +Name[de]=Anhängen und abspielen +Name[el]=Προσθήκη & αναπαραγωγή +Name[et]=Lisa ja esita +Name[fi]=Lisää soittolistaan ja toista +Name[fr]=Ajouter & Écouter +Name[ga]=Iarcheangail & Seinn +Name[it]=Aggiungi & Riproduci +Name[ja]=追加して再生 +Name[km]=បន្ថែមខាងចុង & ចាក់ +Name[nl]=Toevoegen en afspelen +Name[pa]=ਜੋੜੋ ਅਤੇ ਚਲਾਓ +Name[pl]=Dołącz i odtwórz +Name[pt]=Adicionar & Reproduzir +Name[pt_BR]=Anexar & Reproduzir +Name[ru]=Добавить и запустить +Name[sv]=Lägg till och spela +Name[uk]=Додати і програти +Name[uz]=Қўшиш ва ўйнаш +Name[xx]=xxAppend & Playxx +Name[zh_CN]=追加并播放 +Icon=amarok +Exec=dcop amarok playlist playMedia %U + +[Desktop Action queueTrack] +Name=Queue Track +Name[bg]=Добавяне и възпроизвеждане +Name[bn]=গান সারিবদ্ধ করো +Name[cs]=Zařadit skladbu +Name[da]=Sæt spor i kø +Name[de]=Stück in Warteschlange einstellen +Name[el]=Εισαγωγή του κομματιού στην ουρά +Name[et]=Sea pala järjekorda +Name[fi]=Lisää jonoon +Name[fr]=Ajouter à la file d'attente +Name[ga]=Ciúáil Amhrán +Name[it]=Accoda traccia +Name[ja]=トラックをキュー +Name[km]=ដាក់បទក្នុងជួរ +Name[nl]=Track in wachtrij plaatsen +Name[pa]=ਟਰੈਕ ਕਤਾਰ 'ਚ +Name[pl]=Wstaw utwór do kolejki +Name[pt]=Pôr a Faixa na Fila +Name[pt_BR]=Faixa para Fila +Name[ru]=Добавить после текущей +Name[sv]=Köa spår +Name[uk]=Додати доріжку в чергу +Name[uz]=Навбатга қўйиш +Name[xx]=xxQueue Trackxx +Name[zh_CN]=音轨排队 +Icon=amarok +Exec=amarok --queue %U diff --git a/src/servicemenus/amarok_play_audiocd.desktop b/src/servicemenus/amarok_play_audiocd.desktop new file mode 100644 index 0000000..4bfa828 --- /dev/null +++ b/src/servicemenus/amarok_play_audiocd.desktop @@ -0,0 +1,49 @@ +[Desktop Entry] +ServiceTypes=media/audiocd +Actions=Play; +Encoding=UTF-8 +X-KDE-Priority=TopLevel + +[Desktop Action Play] +Name=Play Audio CD with Amarok +Name[af]=Speel oudio CD met Amarok +Name[bg]=Изпълнение на компактдиск с Amarok +Name[bn]=আমারক দিয়ে অডিও সিডি চালাও +Name[ca]=Reprodueix el CD Àudio amb l'Amarok +Name[cs]=Přehrát audio CD +Name[da]=Afspil lyd-cd med Amarok +Name[de]=Audio-CD mit Amarok wiedergeben +Name[el]=Αναπαραγωγή CD ήχου με το Amarok +Name[eo]=Ludi Muzikan KD-n per Amarok +Name[es]=Reproducir CD con Amarok +Name[et]=Esita audio CD Amarokis +Name[fa]=پخش دیسک فشردۀ صوتی با Amarok +Name[fi]=Soita CD-levy Amarokilla +Name[fr]=Écouter un CD Audio avec Amarok +Name[ga]=Seinn Dlúthdhiosca Fuaime le Amarok +Name[hu]=Hang-CD lejátszása az Amarokkal +Name[is]=Spila tónlistardisk með Amarok +Name[it]=Riproduci CD audio con Amarok +Name[ja]=Amarok でオーディオ CD を再生 +Name[km]=ចាក់ស៊ីឌីអូឌីយ៉ូជាមួយ Amarok +Name[lt]=Groti audio CD su Amarok +Name[mk]=Свири аудиоцд со Амарок +Name[nds]=Audio-CD mit Amarok afspelen +Name[nl]=Audio-cd met Amarok afspelen +Name[pa]=ਅਮਰੋਕ ਨਾਲ ਆਡੀਓ CD ਚਲਾਓ +Name[pl]=Odtwórz Audio CD za pomocą Amarok +Name[pt]=Tocar o CD de Áudio com o Amarok +Name[pt_BR]=Reproduzir CD de Áudio com o Amarok +Name[se]=Čuojat jietna-CD:a Amarokain +Name[sk]=Zahrať Audio CD pomocou Amarok +Name[sr]=Пусти аудио CD помоћу Amarok-а +Name[sr@Latn]=Pusti audio CD pomoću Amarok-a +Name[sv]=Spela ljud-cd med Amarok +Name[th]=เล่นซีดีบันทึกเสียงด้วย Amarok +Name[tr]=Ses CD'sini Amarok ile Çal +Name[uk]=Грати аудіо-КД в Amarok +Name[uz]=Аудио-дискни Amarok билан тинглаш +Name[wa]=Djouwer l' CD d' muzike avou Amarok +Name[zh_CN]=用 Amarok 播放音频 CD +Icon=amarok +Exec=amarok --cdplay %u diff --git a/src/servicemenus/ark_compress.desktop b/src/servicemenus/ark_compress.desktop new file mode 100644 index 0000000..308a450 --- /dev/null +++ b/src/servicemenus/ark_compress.desktop @@ -0,0 +1,21 @@ +[Desktop Entry] +ServiceTypes=inode/directory +Actions=CompressZip;CompressTarGz;CompressTarBz2 +X-KDE-Priority=TopLevel +X-KDE-Submenu=Compress + +[Desktop Action CompressZip] +Name=Zip Archive +Icon=ark +Exec=ark --add-to %u %u.zip + +[Desktop Action CompressTarGz] +Name=Gzipped Tar Archive +Icon=ark +Exec=ark --add-to %u %u.tar.gz + +[Desktop Action CompressTarBz2] +Name=Bzip2 Tar Archive +Icon=ark +Exec=ark --add-to %u %u.tar.bz2 + diff --git a/src/servicemenus/ark_extract.desktop b/src/servicemenus/ark_extract.desktop new file mode 100644 index 0000000..1c54fd6 --- /dev/null +++ b/src/servicemenus/ark_extract.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +X-SuSE-translate=true +Encoding=UTF-8 +ServiceTypes=application/x-gzip,application/x-lha,application/x-tar,application/x-tgz,application/x-tbz,application/x-tbz2,application/x-zip,application/x-bzip,application/x-tzo,application/x-lzop,application/x-rar,application/x-rar-compressed,application/x-zoo,application/x-tarz,application/x-archive,application/x-bzip2,application/x-jar,application/x-deb,application/x-ace,application/x-7z,application/x-arc,application/x-arj,application/x-compress,application/x-cpio,application/x-pak +Actions=extractHere + +[Desktop Action extractHere] +Name=Extract Here +Name[de]=Hierher entpacken +Exec=ark --extract-to %d %u +Icon=ark diff --git a/src/servicemenus/ark_extract_subdir.desktop b/src/servicemenus/ark_extract_subdir.desktop new file mode 100644 index 0000000..9d52df1 --- /dev/null +++ b/src/servicemenus/ark_extract_subdir.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +X-SuSE-translate=true +Encoding=UTF-8 +ServiceTypes=application/x-gzip,application/x-lha,application/x-tar,application/x-tgz,application/x-tbz,application/x-tbz2,application/x-zip,application/x-bzip,application/x-tzo,application/x-lzop,application/x-rar,application/x-rar-compressed,application/x-zoo,application/x-tarz,application/x-archive,application/x-bzip2,application/x-jar,application/x-deb,application/x-ace,application/x-7z,application/x-arc,application/x-arj,application/x-compress,application/x-cpio,application/x-pak +Actions=ExtractSubdir + +[Desktop Action ExtractSubdir] +Name=Extract to subdirectory +Name[de]=In Unterordner entpacken +Icon=ark +Exec=ark -caption "%c" %i %m --guess-name --extract-to "%d" "%u" diff --git a/src/servicemenus/compress.desktop b/src/servicemenus/compress.desktop new file mode 100644 index 0000000..5d199ba --- /dev/null +++ b/src/servicemenus/compress.desktop @@ -0,0 +1,21 @@ +[Desktop Entry] +ServiceTypes=all/allfiles +Actions=CompressZip;CompressTarGz;CompressTarBz2 +X-KDE-Priority=TopLevel +X-KDE-Submenu=Compress + +[Desktop Action CompressZip] +Name=Zip Archive +Icon=ark +Exec=ark --add-to %u %u.zip + +[Desktop Action CompressTarGz] +Name=Gzipped Tar Archive +Icon=ark +Exec=ark --add-to %u %u.tar.gz + +[Desktop Action CompressTarBz2] +Name=Bzip2 Tar Archive +Icon=ark +Exec=ark --add-to %u %u.tar.bz2 + diff --git a/src/servicemenus/d3lphin_su.desktop b/src/servicemenus/d3lphin_su.desktop new file mode 100644 index 0000000..ea6cb55 --- /dev/null +++ b/src/servicemenus/d3lphin_su.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +ServiceTypes=inode/directory +Actions=D3lphinSU; + +[Desktop Action D3lphinSU] +ServiceTypes=inode/directory +Name=Open as Root +Name[de]=Öffne als Root +Name[ru]=Открыть под root +Icon=d3lphin +Exec=kdesu -c "d3lphin '%U'" diff --git a/src/servicemenus/edit_as_root.desktop b/src/servicemenus/edit_as_root.desktop new file mode 100644 index 0000000..049454e --- /dev/null +++ b/src/servicemenus/edit_as_root.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +ServiceTypes=text/*,application/x-desktop +Actions=Editassu + +[Desktop Action Editassu] +Name=Edit as Root +Name[it]=Edita come Root +Name[fr]=Editer en tant que Root +Name[es]=Editar como Root +Name[de]=Als root bearbeiten +Icon=kfm +Exec=kdesu "kwrite" "%U" diff --git a/src/servicemenus/encryptfile.desktop b/src/servicemenus/encryptfile.desktop new file mode 100644 index 0000000..797698e --- /dev/null +++ b/src/servicemenus/encryptfile.desktop @@ -0,0 +1,59 @@ +[Desktop Entry] +ServiceTypes=all/allfiles +ExcludeServiceTypes=kdedevice/* +Actions=encrypt + +[Desktop Action encrypt] +Name=Encrypt File +Name[ar]=تشفير ملف +Name[bg]=Шифроване на файл +Name[bs]=Šifriraj datoteku +Name[ca]=Xifra fitxer +Name[cs]=Zašifrovat soubor +Name[cy]=Cêl-ysgrifo Ffeil +Name[da]=Indkod fil +Name[de]=Datei verschlüsseln +Name[el]=Κρυπτογράφηση αρχείου +Name[es]=Cifrar archivo +Name[et]=Krüpti fail +Name[eu]=Fitxategiak Zifratu +Name[fa]=رمزبندی پرونده +Name[fi]=Salaa tiedosto +Name[fr]=Chiffrer le fichier +Name[ga]=Criptigh Comhad +Name[he]=הצפן קובץ +Name[hi]=एनक्रिप्ट फ़ाइल +Name[hu]=Fájl titkosítása +Name[is]=Dulrita skrá +Name[it]=Cifratura file +Name[ja]=ファイルを暗号化 +Name[kk]=Файлды шифрлау +Name[km]=អ៊ិនគ្រីបឯកសារ +Name[lt]=Šifruoti bylą +Name[mk]=Криптирај датотеки +Name[nb]=Krypter fil +Name[nds]=Dateiverslöteln +Name[ne]=फाइल गुप्तीकरण गर्नुहोस् +Name[nl]=Bestand versleutelen +Name[nn]=Krypter fil +Name[pa]=ਇੰਕਰਿਪਟ ਫਾਇਲ +Name[pl]=Zaszyfruj plik +Name[pt]=Cifrar Ficheiro +Name[pt_BR]=Criptografar Arquivo +Name[ro]=Criptează fişierul +Name[ru]=Зашифровать файл +Name[sk]=Šifrovať súbor +Name[sl]=Šifriraj datoteko +Name[sr]=Шифруј фајл +Name[sr@Latn]=Šifruj fajl +Name[sv]=Kryptera fil +Name[ta]=சங்கேத கோப்பு +Name[tg]=Рамзкунонии Файл +Name[tr]=Dosya Şifrele +Name[uk]=Зашифрувати файл +Name[wa]=Ecripter fitchî +Name[zh_CN]=加密文件 +Name[zh_TW]=加密檔案 +Icon=kgpg +Exec=kgpg -e %F + diff --git a/src/servicemenus/encryptfolder.desktop b/src/servicemenus/encryptfolder.desktop new file mode 100644 index 0000000..b322b64 --- /dev/null +++ b/src/servicemenus/encryptfolder.desktop @@ -0,0 +1,50 @@ +[Desktop Entry] +ServiceTypes=inode/directory +Actions=encrypt + +[Desktop Action encrypt] +Name=Archive & Encrypt Folder +Name[ar]=أرشفة و تشفير مجلّد +Name[bg]=Архивиране и шифроване на директория +Name[bs]=Arhiviraj i šifriraj direktorij +Name[ca]=Arxiva i xifra la carpeta +Name[cs]=Archivovat a zašifrovat složku +Name[da]=Arkivér & kryptér mappe +Name[de]=Ordner packen und verschlüsseln +Name[el]=Αρχειοθέτηση & κρυπτογράφηση φακέλου +Name[es]=Archivar y cifrar carpeta +Name[et]=Arhiveeri ja krüpti kataloog +Name[eu]=Artxibatu eta enkriptatu karpeta +Name[fa]=بایگانی و رمزبندی پوشه +Name[fi]=Pakkaa ja salaa kansio +Name[fr]=Archiver puis chiffrer le dossier +Name[ga]=Cuir Fillteán i gCartlann & Criptigh É +Name[he]=כלי להצפנה וכיווץ תקייה +Name[hu]=Könyvtár titkosítása és archiválása +Name[is]=Pakka og dulrita möppu +Name[it]=Archivia e cifra cartella +Name[ja]=フォルダをアーカイブ化 & 暗号化 +Name[kk]=Қапшықты архивтеп шифрлау +Name[km]=ថតប័ណ្ណសារ & អ៊ិនគ្រីប +Name[lt]=Archyvuoti ir šifruoti aplanką +Name[nb]=Arkiver og krypter mappe +Name[nds]=Ornern komprimeren un verslöteln +Name[ne]=फोल्डरलाई सङ्ग्रह र गुप्तीकरण गर्नुहोस् +Name[nl]=Map archiveren en versleutelen +Name[nn]=Arkiver og krypter mappe +Name[pa]=ਆਕੀਵੀ & ਇੰਕਰਿਪਟ ਫੋਲਡਰ +Name[pl]=Zarchiwizuj i zaszyfruj katalog +Name[pt]=Arquivar e Cifrar a Pasta +Name[pt_BR]=Arquivar & Criptografar Pasta +Name[ru]=Архивировать и зашифровать папку +Name[sk]=Archivovať a šifrovať priečinok +Name[sl]=Arhiviranje in ši&friranje imenika +Name[sr]=Архивирај и шифруј фасциклу +Name[sr@Latn]=Arhiviraj i šifruj fasciklu +Name[sv]=Arkivera och kryptera katalog +Name[tr]=Arşiv ve Klasör Şifrele +Name[uk]=Зробити архів теки і зашифрувати +Name[zh_CN]=存档并加密文件夹 +Name[zh_TW]=壓縮並加密資料夾 +Icon=kgpg +Exec=kgpg -e %F diff --git a/src/servicemenus/floppy_format.desktop b/src/servicemenus/floppy_format.desktop new file mode 100644 index 0000000..b175347 --- /dev/null +++ b/src/servicemenus/floppy_format.desktop @@ -0,0 +1,36 @@ +[Desktop Action Format] +Exec=kfloppy %u +Icon=kfloppy +Name=Format +Name[bg]=Форматиране +Name[br]=Furmadiñ +Name[ca]=Dona format +Name[cs]=Formátovat +Name[cy]=Fformat +Name[de]=Formatieren +Name[eo]=Formato +Name[es]=Formatear +Name[fr]=Formater +Name[ga]=Formáid +Name[it]=Formatta +Name[ja]=フォーマット +Name[lt]=Formatas +Name[nl]=Formatteren +Name[pa]=ਫਾਰਮਿਟ +Name[pl]=Formatuj +Name[pt]=Formatar +Name[pt_BR]=Formatar +Name[ru]=Форматирование дискет +Name[rw]=Imiterere +Name[sr]=Форматирај +Name[sr@Latn]=Formatiraj +Name[sv]=Formatera +Name[uk]=Форматування +Name[xx]=xxFormatxx +Name[zh_CN]=格式化 + +[Desktop Entry] +Actions=Format; +ServiceTypes=media/floppy_unmounted,media/floppy5_unmounted +X-KDE-Priority=TopLevel +X-KDE-MediaNotifierHide=true diff --git a/src/servicemenus/imageconverter.desktop b/src/servicemenus/imageconverter.desktop new file mode 100644 index 0000000..941a20b --- /dev/null +++ b/src/servicemenus/imageconverter.desktop @@ -0,0 +1,61 @@ +# +# Servicemenu image converter, by Jens Benecke <jens-kde@spamfreemail.de>. +# Released under the same license as the KDE core distribution (GPL 2.0). +# +[Desktop Entry] +ServiceTypes=image/* +Actions=convToJPEG;convToPNG;convToGIF;convToTIF; +X-KDE-Submenu=Convert To +X-KDE-Submenu[bg]=Конвертиране в +X-KDE-Submenu[ca]=Converteix a +X-KDE-Submenu[cs]=Převést na +X-KDE-Submenu[da]=Konvertér til +X-KDE-Submenu[de]=Konvertieren nach +X-KDE-Submenu[es]=Convertir a +X-KDE-Submenu[fi]=Muunna +X-KDE-Submenu[fr]=Convertir en +X-KDE-Submenu[hu]=Átalakítás +X-KDE-Submenu[is]=Umbreyta í +X-KDE-Submenu[it]=Converti in +X-KDE-Submenu[nb]=Konverter til +X-KDE-Submenu[nl]=Converteren naar +X-KDE-Submenu[pl]=Konwertuj do +X-KDE-Submenu[pt]=Converter Para +X-KDE-Submenu[pt_BR]=Converter Para +X-KDE-Submenu[ru]=Сохранить как +X-KDE-Submenu[sr]=Претвори у +X-KDE-Submenu[sr@Latn]=Pretvori u +X-KDE-Submenu[sv]=Konvertera till +X-KDE-Submenu[uk]=Перетворити в +X-KDE-Submenu[xx]=xxConvert Toxx +X-KDE-Submenu[zh_CN]=转换为 +TryExec=convert + +[Desktop Action convToJPEG] +Name=JPEG +Name[hi]=जेपीईजी +Name[xx]=xxJPEGxx +Icon=image +Exec=convert %f "`echo %f | perl -pe 's/\.[^.]+$//'`.jpg" + +[Desktop Action convToPNG] +Name=PNG +Name[hi]=पीएनजी +Name[xx]=xxPNGxx +Icon=image +Exec=convert %f "`echo %f | perl -pe 's/\.[^.]+$//'`.png" + +[Desktop Action convToTIF] +Name=TIF +Name[hi]=टिफ़ +Name[xx]=xxTIFxx +Icon=image +Exec=convert %f "`echo %f | perl -pe 's/\.[^.]+$//'`.tif" + +[Desktop Action convToGIF] +Name=GIF +Name[hi]=जिफ़ +Name[xx]=xxGIFxx +Icon=image +Exec=convert %f "`echo %f | perl -pe 's/\.[^.]+$//'`.gif" + diff --git a/src/servicemenus/installfont.desktop b/src/servicemenus/installfont.desktop new file mode 100644 index 0000000..3ca14fa --- /dev/null +++ b/src/servicemenus/installfont.desktop @@ -0,0 +1,143 @@ +[Desktop Entry] +ServiceTypes=application/x-font-ttf,application/x-font-type1,application/x-font-speedo,application/x-font-bdf,application/x-font-pcf,application/x-font-snf,application/x-font-otf,application/x-font-ttc,application/x-afm +Actions=installFont; + +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +[Desktop Action installFont] +Name=Install +Name[af]=Installeer +Name[be]=Усталяваць +Name[bg]=Инсталиране +Name[bn]=ইনস্টল +Name[br]=Staliañ +Name[bs]=Instaliraj +Name[ca]=Instal·la +Name[cs]=Instalovat +Name[cy]=Gosod +Name[da]=Installér +Name[de]=Installieren +Name[el]=Εγκατάσταση +Name[eo]=Instalu +Name[es]=Instalar +Name[et]=Paigaldamine +Name[eu]=Instalatu +Name[fa]=نصب +Name[fi]=Asenna +Name[fr]=Installer +Name[fy]=Ynstallearje +Name[ga]=Suiteáil +Name[gl]=Instalar +Name[he]=התקנה +Name[hi]=संस्थापित +#SUSE-Overwrite Name[hr]=Instaliraj +Name[hu]=Telepítő +Name[is]=Setja upp +Name[it]=Installa +Name[ja]=インストール +Name[km]=ដំឡើង +Name[lt]=Įdiegti +Name[lv]=Instalēt +Name[mk]=Инсталирај +Name[ms]=Pasang +Name[mt]=Installa +Name[nb]=Installer +Name[nds]=Installeren +Name[nl]=Installeren +Name[nn]=Installer +Name[pa]=ਇੰਸਟਾਲ +#SUSE-Overwrite Name[pl]=Instaluj +Name[pl]=Zainstaluj +Name[pt]=Instalar +Name[pt_BR]=Instalar +Name[ro]=Instalare +Name[ru]=Установка +Name[rw]=Kwinjizaporogaramu +Name[se]=Sajáiduhte +Name[sk]=Inštalácia +Name[sl]=Namesti +Name[sr]=Инсталирај +Name[sr@Latn]=Instaliraj +Name[sv]=Installera +Name[ta]=நிறுவி +Name[tg]=Гузоштан +Name[th]=ติดตั้ง +Name[tr]=Kur +Name[tt]=Quyu +Name[uk]=Встановлення +Name[uz]=Ўрнатиш +#SUSE-Overwrite Name[vi]=Cài đặt +Name[zh_CN]=安装 +Name[zh_TW]=安裝 +Icon=fonts +Exec=kfmclient copy %U fonts:/ + diff --git a/src/servicemenus/isoservice.desktop b/src/servicemenus/isoservice.desktop new file mode 100644 index 0000000..4b86111 --- /dev/null +++ b/src/servicemenus/isoservice.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Encoding=UTF-8 +Actions=OpenISO +ServiceTypes=inode/blockdevice,application/x-iso + +[Desktop Action OpenISO] +Comment=ISO9660 View +Comment[hu]=ISO9660 Nézet +Comment[fr]=Lecteur ISO9660 +Icon=cd +Name=ISO9660 View +Name[hu]=ISO9660 Nézet +Name[fr]=Lecteur ISO9660 diff --git a/src/servicemenus/jpegorient.desktop b/src/servicemenus/jpegorient.desktop new file mode 100644 index 0000000..5b25d24 --- /dev/null +++ b/src/servicemenus/jpegorient.desktop @@ -0,0 +1,222 @@ +[Desktop Entry] +ServiceTypes=image/jpeg +Actions=jpegRot90;jpegRot270;jpegFlipV;jpegFlipH; +X-KDE-Submenu=Transform Image +X-KDE-Submenu[bg]=Конвертиране на изображението +X-KDE-Submenu[ca]=Transforma la imatge +X-KDE-Submenu[cs]=Převést obrázek +X-KDE-Submenu[da]=Transformér billede +X-KDE-Submenu[de]=Bild transformieren +X-KDE-Submenu[es]=Transformar imagen +X-KDE-Submenu[fi]=Muuta kuva +X-KDE-Submenu[fr]=Transformer l'image +X-KDE-Submenu[hu]=Képátalakítás +X-KDE-Submenu[is]=Ummynda +X-KDE-Submenu[it]=Trasforma immagine +X-KDE-Submenu[nb]=Transformer bilde +X-KDE-Submenu[nl]=Afbeelding transformeren +X-KDE-Submenu[pl]=Przekształć obrazek +X-KDE-Submenu[pt]=Transformar a Imagem +X-KDE-Submenu[pt_BR]=Transformar Imagem +X-KDE-Submenu[ru]=Преобразовать +X-KDE-Submenu[sr]=Трансформиши слику +X-KDE-Submenu[sr@Latn]=Transformiši sliku +X-KDE-Submenu[sv]=Ändra bild +X-KDE-Submenu[uk]=Перетворити зображення +X-KDE-Submenu[xx]=xxTransform Imagexx +X-KDE-Submenu[zh_CN]=图像变形 +X-KDE-Require=Write + +[Desktop Action jpegRot90] +Name=Rotate Clockwise +Name[ar]=تدوير في اتجاه الساعة +Name[az]=Saat Əqrəbi İstiqamətində Fırlat +Name[bg]=Завъртане по посока на часов. стрелка +Name[ca]=Gira 90 graus +Name[cs]=Rotovat ve směru hod. ručiček +Name[cy]=Cylchdroi yn Glocwedd +Name[da]=Rotér med uret +Name[de]=Im Uhrzeigersinn drehen (nach rechts) +Name[el]=Περιστροφή δεξιόστροφα +Name[es]=Girar en el sentido de las agujas del reloj +Name[et]=Pööra päripäeva +Name[eu]=Biratu erloju orratzen norabidean +Name[fi]=Käännä myötäpäivään +Name[fr]=Tourner en sens horaire +Name[ga]=Rothlaigh go Deisealach +Name[he]=סובב עם כיוון השעון +Name[hi]=घड़ी की दिशा में घुमाएँ +Name[hu]=Forgatás jobbra +Name[is]=Snúa réttsælis +Name[it]=Ruota in senso orario +Name[ja]=右回りに回転します +Name[nb]=Roter medurs +Name[nl]=Klokgewijs draaien +Name[nn]=Roter med klokka +Name[pa]=ਸੱਜਾ ਦਾਅ ਘੁੰਮਾਉ +Name[pl]=Obróć zgodnie z ruchem wskazówek zegara +Name[pt]=Rodar no Sentido Horário +Name[pt_BR]=Rodar Relógio Sentido Horário +Name[ro]=Roteşte la dreapta +Name[ru]=Повернуть по часовой стрелке +Name[sk]=Otočiť v smere hodinových ručičiek +Name[sl]=Zasuči v smeri urinega kazalca +Name[sr]=Ротирај у смеру казаљке на часовнику +Name[sr@Latn]=Rotiraj u smeru kazaljke na časovniku +Name[sv]=Rotera medurs +Name[ta]=வலதுபுறமாக சுழற்று +Name[tg]=Чархиш бо ақрабаки соат +Name[tr]=Saat Yönünde Döndürme +Name[uk]=Обернути за годинниковою стрілкою +Name[uz]=Соат кўрсатгичи бўйича айлантириш +Name[xx]=xxRotate Clockwisexx +Name[zh_CN]=顺时针旋转 +Icon=rotate_cw +Exec=jpegorient +90 %F + +[Desktop Action jpegRot270] +Name=Rotate Counter-Clockwise +Name[ar]=تدوير عكس اتجاه الساعة +Name[az]=Saat Əqrəbinə Tərs İstiqamətdə Fırlat +Name[bg]=Завъртане обратно на часов. стрелка +Name[ca]=Gira 270 graus +Name[cs]=Rotovat proti směru hod. ručiček +Name[cy]=Cylchdroi yn Wrthglocwedd +Name[da]=Rotér mod uret +Name[de]=Gegen den Uhrzeigersinn drehen (nach links) +Name[el]=Περιστροφή αριστερόστροφα +Name[en_GB]=Rotate Anti-Clockwise +Name[es]=Girar en el sentido contrario a las agujas del reloj +Name[et]=Pööra vastupäeva +Name[eu]=Biratu erloju orratzen aurkako norabidean +Name[fi]=Käännä vastapäivään +Name[fr]=Tourner en sens anti-horaire +Name[ga]=Rothlaigh go Tuathalach +Name[he]=סובב נגד כיוון השעון +Name[hi]=घड़ी की उलटी दिशा में घुमाएँ +Name[hu]=Forgatás balra +Name[is]=Snúa rangsælis +Name[it]=Ruota in senso anti-orario +Name[ja]=左回りに回転します +Name[nb]=Roter moturs +Name[nl]=Anti-klokgewijs draaien +Name[nn]=Roter mot klokka +Name[pa]=ਖੱਬੇ ਦਾਅ ਘੁੰਮਾਓ +Name[pl]=Obróć przeciwnie do ruchu wskazówek zegara +Name[pt]=Rodar no Sentido Anti-horário +Name[pt_BR]=Rodar Contador de Relógio +Name[ro]=Roteşte la stînga +Name[ru]=Повернуть против часовой стрелки +Name[sk]=Otočiť proti smeru hodinových ručičiek +Name[sl]=Zasuči v nasportni smeri urinega kazalca +Name[sr]=Ротирај супротно смеру казаљке на часовнику +Name[sr@Latn]=Rotiraj suprotno smeru kazaljke na časovniku +Name[sv]=Rotera moturs +Name[ta]=கடிகார ஓட்டத்திற்கெதிராக சுழற்று +Name[tg]=Чархиш ба муқобили ақрабаки соат +Name[tr]=Sayacı Saat Yönünde Döndürme +Name[uk]=Обернути проти годинникової стрілки +Name[uz]=Соат кўрсатгичига қарши айлантириш +Name[xx]=xxRotate Counter-Clockwisexx +Name[zh_CN]=逆时针旋转 +Icon=rotate_ccw +Exec=jpegorient +270 %F + +#[Desktop Action jpegRot180] +#Name=Rotate 180 +#Icon=misc +#Exec=jpegorient +180 %F + +[Desktop Action jpegFlipV] +Name=Flip Vertically +Name[ar]=تدوير رأسي +Name[az]=Şaquli Olaraq Çevir +Name[bg]=Вертикално обръщане +Name[ca]=Torna vertical +Name[cs]=Převrátit svisle +Name[cy]=Troi Drosodd yn Fertigol +Name[da]=Flip lodret +Name[de]=Vertikal kippen +Name[el]=Αναστροφή κατακόρυφα +Name[es]=Reflejar verticalmente +Name[et]=Keera ümber vertikaalselt +Name[eu]=Buruz behera ipini +Name[fi]=Käännä pystysuorassa +Name[fr]=Retourner verticalement +Name[ga]=Smeach go hIngearach +Name[he]=שקף אנכית +Name[hi]=खड़ा पलटें +Name[hu]=Tükrözés függőlegesen +Name[is]=Snúa við um miðju lóðrétt +Name[it]=Fletti verticalmente +Name[ja]=縦のフリップ +Name[nb]=Speilvend loddrett +Name[nl]=Verticaal omdraaien +Name[nn]=Snu loddrett +Name[pa]=ਲੰਬਕਾਰੀ ਝਟਕੋ +Name[pl]=Odwróć pionowo +Name[pt]=Trocar Verticalmente +Name[pt_BR]=Refletir Verticalmente +Name[ro]=Întoarce pe verticală +Name[ru]=Отразить вертикально +Name[sk]=Preklopiť vertikálne +Name[sl]=Obrni navpično +Name[sr]=Преврни усправно +Name[sr@Latn]=Prevrni uspravno +Name[sv]=Vänd vertikalt +Name[ta]=மேல்கீழாக திருப்பு +Name[tg]=Баргардондан ба амудӣ +Name[tr]=Dik Olarak Dağıtma +Name[uk]=Перекинути вертикально +Name[uz]=Эни бўйича айлантириш +Name[xx]=xxFlip Verticallyxx +Name[zh_CN]=上下翻转 +Icon=2uparrow +Exec=jpegorient v %F + +[Desktop Action jpegFlipH] +Name=Flip Horizontally +Name[ar]=تدوير أفقي +Name[az]=Üfüqi Olaraq Çevir +Name[bg]=Хоризонтално обръщане +Name[ca]=Torna horitzontal +Name[cs]=Převrátit vodorovně +Name[cy]=Troi Drosodd yn Llorweddol +Name[da]=Flip vandret +Name[de]=Horizontal kippen +Name[el]=Αναστροφή οριζόντια +Name[es]=Reflejar horizontalmente +Name[et]=Keera ümber horisontaalselt +Name[eu]=Biratu horizontalki +Name[fi]=Käännä vaakasuorassa +Name[fr]=Retourner horizontalement +Name[ga]=Smeach go Cothrománach +Name[he]=שקף אופקית +Name[hi]=आड़ा पलटें +Name[hu]=Tükrözés vízszintesen +Name[is]=Snúa við um miðju lárétt +Name[it]=Fletti orizzontalmente +Name[ja]=水平にフリップ +Name[nb]=Speilvend vannrett +Name[nl]=Horizontaal omdraaien +Name[nn]=Snu vassrett +Name[pa]=ਖਿਤਿਜੀ ਝਟਕੋ +Name[pl]=Odwróć poziomo +Name[pt]=Trocar Horizontalmente +Name[pt_BR]=Refletir Horizontalmente +Name[ro]=Întoarce pe orizontală +Name[ru]=Отразить горизонтально +Name[sk]=Preklopiť horizontálne +Name[sl]=Obrni vodoravno +Name[sr]=Преврни водоравно +Name[sr@Latn]=Prevrni vodoravno +Name[sv]=Vänd horisontellt +Name[ta]=இடம்வலமாக திருப்புக +Name[tg]=Баргардондан ба уфуқӣ +Name[tr]=Yatay Olarak Dağıtma +Name[uk]=Перекинути горизонтально +Name[uz]=Бўйи бўйича айлантириш +Name[xx]=xxFlip Horizontallyxx +Name[zh_CN]=左右翻转 +Icon=2rightarrow +Exec=jpegorient h %F diff --git a/src/servicemenus/k3b_audiocd_rip.desktop b/src/servicemenus/k3b_audiocd_rip.desktop new file mode 100644 index 0000000..387d44a --- /dev/null +++ b/src/servicemenus/k3b_audiocd_rip.desktop @@ -0,0 +1,46 @@ +[Desktop Entry] +ServiceTypes=media/audiocd,media/mixedcd +Actions=K3bRip; +X-KDE-Priority=TopLevel + +[Desktop Action K3bRip] +Name=Extract Digital Audio with K3b +Name[af]=Onttrek digitale oudio m.b.v. K3b +Name[ar]= استعمل K3b لاستخراج الصوتي الرقمي. +Name[bg]=Извличане на цифров звук с K3b +Name[br]=Eztennañ klevet niverel gant K3b +Name[ca]=Extreu àudio digital amb el K3b +Name[cs]=Extrahovat digitální zvuk pomocí K3b +Name[da]=Rip digitallyd med K3b +Name[de]=Digital-Audio mit K3b auslesen +Name[el]=Εξαγωγή ψηφιακού ήχου με το K3b +Name[es]=Extraer audio digital con K3b +Name[et]=Ekstrakti digitaalne audio K3b abil +Name[fa]=استخراج صوتی رقمی با K3b +Name[fi]=Pura sisältö digitaalisesti K3b:llä +Name[fr]=Extraction Audio avec K3b +Name[gl]=Extrair Áudio Dixital con K3b +Name[hu]=Digitális hanganyag kimásolása a K3b-vel +Name[is]=Afrita stafrænt hljóð með K3b +Name[it]=Estrai audio digitale con K3b +Name[ja]=K3b でデジタルオーディオを吸い出し +Name[km]=ស្រង់ចេញអូឌីយ៉ូឌីជីថលដោយប្រើ K3b +Name[lt]=Nurašyti skaitmeninį audio su K3b +Name[ms]=Ekstrak Audio Digital dengan K3b +Name[nds]=Digitaal Audiodaten mit K3b ruttrecken +Name[nl]=Digitale audio rippen met K3b +Name[pa]=K3b ਨਾਲ ਡਿਜ਼ੀਟਲ ਆਡੀਓ ਖੋਲ੍ਹੋ +Name[pl]=Zgraj utwory za pomocą K3b +Name[pt]=Extrair o Áudio Digital com o K3b +Name[pt_BR]=Extrair Áudio Digital com o K3b +Name[sk]=Vytiahnuť digitálny zvuk pomocou K3b +Name[sr]=Издвој дигитални звук помоћу K3b-а +Name[sr@Latn]=Izdvoj digitalni zvuk pomoću K3b-a +Name[sv]=Lagra digitalljud med K3b +Name[tr]=K3b ile Sayısal Ses Aktar +Name[uk]=Витягування цифрового аудіо за допомогою K3b +Name[uz]=K3b ёрдамида қўшиқларни аудио-файлга айлантириш +Name[zh_CN]=用 K3b 提取数字音频 +Name[zh_TW]=使用 K3b 以數位方式提取音樂 +Exec=k3b --cddarip %u +Icon=k3b diff --git a/src/servicemenus/k3b_cd_copy.desktop b/src/servicemenus/k3b_cd_copy.desktop new file mode 100644 index 0000000..fc78f8a --- /dev/null +++ b/src/servicemenus/k3b_cd_copy.desktop @@ -0,0 +1,48 @@ +[Desktop Entry] +ServiceTypes=media/cdrom_unmounted,media/cdwriter_unmounted,media/audiocd +Actions=K3bCDCopy; +X-KDE-Priority=TopLevel + +[Desktop Action K3bCDCopy] +Name=Copy CD with K3b +Name[af]=Kopiëer CD m.b.v. K3b... +Name[ar]= انقل القرص المدمج بواسطة K3b . +Name[bg]=Копиране на CD с K3b +Name[br]=Eilañ ur CD gant K3b +Name[ca]=Copia CD amb el K3b +Name[cs]=Kopírovat CD pomocí K3b +Name[da]=Kopiér cd med K3b +Name[de]=CD mit K3b kopieren +Name[el]=Αντιγραφή CD με το K3b +Name[es]=Copiar CD con K3b +Name[et]=Kopeeri CD K3b abil +Name[fa]=رونوشت دیسک فشرده با K3b +Name[fi]=Kopioi cd K3b:llä +Name[fr]=Copier le CD avec K3b +Name[gl]=Copiar CD con K3b +Name[hu]=CD-másolás a K3b-vel +Name[is]=Afrita geisladisk með K3b +Name[it]=Copia CD con K3b +Name[ja]=K3b で CD をコピー +Name[km]=ចម្លងស៊ីឌីដោយប្រើ K3b +Name[lt]=Kopijuoti CD su K3b +Name[mk]=Копирајте CD со K3b +Name[ms]=Salin CD dengan K3b +Name[nds]=CD mit K3b koperen +Name[nl]=CD kopiëren met K3b +Name[pa]=K3b ਨਾਲ CD ਨਕਲ +Name[pl]=Skopiuj płytę CD za pomocą K3b +Name[pt]=Copiar o CD com o K3b +Name[pt_BR]=Copiar CD com o K3b +Name[ru]=Записать компакт-диск, используя K3b... +Name[sk]=Kopírovať CD pomocou K3b +Name[sr]=Копирај CD помоћу K3b-а +Name[sr@Latn]=Kopiraj CD pomoću K3b-a +Name[sv]=Kopiera cd med K3b +Name[tr]=K3b ile CD Kopyala +Name[uk]=Копіювати КД за допомогою K3b +Name[uz]=K3b ёрдамида CD'дан нусха олиш +Name[zh_CN]=用 K3b 复制 CD +Name[zh_TW]=使用 K3b 複製 CD +Exec=k3b --copycd %u +Icon=k3b diff --git a/src/servicemenus/k3b_create_audio_cd.desktop b/src/servicemenus/k3b_create_audio_cd.desktop new file mode 100644 index 0000000..efc1a79 --- /dev/null +++ b/src/servicemenus/k3b_create_audio_cd.desktop @@ -0,0 +1,124 @@ +[Desktop Entry] +Actions=CreateK3bAudioProject; +Encoding=UTF-8 +ServiceTypes=audio/x-mp3,audio/x-vorbis,application/x-ogg,audio/x-mp2,audio/x-mpegurl,audio/x-wav,media/blankcd + +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +[Desktop Action CreateK3bAudioProject] +Exec=k3b --audiocd %U +Name=Create Audio CD with K3b... +Name[af]=Skep oudio CD met K3b... +Name[bg]=Създаване на аудио CD с K3b... +Name[bn]=কে-থ্রি-বি দিয়ে অডিও সিডি তৈরি করো... +Name[br]=Krouiñ ur CD klevet gant K3b ... +Name[bs]=Napravio audio CD koristeći K3b... +Name[ca]=Crea CD d'àudio amb K3b... +Name[cs]=Vytvořit zvukové CD... +#SUSE-Overwrite Name[da]=Lav lyd-cd med K3b... +Name[da]=Lav lyd-CD med K3b... +Name[de]=Audio-CD mit K3b erstellen ... +Name[el]=Δημιουργία μουσικού CD με το K3b... +Name[es]=Crear CD de audio con K3b... +Name[et]=Kirjuta audio-CD K3b abil... +Name[eu]=Sortu audio cdak K3b-rekin... +Name[fr]=Créer un CD audio avec K3b... +Name[he]=צור תקליטור שמע בעזרת K3b... +Name[hi]=के3बी के साथ ऑडियो सीडी बनाए... +Name[hu]=Hang-CD létrehozása a K3b-vel... +Name[is]=Búa til hljóðdisk með K3b... +Name[it]=Crea CD audio con K3b... +#SUSE-Overwrite Name[ja]=オーディオ CD を K3b で作成... +Name[ja]=K3bによるオーディオCDの作成... +Name[lt]=Kurkite audio CD su K3b... +Name[mk]=Креирајте аудио-CD со K3b... +#SUSE-Overwrite Name[nb]=Lag lyd-CD med K3b . . . +Name[nb]=Brenn lyd-CD-er med K3b... +Name[nl]=Audio-cd aanmaken met K3b... +Name[pa]=K3b ਨਾਲ ਆਡੀਓ CD ਬਣਾਓ... +Name[pl]=Stwórz płytę CD Audio za pomocą K3b... +Name[pt]=Criar um CD de Áudio com o K3b... +Name[pt_BR]=Criar CD de Áudio com K3b... +Name[ru]=Записать аудио компакт-диск, используя K3b... +Name[sl]=Ustvari avdio CD s K3b ... +Name[sr]=Направи аудио CD помоћу K3b-а... +Name[sr@Latn]=Napravi audio CD pomoću K3b-a... +Name[sv]=Skapa ljud-cd med K3b... +Name[ta]=ஒலிக் குறுந்தகட்டோடு K3bயை உருவாக்குக... +Name[tr]=K3b ile Ses CD'si oluştur... +Name[uk]=Створити аудіо-КД за допомогою K3b... +Name[zh_CN]=用 K3b 创建音频 CD... +Icon=k3b + +Name[fi]=Luo ääni-CD K3b:llä +Name[km]=បង្កើតស៊ីឌីអូឌីយ៉ូជាមួយ K3b... +Name[zh_TW]=以 K3b 建立音效 CD... diff --git a/src/servicemenus/k3b_create_video_cd.desktop b/src/servicemenus/k3b_create_video_cd.desktop new file mode 100644 index 0000000..45cca6a --- /dev/null +++ b/src/servicemenus/k3b_create_video_cd.desktop @@ -0,0 +1,125 @@ +[Desktop Entry] +Actions=CreateK3bVcdProject; +Encoding=UTF-8 +ServiceTypes=video/mpeg + +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +[Desktop Action CreateK3bVcdProject] +Exec=k3b --videocd %F +Name=Create Video CD with K3b... +Name[af]=Skep video CD met K3b... +Name[bg]=Създаване на видео CD с K3b... +Name[bn]=কে-থ্রি-বি দিয়ে ভিডিও সিডি তৈরি করো... +Name[br]=Krouiñ ur CD video gant K3b ... +Name[bs]=Napravi video CD koristeći K3b... +Name[ca]=Crea CD de vídeo amb K3b... +Name[cs]=Vytvořit video CD... +#SUSE-Overwrite Name[da]=Lav video-cd med K3b... +Name[da]=Lav Video CD med K3b... +Name[de]=Video-CD mit K3b erstellen ... +Name[el]=Δημιουργία Video CD με το K3b... +Name[es]=Crear Video CD con K3b... +Name[et]=Kirjuta video-CD K3b abil... +Name[eu]=Sortu Bideo CDak K3b-rekin... +Name[fr]=Créer un CD vidéo avec K3b... +Name[he]=צור תקליטורי וידאו VCD בעזרת K3b... +Name[hi]=के3बी के साथ वीडियो सीडी बनाए... +Name[hu]=Video-CD létrehozása a K3b-vel... +Name[is]=Búa til vídeódisk með K3b... +Name[it]=Crea Video CD con K3b... +#SUSE-Overwrite Name[ja]=Video CD を K3b で作成... +Name[ja]=K3bによるビデオCDの作成... +Name[lt]=Kurkite video CD su K3b... +Name[mk]=Креирајте видео-CD со K3b... +#SUSE-Overwrite Name[nb]=Lag video-CD med K3b . . . +Name[nb]=Brenn video-CD-er med K3b... +Name[nl]=Video-cd aanmaken K3b... +#SUSE-Overwrite Name[pa]=K3b ਨਾਲ ਵੀਡਿਓ CD ਬਣਾਓ... +Name[pa]=K3b ਨਾਲ ਵੀਡਿਓ CD ਬਣਾਓ +Name[pl]=Stwórz płytę Video CD za pomocą K3b... +Name[pt]=Criar um Video CD com o K3b... +Name[pt_BR]=Criar CD de Vídeo com K3b... +Name[ru]=Записать видео компакт-диск, используя K3b... +Name[sl]=Ustvari video CD s K3b ... +Name[sr]=Направи видео CD помоћу K3b-а... +Name[sr@Latn]=Napravi video CD pomoću K3b-a... +Name[sv]=Skapa video-cd med K3b... +Name[ta]=ஒளிக் குறுந்தகட்டோடு K3bஐ உருவாக்குக... +Name[tr]=K3b ile Video CD'si oluştur... +Name[uk]=Створити відео-КД за допомогою K3b... +Name[zh_CN]=用 K3b 创建视频 CD... +Icon=k3b + +Name[fi]=Luo video-CD K3b:llä +Name[km]=បង្កើតស៊ីឌីវីដេអូជាមួយ K3b... +Name[zh_TW]=以 K3b 建立視訊 CD... diff --git a/src/servicemenus/k3b_dvd_copy.desktop b/src/servicemenus/k3b_dvd_copy.desktop new file mode 100644 index 0000000..f85ffcb --- /dev/null +++ b/src/servicemenus/k3b_dvd_copy.desktop @@ -0,0 +1,48 @@ +[Desktop Entry] +ServiceTypes=media/dvdrom_unmounted,media/dvdwriter_unmounted,media/dvdvideo +Actions=K3bDVDCopy; +X-KDE-Priority=TopLevel + +[Desktop Action K3bDVDCopy] +Name=Copy DVD with K3b +Name[af]=Kopiëer DVD m.b.v. K3b +Name[ar]= انسخ القرص الرقمي المرئي (DVD) بواسطة K3b . +Name[bg]=Копиране на DVD с K3b +Name[br]=Eilañ un DVD gant K3b +Name[ca]=Copia un DVD amb el K3b +Name[cs]=Kopírovat DVD pomocí K3b +Name[da]=Kopiér dvd med K3b +Name[de]=DVD mit K3b kopieren +Name[el]=Αντιγραφή DVD με το K3b +Name[es]=Copiar DVD con K3b +Name[et]=Kopeeri DVD K3b abil +Name[fa]=رونوشت دی وی دی با K3b +Name[fi]=Kopioi dvd K3b:llä +Name[fr]=Copier le DVD avec K3b +Name[gl]=Copiar DVD con K3b +Name[hu]=DVD-másolás a K3b-vel +Name[is]=Afrita DVD með K3b +Name[it]=Copia DVD con K3b +Name[ja]=K3b で DVD をコピー... +Name[km]=ចម្លងឌីវីឌីដោយប្រើ K3b +Name[lt]=Kopijuoti DVD su K3b +Name[mk]=Копирајте DVD со K3b... +Name[ms]=Salin DVD dengan K3b +Name[nds]=DVD mit K3b koperen +Name[nl]=DVD kopiëren met K3b +Name[pa]=K3b ਨਾਲ DVD ਨਕਲ +Name[pl]=Skopiuj DVD za pomocą K3b +Name[pt]=Copiar o DVD com o K3b +Name[pt_BR]=Copiar DVD com o K3b +Name[ru]=Копировать DVD, используя K3b... +Name[sk]=Vytvoriť DVD pomocou K3b +Name[sr]=Копирај DVD помоћу K3b-а +Name[sr@Latn]=Kopiraj DVD pomoću K3b-a +Name[sv]=Kopiera dvd med K3b +Name[tr]=K3b ile Veri DVD'si Kopyala +Name[uk]=Копіювати DVD за допомогою K3b +Name[uz]=K3b ёрдамида DVD'дан нусха олиш +Name[zh_CN]=用 K3b 复制 DVD +Name[zh_TW]=使用 K3b 複製 DVD +Exec=k3b --copydvd %u +Icon=k3b diff --git a/src/servicemenus/k3b_handle_empty_cd.desktop b/src/servicemenus/k3b_handle_empty_cd.desktop new file mode 100644 index 0000000..63f9283 --- /dev/null +++ b/src/servicemenus/k3b_handle_empty_cd.desktop @@ -0,0 +1,114 @@ +[Desktop Entry] +ServiceTypes=media/blankcd +Actions=K3bDataProject;K3bAudioCDProject; +X-KDE-Priority=TopLevel + +[Desktop Action K3bDataProject] +Exec=k3b --device %u --datacd +Name=Create Data CD with K3b... +Name[af]=Skep data CD met K3b... +Name[ar]= انشيء القرص المدمج لحفظ البيانات (Data) بواسطة K3b ... +Name[bg]=Създаване на CD с данни с K3b... +Name[bn]=কে-থ্রি-বি দিয়ে ডেটা-সিডি তৈরি করো... +Name[br]=Krouiñ ur CD roadoù gant K3b ... +Name[bs]=Napravi podatkovni CD koristeći K3b... +Name[ca]=Crea un CD de dades amb el K3b... +Name[cs]=Vytvořit datové CD... +Name[da]=Lav data-cd med K3b... +Name[de]=Daten-CD mit K3b erstellen ... +Name[el]=Δημιουργία CD δεδομένων με το K3b... +Name[es]=Crear CD de datos con K3b... +Name[et]=Kirjuta andme-CD K3b abil... +Name[fa]=ایجاد دیسک فشردۀ داده با K3b... +Name[fi]=Luo data-cd K3b:llä... +Name[fr]=Créer un CD de données avec K3b... +Name[gl]=Criar un CD de Dados con K3b... +Name[he]=צור תקליטורי מידע CD בעזרת K3b... +Name[hi]=के3बी के साथ डाटा सीडी बनाए... +Name[hu]=Adat-CD létrehozása a K3b-vel... +Name[is]=Búa til gagnadisk með K3b... +Name[it]=Crea CD dati con K3b... +Name[ja]=K3b でデータ CD を作成... +Name[km]=បង្កើតស៊ីឌីទិន្ន័យជាមួយនឹង K3b... +Name[lt]=Kurti duomenų CD su K3b... +Name[mk]=Креирајте податочно CD со K3b... +Name[ms]= Cipta CD Data dengan K3b... +Name[nb]=Lag data-CD med K3b . . . +Name[nds]=Daten-CD mit K3b opstellen... +Name[ne]=K3b... +Name[nl]=Gegevens-cd aanmaken met K3b... +Name[nn]=Lag data-CD med K3b … +Name[pa]=K2b ਨਾਲ ਡਾਟਾ CD ਬਣਾਓ... +Name[pl]=Stwórz płytę CD z danymi za pomocą K3b... +Name[pt]=Criar um CD de Dados com o K3b... +Name[pt_BR]=Criar CD de Dados com o K3b... +Name[ru]=Записать компакт-диск с данными, используя K3b... +Name[sk]=Vytvoriť dátové CD pomocou K3b... +Name[sl]=Ustvari podatkovni CD s K3b ... +Name[sr]=Направи CD са подацима помоћу K3b-а... +Name[sr@Latn]=Napravi CD sa podacima pomoću K3b-a... +Name[sv]=Skapa data-cd med K3b... +Name[ta]=தகவல் குறுந்தகட்டோடு K3b ஐ உருவாக்குக... +Name[tg]=Сабт кардани CD бо маълумотҳо,бо истифодабарии K3b... +Name[tr]=K3b ile Veri CD'si oluştur... +Name[uk]=Створити КД з даними за допомогою K3b... +Name[uz]=K3b ёрдамида маълумот CD яратиш +Name[xh]=Yenza i CD yolwazi nge K3b... +Name[zh_CN]=用 K3b 创建数据 CD... +Name[zh_TW]=使用 K3b 建立資料 CD... +Icon=k3b + +[Desktop Action K3bAudioCDProject] +Exec=k3b --device %u --audiocd +Name=Create Audio CD with K3b... +Name[af]=Skep oudio CD met K3b... +Name[ar]= انشيء القرص المدمج السمعي بواسطة K3b ... +Name[bg]=Създаване на аудио CD с K3b... +Name[bn]=কে-থ্রি-বি দিয়ে অডিও সিডি তৈরি করো... +Name[br]=Krouiñ ur CD klevet gant K3b ... +Name[bs]=Napravio audio CD koristeći K3b... +Name[ca]=Crea un CD d'àudio amb el K3b... +Name[cs]=Vytvořit zvukové CD... +Name[da]=Lav lyd-cd med K3b... +Name[de]=Audio-CD mit K3b erstellen ... +Name[el]=Δημιουργία CD ήχου με το K3b... +Name[es]=Crear CD de audio con K3b... +Name[et]=Kirjuta audio-CD K3b abil... +Name[fa]=ایجاد دیسک فشردۀ صوتی با K3b... +Name[fi]=Luo musiikki-cd K3b:llä... +Name[fr]=Créer un CD audio avec K3b... +Name[gl]=Criar un CD de Áudio con K3b... +Name[he]=צור תקליטור שמע בעזרת K3b... +Name[hi]=के3बी के साथ ऑडियो सीडी बनाए... +Name[hu]=Hang-CD létrehozása a K3b-vel... +Name[is]=Búa til hljóðdisk með K3b... +Name[it]=Crea CD audio con K3b... +Name[ja]=K3b でオーディオ CD を作成... +Name[km]=បង្កើតស៊ីឌីអូឌីយ៉ូជាមួយនឹង K3b... +Name[lt]=Kurti audio CD su K3b... +Name[mk]=Креирајте аудио-CD со K3b... +Name[ms]= Cipta Audio CD dengan K3b... +Name[nb]=Lag lyd-CD med K3b . . . +Name[nds]=Audio-CD mit K3b opstellen... +Name[ne]=K3b सँग अडियो सीडी सिर्जना गर्नुहोस्... +Name[nl]=Audio-cd aanmaken met K3b... +Name[nn]=Lag lyd-CD med K3b … +Name[pa]=K2b ਨਾਲ ਆਡੀਓ CD ਬਣਾਓ... +Name[pl]=Stwórz płytę CD Audio za pomocą K3b... +Name[pt]=Criar um CD de Áudio com o K3b... +Name[pt_BR]=Criar CD de Áudio com o K3b... +Name[ru]=Записать аудио компакт-диск, используя K3b... +Name[sk]=Vytvoriť zvukové CD pomocou K3b... +Name[sl]=Ustvari avdio CD s K3b ... +Name[sr]=Направи аудио CD помоћу K3b-а... +Name[sr@Latn]=Napravi audio CD pomoću K3b-a... +Name[sv]=Skapa ljud-cd med K3b... +Name[ta]=ஒலிக் குறுந்தகட்டோடு K3bயை உருவாக்குக... +Name[tg]=Сабт кардани аудио компакт-диск бо истифодаи K3b... +Name[tr]=K3b ile Ses CD'si oluştur... +Name[uk]=Створити аудіо-КД за допомогою K3b... +Name[uz]=K3b ёрдамида аудио CD яратиш +Name[xh]=Yenza i CD Yokuvakalayo nge K3b... +Name[zh_CN]=用 K3b 创建音频 CD... +Name[zh_TW]=使用 K3b 建立音樂 CD... +Icon=k3b diff --git a/src/servicemenus/k3b_handle_empty_dvd.desktop b/src/servicemenus/k3b_handle_empty_dvd.desktop new file mode 100644 index 0000000..74f8780 --- /dev/null +++ b/src/servicemenus/k3b_handle_empty_dvd.desktop @@ -0,0 +1,103 @@ +[Desktop Entry] +ServiceTypes=media/blankdvd +Actions=K3bDataProject; +X-KDE-Priority=TopLevel + +[Desktop Action K3bDataProject] +Exec=k3b --device %u --datadvd +Name=Create Data CD with K3b... +Name[af]=Skep data CD met K3b... +Name[ar]= انشيء القرص المدمج لحفظ البيانات (Data) بواسطة K3b ... +Name[bg]=Създаване на CD с данни с K3b... +Name[bn]=কে-থ্রি-বি দিয়ে ডেটা-সিডি তৈরি করো... +Name[br]=Krouiñ ur CD roadoù gant K3b ... +Name[bs]=Napravi podatkovni CD koristeći K3b... +Name[ca]=Crea un CD de dades amb el K3b... +Name[cs]=Vytvořit datové CD... +Name[da]=Lav data-cd med K3b... +Name[de]=Daten-CD mit K3b erstellen ... +Name[el]=Δημιουργία CD δεδομένων με το K3b... +Name[es]=Crear CD de datos con K3b... +Name[et]=Kirjuta andme-CD K3b abil... +Name[fa]=ایجاد دیسک فشردۀ داده با K3b... +Name[fi]=Luo data-cd K3b:llä... +Name[fr]=Créer un CD de données avec K3b... +Name[gl]=Criar un CD de Dados con K3b... +Name[he]=צור תקליטורי מידע CD בעזרת K3b... +Name[hi]=के3बी के साथ डाटा सीडी बनाए... +Name[hu]=Adat-CD létrehozása a K3b-vel... +Name[is]=Búa til gagnadisk með K3b... +Name[it]=Crea CD dati con K3b... +Name[ja]=K3b でデータ CD を作成... +Name[km]=បង្កើតស៊ីឌីទិន្ន័យជាមួយនឹង K3b... +Name[lt]=Kurti duomenų CD su K3b... +Name[mk]=Креирајте податочно CD со K3b... +Name[ms]= Cipta CD Data dengan K3b... +Name[nb]=Lag data-CD med K3b . . . +Name[nds]=Daten-CD mit K3b opstellen... +Name[ne]=K3b... +Name[nl]=Gegevens-cd aanmaken met K3b... +Name[nn]=Lag data-CD med K3b … +Name[pa]=K2b ਨਾਲ ਡਾਟਾ CD ਬਣਾਓ... +Name[pl]=Stwórz płytę CD z danymi za pomocą K3b... +Name[pt]=Criar um CD de Dados com o K3b... +Name[pt_BR]=Criar CD de Dados com o K3b... +Name[ru]=Записать компакт-диск с данными, используя K3b... +Name[sk]=Vytvoriť dátové CD pomocou K3b... +Name[sl]=Ustvari podatkovni CD s K3b ... +Name[sr]=Направи CD са подацима помоћу K3b-а... +Name[sr@Latn]=Napravi CD sa podacima pomoću K3b-a... +Name[sv]=Skapa data-cd med K3b... +Name[ta]=தகவல் குறுந்தகட்டோடு K3b ஐ உருவாக்குக... +Name[tg]=Сабт кардани CD бо маълумотҳо,бо истифодабарии K3b... +Name[tr]=K3b ile Veri CD'si oluştur... +Name[uk]=Створити КД з даними за допомогою K3b... +Name[uz]=K3b ёрдамида маълумот CD яратиш +Name[xh]=Yenza i CD yolwazi nge K3b... +Name[zh_CN]=用 K3b 创建数据 CD... +Name[zh_TW]=使用 K3b 建立資料 CD... +Name=Create Data DVD with K3b... +Name[af]=Skep 'n Data DVD m.b.v. K3b... +Name[ar]= انشيء القرص المرئي الرقمي (DVD) لحفظ البيانات (Data) بواسطة K3b ... +Name[bg]=Създаване на DVD с данни с K3b... +Name[bn]=কে-থ্রি-বি দিয়ে ডেটা-ডিভিডি তৈরি করো... +Name[br]=Krouiñ un DVD roadoù gant K3b ... +Name[ca]=Crea un DVD de dades amb el K3b... +Name[cs]=Vytvořit datové DVD... +Name[da]=Lav data-cd med K3b... +Name[de]=Daten-DVD mit K3b erstellen ... +Name[el]=Δημιουργία DVD δεδομένων με το K3b... +Name[es]=Crear DVD de datos con K3b... +Name[et]=Kirjuta andme-DVD K3b abil... +Name[fa]=ایجاد دی وی دی داده با K3b... +Name[fi]=Luo data-dvd K3b:llä... +Name[fr]=Créer un DVD de données avec K3b... +Name[gl]=Criar un DVD de Dados con K3b... +Name[he]=צור תקליטורי מידע DVD בעזרת K3b... +Name[hu]=Adat-DVD létrehozása a K3b-vel... +Name[is]=Búa til DVD gagnadisk með K3b... +Name[it]=Crea DVD dati con K3b... +Name[ja]=K3b でデータ DVD を作成... +Name[km]=បង្កើតឌីវីឌីទិន្នន័យដោយប្រើ K3b... +Name[lt]=Kurti duomenų DVD su K3b... +Name[mk]=Креирајте податочно DVD со K3b... +Name[ms]=Cipta DVD Data dengan K3b... +Name[nb]=Lag data-DVD med K3b . . . +Name[nds]=Daten-DVD mit K3b opstellen... +Name[nl]=Gegevens-dvd aanmaken met K3b... +Name[pa]=K3b ਨਾਲ ਡਾਟਾ DVD ਬਣਾਓ... +Name[pl]=Stwórz płytę DVD z danymi za pomocą K3b... +Name[pt]=Criar um DVD de Dados com o K3b... +Name[pt_BR]=Criar DVD de Dados com o K3b... +Name[ru]=Записать DVD с данными, используя K3b... +Name[sk]=Vytvoriť dátové DVD pomocou K3b... +Name[sr]=Направи DVD са подацима помоћу K3b-а... +Name[sr@Latn]=Napravi DVD sa podacima pomoću K3b-a... +Name[sv]=Skapa data-dvd med K3b... +Name[tg]=Сабт кардани Маълумотҳои CD бо истифодабарии K3b... +Name[tr]=K3b ile Veri DVD'si oluştur... +Name[uk]=Створити DVD з даними у K3b... +Name[uz]=K3b ёрдамида маълумот DVD яратиш +Name[zh_CN]=用 K3b 创建数据 DVD... +Name[zh_TW]=使用 K3b 建立資料 DVD... +Icon=k3b diff --git a/src/servicemenus/k3b_videodvd_rip.desktop b/src/servicemenus/k3b_videodvd_rip.desktop new file mode 100644 index 0000000..a915e67 --- /dev/null +++ b/src/servicemenus/k3b_videodvd_rip.desktop @@ -0,0 +1,45 @@ +[Desktop Entry] +ServiceTypes=media/dvdvideo +Actions=K3bRip; +X-KDE-Priority=TopLevel + +[Desktop Action K3bRip] +Name=Rip Video DVD Titles with K3b +Name[af]=Kopiëer Video DVD titels m.b.v. K3b +Name[ar]= استخرج عناوين مرئيات من القرص المرئي الرقمي (DVD) بواسطة K3b +Name[bg]=Извличане на DVD заглавия с K3b +Name[ca]=Extreure pistes de DVD amb el K3b +Name[cs]=Ripovat titulky video DVD pomocí K3b +Name[da]=Rip dvd-titler med K3b +Name[de]=DVD-Titel mit K3b auslesen +Name[el]=Εξαγωγή τίτλων DVD με το K3b +Name[es]=Extraer DVD de vídeo con K3b +Name[et]=Ripi video-DVD tiitlid K3b abil +Name[fa]=تبدیل عناوین دی وی دی ویدئویی با K3b +Name[fi]=Pura dvd K3b:llä +Name[fr]=Extraire les titres du DVD avec K3b +Name[gl]=Gravar título de Vídeo DVD con K3b +Name[hu]=Video DVD-címek beolvasása a K3b-vel +Name[is]=Afrita DVD titla með K3b +Name[it]=Estrai titoli DVD video con K3b +Name[ja]=K3b で DVD タイトルを吸い出し... +Name[km]=ច្រៀកចំណងជើងឌីវីឌីវីដេអូដោយប្រើ K3b +Name[lt]=Nurašyti video DVD su K3b +Name[ms]=Keluarkan Tajuk Video DVD dengan K3b +Name[nds]=Video-DVD-Stücken mit K3b utlesen +Name[nl]=Video-dvd-titels rippen met K3b +Name[pa]=K3b ਨਾਲ ਵੀਡਿਓ DVD ਟਾਇਟਲ ਰਿਪ +Name[pl]=Zgraj filmy z płyty DVD Video za pomocą K3b +Name[pt]=Extrair os Títulos do DVD de Vídeo com o K3b +Name[pt_BR]=Ripar DVD de Vídeo com o K3b +Name[sk]=Ripovať titulky video DVD pomocou K3b +Name[sr]=Исчупај титлове са видео DVD-а помоћу K3b-а +Name[sr@Latn]=Isčupaj titlove sa video DVD-a pomoću K3b-a +Name[sv]=Lagra dvd-titlar med K3b +Name[tr]=K3b ile Görüntü DVD'si Başlıklarını Aktar +Name[uk]=Видерти заголовки з відео-DVD за допомогою K3b +Name[uz]=K3b ёрдамида филмларни видео-файлга айлантириш +Name[zh_CN]=用 K3b 提取视频 DVD +Name[zh_TW]=使用 K3b 提取視像 DVD Titles +Exec=k3b --videodvdrip %u +Icon=k3b diff --git a/src/servicemenus/k3b_write_bin_image.desktop b/src/servicemenus/k3b_write_bin_image.desktop new file mode 100644 index 0000000..aaf7967 --- /dev/null +++ b/src/servicemenus/k3b_write_bin_image.desktop @@ -0,0 +1,124 @@ +[Desktop Entry] +Actions=WriteCdImage; +Encoding=UTF-8 +ServiceTypes=application/x-cue + +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +[Desktop Action WriteCdImage] +Exec=k3b --cdimage %F +Name=Write CD Image with K3b... +Name[af]=Skryf CD beeld met K3b... +Name[bg]=Запис на CD образ с K3b... +Name[bn]=কে-থ্রি-বি দিয়ে সিডি ইমেজ লেখো... +Name[br]=srivañ ar skeudenn CD gant K3b ... +Name[bs]=Zapiši CD image koristeći K3b... +Name[ca]=Escriu imatge per a CD amb K3b... +Name[cs]=Vypálit obraz CD... +#SUSE-Overwrite Name[da]=Skriv cd-billede med K3b... +Name[da]=Skriv CD-billede med K3b... +Name[de]=CD-Abbild mit K3b brennen ... +Name[el]=Εγγραφή εικόνας CD με το K3b... +Name[es]=Escribir imagen de CD con K3b... +Name[et]=Kirjuta tõmmis K3b abil plaadile... +Name[eu]=Idatzi CD irudiak K3b-rekin... +Name[fr]=Graver une image CD avec K3b... +Name[he]=כתוב תבנית CD בעזרת K3b... +Name[hi]=के3बी के साथ सीडी इमेज लिखें... +Name[hu]=CD-képmásfájl írása a K3b-vel... +Name[is]=Skrifa diskmynd með K3b... +Name[it]=Scrivi immagine CD con K3b... +#SUSE-Overwrite Name[ja]=CD イメージを K3b で書き込み... +Name[ja]=K3bによるCDイメージの書込み... +Name[lt]=Įrašykite CD atvaizdą su K3b... +Name[mk]=Запишете CD-слика со K3b... +#SUSE-Overwrite Name[nb]=Skriv CD-bilde med K3b . . . +Name[nb]=Brenn diskbilde på CD med K3b... +Name[nl]=CD-image schrijven met K3b... +Name[pa]=K3b ਨਾਲ CD ਪ੍ਰਤੀਬਿੰਬ ਲਿਖੋ... +Name[pl]=Stwórz obraz płyty CD za pomocą K3b... +Name[pt]=Escrever uma Imagem de CD com o K3b... +Name[pt_BR]=Gravar Imagem em CD com K3b... +Name[ru]=Записать образ CD, используя K3b... +Name[sl]=Zapiši sliko CD-ja s K3b ... +Name[sr]=Направи одраз CD-а помоћу K3b-а... +Name[sr@Latn]=Napravi odraz CD-a pomoću K3b-a... +Name[sv]=Skriv cd-avbild med K3b... +Name[ta]=குறுந்தகட்டு நிழலுடன் K3bஐ உருவாக்குக... +Name[tr]=K3b ile CD Kalıbı yazdır... +Name[uk]=Записати штамп КД за допомогою K3b... +Name[zh_CN]=用 K3b 刻录 CD 映像... +Icon=k3b + +Name[fi]=Kirjoita CD-levynkuva K3b:llä +Name[km]=សរសេររូបភាពស៊ីឌីជាមួយ K3b... +Name[zh_TW]=以 K3b 燒錄 CD 映像... diff --git a/src/servicemenus/k3b_write_iso_image.desktop b/src/servicemenus/k3b_write_iso_image.desktop new file mode 100644 index 0000000..8808f80 --- /dev/null +++ b/src/servicemenus/k3b_write_iso_image.desktop @@ -0,0 +1,124 @@ +[Desktop Entry] +Actions=WriteCdImage; +Encoding=UTF-8 +ServiceTypes=application/x-iso,inode/ISO-image + +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +[Desktop Action WriteCdImage] +Exec=k3b --image %F +Name=Write CD Image with K3b... +Name[af]=Skryf CD beeld met K3b... +Name[bg]=Запис на CD образ с K3b... +Name[bn]=কে-থ্রি-বি দিয়ে সিডি ইমেজ লেখো... +Name[br]=srivañ ar skeudenn CD gant K3b ... +Name[bs]=Zapiši CD image koristeći K3b... +Name[ca]=Escriu imatge per a CD amb K3b... +Name[cs]=Vypálit obraz CD... +#SUSE-Overwrite Name[da]=Skriv cd-billede med K3b... +Name[da]=Skriv CD-billede med K3b... +Name[de]=CD-Abbild mit K3b brennen ... +Name[el]=Εγγραφή εικόνας CD με το K3b... +Name[es]=Escribir imagen de CD con K3b... +Name[et]=Kirjuta tõmmis K3b abil plaadile... +Name[eu]=Idatzi CD irudiak K3b-rekin... +Name[fr]=Graver une image CD avec K3b... +Name[he]=כתוב תבנית CD בעזרת K3b... +Name[hi]=के3बी के साथ सीडी इमेज लिखें... +Name[hu]=CD-képmásfájl írása a K3b-vel... +Name[is]=Skrifa diskmynd með K3b... +Name[it]=Scrivi immagine CD con K3b... +#SUSE-Overwrite Name[ja]=CD イメージを K3b で書き込み... +Name[ja]=K3bによるCDイメージの書込み... +Name[lt]=Įrašykite CD atvaizdą su K3b... +Name[mk]=Запишете CD-слика со K3b... +#SUSE-Overwrite Name[nb]=Skriv CD-bilde med K3b . . . +Name[nb]=Brenn diskbilde på CD med K3b... +Name[nl]=CD-image schrijven met K3b... +Name[pa]=K3b ਨਾਲ CD ਪ੍ਰਤੀਬਿੰਬ ਲਿਖੋ... +Name[pl]=Stwórz obraz płyty CD za pomocą K3b... +Name[pt]=Escrever uma Imagem de CD com o K3b... +Name[pt_BR]=Gravar Imagem em CD com K3b... +Name[ru]=Записать образ CD, используя K3b... +Name[sl]=Zapiši sliko CD-ja s K3b ... +Name[sr]=Направи одраз CD-а помоћу K3b-а... +Name[sr@Latn]=Napravi odraz CD-a pomoću K3b-a... +Name[sv]=Skriv cd-avbild med K3b... +Name[ta]=குறுந்தகட்டு நிழலுடன் K3bஐ உருவாக்குக... +Name[tr]=K3b ile CD Kalıbı yazdır... +Name[uk]=Записати штамп КД за допомогою K3b... +Name[zh_CN]=用 K3b 刻录 CD 映像... +Icon=k3b + +Name[fi]=Kirjoita CD-levynkuva K3b:llä +Name[km]=សរសេររូបភាពស៊ីឌីជាមួយ K3b... +Name[zh_TW]=以 K3b 燒錄 CD 映像... diff --git a/src/servicemenus/kdesktopSetAsBackground.desktop b/src/servicemenus/kdesktopSetAsBackground.desktop new file mode 100644 index 0000000..5606bb5 --- /dev/null +++ b/src/servicemenus/kdesktopSetAsBackground.desktop @@ -0,0 +1,201 @@ +[Desktop Entry] +ServiceTypes=image/* +Actions=setAsBackground;tileAsBackground; +X-KDE-Submenu=Set as Background +X-KDE-Submenu[af]=Stel as agtergrond +X-KDE-Submenu[be]=Зрабіць фонавым малюнкам +X-KDE-Submenu[bg]=Установяване като фон +X-KDE-Submenu[bn]=পশ্চাদ্পট হিসাবে বেছে নাও +X-KDE-Submenu[bs]=Postavi kao pozadinu +X-KDE-Submenu[ca]=Estableix com a fons +X-KDE-Submenu[cs]=Nastavit jako pozadí +X-KDE-Submenu[csb]=Ùstôwi jakno spòdlé +X-KDE-Submenu[da]=Sæt som baggrund +X-KDE-Submenu[de]=Als Hintergrund setzen +X-KDE-Submenu[el]=Ορισμός ως ταπετσαρία +X-KDE-Submenu[eo]=Agordu kiel fono +X-KDE-Submenu[es]=Establecer como fondo +X-KDE-Submenu[et]=Sea taustapildiks +X-KDE-Submenu[eu]=Ezarri atzeko plano gisa +X-KDE-Submenu[fa]=تنظیم به عنوان زمینه +X-KDE-Submenu[fi]=Aseta taustakuvaksi +X-KDE-Submenu[fr]=Définir comme arrière-plan +X-KDE-Submenu[fy]=As eftergrûn brûke +X-KDE-Submenu[gl]=Pór como Fondo de Escritório +X-KDE-Submenu[he]=קבע כרקע +X-KDE-Submenu[hr]=Postavi kao pozadinu +X-KDE-Submenu[hu]=Beállítás háttérképnek +X-KDE-Submenu[is]=Setja sem bakgrunn +X-KDE-Submenu[it]=Imposta come sfondo +X-KDE-Submenu[ja]=背景としてセット +X-KDE-Submenu[kk]=Ая ретінде орнату +X-KDE-Submenu[km]=កំណត់ជាផ្ទៃខាងក្រោយ +X-KDE-Submenu[lt]=Nustatyti fonu +X-KDE-Submenu[mk]=Постави како подлога +X-KDE-Submenu[nb]=Sett som bakgrunn +X-KDE-Submenu[nds]=As Achtergrund fastleggen +X-KDE-Submenu[ne]=पृष्ठभूमिको रुपमा सेट गर्छ +X-KDE-Submenu[nl]=Als achtergrond gebruiken +X-KDE-Submenu[nn]=Bruk som bakgrunn +X-KDE-Submenu[pa]=ਪਿੱਠਭੂਮੀ ਬਣਾਓ +X-KDE-Submenu[pl]=Ustaw jako tło +X-KDE-Submenu[pt]=Definir como Fundo +X-KDE-Submenu[pt_BR]=Configurar como Plano de fundo +X-KDE-Submenu[ro]=Setează ca fundal +X-KDE-Submenu[ru]=Сделать фоновым рисунком +X-KDE-Submenu[se]=Geavat duogášgovvan +X-KDE-Submenu[sk]=Nastaviť ako pozadie +X-KDE-Submenu[sl]=Nastavi kot ozadje +X-KDE-Submenu[sr]=Постави као позадину +X-KDE-Submenu[sr@Latn]=Postavi kao pozadinu +X-KDE-Submenu[sv]=Använd som bakgrund +X-KDE-Submenu[th]=ตั้งให้เป็นพื้นหลัง +X-KDE-Submenu[uk]=Встановити як тло +X-KDE-Submenu[uz]=Иш столига қўйиш +X-KDE-Submenu[vi]=Đặt làm Hình nền +X-KDE-Submenu[zh_CN]=设为背景 +X-KDE-Submenu[zh_TW]=設為背景 + +[Desktop Action setAsBackground] +Name=Centered +Name[af]=Gesentreer +Name[ar]=مركز +Name[be]=Пасярэдзіне +Name[bg]=Центрирано +Name[bn]=মাঝামাঝি +Name[br]=Kreizennet +Name[bs]=Centrirano +Name[ca]=Centrat +Name[cs]=Na střed +Name[csb]=Na westrzódkù +Name[cy]=Canoledig +Name[da]=Centreret +Name[de]=Zentriert +Name[el]=Κεντράρισμα +Name[en_GB]=Centred +Name[eo]=Meza +Name[es]=Centrado +Name[et]=Tsentreeritud +Name[eu]=Erdiratua +Name[fa]=مرکزی +Name[fi]=Keskitetty +Name[fr]=Centré +Name[fy]=sintraal setten +Name[ga]=Láraithe +Name[gl]=Centrado +Name[he]=ממורכז +Name[hi]=बीचों-बीच +Name[hr]=Sredinom +Name[hu]=Középre igazítva +Name[is]=Miðjað +Name[it]=Centrato +Name[ja]=中央 +Name[kk]=Ортаға +Name[km]=កណ្ដាល +Name[lt]=Centruota +Name[lv]=Centrēts +Name[mk]=Центриран +Name[ms]=Tengah +Name[mt]=Iċċentrat +Name[nb]=Sentrert +Name[nds]=In de Merrn +Name[ne]=केन्द्रित +Name[nl]=Gecentreerd +Name[nn]=Sentrert +Name[pa]=ਕੇਂਦਰੀ +Name[pl]=Wyśrodkowane +Name[pt]=Centrado +Name[pt_BR]=Centralizado +Name[ro]=Centrat +Name[ru]=По центру +Name[rw]=Biri hagati +Name[se]=Guovdut +Name[sk]=V strede +Name[sl]=Usrediščeno +Name[sr]=Центрирано +Name[sr@Latn]=Centrirano +Name[sv]=Centrerad +Name[ta]=மைய +Name[te]=మద్యన +Name[tg]=Марказӣ +Name[th]=จัดกลาง +Name[tr]=Ortalanmış +Name[tt]=Üzäkläşep +Name[uk]=По центру +Name[uz]=Марказда +Name[vi]=Giữa +Name[zh_CN]=居中 +Name[zh_TW]=置中 +Icon=background +Exec=dcop kdesktop KBackgroundIface setWallpaper %u 6 + +[Desktop Action tileAsBackground] +Name=Tiled +Name[af]=Geteël +Name[ar]=مبلّط +Name[be]=Расцягнутае +Name[bg]=Каскадно +Name[bn]=টাইল করা +Name[br]=Teolet +Name[bs]=Popločano +Name[ca]=Repetit +Name[cs]=Dlaždice +Name[csb]=Kachelkòwóné +Name[cy]=Teiledig +Name[da]=Fliselagt +Name[de]=Gekachelt +Name[el]=Σε παράθεση +Name[eo]=kahela +Name[es]=Mosaico +Name[et]=Paanidena +Name[eu]=Mosaikoa +Name[fa]=کاشیشده +Name[fi]=Vierekkäin +Name[fr]=Mosaïque +Name[fy]=Tegele +Name[ga]=Tilithe +Name[gl]=Mosaico +Name[he]=פרוש +Name[hi]=चटाई-दार +Name[hr]=Popločeno +Name[hu]=Mozaikszerűen +Name[is]=Flísað +Name[it]=Ripetuto +Name[ja]=タイル状 +Name[kk]=Қатарлап +Name[km]=ក្បឿង +Name[lt]=Iškloti +Name[mk]=Поплочен +Name[ms]=Berjubin +Name[mt]=Madum +Name[nb]=Flislagt +Name[nds]=Kachelt +Name[ne]=टायल गरिएको +Name[nl]=Tegels +Name[nn]=Jamsides +Name[pa]=ਤਣਿਆ +Name[pl]=Kafelkowane +Name[pt]=Mosaico +Name[pt_BR]=Ladrilhado +Name[ro]=Mozaic +Name[ru]=Черепицей +Name[rw]=Byudukaro +Name[se]=Bálddalaga +Name[sk]=Dlaždice +Name[sl]=Razdeljeno +Name[sr]=Поређано +Name[sr@Latn]=Poređano +Name[sv]=Sida vid sida +Name[ta]=பிண்ணனி +Name[te]=పలకలుగా +Name[tg]=Тахтасангӣ +Name[th]=ปูทั้งหน้าจอ +Name[tr]=Uzatılmış +Name[tt]=Bülengän +Name[uk]=Плиткою +Name[uz]=Кафель +Name[vi]=Xếp ngói +Name[zh_CN]=平铺 +Name[zh_TW]=拼貼 +Icon=background +Exec=dcop kdesktop KBackgroundIface setWallpaper %u 2 diff --git a/src/servicemenus/konqgwenview.desktop b/src/servicemenus/konqgwenview.desktop new file mode 100644 index 0000000..1354948 --- /dev/null +++ b/src/servicemenus/konqgwenview.desktop @@ -0,0 +1,53 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=inode/directory +Actions=gwenview; + +[Desktop Action gwenview] +Name=Browse with Gwenview +Name[ar]=تصفح بواسطة Gwenview +Name[bg]=Преглед с Gwenview +Name[br]=Furchal gant Gwenview +Name[bs]=Pregledaj sa Gwenview +Name[ca]=Navega amb el Gwenview +Name[cs]=Prohlížet pomocí Gwenview +Name[da]=Gennemse med Gwenview +Name[de]=Dateien mit Gwenview durchsehen +Name[el]=Εξερεύνηση με το Gwenview +Name[es]=Navegación con Gwenview +Name[et]=Lehitse kasutades Gwenview'd +Name[fi]=Katsele Gwenviewilla +Name[fr]=Naviguer avec Gwenview +Name[ga]=Brabhsáil le Gwenview +Name[gl]=Examinar con Gwenview +Name[he]=עיין בעזרת Gwenview +Name[hi]=ग्वेनव्यू के साथ ब्राउज़ करें +Name[hr]=Pretraži s Gwenview +Name[hu]=Böngészés a Gwenview-val +Name[is]=Skoða með Gwenview +Name[it]=Sfoglia con Gwenview +Name[ja]=Gwenview で閲覧 +Name[ka]=დათვალიერება Gwenview-ით +Name[ms]= Lungsur dengan Gwenview +Name[nl]=Bladeren met Gwenview +Name[pa]=Gwenview ਨਾਲ ਵੇਖੋ +Name[pl]=Przeglądaj za pomocą Gwenview +Name[pt]=Navegar com o Gwenview +Name[pt_BR]=Navegar com Gwenview +Name[ru]=Просмотреть в Gwenview +Name[sk]=Prehliadať s Gwenview +Name[sl]=Brskaj z Gwenview +Name[sr]=Прегледај помоћу Gwenview-а +Name[sr@Latn]=Pregledaj pomoću Gwenview-a +Name[sv]=Bläddra med Gwenview +Name[ta]=GWEN பார்வையை வைத்து தேடு +Name[tg]=Ҷустан бо НамоишиGwen +Name[tr]=Gwenview ile gözat +Name[uk]=Перегляд у Gwenview +Name[xh]=Khangela nge Gwenview +Name[xx]=xxBrowse with Gwenviewxx +Name[zh_CN]=用 Gwenview 浏览 +Name[zh_TW]=以 Gwenview 瀏覽 +Name[zu]=Cinga nge-Gwenview +Icon=gwenview +Exec=gwenview %u diff --git a/src/servicemenus/konsolehere.desktop b/src/servicemenus/konsolehere.desktop new file mode 100644 index 0000000..a46d1c3 --- /dev/null +++ b/src/servicemenus/konsolehere.desktop @@ -0,0 +1,123 @@ +[Desktop Entry] +ServiceTypes=inode/directory +Actions=openTerminalHere; +X-KDE-AuthorizeAction=shell_access +Encoding=UTF-8 +Type=Application + +Name=Konsole +Name[ar]=طرفية التحكم +Name[az]=Konsol +Name[be]=Кансоль +Name[bg]=Конзола +Name[bn]=কনসোল +Name[bs]=Konzola +Name[ca]=Consola +Name[csb]=Kònsola +Name[el]=Κονσόλα +Name[eo]=Konzolo +Name[et]=Konsool +Name[eu]=Kontsola +Name[he]=מסוף +Name[hi]=कंसोल +Name[hr]=Konzola +Name[is]=Skjáhermir +Name[ko]=KDE용 콘솔 +Name[lo]=ຄອນໂຊລ - K +Name[mk]=Конзола +Name[mn]=Консол +Name[nb]=Konsoll +Name[ne]=कन्सोल +Name[nn]=Konsoll +Name[pa]=ਕੰਨਸੋਲ +Name[pl]=Konsola +Name[ro]=Consolă +Name[ru]=Консоль +Name[se]=Konsolla +Name[sk]=Konzola +Name[sl]=Konzola +Name[ta]=கான்சோல் +Name[te]=కాన్సోల్ +Name[tg]=Консол +Name[th]=คอนโซล K +Name[zu]=Ikhonsoli + +[Desktop Action openTerminalHere] +Name=Open Terminal Here +Name[af]=Maak Terminaal Hier Oop +Name[ar]=إفتح مطراف سطر الأوامر هنا +Name[az]=Terminalı Burada Aç +Name[be]=Адкрыць тэрмінал тут +Name[bg]=Отваряне на конзола тук +Name[bn]=এখানে টার্মিনাল খোলো +Name[br]=Digeriñ un termenell amañ +Name[bs]=Otvori terminal ovdje +Name[ca]=Obre un terminal aquí +Name[cs]=Otevřít terminál zde +Name[csb]=Òtemknij tuwò terminal +Name[cy]=Agor Terfynell Yma +Name[da]=Åbn terminal her +Name[de]=Terminal öffnen +Name[el]=Άνοιγμα τερματικού εδώ +Name[eo]=Lanĉu terminalon ĉi tie +Name[es]=Abrir terminal aquí +Name[et]=Ava siin terminal +Name[eu]=Ireki terminala hemen +Name[fa]=باز کردن پایانه در اینجا +Name[fi]=Avaa komentoikkuna tähän +Name[fr]=Ouvrir un terminal ici +Name[fy]=Terminal iepenje +Name[ga]=Oscail Teirminéal Anseo +Name[gl]=Abrir Terminal Aqui +Name[he]=פתח מסוף כאן +Name[hi]=टर्मिनल यहाँ खोलें +Name[hr]=Ovdje otvori terminal +Name[hu]=Parancsértelmező megnyitása itt +Name[is]=Opna skjáhermi hér +Name[it]=Apri terminale qui +Name[ja]=ここでターミナルを開く +Name[kk]=Терминалды ашу +Name[km]=បើកស្ថានីយទីនេះ +Name[lo]=ເທີມິເນລຂອງ X +Name[lt]=Atverti čia terminalą +Name[lv]=Atvērt termināli šeit +Name[mk]=Отвори терминал тука +Name[mn]=Терминал нээх +Name[ms]=Buka Terminal Di Sini +Name[mt]=Iftaħ terminal hawn +Name[nb]=Åpne terminal her +Name[nds]=Terminal hier opmaken +Name[ne]=यहाँ टर्मिनल खोल्नुहोस् +Name[nl]=Terminal openen +Name[nn]=Opna terminal her +Name[nso]=Bula mafelelo Mo +Name[pa]=ਟਰਮੀਨਲ ਇੱਥੇ ਖੋਲੋ +Name[pl]=Otwórz tutaj terminal +Name[pt]=Abrir um Terminal Aqui +Name[pt_BR]=Abrir Terminal Aqui +Name[ro]=Deschide un terminal aici +Name[ru]=Открыть терминал в этой папке +Name[rw]= Gufungura Igihera Hano +Name[se]=Raba terminála dáppe +Name[sk]=Tu otvoriť terminál +Name[sl]=Tu odpri terminal +Name[sr]=Отвори терминал овде +Name[sr@Latn]=Otvori terminal ovde +Name[ss]=Vula sikhungo lapha +Name[sv]=Öppna terminal här +Name[ta]=முனைய இங்கே திற +Name[tg]=Терминалро дар инҷо боз кунед +Name[th]=เปิดเทอร์มินัลที่นี่ +Name[tr]=Terminali Burada Aç +Name[tt]=Terminalnı Monda Açası +Name[uk]=Відкрити термінал +Name[uz]=Терминални шу ерда очиш +Name[ven]=Vulani theminala hafhano +Name[vi]=Mở một Thiết bị cuối ở Đây +Name[wa]=Drovi on terminå chal +Name[xh]=Vula Isiphelo Sendlela Apha +Name[zh_CN]=在此打开终端 +Name[zh_TW]=在這裡開啟終端機 +Name[zu]=Vula ithuluzi langaphandle lapha +Icon=konsole +Exec=konsole --workdir %f diff --git a/src/servicemenus/mail_as_attachment.desktop b/src/servicemenus/mail_as_attachment.desktop new file mode 100644 index 0000000..f8a7c23 --- /dev/null +++ b/src/servicemenus/mail_as_attachment.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=all/allfiles +Actions=mail_as_attachment + +[Desktop Action mail_as_attachment] +Name=Mail as Attachment... +Name[de]=Verschicken als Anhang... +Icon=mail_send +Exec=kmail --attach %U diff --git a/src/servicemenus/media_eject.desktop b/src/servicemenus/media_eject.desktop new file mode 100644 index 0000000..151790f --- /dev/null +++ b/src/servicemenus/media_eject.desktop @@ -0,0 +1,158 @@ +[Desktop Entry] +ServiceTypes=media/cdrom_mounted,media/cdrom_unmounted,media/cdwriter_mounted,media/cdwriter_unmounted,media/dvd_mounted,media/dvd_unmounted,media/audiocd,media/blankcd,media/blankdvd,media/dvdvideo,media/svcd,media/vcd +Actions=MediaEject; +X-KDE-Priority=TopLevel +X-KDE-MediaNotifierHide=true + +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +[Desktop Action MediaEject] +Name=Eject +Name[af]=Uitskiet +Name[ar]=اخراج +Name[az]=Çıxart +Name[be]=Выняць +Name[bg]=Изваждане +Name[bn]=ইজেক্ট +Name[br]=Stlepel +Name[bs]=Izbaci +Name[ca]=Expulsa +Name[cs]=Vysunout +Name[cy]=Allfwrw +Name[da]=Skub ud +Name[de]=Auswerfen +Name[el]=Εξαγωγή +Name[eo]=Eligo +Name[es]=Expulsar +Name[et]=Väljastamine +Name[eu]=Kanporatu +Name[fa]=اخراج +Name[fi]=Poista +Name[fr]=Éjecter +Name[fy]=Utsmytknop +Name[ga]=Díchuir +Name[gl]=Expulsar +Name[he]=הוצא +Name[hi]=बाहर +Name[hr]=Izbaci +#SUSE-Overwrite Name[hu]=Kidobás +Name[hu]=Kiadás +Name[is]=Henda út +Name[it]=Espelli +Name[ja]=取り出し +#SUSE-Overwrite Name[km]=ច្រានចេញ +Name[km]=ច្រានចេញ +Name[ko]=꺼내기 +Name[lo]=ເອົາແຜ່ນອອກ +Name[lt]=Išmesti +Name[lv]=Izņemt +Name[mk]=Извади +Name[mn]=Гаргах +Name[ms]=Lenting +Name[mt]=Iftaħ +Name[nb]=Løs ut +Name[nds]=Rutsmieten +Name[nl]=Uitwerpen +Name[nn]=Løys ut +Name[nso]=Ntsha +Name[oc]=Expulsa +Name[pa]=ਬਾਹਰ ਕੱਢੋ +Name[pl]=Wysuń +Name[pt]=Ejectar +Name[pt_BR]=Ejetar +Name[ro]=Ejectează +Name[ru]=Извлечь CD +Name[rw]=Gusohora +Name[se]=Bálkes olggos +Name[sk]=Vysunúť +Name[sl]=Izvrzi +Name[sr]=Избаци +Name[sr@Latn]=Izbaci +Name[ss]=Khafuna +Name[sv]=Mata ut +Name[ta]=வெளித்தள் +Name[tg]=Ихроҷ +Name[th]=เอาแผ่นออก +Name[tr]=Çıkart +Name[tt]=Çığar +Name[uk]=Виштовхнути +Name[uz]=Чиқариш +Name[ven]=Bvisa +Name[vi]=Đẩy ra +Name[wa]=Fé rexhe +Name[xh]=Khuphela ngaphandle +Name[zh_CN]=弹出 +Name[zh_TW]=退出 +Name[zu]=Khipha +Exec=kio_media_mounthelper -e %u + + diff --git a/src/servicemenus/media_mount.desktop b/src/servicemenus/media_mount.desktop new file mode 100644 index 0000000..12fa545 --- /dev/null +++ b/src/servicemenus/media_mount.desktop @@ -0,0 +1,155 @@ +[Desktop Entry] +ServiceTypes=media/cdrom_unmounted,media/cdwriter_unmounted,media/dvd_unmounted,media/floppy5_unmounted,media/floppy_unmounted,media/hdd_unmounted,media/nfs_unmounted,media/removable_unmounted,media/smb_unmounted,media/zip_unmounted,media/camera_unmounted +Actions=MediaMount; +X-KDE-Priority=TopLevel +X-KDE-MediaNotifierHide=true + +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +[Desktop Action MediaMount] +Name=Mount +Name[af]=Koppel +Name[ar]=حمّل +Name[az]=Bağla +Name[bg]=Монтиране +Name[bn]=মাউন্ট +Name[br]=Marc'hañ +Name[bs]=Montiraj +Name[ca]=Munta +Name[cs]=Připojit +Name[cy]=Gosod +Name[da]=Montér +Name[de]=Laufwerk einbinden +Name[el]=Προσάρτηση +Name[eo]=Kroĉo +Name[es]=Montar +Name[et]=Ühenda +Name[eu]=Muntatu +Name[fa]=سوارکردن +Name[fi]=Liitä +Name[fr]=Monter +Name[fy]=Oankeppelje (mount) +Name[ga]=Feistigh +Name[gl]=Montar +Name[he]=חבר +Name[hi]=माउन्ट +Name[hr]=Montiraj +Name[hsb]=montować +Name[hu]=Csatlakoztatás +Name[is]=Tengja +Name[it]=Monta +Name[ja]=マウント +#SUSE-Overwrite Name[km]=រៀបចំ +Name[km]=ម៉ោន +Name[lo]=ຈໍພາບ +Name[lt]=Montuoti +Name[lv]=Piemontēt +Name[mk]=Монтирај +Name[mn]=Залгах +Name[ms]=Lekap +Name[mt]=Immonta +Name[nb]=Monter +Name[nds]=Inhangen +Name[nl]=Aankoppelen (mount) +Name[nn]=Monter +Name[nso]=Nameletsa +#SUSE-Overwrite Name[pa]=ਮਾਊਟ +Name[pa]=ਮਾਊਂਟ +Name[pl]=Zamontuj +Name[pt]=Montar +Name[pt_BR]=Montar +Name[ro]=Montează +Name[ru]=Монтировать +Name[rw]=Gushyiramo +Name[se]=Čana +Name[sk]=Pripojiť +Name[sl]=Priklopi +Name[sr]=Монтирај +Name[sr@Latn]=Montiraj +Name[sv]=Montera +Name[ta]=ஏற்று +Name[tg]=Васл кунӣ +Name[th]=เม้าทน์ +Name[tr]=Bağla +Name[tt]=Bäyläp quy +Name[uk]=Змонтувати +Name[uz]=Улаш +Name[ven]=Gonya +Name[vi]=Gắn kết +Name[wa]=Monter +Name[xh]=Layisha +Name[zh_CN]=挂载 +Name[zh_TW]=掛載 +Name[zu]=Yenyusa +Exec=kio_media_mounthelper -m %u + + diff --git a/src/servicemenus/media_realfolder.desktop b/src/servicemenus/media_realfolder.desktop new file mode 100644 index 0000000..b53f546 --- /dev/null +++ b/src/servicemenus/media_realfolder.desktop @@ -0,0 +1,114 @@ +[Desktop Entry] +ServiceTypes=media/cdrom_mounted,media/cdwriter_mounted,media/dvd_mounted,media/floppy5_mounted,media/floppy_mounted,media/hdd_mounted,media/nfs_mounted,media/smb_mounted,media/removable_mounted,media/zip_mounted +Actions=MediaRealFolder +X-KDE-Priority=TopLevel +X-KDE-MediaNotifierHide=true + +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +[Desktop Action MediaRealFolder] +Name=Open Medium System Folder +Name[ca]=Obre la carpeta de mitjans del sistema +Name[cs]=Otevřít systémovou složku média +Name[da]=Åbn medium-system-mappen +Name[de]=Systemordner des Mediums öffnen +Name[el]=Άνοιγμα του φακέλου συστήματος του μέσου +Name[es]=Abrir la carpeta del administrador de medios... +Name[et]=Ava andmekandja süsteemi kataloog +Name[eu]=Ireki euskarriaren kudeatzailea +Name[fi]=Avaa mediajärjestelmän kansio +Name[fr]=Dossier système d'ouverture de média +Name[he]=פתח את תיקיית מדיית המערכת +Name[hu]=A médiaanyagok rendszerkönyvtárának megnyitása +Name[is]=Opin miðils kerfismappa +Name[it]=Cartella di sistema per l'apertura di supporti +Name[lt]=Atverti sisteminį įrenginio aplanką +Name[nb]=Åpne systemmappe for medie +Name[nl]=Systeemmap medium openen +#SUSE-Overwrite Name[pa]=ਮੀਡੀਅਮ ਸਿਸਟਮ ਫੋਲਡਰ ਖੋਲੋ +Name[pa]=ਮੀਡਿਅਮ ਸਿਸਟਮ ਫੋਲਡਰ ਖੋਲੋ +Name[pl]=Otwórz folder systemowy mediów +Name[pt]=Pasta de Sistema Média Aberto +Name[pt_BR]=Abrir a Pasta de Mídias do Sistema +Name[ru]=Открыть системную папку +Name[sr]=Отвори системску фасциклу медијума +Name[sr@Latn]=Otvori sistemsku fasciklu medijuma +Name[sv]=Öppna mediumsystemkatalog +Name[uk]=Відкрити системну теку носія +Name[zh_CN]=打开介质系统文件夹 +Exec=kio_media_realfolder %u + + +Name[bg]=Системна папка на Open Medium +Name[ja]=オープン メディアシステムフォルダ +Name[km]=បើកថតប្រព័ន្ធមេឌៀ +Name[zh_TW]=開啟媒體系統資料夾 diff --git a/src/servicemenus/media_safelyremove.desktop b/src/servicemenus/media_safelyremove.desktop new file mode 100644 index 0000000..7d1ccc2 --- /dev/null +++ b/src/servicemenus/media_safelyremove.desktop @@ -0,0 +1,132 @@ +[Desktop Entry] +ServiceTypes=media/removable_mounted,media/removable_unmounted,media/camera_mounted,media/camera_unmounted +Actions=MediaSafelyRemove; +X-KDE-Priority=TopLevel +X-KDE-MediaNotifierHide=true + +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +[Desktop Action MediaSafelyRemove] +Name=Safely Remove +Name[af]=Verwyder veilig +Name[bg]=Безопасно изваждане +Name[bn]=নিরাপদভাবে সরাও +Name[ca]=Extreu amb seguretat +Name[cs]=Bezpečně odstranit +Name[da]=Fjern sikkert +Name[de]=Sicher entfernen +Name[el]=Ασφαλής αφαίρεση +Name[es]=Extracción segura +Name[et]=Eemalda turvaliselt +Name[eu]=Atera arriskurik gabe +Name[fi]=Poista turvallisesti +Name[fr]=Enlever en toute sécurité +Name[fy]=Feilich ferwiderje +Name[gl]=Eliminar de Maneira Segura +Name[he]=שליפה בבטחה +Name[hu]=Biztonságos leválasztás +Name[is]=Fjarlægja öruggt +Name[it]=Rimozione sicura +Name[ja]=安全に取り除く +#SUSE-Overwrite Name[km]=យកចេញដោយសុវត្ថិភាព +Name[km]=យកចេញដោយសុវត្ថិភាព +Name[lt]=Saugiai pašalinti +Name[mk]=Отстрани безбедно +Name[ms]=Buang Dengan Selamat +Name[nb]=Sikker fjerning +Name[nds]=Seker rutnehmen +Name[nl]=Veilig verwijderen +Name[nn]=Trygg fjerning +#SUSE-Overwrite Name[pa]=ਸੁਰੱਖਿਅਤ ਹਟਾਓ +Name[pa]=ਸੁਰੱਖਿਅਤ ਰੂਪ 'ਚ ਹਟਾਓ +Name[pl]=Usuń w sposób bezpieczny +Name[pt]=Retirar com Segurança +Name[pt_BR]=Remover de Modo Seguro +Name[ro]=Scoate în siguranţă +Name[ru]=Безопасно извлечь +Name[rw]=Gukuramo Neza +Name[se]=Dorvvošlaš eretváldin +Name[sl]=Varno odstrani +Name[sr]=Безбедно уклони +Name[sr@Latn]=Bezbedno ukloni +Name[sv]=Säker urkoppling +Name[ta]=பாதுகாப்பாக நீக்கு +Name[th]=ถอดออกได้อย่างปลอดภัย +Name[tr]=Güvenli Kaldır +Name[tt]=İmin Çığaru +Name[uk]=Безпечно вилучити +Name[uz]=Эҳтиётлик билан узиш +Name[zh_CN]=安全删除 +Name[zh_TW]=安全的移除 +Exec=kio_media_mounthelper -s %u + + diff --git a/src/servicemenus/media_unmount.desktop b/src/servicemenus/media_unmount.desktop new file mode 100644 index 0000000..b70e3a5 --- /dev/null +++ b/src/servicemenus/media_unmount.desktop @@ -0,0 +1,155 @@ +[Desktop Entry] +ServiceTypes=media/cdrom_mounted,media/cdwriter_mounted,media/dvd_mounted,media/floppy5_mounted,media/floppy_mounted,media/hdd_mounted,media/nfs_mounted,media/smb_mounted,media/zip_mounted,media/vcd,media/svcd,media/dvdvideo +Actions=MediaUnmount; +X-KDE-Priority=TopLevel +X-KDE-MediaNotifierHide=true + +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +X-SuSE-translate=true +[Desktop Action MediaUnmount] +Name=Unmount +Name[af]=Ontkoppel +Name[ar]=أزل التحميل +Name[az]=Ayır +Name[bg]=Демонтиране +Name[bn]=আনমাউন্ট +Name[br]=Divarc'hañ +Name[bs]=Demontiraj +Name[ca]= Desmunta +Name[cs]=Odpojit +Name[cy]=Dadosod +Name[da]=Afmontér +Name[de]=Laufwerkeinbindung lösen +Name[el]=Αποπροσάρτηση +Name[eo]=Malkroĉo +Name[es]=Desmontar +Name[et]=Lahuta +Name[eu]=Desmuntatu +Name[fa]=پیاده کردن +Name[fi]=Irrota +Name[fr]=Démonter (enlever de l'arborescence Linux) +Name[fy]=Ofkeppelje (unmount) +Name[ga]=Dífheistigh +Name[gl]=Desmontar +Name[he]=נתק +Name[hi]=अनमाउन्ट +Name[hr]=Demontiraj +Name[hsb]=Wotmontować +Name[hu]=Leválasztás +Name[is]=Aftengja +Name[it]=Smonta +Name[ja]=マウント解除 +#SUSE-Overwrite Name[km]=មិនរៀបចំ +Name[km]=មិនម៉ោន +Name[lo]=ຫັງກາລີ +Name[lt]=Išmontuoti +Name[lv]=Nomontēt +Name[mk]=Демонтирај +Name[mn]=Салгах +Name[ms]=Nyahlekap +Name[mt]=Żmonta +Name[nb]=Avmonter +Name[nds]=Afhangen +Name[nl]=Afkoppelen (unmount) +Name[nn]=Avmonter +Name[nso]=Theosa +#SUSE-Overwrite Name[pa]=ਅਨਮਾਉਟ +Name[pa]=ਅਣ-ਮਾਊਂਟ +Name[pl]=Odmontuj +Name[pt]=Desmontar +Name[pt_BR]=Desmontar +Name[ro]=Demontează +Name[ru]=Отмонтировать +Name[rw]=Gukuramo +Name[se]=Gálgga +Name[sk]=Odpojiť +Name[sl]=Odklopi +Name[sr]=Демонтирај +Name[sr@Latn]=Demontiraj +Name[sv]=Avmontera +Name[ta]=வெளியேற்று +Name[tg]=Ҷудо кунӣ +Name[th]=ยกเลิกเม้าทน์ +Name[tr]=Ayır +Name[tt]=Bäyläwne çiş +Name[uk]=Демонтувати +Name[uz]=Узиш +Name[ven]=Usa gonya +Name[vi]=Gỡ +Name[wa]=Dismonter +Name[xh]=Sukuyilayisha +Name[zh_CN]=卸载 +Name[zh_TW]=未掛載 +Name[zu]=Yehlisa +Exec=kio_media_mounthelper -u %u + + diff --git a/src/servicemenus/open_in_digikam.desktop b/src/servicemenus/open_in_digikam.desktop new file mode 100644 index 0000000..658df91 --- /dev/null +++ b/src/servicemenus/open_in_digikam.desktop @@ -0,0 +1,29 @@ +[Desktop Action OpenDigikam] +Exec=digikam --download-from %u +Icon=digikam +Name=Open in Digikam + +Name[bg]=Отваряне в digiKam +Name[cs]=Otevřít v digiKamu +Name[el]=Άνοιξε στο Digikam +Name[es]=Abrir en digiKam +Name[fi]=Avaa digiKamissa +Name[fr]=Ouvert dans Digikam +Name[hu]=Megnyitás Digikammel +Name[ja]=Digikamでオープン +Name[km]=បើកក្នុង Digikam +Name[nb]=Åpne i digiKam +Name[nl]=Openen in digiKam +Name[pa]=ਡਿਜ਼ੀਕੈਮ 'ਚ ਖੋਲੋ +Name[pl]=Otwórz w Digikam +Name[pt]=Abrir no DigiKam +Name[pt_BR]=Aberto no Digikam +Name[sv]=Öppna med Digikam +Name[uk]=Відкрити в Digikam +Name[zh_CN]=在 Digikam 中打开 +Name[zh_TW]=在 Digikam 中開啟 +[Desktop Entry] +Actions=OpenDigikam; +ServiceTypes=media/gphoto2camera,media/camera_mounted,media/camera_unmounted + +X-SuSE-translate=true diff --git a/src/servicemenus/run_as_root.desktop b/src/servicemenus/run_as_root.desktop new file mode 100644 index 0000000..6ba05c0 --- /dev/null +++ b/src/servicemenus/run_as_root.desktop @@ -0,0 +1,17 @@ +[Desktop Entry] +ServiceTypes=application/x-executable,application/x-shellscript,application/x-python,application/x-perl +Actions=runassu + +[Desktop Action runassu] +Name=Run as Root +Name[de]=Als root ausführen +Name[cs]=Spustit jako root +Name[sk]=Spustiť ako root +Name[hu]=Futtatás rootként +Name[fr]=Lancer en root +Name[el]=Εκτέλεση ως Υπερχρήστη�Name[es]=Ejecutar como Root +Name[pt_br]=Executar como Root +Name[it]=Esegui come Root +Name[pl]=Uruchom jako root +Icon=kfm +Exec=kdesu -c diff --git a/src/servicemenus/smb2rdc.desktop b/src/servicemenus/smb2rdc.desktop new file mode 100644 index 0000000..4b55dea --- /dev/null +++ b/src/servicemenus/smb2rdc.desktop @@ -0,0 +1,55 @@ +# KDE Config File +[Desktop Entry] +ServiceTypes=application/x-smb-server +Actions=smb2rdc + +[Desktop Action smb2rdc] +Name=Open Remote Desktop Connection to This Machine +Name[be]=Адкрыць аддаленае злучэнне з кампутарам +Name[bg]=Връзка с отдалечен работно място с избрания компютър +Name[bn]=এই মেশিনে প্রত্যন্ত ডেস্কটপের সংযোগ খোলো +Name[bs]=Otvori Remote Desktop vezu na ovaj računar +Name[ca]=Obre una connexió remota d'escriptori a aquesta màquina +Name[cs]=Otevřít vzdálené připojení plochy k tomuto počítači +Name[da]=Åbn ekstern desktopforbindelse til denne maskine +Name[de]=Verbindung zur Arbeitsfläche dieses Rechners herstellen +Name[el]=Δημιουργία σύνδεσης σε απομακρυσμένη επιφάνεια εργασίας σε αυτό το μηχάνημα +Name[es]=Abrir conexión remota de escritorio a este sistema +Name[et]=Kaugtöölaua ühenduse avamine sellesse arvutisse +Name[eu]=Open Remote Desktop konexioa makina honetara +Name[fa]=باز کردن اتصال رومیزی راه دور برای این ماشین +Name[fi]=Avaa etätyöpöytäyhteys tähän koneeseen +Name[fr]=Ouvrir une connexion distante au bureau de cette machine +Name[gl]=Abrir Conexión Remota de Escritorio a Esta Máquina +Name[he]=פתח חיבור שולחן עבודה מרוחק למכונה זו +Name[hu]=Távoli munkaasztal nyitása itt +Name[is]=Opna fjarlæga skjáborðtengingu til þessarar vélar +Name[it]=Apri connessione a desktop remoto a questa macchina +Name[ja]=このホストへリモートデスクトップ接続を開く +Name[kk]=Осы компьютердегі үстелге қашық қосылымды ашу +Name[km]=បើកការតភ្ជាបផ្ទៃតុពីចម្ងាយទៅម៉ាស៊ីននេះ +Name[lt]=Užmegzti nutolusio darbastalio prijungimą prie šio kompiuterio +Name[nb]=Åpne fjerntilkobling til skrivebord til denne maskinen +Name[nds]=Schriefdisch-Feernverbinnen na dissen Reekner opmaken +Name[ne]=यो मेशिनमा टाढाको डेस्कटप जडान खोल्नुहोस् +Name[nl]=Externe bureaubladverbinding met deze computer openen +Name[nn]=Opna samband til skrivebordet over nettverket til denne maskina +Name[pa]=ਇਹ ਮਸ਼ੀਨ ਲਈ ਰਿਮੋਟ ਡੈਸਕਟਾਪ ਕੁਨੈਕਸ਼ਨ ਖੋਲ੍ਹੋ +Name[pl]=Otwórz zdalne połączenie z pulpitem na tej maszynie +Name[pt]=Abrir Ligação Remota a Ecrã para Este Computador +Name[pt_BR]=Abre Conexões Remotas para Essa Máquina +Name[ru]=Открыть соединение Remote Desktop с этой машиной +Name[sk]=Otvorí spojenie na vzdialenú pracovnú plochu na tomto počítači +Name[sl]=Odpri povezavo z oddaljenim namizjem na tem računalniku +Name[sr]=Отвори удаљену везу са радном површином на овој машини +Name[sr@Latn]=Otvori udaljenu vezu sa radnom površinom na ovoj mašini +Name[sv]=Öppna fjärrskrivbordsanslutning till den här datorn +Name[tr]=Bu makinaya Uzak Masaüstü Bağlantısı aç +Name[uk]=Відкрити з'єднання з віддаленою стільницею до цього комп'ютера +Name[zh_CN]=打开到此计算机的远程桌面连接 +Name[zh_HK]=開放遠端桌面連線到這電腦 +Name[zh_TW]=在此主機上開啟遠端桌面 +Exec=krdc %u +Icon=krdc + + diff --git a/src/servicemenus/text-ada-print.desktop b/src/servicemenus/text-ada-print.desktop new file mode 100644 index 0000000..c0c04c0 --- /dev/null +++ b/src/servicemenus/text-ada-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-adasrc +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-c++-print.desktop b/src/servicemenus/text-c++-print.desktop new file mode 100644 index 0000000..f34dee4 --- /dev/null +++ b/src/servicemenus/text-c++-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-c++src +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-c++h-print.desktop b/src/servicemenus/text-c++h-print.desktop new file mode 100644 index 0000000..01a8bfc --- /dev/null +++ b/src/servicemenus/text-c++h-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-c++hdr +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-ch-print.desktop b/src/servicemenus/text-ch-print.desktop new file mode 100644 index 0000000..cd3f587 --- /dev/null +++ b/src/servicemenus/text-ch-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-chdr +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-css-print.desktop b/src/servicemenus/text-css-print.desktop new file mode 100644 index 0000000..3659747 --- /dev/null +++ b/src/servicemenus/text-css-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/css +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-diff-print.desktop b/src/servicemenus/text-diff-print.desktop new file mode 100644 index 0000000..a0c39f0 --- /dev/null +++ b/src/servicemenus/text-diff-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-diff +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-html-print.desktop b/src/servicemenus/text-html-print.desktop new file mode 100644 index 0000000..edf95e6 --- /dev/null +++ b/src/servicemenus/text-html-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/html +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-java-print.desktop b/src/servicemenus/text-java-print.desktop new file mode 100644 index 0000000..96dd0d6 --- /dev/null +++ b/src/servicemenus/text-java-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-java +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-log-print.desktop b/src/servicemenus/text-log-print.desktop new file mode 100644 index 0000000..ad44325 --- /dev/null +++ b/src/servicemenus/text-log-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-log +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-makefile-print.desktop b/src/servicemenus/text-makefile-print.desktop new file mode 100644 index 0000000..4f2d679 --- /dev/null +++ b/src/servicemenus/text-makefile-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-makefile +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-pas-print.desktop b/src/servicemenus/text-pas-print.desktop new file mode 100644 index 0000000..e9e303b --- /dev/null +++ b/src/servicemenus/text-pas-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-pascal +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-perl-print.desktop b/src/servicemenus/text-perl-print.desktop new file mode 100644 index 0000000..effdc4a --- /dev/null +++ b/src/servicemenus/text-perl-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-perl +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-print.desktop b/src/servicemenus/text-print.desktop new file mode 100644 index 0000000..2b72284 --- /dev/null +++ b/src/servicemenus/text-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/plain +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-python-print.desktop b/src/servicemenus/text-python-print.desktop new file mode 100644 index 0000000..660f5de --- /dev/null +++ b/src/servicemenus/text-python-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-python +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-tcl-print.desktop b/src/servicemenus/text-tcl-print.desktop new file mode 100644 index 0000000..ce786d1 --- /dev/null +++ b/src/servicemenus/text-tcl-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-tcl +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-tex-print.desktop b/src/servicemenus/text-tex-print.desktop new file mode 100644 index 0000000..32e9c3c --- /dev/null +++ b/src/servicemenus/text-tex-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-tex +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-xml-print.desktop b/src/servicemenus/text-xml-print.desktop new file mode 100644 index 0000000..ad4e8ed --- /dev/null +++ b/src/servicemenus/text-xml-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-xml +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/servicemenus/text-xslt-print.desktop b/src/servicemenus/text-xslt-print.desktop new file mode 100644 index 0000000..c482c0a --- /dev/null +++ b/src/servicemenus/text-xslt-print.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Encoding=UTF-8 +ServiceTypes=text/x-xslt +Actions=Print; + +[Desktop Action Print] +Name=Print... +Name[af]=Druk... +Name[ar]=طباعة... +Name[az]=Çap et... +Name[be]=Друкаваць... +Name[bg]=Печат... +Name[bn]=ছাপাও... +Name[br]=Moulañ ... +Name[bs]=Štampaj... +Name[ca]=Imprimeix... +Name[cs]=Tisknout... +Name[csb]=Drëkùjë... +Name[cy]=Argraffu... +Name[da]=Udskriv... +Name[de]=Drucken ... +Name[el]=Εκτύπωση... +Name[eo]=Printi... +Name[es]=Imprimir... +Name[et]=Trüki... +Name[eu]=Inprimatu... +Name[fa]=چاپ... +Name[fi]=Tulosta... +Name[fr]=Imprimer... +Name[fy]=Printsje... +Name[ga]=Priontáil... +Name[gl]=Imprimir... +Name[he]=הדפס... +Name[hi]=छापें... +Name[hr]=Ispiši... +Name[hu]=Nyomtatás... +Name[is]=Prenta... +Name[it]=Stampa... +Name[ja]=印刷... +Name[kk]=Басып шығару... +Name[km]=បោះពុម្ព... +Name[lv]=Drukāt... +Name[mk]=Печати... +Name[ms]=Cetak... +Name[mt]=Ipprintja... +Name[nb]=Skriv ut... +Name[nds]=Drucken... +Name[ne]=मुद्रण... +Name[nl]=Afdrukken... +Name[nn]=Skriv ut ... +Name[pa]=ਛਪਾਈ... +Name[pl]=Drukuj... +Name[pt]=Imprimir... +Name[pt_BR]=Imprimir... +Name[ro]=Tipăreşte... +Name[ru]=Печать... +Name[rw]=Gucapa... +Name[se]=Čálit … +Name[sk]=Tlač... +Name[sl]=Natisni ... +Name[sr]=Штампа... +Name[sr@Latn]=Štampa... +Name[sv]=Skriv ut... +Name[ta]=அச்சடி... +Name[te]=ప్రచురించు... +Name[tg]=Чоп кардан... +Name[th]=พิมพ์... +Name[tr]=Yazdır... +Name[tt]=Bastıru... +Name[uk]=Друк... +Name[uz]=Босиб чиқариш +Name[vi]=In ấn... +Name[zh_CN]=打印... +Name[zh_TW]=列印... +Exec=kprinter -t %n --caption %n --icon %i --miniicon %m %U +Icon=filequickprint diff --git a/src/settingspagebase.cpp b/src/settingspagebase.cpp new file mode 100644 index 0000000..244242c --- /dev/null +++ b/src/settingspagebase.cpp @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "settingspagebase.h" + +SettingsPageBase::SettingsPageBase(QWidget* parent) : + QWidget(parent) +{ +} + +SettingsPageBase::~SettingsPageBase() +{ +} + + +#include "settingspagebase.moc" diff --git a/src/settingspagebase.h b/src/settingspagebase.h new file mode 100644 index 0000000..0d4ec54 --- /dev/null +++ b/src/settingspagebase.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef SETTINGSPAGEBASE_H +#define SETTINGSPAGEBASE_H + +#include <qwidget.h> + +/** + * @brief Base class for the settings pages of the Dolphin settings dialog. + * + * @author Peter Penz <peter.penz@gmx.at> + */ +class SettingsPageBase : public QWidget +{ + Q_OBJECT + +public: + SettingsPageBase(QWidget* parent); + virtual ~SettingsPageBase(); + + /** + * Must be implemented by a derived class to + * persistently store the settings. + */ + virtual void applySettings() = 0; +}; + +#endif diff --git a/src/sidebarpage.cpp b/src/sidebarpage.cpp new file mode 100644 index 0000000..ab057d1 --- /dev/null +++ b/src/sidebarpage.cpp @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2006 by Cvetoslav Ludmiloff <ludmiloff@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "sidebarpage.h" +#include "dolphin.h" + +SidebarPage::SidebarPage(QWidget* parent) : + QWidget(parent) +{ + connect(&Dolphin::mainWin(), SIGNAL(activeViewChanged()), + this, SLOT(activeViewChanged())); +} + +SidebarPage::~SidebarPage() +{ +} + +void SidebarPage::activeViewChanged() +{ +} diff --git a/src/sidebarpage.h b/src/sidebarpage.h new file mode 100644 index 0000000..e136016 --- /dev/null +++ b/src/sidebarpage.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2006 by Cvetoslav Ludmiloff <ludmiloff@gmail.com> * + * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef _SIDEBARPAGE_H_ +#define _SIDEBARPAGE_H_ + +#include <qwidget.h> + +class Sidebar; + +/** + * @brief Base widget for all pages that can be embedded into the Sidebar. + * + * TODO + */ +class SidebarPage : public QWidget +{ + Q_OBJECT + +public: + SidebarPage(QWidget* parent); + virtual ~SidebarPage(); + +protected slots: + /** + * Is invoked whenever the active view from Dolphin has been changed. + * The active view can be retrieved by Dolphin::mainWin().activeView(); + */ + virtual void activeViewChanged(); +}; + +#endif // _SIDEBARPAGE_H_ diff --git a/src/sidebars.cpp b/src/sidebars.cpp new file mode 100644 index 0000000..6d401be --- /dev/null +++ b/src/sidebars.cpp @@ -0,0 +1,190 @@ +/*************************************************************************** + * Copyright (C) 2007 by Marcel Juhnke * + * marrat@marrat.homelinux.org * + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include <qlayout.h> +#include <qpixmap.h> +#include <kiconloader.h> +#include <klocale.h> +#include <qcombobox.h> + +#include "dolphinsettings.h" +#include "sidebarssettings.h" +#include "bookmarkssidebarpage.h" +#include "infosidebarpage.h" +#include "sidebars.h" + +#include <assert.h> + +/** + * + * @param parent + */ +leftSidebar::leftSidebar(QWidget* parent) : + QWidget(parent), + m_pagesSelector(0), + m_page(0), + m_layout(0) +{ + m_layout = new QVBoxLayout(this); + + m_pagesSelector = new QComboBox(this); + m_pagesSelector->insertItem(i18n("Bookmarks")); + m_pagesSelector->insertItem(i18n("Information")); + + // Assure that the combo box has the same height as the URL navigator for + // a clean layout. + // TODO: the following 2 lines have been copied from the URLNavigator + // constructor (-> provide a shared height setting?) + //QFontMetrics fontMetrics(font()); + QFontMetrics fontMetrics(font()); + m_pagesSelector->setMinimumHeight(fontMetrics.height() + 8); + + leftSidebarSettings* settings = DolphinSettings::instance().leftsidebar(); + const int selectedIndex = indexForName(settings->selectedPage()); + m_pagesSelector->setCurrentItem(selectedIndex); + m_layout->addWidget(m_pagesSelector); + + createPage(selectedIndex); + + connect(m_pagesSelector, SIGNAL(activated(int)), + this, SLOT(createPage(int))); +} + +leftSidebar::~leftSidebar() +{ +} + +QSize leftSidebar::sizeHint() const +{ + QSize size(QWidget::sizeHint()); + + leftSidebarSettings* settings = DolphinSettings::instance().leftsidebar(); + size.setWidth(settings->width()); + return size; +} + +void leftSidebar::createPage(int index) +{ + if (m_page != 0) { + m_page->deleteLater(); + m_page = 0; + } + + switch (index) { + case 0: m_page = new BookmarksSidebarPage(this); break; + case 1: m_page = new InfoSidebarPage(this); break; + default: break; + } + + m_layout->addWidget(m_page); + m_page->show(); + + leftSidebarSettings* settings = DolphinSettings::instance().leftsidebar(); + settings->setSelectedPage(m_pagesSelector->text(index)); +} + +int leftSidebar::indexForName(const QString& name) const +{ + const int count = m_pagesSelector->count(); + for (int i = 0; i < count; ++i) { + if (m_pagesSelector->text(i) == name) { + return i; + } + } + + return 0; +} + +rightSidebar::rightSidebar(QWidget* parent) : + QWidget(parent), + m_pagesSelector(0), + m_page(0), + m_layout(0) +{ + m_layout = new QVBoxLayout(this); + + m_pagesSelector = new QComboBox(this); + m_pagesSelector->insertItem(i18n("Bookmarks")); + m_pagesSelector->insertItem(i18n("Information")); + + // Assure that the combo box has the same height as the URL navigator for + // a clean layout. + // TODO: the following 2 lines have been copied from the URLNavigator + // constructor (-> provide a shared height setting?) + QFontMetrics fontMetrics(font()); + m_pagesSelector->setMinimumHeight(fontMetrics.height() + 8); + + rightSidebarSettings* settings = DolphinSettings::instance().rightsidebar(); + const int selectedIndex = indexForName(settings->selectedPage()); + m_pagesSelector->setCurrentItem(selectedIndex); + m_layout->addWidget(m_pagesSelector); + + createPage(selectedIndex); + + connect(m_pagesSelector, SIGNAL(activated(int)), + this, SLOT(createPage(int))); +} + +rightSidebar::~rightSidebar() +{ +} + +QSize rightSidebar::sizeHint() const +{ + QSize size(QWidget::sizeHint()); + + rightSidebarSettings* settings = DolphinSettings::instance().rightsidebar(); + size.setWidth(settings->width()); + return size; +} + +void rightSidebar::createPage(int index) +{ + if (m_page != 0) { + m_page->deleteLater(); + m_page = 0; + } + + switch (index) { + case 0: m_page = new BookmarksSidebarPage(this); break; + case 1: m_page = new InfoSidebarPage(this); break; + default: break; + } + + m_layout->addWidget(m_page); + m_page->show(); + + rightSidebarSettings* settings = DolphinSettings::instance().rightsidebar(); + settings->setSelectedPage(m_pagesSelector->text(index)); +} + +int rightSidebar::indexForName(const QString& name) const +{ + const int count = m_pagesSelector->count(); + for (int i = 0; i < count; ++i) { + if (m_pagesSelector->text(i) == name) { + return i; + } + } + + return 0; +} diff --git a/src/sidebars.h b/src/sidebars.h new file mode 100644 index 0000000..d7eac77 --- /dev/null +++ b/src/sidebars.h @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 2007 by Marcel Juhnke * + * marrat@marrat.homelinux.org * + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef _SIDEBARS_H_ +#define _SIDEBARS_H_ + +#include <qwidget.h> + + +class KURL; +class QComboBox; +class QVBoxLayout; +class SidebarPage; + +class leftSidebar : public QWidget +{ + Q_OBJECT + + public: + leftSidebar(QWidget* parent); + virtual ~leftSidebar(); + + virtual QSize sizeHint() const; + + signals: + /** + * The user selected an item on sidebar widget and item has + * URL property, so inform the parent to go to this URL; + */ + void urlChanged(const KURL& url); + + private slots: + void createPage(int index); + + private: + int indexForName(const QString& name) const; + + QComboBox* m_pagesSelector; + SidebarPage* m_page; + QVBoxLayout* m_layout; +}; + +class rightSidebar : public QWidget +{ + Q_OBJECT + + public: + rightSidebar(QWidget* parent); + virtual ~rightSidebar(); + + virtual QSize sizeHint() const; + + signals: + /** + * The user selected an item on sidebar widget and item has + * URL property, so inform the parent togo to this URL; + */ + void urlChanged(const KURL& url); + + private slots: + void createPage(int index); + + private: + int indexForName(const QString& name) const; + + QComboBox* m_pagesSelector; + SidebarPage* m_page; + QVBoxLayout* m_layout; +}; + +#endif // _SIDEBARS_H_ diff --git a/src/sidebarssettings.cpp b/src/sidebarssettings.cpp new file mode 100644 index 0000000..01ca5c6 --- /dev/null +++ b/src/sidebarssettings.cpp @@ -0,0 +1,96 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "sidebarssettings.h" +#include <kapplication.h> +#include <kconfig.h> +#include <assert.h> + +leftSidebarSettings::leftSidebarSettings() : + m_visible(true), + m_width(0) +{ + KConfig* config = kapp->config(); + config->setGroup("leftSidebar"); + + m_visible = config->readBoolEntry("Visible", true); + m_width = config->readNumEntry("Width", 150); + m_selectedPage = config->readEntry("Selected Page", "Bookmarks"); +} + +leftSidebarSettings::~leftSidebarSettings() +{ +} + +void leftSidebarSettings::setWidth(int width) +{ + if (width < 50) { + // prevent that a sidebar gets width which makes + // it look invisible + width = 50; + } + m_width = width; +} + +void leftSidebarSettings::save() +{ + KConfig* config = kapp->config(); + config->setGroup("leftSidebar"); + + config->writeEntry("Visible", m_visible); + config->writeEntry("Width", m_width); + config->writeEntry("Selected Page", m_selectedPage); +} + +rightSidebarSettings::rightSidebarSettings() : + m_visible(true), + m_width(0) +{ + KConfig* config = kapp->config(); + config->setGroup("rightSidebar"); + + m_visible = config->readBoolEntry("Visible", true); + m_width = config->readNumEntry("Width", 150); + m_selectedPage = config->readEntry("Selected Page", "Bookmarks"); +} + +rightSidebarSettings::~rightSidebarSettings() +{ +} + +void rightSidebarSettings::setWidth(int width) +{ + if (width < 50) { + // prevent that a sidebar gets width which makes + // it look invisible + width = 50; + } + m_width = width; +} + +void rightSidebarSettings::save() +{ + KConfig* config = kapp->config(); + config->setGroup("rightSidebar"); + + config->writeEntry("Visible", m_visible); + config->writeEntry("Width", m_width); + config->writeEntry("Selected Page", m_selectedPage); +} diff --git a/src/sidebarssettings.h b/src/sidebarssettings.h new file mode 100644 index 0000000..7ef678d --- /dev/null +++ b/src/sidebarssettings.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef SIDEBARSETTINGS_H +#define SIDEBARSETTINGS_H + +#include <qstring.h> +#include <dolphinsettingsbase.h> + + +class leftSidebarSettings +{ +public: + leftSidebarSettings(); + virtual ~leftSidebarSettings(); + void setVisible(bool visible) { m_visible = visible; } + bool isVisible() const { return m_visible; } + + void setWidth(int width); + int width() const { return m_width; } + + void setSelectedPage(const QString& pageName) { m_selectedPage = pageName; } + const QString& selectedPage() const { return m_selectedPage; } + + virtual void save(); + +protected: + bool m_visible; + int m_width; + QString m_selectedPage; +}; + +class rightSidebarSettings +{ +public: + rightSidebarSettings(); + virtual ~rightSidebarSettings(); + void setVisible(bool visible) { m_visible = visible; } + bool isVisible() const { return m_visible; } + + void setWidth(int width); + int width() const { return m_width; } + + void setSelectedPage(const QString& pageName) { m_selectedPage = pageName; } + const QString& selectedPage() const { return m_selectedPage; } + + virtual void save(); + +protected: + bool m_visible; + int m_width; + QString m_selectedPage; +}; + +#endif diff --git a/src/statusbarmessagelabel.cpp b/src/statusbarmessagelabel.cpp new file mode 100644 index 0000000..3c49c7a --- /dev/null +++ b/src/statusbarmessagelabel.cpp @@ -0,0 +1,215 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "statusbarmessagelabel.h" +#include <qpainter.h> +#include <qtimer.h> +#include <qfontmetrics.h> +#include <kiconloader.h> +#include <kglobalsettings.h> + +StatusBarMessageLabel::StatusBarMessageLabel(QWidget* parent) : + QWidget(parent), + m_type(DolphinStatusBar::Default), + m_state(Default), + m_illumination(0), + m_minTextHeight(-1), + m_timer(0) +{ + setMinimumHeight(KIcon::SizeSmall); + + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), + this, SLOT(timerDone())); +} + +StatusBarMessageLabel::~StatusBarMessageLabel() +{ +} + +void StatusBarMessageLabel::setType(DolphinStatusBar::Type type) +{ + if (type != m_type) { + m_type = type; + + m_timer->stop(); + m_illumination = 0; + m_state = Default; + + const char* iconName = 0; + QPixmap pixmap; + switch (type) { + case DolphinStatusBar::OperationCompleted: + iconName = "ok"; + break; + + case DolphinStatusBar::Information: + iconName = "info"; + break; + + case DolphinStatusBar::Error: + iconName = "error"; + m_timer->start(100); + m_state = Illuminate; + break; + + case DolphinStatusBar::Default: + default: break; + } + + m_pixmap = (iconName == 0) ? QPixmap() : SmallIcon(iconName); + assureVisibleText(); + update(); + } +} + +void StatusBarMessageLabel::setText(const QString& text) +{ + if (text != m_text) { + if (m_type == DolphinStatusBar::Error) { + m_timer->start(100); + m_illumination = 0; + m_state = Illuminate; + } + m_text = text; + assureVisibleText(); + update(); + } +} + +void StatusBarMessageLabel::setMinimumTextHeight(int min) +{ + if (min != m_minTextHeight) { + m_minTextHeight = min; + setMinimumHeight(min); + } +} + +void StatusBarMessageLabel::paintEvent(QPaintEvent* /* event */) +{ + QPixmap buffer(size()); + QPainter painter(&buffer); + + // draw background + QColor backgroundColor(colorGroup().background()); + QColor foregroundColor(KGlobalSettings::textColor()); + if (m_illumination > 0) { + backgroundColor = mixColors(backgroundColor, QColor(255, 255, 64), m_illumination); + foregroundColor = mixColors(foregroundColor, QColor(0, 0, 0), m_illumination); + } + painter.setBrush(backgroundColor); + painter.setPen(backgroundColor); + painter.drawRect(QRect(0, 0, width(), height())); + + // draw pixmap + int x = pixmapGap(); + int y = (height() - m_pixmap.height()) / 2; + + if (!m_pixmap.isNull()) { + painter.drawPixmap(x, y, m_pixmap); + x += m_pixmap.width() + pixmapGap(); + } + + // draw text + painter.setPen(foregroundColor); + painter.drawText(QRect(x, 0, width() - x, height()), Qt::AlignVCenter | Qt::WordBreak, m_text); + painter.end(); + + bitBlt(this, 0, 0, &buffer); +} + +void StatusBarMessageLabel::resizeEvent(QResizeEvent* event) +{ + QWidget::resizeEvent(event); + QTimer::singleShot(0, this, SLOT(assureVisibleText())); +} + +void StatusBarMessageLabel::timerDone() +{ + switch (m_state) { + case Illuminate: { + // increase the illumination + if (m_illumination < 100) { + m_illumination += 20; + update(); + } + else { + m_state = Illuminated; + m_timer->start(1000); + } + break; + } + + case Illuminated: { + // start desaturation + m_state = Desaturate; + m_timer->start(100); + break; + } + + case Desaturate: { + // desaturate + if (m_illumination > 0) { + m_illumination -= 5; + update(); + } + else { + m_state = Default; + m_timer->stop(); + } + break; + } + + default: + break; + } +} + +void StatusBarMessageLabel::assureVisibleText() +{ + if (m_text.isEmpty()) { + return; + } + + + int availableWidth = width() - m_pixmap.width() - pixmapGap() * 2; + + QFontMetrics fontMetrics(font()); + QRect bounds(fontMetrics.boundingRect(0, 0, availableWidth, height(), + Qt::AlignVCenter | Qt::WordBreak, + m_text)); + int requiredHeight = bounds.height(); + if (requiredHeight < m_minTextHeight) { + requiredHeight = m_minTextHeight; + } + setMinimumHeight(requiredHeight); + updateGeometry(); +} + +QColor StatusBarMessageLabel::mixColors(const QColor& c1, + const QColor& c2, + int percent) const +{ + const int recip = 100 - percent; + const int red = (c1.red() * recip + c2.red() * percent) / 100; + const int green = (c1.green() * recip + c2.green() * percent) / 100; + const int blue = (c1.blue() * recip + c2.blue() * percent) / 100; + return QColor(red, green, blue); +} diff --git a/src/statusbarmessagelabel.h b/src/statusbarmessagelabel.h new file mode 100644 index 0000000..c743f85 --- /dev/null +++ b/src/statusbarmessagelabel.h @@ -0,0 +1,92 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef STATUSBARMESSAGELABEL_H +#define STATUSBARMESSAGELABEL_H + +#include <qwidget.h> +#include <qpixmap.h> +#include <qstring.h> +#include <dolphinstatusbar.h> +class QTimer; + +/** + * @brief Represents a message text label as part of the status bar. + * + * Dependant from the given type automatically a corresponding icon + * is shown in front of the text. For message texts having the type + * DolphinStatusBar::Error a dynamic color blending is done to get the + * attention from the user. + * + * @author Peter Penz + */ +class StatusBarMessageLabel : public QWidget +{ + Q_OBJECT + +public: + StatusBarMessageLabel(QWidget* parent); + virtual ~StatusBarMessageLabel(); + + void setType(DolphinStatusBar::Type type); + DolphinStatusBar::Type type() const { return m_type; } + + void setText(const QString& text); + const QString& text() const { return m_text; } + + // TODO: maybe a better approach is possible with the size hint + void setMinimumTextHeight(int min); + int minimumTextHeight() const { return m_minTextHeight; } + +protected: + /** @see QWidget::paintEvent */ + virtual void paintEvent(QPaintEvent* event); + + /** @see QWidget::resizeEvent */ + virtual void resizeEvent(QResizeEvent* event); + +private slots: + void timerDone(); + void assureVisibleText(); + +private: + enum State { + Default, + Illuminate, + Illuminated, + Desaturate + }; + + DolphinStatusBar::Type m_type; + State m_state; + int m_illumination; + int m_minTextHeight; + QTimer* m_timer; + QString m_text; + QPixmap m_pixmap; + + QColor mixColors(const QColor& c1, + const QColor& c2, + int percent) const; + + int pixmapGap() const { return 3; } +}; + +#endif diff --git a/src/statusbarspaceinfo.cpp b/src/statusbarspaceinfo.cpp new file mode 100644 index 0000000..221a4f0 --- /dev/null +++ b/src/statusbarspaceinfo.cpp @@ -0,0 +1,192 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) and * + * and Patrice Tremblay * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "statusbarspaceinfo.h" + +#include <qpainter.h> +#include <qtimer.h> +#include <kglobalsettings.h> +#include <kdiskfreesp.h> +#include <klocale.h> +#include <kio/job.h> + +StatusBarSpaceInfo::StatusBarSpaceInfo(QWidget* parent) : + QWidget(parent), + m_gettingSize(false), + m_kBSize(0), + m_kBAvailable(0) +{ + setMinimumWidth(200); + + // Update the space information each 10 seconds. Polling is useful + // here, as files can be deleted/added outside the scope of Dolphin. + QTimer* timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(refresh())); + timer->start(10000); +} + +StatusBarSpaceInfo::~StatusBarSpaceInfo() +{ +} + +void StatusBarSpaceInfo::setURL(const KURL& url) +{ + m_url = url; + refresh(); + update(); +} + +void StatusBarSpaceInfo::paintEvent(QPaintEvent* /* event */) +{ + QPainter painter(this); + const int barWidth = width(); + const int barTop = 2; + const int barHeight = height() - 4; + + QString text; + + const int widthDec = 3; // visual decrement for the available width + + const QColor c1 = colorGroup().background(); + const QColor c2 = KGlobalSettings::buttonTextColor(); + const QColor frameColor((c1.red() + c2.red()) / 2, + (c1.green() + c2.green()) / 2, + (c1.blue() + c2.blue()) / 2); + painter.setPen(frameColor); + + const QColor backgrColor = KGlobalSettings::baseColor(); + painter.setBrush(backgrColor); + + painter.drawRect(QRect(0, barTop + 1 , barWidth - widthDec, barHeight)); + + if ((m_kBSize > 0) && (m_kBAvailable > 0)) { + // draw 'used size' bar + painter.setPen(Qt::NoPen); + painter.setBrush(progressColor(backgrColor)); + int usedWidth = barWidth - static_cast<int>((m_kBAvailable * + static_cast<float>(barWidth)) / m_kBSize); + const int left = 1; + int right = usedWidth - (widthDec + 1); + if (right < left) { + right = left; + } + painter.drawRect(QRect(left, barTop + 2, right, barHeight - 2)); + + text = i18n("%1 free") + .arg(KIO::convertSizeFromKB(m_kBAvailable)); + } + else { + if (m_gettingSize) { + text = i18n("Getting size..."); + } + else { + text = ""; + QTimer::singleShot(0, this, SLOT(hide())); + } + } + + // draw text (usually 'Y GB free') + painter.setPen(KGlobalSettings::textColor()); + painter.drawText(QRect(1, 1, barWidth - 2, barHeight + 4), + Qt::AlignHCenter | Qt::AlignVCenter | Qt::WordBreak, + text); +} + + +void StatusBarSpaceInfo::slotFoundMountPoint(const unsigned long& kBSize, + const unsigned long& /* kBUsed */, + const unsigned long& kBAvailable, + const QString& /* mountPoint */) +{ + m_gettingSize = false; + m_kBSize = kBSize; + m_kBAvailable = kBAvailable; + + // Bypass a the issue (?) of KDiskFreeSp that for protocols like + // FTP, SMB the size of root partition is returned. + // TODO: check whether KDiskFreeSp is buggy or Dolphin uses it in a wrong way + const QString protocol(m_url.protocol()); + if (!protocol.isEmpty() && (protocol != "file")) { + m_kBSize = 0; + m_kBAvailable = 0; + } + + update(); +} + +void StatusBarSpaceInfo::slotDone() +{ + m_gettingSize = false; + if ((m_kBSize > 0) && (m_kBAvailable > 0)) { + show(); + } + + update(); +} + +void StatusBarSpaceInfo::refresh() +{ + m_gettingSize = true; + m_kBSize = 0; + m_kBAvailable = 0; + + const QString mountPoint(KIO::findPathMountPoint(m_url.path())); + + KDiskFreeSp* job = new KDiskFreeSp(this); + connect(job, SIGNAL(foundMountPoint(const unsigned long&, + const unsigned long&, + const unsigned long&, + const QString& )), + this, SLOT(slotFoundMountPoint(const unsigned long&, + const unsigned long&, + const unsigned long&, + const QString& ))); + connect(job, SIGNAL(done()), + this, SLOT(slotDone())); + + job->readDF(mountPoint); +} + +QColor StatusBarSpaceInfo::progressColor(const QColor& bgColor) const +{ + QColor color = KGlobalSettings::buttonBackground(); + + // assure that enough contrast is given between the background color + // and the progressbar color + int bgRed = bgColor.red(); + int bgGreen = bgColor.green(); + int bgBlue = bgColor.blue(); + + const int backgrBrightness = qGray(bgRed, bgGreen, bgBlue); + const int progressBrightness = qGray(color.red(), color.green(), color.blue()); + + const int limit = 32; + const int diff = backgrBrightness - progressBrightness; + bool adjustColor = ((diff >= 0) && (diff < limit)) || + ((diff < 0) && (diff > -limit)); + if (adjustColor) { + const int inc = (backgrBrightness < 2 * limit) ? (2 * limit) : -limit; + color = QColor(bgRed + inc, bgGreen + inc, bgBlue + inc); + } + + return color; +} + +#include "statusbarspaceinfo.moc" diff --git a/src/statusbarspaceinfo.h b/src/statusbarspaceinfo.h new file mode 100644 index 0000000..6409c45 --- /dev/null +++ b/src/statusbarspaceinfo.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) and * + * and Patrice Tremblay * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef STATUSBARSPACEINFO_H +#define STATUSBARSPACEINFO_H + +#include <qwidget.h> +#include <qstring.h> +#include <kurl.h> +#include <qcolor.h> + +class KDiskFreeSp; + +/** + * @short Shows the available space for the current volume as part + * of the status bar. + */ +class StatusBarSpaceInfo : public QWidget +{ + Q_OBJECT + +public: + StatusBarSpaceInfo(QWidget* parent); + virtual ~StatusBarSpaceInfo(); + + void setURL(const KURL& url); + const KURL& url() const { return m_url; } + +protected: + /** @see QWidget::paintEvent */ + virtual void paintEvent(QPaintEvent* event); + +private slots: + /** + * The strange signature of this method is due to a compiler + * bug (?). More details are given inside the class KDiskFreeSp (see + * KDE Libs documentation). + */ + void slotFoundMountPoint(const unsigned long& kBSize, + const unsigned long& kBUsed, + const unsigned long& kBAvailable, + const QString& mountPoint); + void slotDone(); + + /** Refreshs the space information for the current set URL. */ + void refresh(); + +private: + /** + * Returns a color for the progress bar by respecting + * the given background color \a bgColor. It is assured + * that enough contrast is given to have a visual indication. + */ + QColor progressColor(const QColor& bgColor) const; + + KURL m_url; + bool m_gettingSize; + unsigned long m_kBSize; + unsigned long m_kBAvailable; + +}; + +#endif diff --git a/src/undomanager.cpp b/src/undomanager.cpp new file mode 100644 index 0000000..5869e4b --- /dev/null +++ b/src/undomanager.cpp @@ -0,0 +1,402 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "undomanager.h" +#include <klocale.h> +#include <kio/netaccess.h> +#include <qtimer.h> +#include <assert.h> + +#include "dolphin.h" +#include "dolphinstatusbar.h" +#include "progressindicator.h" + +DolphinCommand::DolphinCommand() : + m_type(Copy), + m_macroIndex(-1) +{ + // Implementation note: DolphinCommands are stored in a QValueList, whereas + // QValueList requires a default constructor of the added class. + // Instead of expressing this implementation detail to the interface by adding a + // Type::Undefined just Type::Copy is used to assure that all members have + // a defined state. +} + +DolphinCommand::DolphinCommand(Type type, + const KURL::List& source, + const KURL& dest) : + m_type(type), + m_macroIndex(-1), + m_source(source), + m_dest(dest) +{ +} + +DolphinCommand::~DolphinCommand() +{ +} + +DolphinCommand& DolphinCommand::operator = (const DolphinCommand& command) +{ + m_type = command.m_type; + m_source = command.m_source; + m_dest = command.m_dest; + return *this; +} + +UndoManager& UndoManager::instance() +{ + static UndoManager* instance = 0; + if (instance == 0) { + instance = new UndoManager(); + } + return *instance; +} + +void UndoManager::addCommand(const DolphinCommand& command) +{ + ++m_historyIndex; + + if (m_recordMacro) { + DolphinCommand macroCommand = command; + macroCommand.m_macroIndex = m_macroCounter; + m_history.insert(m_history.at(m_historyIndex), macroCommand); + } + else { + m_history.insert(m_history.at(m_historyIndex), command); + } + + emit undoAvailable(true); + emit undoTextChanged(i18n("Undo: %1").arg(commandText(command))); + + // prevent an endless growing of the Undo history + if (m_historyIndex > 10000) { + m_history.erase(m_history.begin()); + --m_historyIndex; + } +} + +void UndoManager::beginMacro() +{ + assert(!m_recordMacro); + m_recordMacro = true; + ++m_macroCounter; +} + +void UndoManager::endMacro() +{ + assert(m_recordMacro); + m_recordMacro = false; +} + +void UndoManager::undo() +{ + if (m_recordMacro) { + endMacro(); + } + + if (m_historyIndex < 0) { + return; + } + + int progressCount = 0; + int macroCount = 1; + calcStepsCount(macroCount, progressCount); + + m_progressIndicator = new ProgressIndicator(i18n("Executing undo operation..."), + i18n("Executed undo operation."), + progressCount); + + for (int i = 0; i < macroCount; ++i) { + const DolphinCommand command = m_history[m_historyIndex]; + --m_historyIndex; + if (m_historyIndex < 0) { + emit undoAvailable(false); + emit undoTextChanged(i18n("Undo")); + } + else { + emit undoTextChanged(i18n("Undo: %1").arg(commandText(m_history[m_historyIndex]))); + } + + if (m_historyIndex < static_cast<int>(m_history.count()) - 1) { + emit redoAvailable(true); + emit redoTextChanged(i18n("Redo: %1").arg(commandText(command))); + } + else { + emit redoAvailable(false); + emit redoTextChanged(i18n("Redo")); + } + + KURL::List sourceURLs = command.source(); + KURL::List::Iterator it = sourceURLs.begin(); + const KURL::List::Iterator end = sourceURLs.end(); + const QString destURL(command.destination().prettyURL(+1)); + + KIO::Job* job = 0; + switch (command.type()) { + case DolphinCommand::Link: + case DolphinCommand::Copy: { + KURL::List list; + while (it != end) { + const KURL deleteURL(destURL + (*it).filename()); + list.append(deleteURL); + ++it; + } + job = KIO::del(list, false, false); + break; + } + + case DolphinCommand::Move: { + KURL::List list; + const KURL newDestURL((*it).directory()); + while (it != end) { + const KURL newSourceURL(destURL + (*it).filename()); + list.append(newSourceURL); + ++it; + } + job = KIO::move(list, newDestURL, false); + break; + } + + case DolphinCommand::Rename: { + assert(sourceURLs.count() == 1); + KIO::NetAccess::move(command.destination(), (*it)); + break; + } + + case DolphinCommand::Trash: { + while (it != end) { + // TODO: use KIO::special for accessing the trash protocol. See + // also Dolphin::slotJobResult() for further details. + const QString originalFileName((*it).filename().section('-', 1)); + KURL newDestURL(destURL + originalFileName); + KIO::NetAccess::move(*it, newDestURL); + ++it; + + m_progressIndicator->execOperation(); + } + break; + } + + case DolphinCommand::CreateFolder: + case DolphinCommand::CreateFile: { + KIO::NetAccess::del(command.destination(), &Dolphin::mainWin()); + break; + } + } + + if (job != 0) { + // Execute the jobs in a synchronous manner and forward the progress + // information to the Dolphin statusbar. + connect(job, SIGNAL(percent(KIO::Job*, unsigned long)), + this, SLOT(slotPercent(KIO::Job*, unsigned long))); + KIO::NetAccess::synchronousRun(job, &Dolphin::mainWin()); + } + + m_progressIndicator->execOperation(); + } + + delete m_progressIndicator; + m_progressIndicator = 0; +} + +void UndoManager::redo() +{ + if (m_recordMacro) { + endMacro(); + } + + const int maxHistoryIndex = m_history.count() - 1; + if (m_historyIndex >= maxHistoryIndex) { + return; + } + ++m_historyIndex; + + int progressCount = 0; + int macroCount = 1; + calcStepsCount(macroCount, progressCount); + + m_progressIndicator = new ProgressIndicator(i18n("Executing redo operation..."), + i18n("Executed redo operation."), + progressCount); + + for (int i = 0; i < macroCount; ++i) { + const DolphinCommand command = m_history[m_historyIndex]; + if (m_historyIndex >= maxHistoryIndex) { + emit redoAvailable(false); + emit redoTextChanged(i18n("Redo")); + } + else { + emit redoTextChanged(i18n("Redo: %1").arg(commandText(m_history[m_historyIndex + 1]))); + } + + emit undoAvailable(true); + emit undoTextChanged(i18n("Undo: %1").arg(commandText(command))); + + Dolphin& dolphin = Dolphin::mainWin(); + + KURL::List sourceURLs = command.source(); + KURL::List::Iterator it = sourceURLs.begin(); + const KURL::List::Iterator end = sourceURLs.end(); + + KIO::Job* job = 0; + switch (command.type()) { + case DolphinCommand::Link: { + job = KIO::link(sourceURLs, command.destination(), false); + break; + } + + case DolphinCommand::Copy: { + job = KIO::copy(sourceURLs, command.destination(), false); + break; + } + + case DolphinCommand::Rename: + case DolphinCommand::Move: { + job = KIO::move(sourceURLs, command.destination(), false); + break; + } + + case DolphinCommand::Trash: { + const QString destURL(command.destination().prettyURL()); + while (it != end) { + // TODO: use KIO::special for accessing the trash protocol. See + // also Dolphin::slotJobResult() for further details. + const QString originalFileName((*it).filename().section('-', 1)); + KURL originalSourceURL(destURL + "/" + originalFileName); + KIO::Job* moveToTrashJob = KIO::trash(originalSourceURL); + KIO::NetAccess::synchronousRun(moveToTrashJob, &dolphin); + ++it; + + m_progressIndicator->execOperation(); + } + break; + } + + case DolphinCommand::CreateFolder: { + KIO::NetAccess::mkdir(command.destination(), &dolphin); + break; + } + + case DolphinCommand::CreateFile: { + m_progressIndicator->execOperation(); + KURL::List::Iterator it = sourceURLs.begin(); + assert(sourceURLs.count() == 1); + KIO::CopyJob* copyJob = KIO::copyAs(*it, command.destination(), false); + copyJob->setDefaultPermissions(true); + job = copyJob; + break; + } + } + + if (job != 0) { + // Execute the jobs in a synchronous manner and forward the progress + // information to the Dolphin statusbar. + connect(job, SIGNAL(percent(KIO::Job*, unsigned long)), + this, SLOT(slotPercent(KIO::Job*, unsigned long))); + KIO::NetAccess::synchronousRun(job, &dolphin); + } + + ++m_historyIndex; + m_progressIndicator->execOperation(); + } + + --m_historyIndex; + + delete m_progressIndicator; + m_progressIndicator = 0; +} + +UndoManager::UndoManager() : + m_recordMacro(false), + m_historyIndex(-1), + m_macroCounter(0), + m_progressIndicator(0) +{ +} + +UndoManager::~UndoManager() +{ + delete m_progressIndicator; + m_progressIndicator = 0; +} + +QString UndoManager::commandText(const DolphinCommand& command) const +{ + QString text; + switch (command.type()) { + case DolphinCommand::Copy: text = i18n("Copy"); break; + case DolphinCommand::Move: text = i18n("Move"); break; + case DolphinCommand::Link: text = i18n("Link"); break; + case DolphinCommand::Rename: text = i18n("Rename"); break; + case DolphinCommand::Trash: text = i18n("Move to Trash"); break; + case DolphinCommand::CreateFolder: text = i18n("Create New Folder"); break; + case DolphinCommand::CreateFile: text = i18n("Create New File"); break; + default: break; + } + return text; +} + +void UndoManager::slotPercent(KIO::Job* /* job */, unsigned long /* percent */) +{ + // It is not allowed to update the progress indicator in the context + // of this slot, hence do an asynchronous triggering. + QTimer::singleShot(0, this, SLOT(updateProgress())); +} + +void UndoManager::updateProgress() +{ + m_progressIndicator->execOperation(); +} + +void UndoManager::calcStepsCount(int& macroCount, int& progressCount) +{ + progressCount = 0; + macroCount = 0; + + const int macroIndex = m_history[m_historyIndex].m_macroIndex; + if (macroIndex < 0) { + // default use case: no macro has been recorded + macroCount = 1; + progressCount = m_history[m_historyIndex].source().count(); + return; + } + + // iterate backward for undo... + int i = m_historyIndex; + while ((i >= 0) && (m_history[i].m_macroIndex == macroIndex)) { + ++macroCount; + progressCount += m_history[i].source().count(); + --i; + } + + // iterate forward for redo... + const int max = m_history.count() - 1; + i = m_historyIndex + 1; + while ((i <= max) && (m_history[i].m_macroIndex == macroIndex)) { + ++macroCount; + progressCount += m_history[i].source().count(); + ++i; + } +} + +#include "undomanager.moc" + + diff --git a/src/undomanager.h b/src/undomanager.h new file mode 100644 index 0000000..fb6f14e --- /dev/null +++ b/src/undomanager.h @@ -0,0 +1,196 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef UNDOMANAGER_H +#define UNDOMANAGER_H + +#include <qobject.h> +#include <qvaluelist.h> +#include <kurl.h> +#include <kio/jobclasses.h> + +class ProgressIndicator; + +/** + * @short Represents a file manager command which can be undone and redone. + * + * A command is specified by a type, a list of source URLs and a + * destination URL. + * + * Due to the fixed set of commands a file manager offers this class is + * a very simplified version of the classic command pattern. + * + * @see UndoManager + * @author Peter Penz <peter.penz@gmx.at> + */ +class DolphinCommand +{ +public: + enum Type { + Copy, + Move, + Link, + Rename, + Trash, + CreateFolder, + CreateFile + }; + + DolphinCommand(); + DolphinCommand(Type type, const KURL::List& source, const KURL& dest); + ~DolphinCommand(); // non-virtual + + DolphinCommand& operator = (const DolphinCommand& command); + Type type() const { return m_type; } + void setSource(const KURL::List source) { m_source = source; } + const KURL::List& source() const { return m_source; } + const KURL& destination() const { return m_dest; } + +private: + Type m_type; + int m_macroIndex; + KURL::List m_source; + KURL m_dest; + + friend class UndoManager; // allow to modify m_macroIndex +}; + +/** + * @short Stores all file manager commands which can be undone and redone. + * + * During the undo and redo operations a progress information is + * shown in the status bar. + * + * @author Peter Penz <peter.penz@gmx.at> + */ +class UndoManager : public QObject +{ + Q_OBJECT + +public: + static UndoManager& instance(); + + /** + * Adds the command \a command to the undo list. The command + * can be undone by invoking UndoManager::undo(). + */ + void addCommand(const DolphinCommand& command); + + /** + * Allows to summarize several commands into one macro, which + * can be undo in one stop by UndoManager::undo(). Example + * \code + * UndoManager& undoMan = UndoManager.instance(); + * undoMan.beginMacro(); + * undoMan.addCommand(...); + * undoMan.addCommand(...); + * undoMan.addCommand(...); + * undoMan.endMacro(); + * \endcode + * It is not allowed to do nested macro recordings. + */ + void beginMacro(); + + /** + * Marks the end of a macro command. See UndoManager::beginMacro() + * for sample code. + */ + void endMacro(); + +public slots: + /** + * Performs an undo operation on the last command which has + * been added by UndoManager::addCommand(). + */ + void undo(); + + /** + * Performs a redo operation on the last command where an undo + * operation has been applied. + */ + void redo(); + +signals: + /** + * Is emitted if whenever the availability state + * of the current undo operation changes. + */ + void undoAvailable(bool available); + + /** + * Is emitted whenever the text of the current + * undo operation changes + * (e. g. from 'Undo: Delete' to 'Undo: Copy') + */ + void undoTextChanged(const QString& text); + + /** + * Is emitted if whenever the availability state + * of the current redo operation changes. + */ + void redoAvailable(bool available); + + /** + * Is emitted whenever the text of the current + * redo operation changes + * (e. g. from 'Redo: Delete' to 'Redo: Copy') + */ + void redoTextChanged(const QString& text); + +protected: + UndoManager(); + virtual ~UndoManager(); + QString commandText(const DolphinCommand& command) const; + +private slots: + /** + * Slot for the percent information of the I/O slaves. + * Delegates the updating of the progress information + * to UndoManager::updateProgress(). + */ + void slotPercent(KIO::Job* job, unsigned long percent); + + /** + * Updates the progress information of the statusbar + * by accessing the progress indicator information. + */ + void updateProgress(); + +private: + bool m_recordMacro; + int m_historyIndex; + int m_macroCounter; + QValueList<DolphinCommand> m_history; + ProgressIndicator* m_progressIndicator; + + /** + * Dependent from the current history index \a m_historyIndex + * the number of macro commands is written to the output + * parameter \a macroCount. The number of steps for all macro + * commands is written to the output parameter \a progressCount. + * + * Per default \a macroCount is 1 and \a progressCount represents + * the number of operations for one command. + */ + void calcStepsCount(int& macroCount, + int& progressCount); +}; + +#endif diff --git a/src/urlbutton.cpp b/src/urlbutton.cpp new file mode 100644 index 0000000..27ddc81 --- /dev/null +++ b/src/urlbutton.cpp @@ -0,0 +1,96 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * + * Copyright (C) 2006 by Aaron J. Seigo (<aseigo@kde.org>) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "urlnavigatorbutton.h" +#include <kurl.h> +#include <qtooltip.h> +#include <qcursor.h> +#include <qfontmetrics.h> +#include <kurldrag.h> +#include <kpopupmenu.h> +#include <kiconloader.h> +#include <klocale.h> + +#include "urlnavigator.h" +#include "dolphin.h" + + +URLButton::URLButton(URLNavigator* parent) +: QPushButton(parent), + m_displayHint(0), + m_urlNavigator(parent) +{ + setFocusPolicy(QWidget::NoFocus); + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + setMinimumHeight(parent->minimumHeight()); + + connect(this, SIGNAL(clicked()), parent, SLOT(slotRequestActivation())); + connect(&Dolphin::mainWin(), SIGNAL(activeViewChanged()), + this, SLOT(update())); +} + +URLButton::~URLButton() +{ +} + +URLNavigator* URLButton::urlNavigator() const +{ + return m_urlNavigator; +} + +void URLButton::setDisplayHintEnabled(DisplayHint hint, + bool enable) +{ + if (enable) { + m_displayHint = m_displayHint | hint; + } + else { + m_displayHint = m_displayHint & ~hint; + } + update(); +} + +bool URLButton::isDisplayHintEnabled(DisplayHint hint) const +{ + return (m_displayHint & hint) > 0; +} + +void URLButton::enterEvent(QEvent* event) +{ + QPushButton::enterEvent(event); + setDisplayHintEnabled(EnteredHint, true); + update(); +} + +void URLButton::leaveEvent(QEvent* event) +{ + QPushButton::leaveEvent(event); + setDisplayHintEnabled(EnteredHint, false); + update(); +} + +QColor URLButton::mixColors(const QColor& c1, + const QColor& c2) const +{ + const int red = (c1.red() + c2.red()) / 2; + const int green = (c1.green() + c2.green()) / 2; + const int blue = (c1.blue() + c2.blue()) / 2; + return QColor(red, green, blue); +} diff --git a/src/urlbutton.h b/src/urlbutton.h new file mode 100644 index 0000000..3ede7f8 --- /dev/null +++ b/src/urlbutton.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * + * Copyright (C) 2006 by Aaron J. Seigo (<aseigo@kde.org>) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef URLBUTTON_H +#define URLBUTTON_H + +#include <qpushbutton.h> + +class KURL; +class URLNavigator; +class QPainter; + +/** + * @brief Base class for buttons of the URL navigator. + * + * Each button of the URL navigator contains an URL, which + * is set as soon as the button has been clicked. +* + * @author Peter Penz + */ +class URLButton : public QPushButton +{ + Q_OBJECT + +public: + URLButton(URLNavigator* parent); + virtual ~URLButton(); + + URLNavigator* urlNavigator() const; + +protected: + enum DisplayHint { + ActivatedHint = 1, + EnteredHint = 2, + DraggedHint = 4, + PopupActiveHint = 8 + }; + + void setDisplayHintEnabled(DisplayHint hint, bool enable); + bool isDisplayHintEnabled(DisplayHint hint) const; + + virtual void enterEvent(QEvent* event); + virtual void leaveEvent(QEvent* event); + + QColor mixColors(const QColor& c1, const QColor& c2) const; + +private: + int m_displayHint; + URLNavigator* m_urlNavigator; +}; + +#endif diff --git a/src/urlnavigator.cpp b/src/urlnavigator.cpp new file mode 100644 index 0000000..3f0d278 --- /dev/null +++ b/src/urlnavigator.cpp @@ -0,0 +1,501 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * + * Copyright (C) 2006 by Aaron J. Seigo (<aseigo@kde.org>) * + * Copyright (C) 2006 by Patrice Tremblay * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "urlnavigator.h" + +#include <assert.h> +#include <kurl.h> +#include <qobjectlist.h> +#include <qcombobox.h> +#include <klocale.h> +#include <kiconloader.h> +#include <qpopupmenu.h> +#include <qlineedit.h> +#include <qpushbutton.h> +#include <qsizepolicy.h> +#include <qtooltip.h> +#include <qfont.h> +#include <qlistbox.h> + +#include <kio/job.h> +#include <kurlcombobox.h> +#include <kurlcompletion.h> +#include <kbookmarkmanager.h> + +#include "dolphin.h" +#include "dolphinsettings.h" +#include "bookmarkselector.h" +#include "dolphinstatusbar.h" +#include "urlnavigatorbutton.h" +#include "dolphinview.h" + +URLNavigator::HistoryElem::HistoryElem() + : m_url(), + m_currentFileName(), + m_contentsX(0), + m_contentsY(0) +{ +} + +URLNavigator::HistoryElem::HistoryElem(const KURL& url) + : m_url(url), + m_currentFileName(), + m_contentsX(0), + m_contentsY(0) +{ +} + +URLNavigator::HistoryElem::~HistoryElem() +{ +} + +URLNavigator::URLNavigator(const KURL& url, + DolphinView* dolphinView) : + QHBox(dolphinView), + m_historyIndex(0), + m_dolphinView(dolphinView) +{ + m_history.prepend(HistoryElem(url)); + + QFontMetrics fontMetrics(font()); + setMinimumHeight(fontMetrics.height() + 8); + + m_toggleButton = new QPushButton(SmallIcon("editurl"), 0, this); + m_toggleButton->setFlat(true); + m_toggleButton->setToggleButton(true); + m_toggleButton->setFocusPolicy(QWidget::NoFocus); + m_toggleButton->setMinimumHeight(minimumHeight()); + connect(m_toggleButton, SIGNAL(clicked()), + this, SLOT(slotClicked())); + if (DolphinSettings::instance().isURLEditable()) { + m_toggleButton->toggle(); + } + + m_bookmarkSelector = new BookmarkSelector(this); + connect(m_bookmarkSelector, SIGNAL(bookmarkActivated(int)), + this, SLOT(slotBookmarkActivated(int))); + + m_pathBox = new KURLComboBox(KURLComboBox::Directories, true, this); + + KURLCompletion* kurlCompletion = new KURLCompletion(KURLCompletion::DirCompletion); + m_pathBox->setCompletionObject(kurlCompletion); + m_pathBox->setAutoDeleteCompletionObject(true); + + connect(m_pathBox, SIGNAL(returnPressed(const QString&)), + this, SLOT(slotReturnPressed(const QString&))); + connect(m_pathBox, SIGNAL(urlActivated(const KURL&)), + this, SLOT(slotURLActivated(const KURL&))); + + connect(dolphinView, SIGNAL(contentsMoved(int, int)), + this, SLOT(slotContentsMoved(int, int))); + updateContent(); +} + +URLNavigator::~URLNavigator() +{ +} + +void URLNavigator::setURL(const KURL& url) +{ + QString urlStr(url.prettyURL()); + + if (url.protocol() == "zip") { + bool stillInside = false; + if (KMimeType::findByPath(url.url(-1)) + ->is("application/x-zip")) { + stillInside = true; + } + else { + KURL url1 = url.upURL(); + while (url1 != url1.upURL()) { + if (KMimeType::findByPath(url1.url(-1)) + ->is("application/x-zip")) { + stillInside = true; + break; + } + url1 = url1.upURL(); + } + } + if (!stillInside) + { + // Drop the zip:/ protocol since we are not in the zip anymore + urlStr = url.path(); + } + } + else if (url.protocol() == "tar") + { + bool stillInside = false; + KMimeType::Ptr kmp = + KMimeType::findByPath(url.url(-1)); + if (kmp->is("application/x-tar") || + kmp->is("application/x-tarz") || + kmp->is("application/x-tbz") || + kmp->is("application/x-tgz") || + kmp->is("application/x-tzo") + ) { + stillInside = true; + } + else { + KURL url1 = url.upURL(); + while (url1 != url1.upURL()) { + KMimeType::Ptr kmp = + KMimeType::findByPath(url1.url(-1)); + if (kmp->is("application/x-tar") || + kmp->is("application/x-tarz") || + kmp->is("application/x-tbz") || + kmp->is("application/x-tgz") || + kmp->is("application/x-tzo") + ) { + stillInside = true; + break; + } + url1 = url1.upURL(); + } + } + if (!stillInside) + { + // Drop the tar:/ protocol since we are not in the tar anymore + urlStr = url.path(); + } + } + + + if (urlStr.at(0) == '~') { + // replace '~' by the home directory + urlStr.remove(0, 1); + urlStr.insert(0, QDir::home().path()); + } + + const KURL transformedURL(urlStr); + + if (m_historyIndex > 0) { + // Check whether the previous element of the history has the same URL. + // If yes, just go forward instead of inserting a duplicate history + // element. + const KURL& nextURL = m_history[m_historyIndex - 1].url(); + if (transformedURL == nextURL) { + goForward(); + return; + } + } + + const KURL& currURL = m_history[m_historyIndex].url(); + if (currURL == transformedURL) { + // don't insert duplicate history elements + return; + } + + updateHistoryElem(); + + const QValueListIterator<URLNavigator::HistoryElem> it = m_history.at(m_historyIndex); + m_history.insert(it, HistoryElem(transformedURL)); + updateContent(); + emit urlChanged(transformedURL); + emit historyChanged(); + + // Prevent an endless growing of the history: remembering + // the last 100 URLs should be enough... + if (m_historyIndex > 100) { + m_history.erase(m_history.begin()); + --m_historyIndex; + } +} + +const KURL& URLNavigator::url() const +{ + assert(!m_history.empty()); + return m_history[m_historyIndex].url(); +} + +KURL URLNavigator::url(int index) const +{ + assert(index >= 0); + QString path(url().prettyURL()); + path = path.section('/', 0, index); + + if (path.at(path.length()) != '/') + { + path.append('/'); + } + + return path; +} + +const QValueList<URLNavigator::HistoryElem>& URLNavigator::history(int& index) const +{ + index = m_historyIndex; + return m_history; +} + +void URLNavigator::goBack() +{ + updateHistoryElem(); + + const int count = m_history.count(); + if (m_historyIndex < count - 1) { + ++m_historyIndex; + updateContent(); + emit urlChanged(url()); + emit historyChanged(); + } +} + +void URLNavigator::goForward() +{ + if (m_historyIndex > 0) { + --m_historyIndex; + updateContent(); + emit urlChanged(url()); + emit historyChanged(); + } +} + +void URLNavigator::goUp() +{ + setURL(url().upURL()); +} + +void URLNavigator::goHome() +{ + setURL(DolphinSettings::instance().homeURL()); +} + +void URLNavigator::setURLEditable(bool editable) +{ + if (isURLEditable() != editable) { + m_toggleButton->toggle(); + slotClicked(); + } +} + +bool URLNavigator::isURLEditable() const +{ + return m_toggleButton->state() == QButton::On; +} + +void URLNavigator::editURL() +{ + setURLEditable(true); + m_pathBox->setFocus(); +} + +DolphinView* URLNavigator::dolphinView() const +{ + return m_dolphinView; +} + +void URLNavigator::keyReleaseEvent(QKeyEvent* event) +{ + QHBox::keyReleaseEvent(event); + if (isURLEditable() && (event->key() == Qt::Key_Escape)) { + setURLEditable(false); + } +} + +void URLNavigator::slotReturnPressed(const QString& text) +{ + // Parts of the following code have been taken + // from the class KateFileSelector located in + // kate/app/katefileselector.hpp of Kate. + // Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org> + // Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org> + // Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk> + + KURL typedURL(text); + if (typedURL.hasPass()) { + typedURL.setPass(QString::null); + } + + QStringList urls = m_pathBox->urls(); + urls.remove(typedURL.url()); + urls.prepend(typedURL.url()); + m_pathBox->setURLs(urls, KURLComboBox::RemoveBottom); + + setURL(typedURL); + // The URL might have been adjusted by URLNavigator::setURL(), hence + // synchronize the result in the path box. + m_pathBox->setURL(url()); +} + +void URLNavigator::slotURLActivated(const KURL& url) +{ + setURL(url); +} + +void URLNavigator::slotRequestActivation() +{ + m_dolphinView->requestActivation(); +} + +void URLNavigator::slotBookmarkActivated(int index) +{ + m_dolphinView->statusBar()->clear(); + m_dolphinView->requestActivation(); + + KBookmark bookmark = DolphinSettings::instance().bookmark(index); + m_dolphinView->setURL(bookmark.url()); +} + +void URLNavigator::slotContentsMoved(int x, int y) +{ + m_history[m_historyIndex].setContentsX(x); + m_history[m_historyIndex].setContentsY(y); +} + +void URLNavigator::slotClicked() +{ + updateContent(); + if (isURLEditable()) { + m_pathBox->setFocus(); + } + else { + m_dolphinView->setFocus(); + } +} + +void URLNavigator::updateHistoryElem() +{ + assert(m_historyIndex >= 0); + const KFileItem* item = m_dolphinView->currentFileItem(); + if (item != 0) { + m_history[m_historyIndex].setCurrentFileName(item->name()); + } + m_history[m_historyIndex].setContentsX(m_dolphinView->contentsX()); + m_history[m_historyIndex].setContentsY(m_dolphinView->contentsY()); +} + +void URLNavigator::updateContent() +{ + const QObjectList* list = children(); + if (list == 0) { + return; + } + + // set the iterator to the first URL navigator button + QObjectListIterator it(*list); + QObject* object = 0; + while ((object = it.current()) != 0) { + if (object->inherits("URLNavigatorButton")) { + break; + } + ++it; + } + + // delete all existing URL navigator buttons + QPtrList<QWidget> deleteList; + while ((object = it.current()) != 0) { + if (object->inherits("URLNavigatorButton")) { + // Don't close and delete the navigator button immediatly, otherwise + // the iterator won't work anymore and an object would get deleted more + // than once (-> crash). + deleteList.append(static_cast<QWidget*>(object)); + } + ++it; + } + + // now close and delete all unused navigator buttons + QPtrListIterator<QWidget> deleteIter(deleteList); + QWidget* widget = 0; + while ((widget = deleteIter.current()) != 0) { + widget->close(); + widget->deleteLater(); + ++deleteIter; + } + + m_bookmarkSelector->updateSelection(url()); + + QToolTip::remove(m_toggleButton); + QString path(url().prettyURL()); + if (m_toggleButton->state() == QButton::On) { + // TODO: don't hardcode the shortcut as part of the text + QToolTip::add(m_toggleButton, i18n("Browse (Ctrl+B, Escape)")); + + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + m_pathBox->show(); + m_pathBox->setURL(url()); + } + else { + // TODO: don't hardcode the shortcut as part of the text + QToolTip::add(m_toggleButton, i18n("Edit location (Ctrl+L)")); + + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_pathBox->hide(); + QString dir_name; + + // get the data from the currently selected bookmark + KBookmark bookmark = m_bookmarkSelector->selectedBookmark(); + //int bookmarkIndex = m_bookmarkSelector->selectedIndex(); + + QString bookmarkPath; + if (bookmark.isNull()) { + // No bookmark is a part of the current URL. + // The following code tries to guess the bookmark + // path. E. g. "fish://root@192.168.0.2/var/lib" writes + // "fish://root@192.168.0.2" to 'bookmarkPath', which leads to the + // navigation indication 'Custom Path > var > lib". + int idx = path.find(QString("//")); + idx = path.find("/", (idx < 0) ? 0 : idx + 2); + bookmarkPath = (idx < 0) ? path : path.left(idx); + } + else { + bookmarkPath = bookmark.url().prettyURL(); + } + const uint len = bookmarkPath.length(); + + // calculate the start point for the URL navigator buttons by counting + // the slashs inside the bookmark URL + int slashCount = 0; + for (uint i = 0; i < len; ++i) { + if (bookmarkPath.at(i) == QChar('/')) { + ++slashCount; + } + } + if ((len > 0) && bookmarkPath.at(len - 1) == QChar('/')) { + assert(slashCount > 0); + --slashCount; + } + + // create URL navigator buttons + int idx = slashCount; + bool hasNext = true; + do { + dir_name = path.section('/', idx, idx); + const bool isFirstButton = (idx == slashCount); + hasNext = isFirstButton || !dir_name.isEmpty(); + if (hasNext) { + URLNavigatorButton* button = new URLNavigatorButton(idx, this); + if (isFirstButton) { + // the first URL navigator button should get the name of the bookmark + // instead of the directory name + QString text = bookmark.text(); + if (text.isEmpty()) { + text = bookmarkPath; + } + button->setText(text); + } + button->show(); + ++idx; + } + } while (hasNext); + } +} + +#include "urlnavigator.moc" diff --git a/src/urlnavigator.h b/src/urlnavigator.h new file mode 100644 index 0000000..706215a --- /dev/null +++ b/src/urlnavigator.h @@ -0,0 +1,210 @@ +/*************************************************************************** +* Copyright (C) 2006 by Peter Penz * +* peter.penz@gmx.at * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program; if not, write to the * +* Free Software Foundation, Inc., * +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * +***************************************************************************/ + +#ifndef URLNAVIGATOR_H +#define URLNAVIGATOR_H + +#include <qhbox.h> +#include <kurl.h> +#include <qstring.h> + +class DolphinView; +class QPopupMenu; +class QPushButton; +class QComboBox; +class BookmarkSelector; +class KURLComboBox; +class KFileItem; + +/** + * @brief Navigation bar which contains the current shown URL. + * + * The URL navigator offers two modes: + * - Editable: Represents the 'classic' mode, where the current URL + * is editable inside a line editor. + * - Non editable: The URL is represented by a number of buttons, where + * clicking on a button results in activating the URL + * the button represents. This mode also supports drag + * and drop of items. + * + * The mode can be changed by a toggle button located on the left side of + * the navigator. + * + * The URL navigator also remembers the URL history and allows to go + * back and forward within this history. + * + * @author Peter Penz +*/ +class URLNavigator : public QHBox +{ + Q_OBJECT + +public: + /** + * @brief Represents the history element of an URL. + * + * A history element contains the URL, the name of the current file + * (the 'current file' is the file where the cursor is located) and + * the x- and y-position of the content. + */ + class HistoryElem { + public: + HistoryElem(); + HistoryElem(const KURL& url); + ~HistoryElem(); // non virtual + + const KURL& url() const { return m_url; } + + void setCurrentFileName(const QString& name) { m_currentFileName = name; } + const QString& currentFileName() const { return m_currentFileName; } + + void setContentsX(int x) { m_contentsX = x; } + int contentsX() const { return m_contentsX; } + + void setContentsY(int y) { m_contentsY = y; } + int contentsY() const { return m_contentsY; } + + private: + KURL m_url; + QString m_currentFileName; + int m_contentsX; + int m_contentsY; + }; + + URLNavigator(const KURL& url, DolphinView* dolphinView);; + virtual ~URLNavigator(); + + /** + * Sets the current active URL. + * The signals URLNavigator::urlChanged and URLNavigator::historyChanged + * are submitted. + */ + void setURL(const KURL& url); + + /** Returns the current active URL. */ + const KURL& url() const; + + /** Returns the portion of the current active URL up to the button at index. */ + KURL url(int index) const; + + /** + * Returns the complete URL history. The index 0 indicates the oldest + * history element. + * @param index Output parameter which indicates the current + * index of the location. + */ + const QValueList<HistoryElem>& history(int& index) const; + + /** + * Goes back one step in the URL history. The signals + * URLNavigator::urlChanged and URLNavigator::historyChanged + * are submitted. + */ + void goBack(); + + /** + * Goes forward one step in the URL history. The signals + * URLNavigator::urlChanged and URLNavigator::historyChanged + * are submitted. + */ + void goForward(); + + /** + * Goes up one step of the URL path. The signals + * URLNavigator::urlChanged and URLNavigator::historyChanged + * are submitted. + */ + void goUp(); + + /** + * Goes to the home URL. The signals URLNavigator::urlChanged + * and URLNavigator::historyChanged are submitted. + */ + void goHome(); + + /** + * Allows to edit the URL of the navigation bar if \a editable + * is true. If \a editable is false, each part of + * the URL is presented by a button for a fast navigation. + */ + void setURLEditable(bool editable); + + /** + * @return True, if the URL is editable by the user within a line editor. + * If false is returned, each part of the URL is presented by a button + * for fast navigation. + */ + bool isURLEditable() const; + + /** + * Switches to the edit mode and assures that the keyboard focus + * is assigned. + */ + void editURL(); + + DolphinView* dolphinView() const; + +signals: + void urlChanged(const KURL& url); + void historyChanged(); + +protected: + /** If the Escape key is pressed, the navigation bar should switch + to the browse mode. */ + virtual void keyReleaseEvent(QKeyEvent* event); + +private slots: + void slotReturnPressed(const QString& text); + void slotURLActivated(const KURL& url); + + void slotRequestActivation(); + void slotBookmarkActivated(int index); + + /** + * Stores the coordinates of the moved content into + * the current history element. Is usually triggered + * by the signal 'contentsMoved' emitted by DolphinView. + */ + void slotContentsMoved(int x, int y); + + /** + * Switches the navigation bar between the editable and noneditable + * state (see setURLEditable()) and is connected to the clicked signal + * of the navigation bar button. + */ + void slotClicked(); + +private: + int m_historyIndex; + DolphinView* m_dolphinView; + QValueList<HistoryElem> m_history; + QPushButton* m_toggleButton; + BookmarkSelector* m_bookmarkSelector; + KURLComboBox* m_pathBox; + + /** + * Updates the history element with the current file item + * and the contents position. + */ + void updateHistoryElem(); + void updateContent(); +}; + +#endif diff --git a/src/urlnavigatorbutton.cpp b/src/urlnavigatorbutton.cpp new file mode 100644 index 0000000..1cc5bcc --- /dev/null +++ b/src/urlnavigatorbutton.cpp @@ -0,0 +1,393 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * + * Copyright (C) 2006 by Aaron J. Seigo (<aseigo@kde.org>) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "urlnavigatorbutton.h" +#include <qcursor.h> +#include <qfontmetrics.h> +#include <qpainter.h> +#include <qtimer.h> +#include <qtooltip.h> + +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <kio/jobclasses.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <kurl.h> +#include <kurldrag.h> +#include <assert.h> + +#include "urlnavigator.h" +#include "dolphinview.h" +#include "dolphin.h" + +URLNavigatorButton::URLNavigatorButton(int index, URLNavigator* parent) : + URLButton(parent), + m_index(-1), + m_listJob(0) +{ + setAcceptDrops(true); + setMinimumWidth(arrowWidth()); + setIndex(index); + connect(this, SIGNAL(clicked()), this, SLOT(updateNavigatorURL())); + + m_popupDelay = new QTimer(this); + connect(m_popupDelay, SIGNAL(timeout()), this, SLOT(startListJob())); + connect(this, SIGNAL(pressed()), this, SLOT(startPopupDelay())); +} + +URLNavigatorButton::~URLNavigatorButton() +{ +} + +void URLNavigatorButton::setIndex(int index) +{ + if (index < 0) { + index = 0; + } + + m_index = index; + QString path(urlNavigator()->url().prettyURL()); + setText(path.section('/', index, index)); + + // Check whether the button indicates the full path of the URL. If + // this is the case, the button is marked as 'active'. + ++index; + QFont adjustedFont(font()); + if (path.section('/', index, index).isEmpty()) { + setDisplayHintEnabled(ActivatedHint, true); + adjustedFont.setBold(true); + } + else { + setDisplayHintEnabled(ActivatedHint, false); + adjustedFont.setBold(false); + } + + setFont(adjustedFont); + update(); +} + +int URLNavigatorButton::index() const +{ + return m_index; +} + +void URLNavigatorButton::drawButton(QPainter* painter) +{ + const int buttonWidth = width(); + const int buttonHeight = height(); + + QColor backgroundColor; + QColor foregroundColor; + const bool isHighlighted = isDisplayHintEnabled(EnteredHint) || + isDisplayHintEnabled(DraggedHint) || + isDisplayHintEnabled(PopupActiveHint); + if (isHighlighted) { + backgroundColor = KGlobalSettings::highlightColor(); + foregroundColor = KGlobalSettings::highlightedTextColor(); + } + else { + backgroundColor = colorGroup().background(); + foregroundColor = KGlobalSettings::buttonTextColor(); + } + + // dimm the colors if the parent view does not have the focus + const DolphinView* parentView = urlNavigator()->dolphinView(); + const Dolphin& dolphin = Dolphin::mainWin(); + + const bool isActive = (dolphin.activeView() == parentView); + if (!isActive) { + QColor dimmColor(colorGroup().background()); + foregroundColor = mixColors(foregroundColor, dimmColor); + if (isHighlighted) { + backgroundColor = mixColors(backgroundColor, dimmColor); + } + } + + // draw button background + painter->setPen(NoPen); + painter->setBrush(backgroundColor); + painter->drawRect(0, 0, buttonWidth, buttonHeight); + + int textWidth = buttonWidth; + if (isDisplayHintEnabled(ActivatedHint) && isActive || isHighlighted) { + painter->setPen(foregroundColor); + } + else { + // dimm the foreground color by mixing it with the background + foregroundColor = mixColors(foregroundColor, backgroundColor); + painter->setPen(foregroundColor); + } + + if (!isDisplayHintEnabled(ActivatedHint)) { + // draw arrow + const int border = 2; // horizontal border + const int middleY = height() / 2; + const int width = arrowWidth(); + const int startX = (buttonWidth - width) - (2 * border); + const int startTopY = middleY - (width - 1); + const int startBottomY = middleY + (width - 1); + for (int i = 0; i < width; ++i) { + painter->drawLine(startX, startTopY + i, startX + i, startTopY + i); + painter->drawLine(startX, startBottomY - i, startX + i, startBottomY - i); + } + + textWidth = startX - border; + } + + const bool clipped = isTextClipped(); + const int align = clipped ? Qt::AlignVCenter : Qt::AlignCenter; + painter->drawText(QRect(0, 0, textWidth, buttonHeight), align, text()); + + if (clipped) { + // Blend the right area of the text with the background, as the + // text is clipped. + // TODO: use alpha blending in Qt4 instead of drawing the text that often + const int blendSteps = 16; + + QColor blendColor(backgroundColor); + const int redInc = (foregroundColor.red() - backgroundColor.red()) / blendSteps; + const int greenInc = (foregroundColor.green() - backgroundColor.green()) / blendSteps; + const int blueInc = (foregroundColor.blue() - backgroundColor.blue()) / blendSteps; + for (int i = 0; i < blendSteps; ++i) { + painter->setClipRect(QRect(textWidth - i, 0, 1, buttonHeight)); + painter->setPen(blendColor); + painter->drawText(QRect(0, 0, textWidth, buttonHeight), align, text()); + + blendColor.setRgb(blendColor.red() + redInc, + blendColor.green() + greenInc, + blendColor.blue() + blueInc); + } + } +} + +void URLNavigatorButton::enterEvent(QEvent* event) +{ + URLButton::enterEvent(event); + + // if the text is clipped due to a small window width, the text should + // be shown as tooltip + if (isTextClipped()) { + QToolTip::add(this, text()); + } +} + +void URLNavigatorButton::leaveEvent(QEvent* event) +{ + URLButton::leaveEvent(event); + QToolTip::remove(this); +} + +void URLNavigatorButton::dropEvent(QDropEvent* event) +{ + KURL::List urls; + if (KURLDrag::decode(event, urls) && !urls.isEmpty()) { + setDisplayHintEnabled(DraggedHint, true); + + QString path(urlNavigator()->url().prettyURL()); + path = path.section('/', 0, m_index); + + Dolphin::mainWin().dropURLs(urls, KURL(path)); + + setDisplayHintEnabled(DraggedHint, false); + update(); + } +} + +void URLNavigatorButton::dragEnterEvent(QDragEnterEvent* event) +{ + event->accept(KURLDrag::canDecode(event)); + + setDisplayHintEnabled(DraggedHint, true); + update(); +} + +void URLNavigatorButton::dragLeaveEvent(QDragLeaveEvent* event) +{ + URLButton::dragLeaveEvent(event); + + setDisplayHintEnabled(DraggedHint, false); + update(); +} + + +void URLNavigatorButton::updateNavigatorURL() +{ + URLNavigator* navigator = urlNavigator(); + assert(navigator != 0); + navigator->setURL(navigator->url(m_index)); +} + +void URLNavigatorButton::startPopupDelay() +{ + if (m_popupDelay->isActive() || m_listJob) { + return; + } + + m_popupDelay->start(300, true); +} + +void URLNavigatorButton::stopPopupDelay() +{ + m_popupDelay->stop(); + if (m_listJob) { + m_listJob->kill(); + m_listJob = 0; + } +} + +void URLNavigatorButton::startListJob() +{ + if (m_listJob) { + return; + } + + KURL url = urlNavigator()->url(m_index); + m_listJob = KIO::listDir(url, false, false); + m_subdirs.clear(); // just to be ++safe + + connect(m_listJob, SIGNAL(entries(KIO::Job*, const KIO::UDSEntryList &)), + this, SLOT(entriesList(KIO::Job*, const KIO::UDSEntryList&))); + connect(m_listJob, SIGNAL(result(KIO::Job*)), this, SLOT(listJobFinished(KIO::Job*))); +} + +void URLNavigatorButton::entriesList(KIO::Job* job, const KIO::UDSEntryList& entries) +{ + if (job != m_listJob) { + return; + } + + KIO::UDSEntryList::const_iterator it = entries.constBegin(); + KIO::UDSEntryList::const_iterator itEnd = entries.constEnd(); + while (it != itEnd) { + QString name; + bool isDir = false; + KIO::UDSEntry entry = *it; + KIO::UDSEntry::const_iterator atomIt = entry.constBegin(); + KIO::UDSEntry::const_iterator atomEndIt = entry.constEnd(); + + while (atomIt != atomEndIt) { + switch ((*atomIt).m_uds) { + case KIO::UDS_NAME: + name = (*atomIt).m_str; + break; + case KIO::UDS_FILE_TYPE: + isDir = S_ISDIR((*atomIt).m_long); + break; + default: + break; + } + ++atomIt; + } + + if (isDir) { + m_subdirs.append(name); + } + + ++it; + } + + m_subdirs.sort(); +} + +void URLNavigatorButton::listJobFinished(KIO::Job* job) +{ + if (job != m_listJob) { + return; + } + + if (job->error() || m_subdirs.isEmpty()) { + // clear listing + return; + } + + setDisplayHintEnabled(PopupActiveHint, true); + update(); // ensure the button is drawn highlighted + QPopupMenu* dirsMenu = new QPopupMenu(this); + //setPopup(dirsMenu); + QStringList::const_iterator it = m_subdirs.constBegin(); + QStringList::const_iterator itEnd = m_subdirs.constEnd(); + int i = 0; + while (it != itEnd) { + dirsMenu->insertItem(*it, i); + ++i; + ++it; + } + + int result = dirsMenu->exec(urlNavigator()->mapToGlobal(geometry().bottomLeft())); + + if (result >= 0) { + KURL url = urlNavigator()->url(m_index); + url.addPath(*m_subdirs.at(result)); + urlNavigator()->setURL(url); + } + + m_listJob = 0; + m_subdirs.clear(); + delete dirsMenu; + setDisplayHintEnabled(PopupActiveHint, false); +} + +int URLNavigatorButton::arrowWidth() const +{ + int width = (height() / 2) - 7; + if (width < 4) { + width = 4; + } + return width; +} + +bool URLNavigatorButton::isTextClipped() const +{ + int availableWidth = width(); + if (!isDisplayHintEnabled(ActivatedHint)) { + availableWidth -= arrowWidth() + 1; + } + + QFontMetrics fontMetrics(font()); + return fontMetrics.width(text()) >= availableWidth; +} + + +void URLNavigatorButton::mousePressEvent(QMouseEvent * event) +{ + if (event->button() == LeftButton) + dragPos = event->pos(); + URLButton::mousePressEvent(event); +} + +void URLNavigatorButton::mouseMoveEvent(QMouseEvent * event) +{ + if (event->state() & LeftButton) { + int distance = (event->pos() - dragPos).manhattanLength(); + if (distance > QApplication::startDragDistance()*2)//don't start on small move (for submenu usability) + startDrag(); + } + URLButton::mouseMoveEvent(event); +} + +void URLNavigatorButton::startDrag() +{ + KURL url = urlNavigator()->url(m_index); + KURL::List lst; + lst.append( url ); + KURLDrag *drag = new KURLDrag(lst, this); + drag->drag(); +} diff --git a/src/urlnavigatorbutton.h b/src/urlnavigatorbutton.h new file mode 100644 index 0000000..de71fd6 --- /dev/null +++ b/src/urlnavigatorbutton.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) * + * Copyright (C) 2006 by Aaron J. Seigo (<aseigo@kde.org>) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef URLNAVIGATORBUTTON_H +#define URLNAVIGATORBUTTON_H + +#include <qstringlist.h> + +#include <kio/global.h> + +#include <urlbutton.h> + +class KURL; +class URLNavigator; +class QPainter; + +namespace KIO +{ + class Job; +} + +/** + * @brief Button of the URL navigator which contains one part of an URL. + * + * It is possible to drop a various number of items to an URL button. In this case + * a context menu is opened where the user must select whether he wants + * to copy, move or link the dropped items to the URL part indicated by + * the button. + */ +class URLNavigatorButton : public URLButton +{ + Q_OBJECT + +public: + URLNavigatorButton(int index, URLNavigator* parent = 0); + virtual ~URLNavigatorButton(); + void setIndex(int index); + int index() const; + +protected: + virtual void drawButton(QPainter* painter); + virtual void enterEvent(QEvent* event); + virtual void leaveEvent(QEvent* event); + //drag + void mousePressEvent( QMouseEvent *event ); + void mouseMoveEvent( QMouseEvent *event ); + //drop + virtual void dropEvent(QDropEvent* event); + virtual void dragEnterEvent(QDragEnterEvent* event); + virtual void dragLeaveEvent(QDragLeaveEvent* event); + +private slots: + void updateNavigatorURL(); + void startPopupDelay(); + void stopPopupDelay(); + void startListJob(); + void entriesList(KIO::Job* job, const KIO::UDSEntryList& entries); + void listJobFinished(KIO::Job* job); + +private: + int arrowWidth() const; + bool isTextClipped() const; + void startDrag(); + + int m_index; + QTimer* m_popupDelay; + KIO::Job* m_listJob; + QStringList m_subdirs; + QPoint dragPos; +}; + +#endif diff --git a/src/viewproperties.cpp b/src/viewproperties.cpp new file mode 100644 index 0000000..66d5935 --- /dev/null +++ b/src/viewproperties.cpp @@ -0,0 +1,362 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include <assert.h> + +#include <qdatetime.h> +#include <qdir.h> +#include <qfile.h> + +#include <klocale.h> +#include <kstandarddirs.h> +#include <kurl.h> + +#include "viewproperties.h" +#include "dolphinsettings.h" + +#define FILE_NAME "/.d3lphinview" + +ViewProperties::ViewProperties(KURL url) : + m_changedProps(false), + m_autoSave(true), + m_subDirValidityHidden(false) +{ + url.cleanPath(true); + m_filepath = url.path(); + + if ((m_filepath.length() < 1) || (m_filepath.at(0) != QChar('/'))) { + return; + } + + // we try and save it to a file in the directory being viewed + // if the directory is not writable by the user or the directory is not local + // we store the properties information in a local file + DolphinSettings& settings = DolphinSettings::instance(); + if (settings.isSaveView()) { + QString rootDir("/"); // TODO: should this be set to the root of the bookmark, if any? + if (url.isLocalFile()) { + QFileInfo info(m_filepath); + + if (!info.isWritable()) { + QString basePath = KGlobal::instance()->instanceName(); + basePath.append("/view_properties/local"); + rootDir = locateLocal("data", basePath); + m_filepath = rootDir + m_filepath; + } + } + else { + QString basePath = KGlobal::instance()->instanceName(); + basePath.append("/view_properties/remote/").append(url.host()); + rootDir = locateLocal("data", basePath); + m_filepath = rootDir + m_filepath; + } + + QDir dir(m_filepath); + QFile file(m_filepath + FILE_NAME); + + + PropertiesNode node(&file); + + const bool isValidForSubDirs = !node.isEmpty() && node.isValidForSubDirs(); + while ((dir.path() != rootDir) && dir.cdUp()) { + QFile file(dir.path() + FILE_NAME); + PropertiesNode parentNode(&file); + if (!parentNode.isEmpty()) { + const bool inheritProps = parentNode.isValidForSubDirs() && + (parentNode.subDirProperties().m_timeStamp > + node.localProperties().m_timeStamp); + + if (inheritProps) { + node.setLocalProperties(parentNode.subDirProperties()); + break; + } + } + } + + m_node = node; + + if (isValidForSubDirs) { + m_subDirValidityHidden = true; + } + m_node.setValidForSubDirs(false); + } +} + +ViewProperties::~ViewProperties() +{ + if (m_changedProps && m_autoSave) { + save(); + } +} + +void ViewProperties::setViewMode(DolphinView::Mode mode) +{ + if (m_node.localProperties().m_viewMode != mode) { + m_node.setViewMode(mode); + updateTimeStamp(); + } +} + +DolphinView::Mode ViewProperties::viewMode() const +{ + return m_node.localProperties().m_viewMode; +} + +void ViewProperties::setShowHiddenFilesEnabled(bool show) +{ + if (m_node.localProperties().m_showHiddenFiles != show) { + m_node.setShowHiddenFilesEnabled(show); + updateTimeStamp(); + } +} + +bool ViewProperties::isShowHiddenFilesEnabled() const +{ + return m_node.localProperties().m_showHiddenFiles; +} + +void ViewProperties::setSorting(DolphinView::Sorting sorting) +{ + if (m_node.localProperties().m_sorting != sorting) { + m_node.setSorting(sorting); + updateTimeStamp(); + } +} + +DolphinView::Sorting ViewProperties::sorting() const +{ + return m_node.localProperties().m_sorting; +} + +void ViewProperties::setSortOrder(Qt::SortOrder sortOrder) +{ + if (m_node.localProperties().m_sortOrder != sortOrder) { + m_node.setSortOrder(sortOrder); + updateTimeStamp(); + } +} + +Qt::SortOrder ViewProperties::sortOrder() const +{ + return m_node.localProperties().m_sortOrder; +} + +void ViewProperties::setValidForSubDirs(bool valid) +{ + if (m_node.isValidForSubDirs() != valid) { + m_node.setValidForSubDirs(valid); + updateTimeStamp(); + } +} + +bool ViewProperties::isValidForSubDirs() const +{ + return m_node.isValidForSubDirs(); +} + +void ViewProperties::setAutoSaveEnabled(bool autoSave) +{ + m_autoSave = autoSave; +} + +bool ViewProperties::isAutoSaveEnabled() const +{ + return m_autoSave; +} + +void ViewProperties::save() +{ + DolphinSettings& settings = DolphinSettings::instance(); + if (settings.isSaveView()) { + QFile file(m_filepath + FILE_NAME); + KStandardDirs::makeDir(m_filepath); + if (!file.open(IO_WriteOnly)) { + return; + } + + const Properties& props = m_node.localProperties(); + char viewMode = static_cast<char>(props.m_viewMode) + '0'; + char sorting = static_cast<char>(props.m_sorting) + '0'; + const bool isValidForSubDirs = m_node.isValidForSubDirs() || m_subDirValidityHidden; + + QTextStream stream(&file); + stream << "V01" + << viewMode + << (props.m_showHiddenFiles ? '1' : '0') + << props.m_timeStamp.toString("yyyyMMddhhmmss") + << sorting + << ((props.m_sortOrder == Qt::Ascending) ? 'A' : 'D') + << (isValidForSubDirs ? '1' : '0'); + + if (m_node.isValidForSubDirs()) { + m_node.setSubDirProperties(props); + } + + if (isValidForSubDirs) { + const Properties& subDirProps = m_node.subDirProperties(); + viewMode = static_cast<char>(subDirProps.m_viewMode) + '0'; + sorting = static_cast<char>(subDirProps.m_sorting) + '0'; + stream << viewMode + << (subDirProps.m_showHiddenFiles ? '1' : '0') + << subDirProps.m_timeStamp.toString("yyyyMMddhhmmss") + << sorting + << ((subDirProps.m_sortOrder == Qt::Ascending) ? 'A' : 'D'); + } + file.flush(); + file.close(); + + m_changedProps = false; + } +} + +void ViewProperties::updateTimeStamp() +{ + m_changedProps = true; + m_node.setTimeStamp(QDateTime::currentDateTime()); +} + +ViewProperties::Properties::Properties() : + m_showHiddenFiles(false), + m_viewMode(DolphinView::IconsView), + m_sorting(DolphinView::SortByName), + m_sortOrder(Qt::Ascending) +{ + m_timeStamp.setDate(QDate(1999, 12, 31)); + m_timeStamp.setTime(QTime(23, 59, 59)); + + m_viewMode = DolphinSettings::instance().defaultViewMode(); +} + +ViewProperties::Properties::~Properties() +{ +} + +ViewProperties::PropertiesNode::PropertiesNode(QFile* file) : + m_empty(true) +{ + m_isValidForSubDirs = false; + + if ((file != 0) && file->open(IO_ReadOnly)) { + m_empty = false; + + const int max_len = 41; + static char buffer[max_len]; + + // TODO: use memset + for (int i = 0; i < max_len; ++i) { + buffer[i] = 0; + } + + file->readLine(buffer, max_len); + + // Check version of viewproperties file. The initial format + // sadly had no version numbering, which is indicated by a missing 'V' + // as first letter. The current scheme uses V + 2 digits. + int version = 0; + int startInc = 0; + if (buffer[0] == 'V') { + startInc = 3; // skip version info (e. g. V01) + version = 1; + // currently no further versions are available: + assert(buffer[1] == '0'); + assert(buffer[2] == '1'); + } + + int readBytes = readProperties(m_props, &buffer[startInc], version); + assert(readBytes >= 0); + + // check whether sub directory properties are available + m_isValidForSubDirs = (buffer[startInc + readBytes] != '0'); + if (m_isValidForSubDirs) { + readBytes = readProperties(m_subDirProps, + &buffer[startInc + readBytes + 1], + version); + } + file->close(); + + m_empty = (readBytes <= 0); + } +} + +ViewProperties::PropertiesNode::~PropertiesNode() +{ +} + +ViewProperties::PropertiesNode& + ViewProperties::PropertiesNode::operator = (const PropertiesNode& node) +{ + if (&node != this) { + m_empty = node.m_empty; + m_isValidForSubDirs = node.m_isValidForSubDirs; + m_props = node.m_props; + m_subDirProps = node.m_subDirProps; + } + + return *this; +} + +int ViewProperties::PropertiesNode::toInt(const char* buffer, int count) const +{ + assert(buffer != 0); + + int value = 0; + for (int i = 0; i < count; ++i) { + value = value * 10 + static_cast<int>(buffer[i] - '0'); + } + + return value; +} + +int ViewProperties::PropertiesNode::readProperties(Properties& props, + const char* buffer, + int version) +{ + props.m_viewMode = static_cast<DolphinView::Mode>(buffer[0] - '0'); + props.m_showHiddenFiles = (buffer[1] != '0'); + + // read date + QDateTime timeStamp; + const int year = toInt(&(buffer[2]), 4); + const int month = toInt(&(buffer[6]), 2); + const int day = toInt(&(buffer[8]), 2); + QDate date(year, month, day); + timeStamp.setDate(date); + + // read time + const int hour = toInt(&(buffer[10]), 2); + const int minute = toInt(&(buffer[12]), 2); + const int second = toInt(&(buffer[14]), 2); + QTime time(hour, minute, second); + timeStamp.setTime(time); + + props.m_timeStamp = timeStamp; + + int readCount = 16; + if (version >= 1) { + // read sorting type and sorting order + props.m_sorting = static_cast<DolphinView::Sorting>(buffer[16] - '0'); + props.m_sortOrder = (buffer[17] == 'A') ? Qt::Ascending : Qt::Descending; + readCount = 18; + } + + return (date.isValid() && time.isValid()) ? readCount : -1; +} + + diff --git a/src/viewproperties.h b/src/viewproperties.h new file mode 100644 index 0000000..77f0a05 --- /dev/null +++ b/src/viewproperties.h @@ -0,0 +1,129 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef VIEWPROPERTIES_H +#define VIEWPROPERTIES_H + +#include <dolphinview.h> +#include <kurl.h> +#include <qdatetime.h> +class QFile; + +/** + * @short Maintains the view properties like 'view mode' or 'show hidden files' for a directory. + * + * The view properties are automatically stored inside + * the directory as hidden file called '.dolphinview'. To read out the view properties + * just construct an instance by passing the URL of the directory: + * \code + * ViewProperties props(KURL("/home/peter/Documents")); + * const DolphinView::Mode mode = props.viewMode(); + * const bool showHiddenFiles = props.isShowHiddenFilesEnabled(); + * \endcode + * When modifying a view property, the '.dolphinview' file is automatically updated + * inside the destructor. + * + * @author Peter Penz + */ +// TODO: provide detailed design description, as mapping the user model to +// the physical modal is not trivial. +class ViewProperties +{ +public: + ViewProperties(KURL url); + virtual ~ViewProperties(); + + void setViewMode(DolphinView::Mode mode); + DolphinView::Mode viewMode() const; + + void setShowHiddenFilesEnabled(bool show); + bool isShowHiddenFilesEnabled() const; + + void setSorting(DolphinView::Sorting sorting); + DolphinView::Sorting sorting() const; + + void setSortOrder(Qt::SortOrder sortOrder); + Qt::SortOrder sortOrder() const; + + void setValidForSubDirs(bool valid); + bool isValidForSubDirs() const; + + void setAutoSaveEnabled(bool autoSave); + bool isAutoSaveEnabled() const; + + void updateTimeStamp(); + void save(); + +private: + class Properties + { + public: + Properties(); + ~Properties(); // non virtual + + bool m_showHiddenFiles; + DolphinView::Mode m_viewMode; + QDateTime m_timeStamp; + DolphinView::Sorting m_sorting; + Qt::SortOrder m_sortOrder; + }; + + class PropertiesNode + { + public: + PropertiesNode(QFile* file = 0); + ~PropertiesNode(); + PropertiesNode& operator = (const PropertiesNode& node); + bool isEmpty() const { return m_empty; } + + void setValidForSubDirs(bool valid) { m_isValidForSubDirs = valid; } + bool isValidForSubDirs() const { return m_isValidForSubDirs; } + + void setLocalProperties(const Properties& props) { m_props = props; } + const Properties& localProperties() const { return m_props; } + + void setShowHiddenFilesEnabled(bool show) { m_props.m_showHiddenFiles = show; } + void setViewMode(DolphinView::Mode mode) { m_props.m_viewMode = mode; } + void setTimeStamp(const QDateTime timeStamp) { m_props.m_timeStamp = timeStamp; } + const QDateTime& timeStamp() const { return m_props.m_timeStamp; } + void setSorting(DolphinView::Sorting sorting) { m_props.m_sorting = sorting; } + void setSortOrder(Qt::SortOrder sortOrder) { m_props.m_sortOrder = sortOrder; } + + void setSubDirProperties(const Properties& props) { m_subDirProps = props; } + const Properties& subDirProperties() const { return m_subDirProps; } + + private: + int toInt(const char* buffer, int count) const; + int readProperties(Properties& props, const char* buffer, int version); + + bool m_empty; + bool m_isValidForSubDirs; + Properties m_props; + Properties m_subDirProps; + }; + + bool m_changedProps; + bool m_autoSave; + bool m_subDirValidityHidden; + QString m_filepath; + PropertiesNode m_node; +}; + +#endif diff --git a/src/viewpropertiesdialog.cpp b/src/viewpropertiesdialog.cpp new file mode 100644 index 0000000..0739ad8 --- /dev/null +++ b/src/viewpropertiesdialog.cpp @@ -0,0 +1,235 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "viewpropertiesdialog.h" +#include <klocale.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qvbox.h> +#include <qbuttongroup.h> +#include <qcheckbox.h> +#include <qradiobutton.h> +#include <qpushbutton.h> +#include <qsizepolicy.h> +#include <qgroupbox.h> +#include <qcombobox.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <assert.h> + +#include "viewproperties.h" +#include "dolphinview.h" + +ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) : + KDialogBase(Plain, i18n("View Properties"), + Ok|Apply|Cancel, Ok), + m_isDirty(false), + m_dolphinView(dolphinView) +{ + assert(dolphinView != 0); + + const int margin = KDialog::marginHint(); + const QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + const KURL& url = dolphinView->url(); + m_viewProps = new ViewProperties(url); + m_viewProps->setAutoSaveEnabled(false); + + QVBoxLayout* topLayout = new QVBoxLayout(plainPage(), 0, spacingHint()); + + // create 'Properties' group containing view mode, sorting, sort order and show hidden files + QGroupBox* propsGroup = new QGroupBox(2, Qt::Horizontal, i18n("Properties"), plainPage()); + propsGroup->setSizePolicy(sizePolicy); + propsGroup->setMargin(margin); + + new QLabel(i18n("View mode:"), propsGroup); + m_viewMode = new QComboBox(propsGroup); + m_viewMode->insertItem(SmallIcon("view_icon"), i18n("Icons")); + m_viewMode->insertItem(SmallIcon("view_text"), i18n("Details")); + m_viewMode->insertItem(SmallIcon("gvdirpart"), i18n("Previews")); + const int index = static_cast<int>(m_viewProps->viewMode()); + m_viewMode->setCurrentItem(index); + + new QLabel(i18n("Sorting:"), propsGroup); + m_sorting = new QComboBox(propsGroup); + m_sorting->insertItem("By Name"); + m_sorting->insertItem("By Size"); + m_sorting->insertItem("By Date"); + int sortingIdx = 0; + switch (m_viewProps->sorting()) { + case DolphinView::SortByName: sortingIdx = 0; break; + case DolphinView::SortBySize: sortingIdx = 1; break; + case DolphinView::SortByDate: sortingIdx = 2; break; + default: break; + } + m_sorting->setCurrentItem(sortingIdx); + + new QLabel(i18n("Sort order:"), propsGroup); + m_sortOrder = new QComboBox(propsGroup); + m_sortOrder->insertItem(i18n("Ascending")); + m_sortOrder->insertItem(i18n("Descending")); + const int sortOrderIdx = (m_viewProps->sortOrder() == Qt::Ascending) ? 0 : 1; + m_sortOrder->setCurrentItem(sortOrderIdx); + + m_showHiddenFiles = new QCheckBox(i18n("Show hidden files"), propsGroup); + m_showHiddenFiles->setChecked(m_viewProps->isShowHiddenFilesEnabled()); + + // create 'Apply view properties to:' group + QButtonGroup* buttonGroup = new QButtonGroup(3, + Qt::Vertical, + i18n("Apply view properties to:"), + plainPage()); + buttonGroup->setSizePolicy(sizePolicy); + buttonGroup->setMargin(margin); + + m_applyToCurrentFolder = new QRadioButton(i18n("Current folder"), buttonGroup); + buttonGroup->insert(m_applyToCurrentFolder); + + m_applyToSubFolders = new QRadioButton(i18n("Current folder including all sub folders"), buttonGroup); + buttonGroup->insert(m_applyToSubFolders); + + m_applyToAllFolders = new QRadioButton(i18n("All folders"), buttonGroup); + buttonGroup->insert(m_applyToAllFolders); + + if (m_viewProps->isValidForSubDirs()) { + m_applyToSubFolders->setChecked(true); + } + else { + m_applyToCurrentFolder->setChecked(true); + } + + topLayout->addWidget(propsGroup); + topLayout->addWidget(buttonGroup); + + connect(m_viewMode, SIGNAL(activated(int)), + this, SLOT(slotViewModeChanged(int))); + connect(m_sorting, SIGNAL(activated(int)), + this, SLOT(slotSortingChanged(int))); + connect(m_sortOrder, SIGNAL(activated(int)), + this, SLOT(slotSortOrderChanged(int))); + connect(m_showHiddenFiles, SIGNAL(clicked()), + this, SLOT(slotShowHiddenFilesChanged())); + connect(m_applyToCurrentFolder, SIGNAL(clicked()), + this, SLOT(slotApplyToCurrentFolder())); + connect(m_applyToSubFolders, SIGNAL(clicked()), + this, SLOT(slotApplyToSubFolders())); + connect(m_applyToAllFolders, SIGNAL(clicked()), + this, SLOT(slotApplyToAllFolders())); +} + +ViewPropertiesDialog::~ViewPropertiesDialog() +{ + m_isDirty = false; + delete m_viewProps; + m_viewProps = 0; +} + +void ViewPropertiesDialog::slotOk() +{ + applyViewProperties(); + KDialogBase::slotOk(); +} + +void ViewPropertiesDialog::slotApply() +{ + applyViewProperties(); + KDialogBase::slotApply(); +} + +void ViewPropertiesDialog::slotViewModeChanged(int index) +{ + assert((index >= 0) && (index <= 2)); + m_viewProps->setViewMode(static_cast<DolphinView::Mode>(index)); + m_isDirty = true; +} + +void ViewPropertiesDialog::slotSortingChanged(int index) +{ + DolphinView::Sorting sorting = DolphinView::SortByName; + switch (index) { + case 1: sorting = DolphinView::SortBySize; break; + case 2: sorting = DolphinView::SortByDate; break; + default: break; + } + m_viewProps->setSorting(sorting); + m_isDirty = true; +} + +void ViewPropertiesDialog::slotSortOrderChanged(int index) +{ + Qt::SortOrder sortOrder = (index == 0) ? Qt::Ascending : Qt::Descending; + m_viewProps->setSortOrder(sortOrder); + m_isDirty = true; +} + +void ViewPropertiesDialog::slotShowHiddenFilesChanged() +{ + const bool show = m_showHiddenFiles->isChecked(); + m_viewProps->setShowHiddenFilesEnabled(show); + m_isDirty = true; +} + +void ViewPropertiesDialog::slotApplyToCurrentFolder() +{ + m_viewProps->setValidForSubDirs(false); + m_isDirty = true; +} + +void ViewPropertiesDialog::slotApplyToSubFolders() +{ + m_viewProps->setValidForSubDirs(true); + m_isDirty = true; +} + +void ViewPropertiesDialog::slotApplyToAllFolders() +{ + m_isDirty = true; +} + +void ViewPropertiesDialog::applyViewProperties() +{ + if (m_applyToAllFolders->isChecked()) { + if (m_isDirty) { + const QString text(i18n("The view properties of all folders will be replaced. Do you want to continue?")); + if (KMessageBox::questionYesNo(this, text) == KMessageBox::No) { + return; + } + } + + ViewProperties props(QDir::homeDirPath()); + props.setViewMode(m_viewProps->viewMode()); + props.setSorting(m_viewProps->sorting()); + props.setSortOrder(m_viewProps->sortOrder()); + props.setShowHiddenFilesEnabled(m_viewProps->isShowHiddenFilesEnabled()); + props.setValidForSubDirs(true); + } + else if (m_applyToSubFolders->isChecked() && m_isDirty) { + const QString text(i18n("The view properties of all sub folders will be replaced. Do you want to continue?")); + if (KMessageBox::questionYesNo(this, text) == KMessageBox::No) { + return; + } + } + + m_viewProps->save(); + m_dolphinView->setViewProperties(*m_viewProps); + m_isDirty = false; +} + +#include "viewpropertiesdialog.moc" diff --git a/src/viewpropertiesdialog.h b/src/viewpropertiesdialog.h new file mode 100644 index 0000000..0731a27 --- /dev/null +++ b/src/viewpropertiesdialog.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef VIEWPROPERTIESDIALOG_H +#define VIEWPROPERTIESDIALOG_H + +#include <kdialogbase.h> + +class QCheckBox; +class QButtonGroup; +class QComboBox; +class QRadioButton; +class ViewProperties; +class DolphinView; + +/** + * @brief Dialog for changing the current view properties of a directory. + * + * It is possible to specify the view mode and whether hidden files + * should be shown. The properties can be assigned to the current folder, + * recursively to all sub folders or to all folders. + * + * @author Peter Penz + */ +class ViewPropertiesDialog : public KDialogBase +{ + Q_OBJECT + +public: + ViewPropertiesDialog(DolphinView* dolphinView); + virtual ~ViewPropertiesDialog(); + +protected slots: + virtual void slotOk(); + virtual void slotApply(); + +private slots: + void slotViewModeChanged(int index); + void slotSortingChanged(int index); + void slotSortOrderChanged(int index); + void slotShowHiddenFilesChanged(); + void slotApplyToCurrentFolder(); + void slotApplyToSubFolders(); + void slotApplyToAllFolders(); + +private: + bool m_isDirty; + DolphinView* m_dolphinView; + ViewProperties* m_viewProps; + + QComboBox* m_viewMode; + QComboBox* m_sorting; + QComboBox* m_sortOrder; + QCheckBox* m_showHiddenFiles; + QRadioButton* m_applyToCurrentFolder; + QRadioButton* m_applyToSubFolders; + QRadioButton* m_applyToAllFolders; + + void applyViewProperties(); +}; + +#endif diff --git a/src/viewsettingspage.cpp b/src/viewsettingspage.cpp new file mode 100644 index 0000000..ccfa80e --- /dev/null +++ b/src/viewsettingspage.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "viewsettingspage.h" +#include <qtabwidget.h> +#include <qlayout.h> +#include <qlabel.h> +#include <kdialogbase.h> +#include <klocale.h> +#include "iconsviewsettingspage.h" +#include "detailsviewsettingspage.h" + +ViewSettingsPage::ViewSettingsPage(QWidget *parent) : + SettingsPageBase(parent), + m_iconsPage(0), + m_detailsPage(0), + m_previewsPage(0) +{ + QVBoxLayout* topLayout = new QVBoxLayout(parent, 0, KDialog::spacingHint()); + + QTabWidget* tabWidget = new QTabWidget(parent); + + // initialize 'Icons' tab + m_iconsPage = new IconsViewSettingsPage(DolphinIconsView::Icons, tabWidget); + tabWidget->addTab(m_iconsPage, SmallIcon("view_icon"), i18n("Icons")); + + // initialize 'Details' tab + m_detailsPage = new DetailsViewSettingsPage(tabWidget); + tabWidget->addTab(m_detailsPage, SmallIcon("view_text"), i18n("Details")); + + // initialize 'Previews' tab + m_previewsPage = new IconsViewSettingsPage(DolphinIconsView::Previews, tabWidget); + tabWidget->addTab(m_previewsPage, SmallIcon("gvdirpart"), i18n("Previews")); + + topLayout->addWidget(tabWidget, 0, 0 ); +} + +ViewSettingsPage::~ViewSettingsPage() +{ +} + +void ViewSettingsPage::applySettings() +{ + m_iconsPage->applySettings(); + m_detailsPage->applySettings(); + m_previewsPage->applySettings(); +} + +#include "viewsettingspage.moc" diff --git a/src/viewsettingspage.h b/src/viewsettingspage.h new file mode 100644 index 0000000..06017dd --- /dev/null +++ b/src/viewsettingspage.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz * + * peter.penz@gmx.at * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef VIEWSETTINGSPAGE_H +#define VIEWSETTINGSPAGE_H + +#include <qwidget.h> +#include <settingspagebase.h> + +class IconsViewSettingsPage; +class DetailsViewSettingsPage; + +/** + * @brief Page for the 'View' settings of the Dolphin settings dialog. + * + * The vies settings allow to set the properties for the icons mode, + * the details mode and the previews mode. + * + * @author Peter Penz <peter.penz@gmx.at> + */ +class ViewSettingsPage : public SettingsPageBase +{ + Q_OBJECT + +public: + ViewSettingsPage(QWidget* parent); + + virtual ~ViewSettingsPage(); + + /** @see SettingsPageBase::applySettings */ + virtual void applySettings(); + +private: + IconsViewSettingsPage* m_iconsPage; + DetailsViewSettingsPage* m_detailsPage; + IconsViewSettingsPage* m_previewsPage; +}; + +#endif |