diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ffb232ce28..6856991d5e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -91,6 +91,7 @@ set(dolphinprivate_LIB_SRCS views/viewmodecontroller.cpp views/viewproperties.cpp views/zoomlevelinfo.cpp + dolphinremoveaction.cpp ) if(HAVE_NEPOMUK) diff --git a/src/dolphincontextmenu.cpp b/src/dolphincontextmenu.cpp index 89a169f32d..af8b613849 100644 --- a/src/dolphincontextmenu.cpp +++ b/src/dolphincontextmenu.cpp @@ -24,6 +24,7 @@ #include "dolphinnewfilemenu.h" #include "dolphinviewcontainer.h" #include "dolphin_generalsettings.h" +#include "dolphinremoveaction.h" #include #include @@ -73,17 +74,14 @@ DolphinContextMenu::DolphinContextMenu(DolphinMainWindow* parent, m_context(NoContext), m_copyToMenu(parent), m_customActions(), - m_command(None), - m_shiftPressed(qApp->keyboardModifiers() & Qt::ShiftModifier), - m_removeAction(0) + m_command(None) { // The context menu either accesses the URLs of the selected items // or the items itself. To increase the performance both lists are cached. const DolphinView* view = m_mainWindow->activeViewContainer()->view(); m_selectedItems = view->selectedItems(); - m_removeAction = new QAction(this); - connect(m_removeAction, SIGNAL(triggered()), this, SLOT(slotRemoveActionTriggered())); + m_removeAction = new DolphinRemoveAction(this, m_mainWindow->actionCollection()); } DolphinContextMenu::~DolphinContextMenu() @@ -129,8 +127,7 @@ DolphinContextMenu::Command DolphinContextMenu::open() void DolphinContextMenu::keyPressEvent(QKeyEvent *ev) { if (ev->key() == Qt::Key_Shift) { - m_shiftPressed = true; - updateRemoveAction(); + m_removeAction->update(); } KMenu::keyPressEvent(ev); } @@ -138,23 +135,11 @@ void DolphinContextMenu::keyPressEvent(QKeyEvent *ev) void DolphinContextMenu::keyReleaseEvent(QKeyEvent *ev) { if (ev->key() == Qt::Key_Shift) { - // not just "m_shiftPressed = false", the user could be playing with both Shift keys... - m_shiftPressed = qApp->keyboardModifiers() & Qt::ShiftModifier; - updateRemoveAction(); + m_removeAction->update(); } KMenu::keyReleaseEvent(ev); } -void DolphinContextMenu::slotRemoveActionTriggered() -{ - const KActionCollection* collection = m_mainWindow->actionCollection(); - if (moveToTrash()) { - collection->action("move_to_trash")->trigger(); - } else { - collection->action("delete")->trigger(); - } -} - void DolphinContextMenu::openTrashContextMenu() { Q_ASSERT(m_context & TrashContext); @@ -374,7 +359,7 @@ void DolphinContextMenu::insertDefaultItemActions() addAction(collection->action("delete")); } else { addAction(m_removeAction); - updateRemoveAction(); + m_removeAction->update(); } } @@ -509,28 +494,4 @@ void DolphinContextMenu::addCustomActions() } } -void DolphinContextMenu::updateRemoveAction() -{ - const KActionCollection* collection = m_mainWindow->actionCollection(); - - // Using m_removeAction->setText(action->text()) does not apply the &-shortcut. - // This is only done until the original action has been shown at least once. To - // bypass this issue, the text and &-shortcut is applied manually. - const QAction* action = 0; - if (moveToTrash()) { - action = collection->action("move_to_trash"); - m_removeAction->setText(i18nc("@action:inmenu", "&Move to Trash")); - } else { - action = collection->action("delete"); - m_removeAction->setText(i18nc("@action:inmenu", "&Delete")); - } - m_removeAction->setIcon(action->icon()); - m_removeAction->setShortcuts(action->shortcuts()); -} - -bool DolphinContextMenu::moveToTrash() const -{ - return !m_shiftPressed; -} - #include "dolphincontextmenu.moc" diff --git a/src/dolphincontextmenu.h b/src/dolphincontextmenu.h index 1c65fab138..160f088040 100644 --- a/src/dolphincontextmenu.h +++ b/src/dolphincontextmenu.h @@ -36,6 +36,7 @@ class QAction; class DolphinMainWindow; class KFileItemActions; class KFileItemListProperties; +class DolphinRemoveAction; /** * @brief Represents the context menu which appears when doing a right @@ -94,13 +95,6 @@ protected: virtual void keyPressEvent(QKeyEvent *ev); virtual void keyReleaseEvent(QKeyEvent *ev); -private slots: - /** - * Triggers the 'Delete'-action if the shift-key has been pressed, otherwise - * the 'Move to Trash'-action gets triggered. - */ - void slotRemoveActionTriggered(); - private: void openTrashContextMenu(); void openTrashItemContextMenu(); @@ -148,20 +142,6 @@ private: */ void addCustomActions(); - /** - * Updates m_removeAction to represent the 'Delete'-action if the shift-key - * has been pressed or the selection is not local. Otherwise it represents - * the 'Move to Trash'-action. - */ - void updateRemoveAction(); - - /** - * @return True if a moving to the trash should be done instead of - * deleting the selected items. - * @see updateRemoveAction(), slotRemoveActionTriggered() - */ - bool moveToTrash() const; - private: struct Entry { @@ -197,8 +177,7 @@ private: Command m_command; - bool m_shiftPressed; - QAction* m_removeAction; // Action that represents either 'Move To Trash' or 'Delete' + DolphinRemoveAction* m_removeAction; // Action that represents either 'Move To Trash' or 'Delete' }; #endif diff --git a/src/dolphinpart.cpp b/src/dolphinpart.cpp index 627ba79c56..642b150136 100644 --- a/src/dolphinpart.cpp +++ b/src/dolphinpart.cpp @@ -18,6 +18,7 @@ */ #include "dolphinpart.h" +#include "dolphinremoveaction.h" #include #include @@ -64,6 +65,7 @@ K_EXPORT_PLUGIN(DolphinPartFactory("dolphinpart", "dolphin")) DolphinPart::DolphinPart(QWidget* parentWidget, QObject* parent, const QVariantList& args) : KParts::ReadOnlyPart(parent) ,m_openTerminalAction(0) + ,m_removeAction(0) { Q_UNUSED(args) setComponentData(DolphinPartFactory::componentData(), false); @@ -145,6 +147,10 @@ DolphinPart::DolphinPart(QWidget* parentWidget, QObject* parent, const QVariantL m_actionHandler->updateViewActions(); slotSelectionChanged(KFileItemList()); // initially disable selection-dependent actions + // Listen to events from the app so we can update the remove key by + // checking for a Shift key press. + qApp->installEventFilter(this); + // TODO there was a "always open a new window" (when clicking on a directory) setting in konqueror // (sort of spacial navigation) @@ -447,10 +453,18 @@ void DolphinPart::slotOpenContextMenu(const QPoint& pos, } } - if (addTrash) + if (!addTrash || !addDel) { + if (!m_removeAction) { + m_removeAction = new DolphinRemoveAction(this, actionCollection()); + } + editActions.append(m_removeAction); + m_removeAction->update(); + } else { + delete m_removeAction; + m_removeAction = 0; editActions.append(actionCollection()->action("move_to_trash")); - if (addDel) editActions.append(actionCollection()->action("delete")); + } // Normally KonqPopupMenu only shows the "Create new" submenu in the current view // since otherwise the created file would not be visible. @@ -593,6 +607,23 @@ void DolphinPart::setFilesToSelect(const KUrl::List& files) m_view->markUrlAsCurrent(files.at(0)); } +bool DolphinPart::eventFilter(QObject* obj, QEvent* event) +{ + const int type = event->type(); + + if ((type == QEvent::KeyPress || type == QEvent::KeyRelease) && m_removeAction) { + QMenu* menu = qobject_cast(obj); + if (menu && menu->parent() == m_view) { + QKeyEvent* ev = static_cast(event); + if (ev->key() == Qt::Key_Shift) { + m_removeAction->update(); + } + } + } + + return KParts::ReadOnlyPart::eventFilter(obj, event); +} + //// void DolphinPartBrowserExtension::restoreState(QDataStream &stream) diff --git a/src/dolphinpart.h b/src/dolphinpart.h index 7881ded43c..172bfafc6d 100644 --- a/src/dolphinpart.h +++ b/src/dolphinpart.h @@ -39,6 +39,7 @@ class DolphinModel; class KDirLister; class DolphinView; class KAboutData; +class DolphinRemoveAction; class DolphinPart : public KParts::ReadOnlyPart { @@ -227,6 +228,8 @@ private Q_SLOTS: void setFilesToSelect(const KUrl::List& files); KUrl::List filesToSelect() const { return KUrl::List(); } // silence moc + virtual bool eventFilter(QObject*, QEvent*); + private: void createActions(); void createGoAction(const char* name, const char* iconName, @@ -245,6 +248,7 @@ private: KAction* m_findFileAction; KAction* m_openTerminalAction; QString m_nameFilter; + DolphinRemoveAction* m_removeAction; Q_DISABLE_COPY(DolphinPart) }; diff --git a/src/dolphinremoveaction.cpp b/src/dolphinremoveaction.cpp new file mode 100644 index 0000000000..200fc407db --- /dev/null +++ b/src/dolphinremoveaction.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2013 by Dawit Alemayehu + +#include + + +DolphinRemoveAction::DolphinRemoveAction(QObject* parent, KActionCollection* collection) : + QAction(parent), + m_collection(collection) +{ + update(); + connect(this, SIGNAL(triggered()), this, SLOT(slotRemoveActionTriggered())); +} + +void DolphinRemoveAction::slotRemoveActionTriggered() +{ + if (m_action) { + m_action->trigger(); + } +} + +void DolphinRemoveAction::update() +{ + Q_ASSERT(m_collection); + // Using setText(action->text()) does not apply the &-shortcut. + // This is only done until the original action has been shown at least once. To + // bypass this issue, the text and &-shortcut is applied manually. + if (qApp->keyboardModifiers() & Qt::ShiftModifier) { + m_action = m_collection ? m_collection->action("delete") : 0; + setText(i18nc("@action:inmenu", "&Delete")); + } else { + m_action = m_collection ? m_collection->action("move_to_trash") : 0; + setText(i18nc("@action:inmenu", "&Move to Trash")); + } + + if (m_action) { + setIcon(m_action->icon()); + setShortcuts(m_action->shortcuts()); + } +} diff --git a/src/dolphinremoveaction.h b/src/dolphinremoveaction.h new file mode 100644 index 0000000000..1a123ace54 --- /dev/null +++ b/src/dolphinremoveaction.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2013 by Dawit Alemayehu +#include + +#include + +/** + * A QAction that manages the delete based on the current state of + * the Shift key or the parameter passed to update. + * + * This class expects the presence of both the "move_to_trash" and "delete" + * actions in @ref collection. + */ +class LIBDOLPHINPRIVATE_EXPORT DolphinRemoveAction : public QAction +{ + Q_OBJECT +public: + DolphinRemoveAction(QObject* parent, KActionCollection* collection); + /** + * Updates this action key based on the state of the Shift key. + */ + void update(); + +private Q_SLOTS: + void slotRemoveActionTriggered(); + +private: + QPointer m_collection; + QPointer m_action; +}; + +#endif