diff options
Diffstat (limited to 'src/views')
| -rw-r--r-- | src/views/dolphinview.cpp | 38 | ||||
| -rw-r--r-- | src/views/dolphinview.h | 2 | ||||
| -rw-r--r-- | src/views/dolphinviewactionhandler.cpp | 97 | ||||
| -rw-r--r-- | src/views/dolphinviewactionhandler.h | 8 | ||||
| -rw-r--r-- | src/views/versioncontrol/fileviewversioncontrolplugin.desktop | 1 | ||||
| -rw-r--r-- | src/views/versioncontrol/kversioncontrolplugin.h | 23 | ||||
| -rw-r--r-- | src/views/versioncontrol/versioncontrolobserver.cpp | 37 |
7 files changed, 172 insertions, 34 deletions
diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index f0f67c9d0..ce77dd325 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -18,6 +18,7 @@ #include "kitemviews/kitemlistcontroller.h" #include "kitemviews/kitemlistheader.h" #include "kitemviews/kitemlistselectionmanager.h" +#include "kitemviews/private/kitemlistroleeditor.h" #include "versioncontrol/versioncontrolobserver.h" #include "viewproperties.h" #include "views/tooltips/tooltipmanager.h" @@ -178,6 +179,7 @@ DolphinView::DolphinView(const QUrl& url, QWidget* parent) : connect(m_model, &KFileItemModel::errorMessage, this, &DolphinView::errorMessage); connect(m_model, &KFileItemModel::directoryRedirection, this, &DolphinView::slotDirectoryRedirection); connect(m_model, &KFileItemModel::urlIsFileError, this, &DolphinView::urlIsFileError); + connect(m_model, &KFileItemModel::fileItemsChanged, this, &DolphinView::fileItemsChanged); connect(this, &DolphinView::itemCountChanged, this, &DolphinView::updatePlaceholderLabel); @@ -674,12 +676,21 @@ void DolphinView::renameSelectedItems() if (items.count() == 1 && GeneralSettings::renameInline()) { const int index = m_model->index(items.first()); - m_view->editRole(index, "text"); - hideToolTip(); + QMetaObject::Connection * const connection = new QMetaObject::Connection; + *connection = connect(m_view, &KItemListView::scrollingStopped, this, [=](){ + QObject::disconnect(*connection); + delete connection; + + m_view->editRole(index, "text"); + + hideToolTip(); + + connect(m_view, &DolphinItemListView::roleEditingFinished, + this, &DolphinView::slotRoleEditingFinished); + }); + m_view->scrollToItem(index); - connect(m_view, &DolphinItemListView::roleEditingFinished, - this, &DolphinView::slotRoleEditingFinished); } else { KIO::RenameFileDialog* dialog = new KIO::RenameFileDialog(items, this); connect(dialog, &KIO::RenameFileDialog::renamingFinished, @@ -1736,13 +1747,15 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, con disconnect(m_view, &DolphinItemListView::roleEditingFinished, this, &DolphinView::slotRoleEditingFinished); - if (index < 0 || index >= m_model->count()) { + const KFileItemList items = selectedItems(); + if (items.count() != 1) { return; } if (role == "text") { - const KFileItem oldItem = m_model->fileItem(index); - const QString newName = value.toString(); + const KFileItem oldItem = items.first(); + const EditResult retVal = value.value<EditResult>(); + const QString newName = retVal.newName; if (!newName.isEmpty() && newName != oldItem.text() && newName != QLatin1Char('.') && newName != QLatin1String("..")) { const QUrl oldUrl = oldItem.url(); @@ -1773,14 +1786,14 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, con #endif const bool newNameExistsAlready = (m_model->index(newUrl) >= 0); - if (!newNameExistsAlready) { + if (!newNameExistsAlready && m_model->index(oldUrl) == index) { // Only change the data in the model if no item with the new name // is in the model yet. If there is an item with the new name // already, calling KIO::CopyJob will open a dialog // asking for a new name, and KFileItemModel will update the // data when the dir lister signals that the file name has changed. QHash<QByteArray, QVariant> data; - data.insert(role, value); + data.insert(role, retVal.newName); m_model->setData(index, data); } @@ -1797,6 +1810,13 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, con connect(job, &KJob::result, this, &DolphinView::slotRenamingResult); } } + if (retVal.direction != EditDone) { + const short indexShift = retVal.direction == EditNext ? 1 : -1; + m_container->controller()->selectionManager()->setSelected(index, 1, KItemListSelectionManager::Deselect); + m_container->controller()->selectionManager()->setSelected(index + indexShift, 1, + KItemListSelectionManager::Select); + renameSelectedItems(); + } } } diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index be8263917..bb093774f 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -593,6 +593,8 @@ Q_SIGNALS: void goUpRequested(); + void fileItemsChanged(const KFileItemList &changedFileItems); + protected: /** Changes the zoom level if Control is pressed during a wheel event. */ void wheelEvent(QWheelEvent* event) override; diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp index 236daed5f..4acc420b0 100644 --- a/src/views/dolphinviewactionhandler.cpp +++ b/src/views/dolphinviewactionhandler.cpp @@ -18,6 +18,7 @@ #endif #include <KActionCollection> #include <KActionMenu> +#include <KFileItemListProperties> #include <KLocalizedString> #include <KNewFileMenu> #include <KPropertiesDialog> @@ -68,6 +69,9 @@ void DolphinViewActionHandler::setCurrentView(DolphinView* view) this, &DolphinViewActionHandler::slotZoomLevelChanged); connect(view, &DolphinView::writeStateChanged, this, &DolphinViewActionHandler::slotWriteStateChanged); + connect(view, &DolphinView::selectionChanged, + this, &DolphinViewActionHandler::slotSelectionChanged); + slotSelectionChanged(m_currentView->selectedItems()); } DolphinView* DolphinViewActionHandler::currentView() @@ -155,6 +159,25 @@ void DolphinViewActionHandler::createActions() m_actionCollection->setDefaultShortcuts(copyPathAction, {Qt::CTRL | Qt::ALT | Qt::Key_C}); connect(copyPathAction, &QAction::triggered, this, &DolphinViewActionHandler::slotCopyPath); + // This menu makes sure that users who don't know how to open a context menu and haven't + // figured out how to enable the menu bar can still perform basic file manipulation. + // This only works if they know how to select a file. + // The text when nothing is selected at least implies that a selection can /somehow/ be made. + // This menu is by default only used in the hamburger menu but created here so users can put + // it on their toolbar. + KActionMenu *basicActionsMenu = m_actionCollection->add<KActionMenu>(QStringLiteral("basic_actions"), this); + // The text is set later depending on the selection in the currently active view. + basicActionsMenu->setPopupMode(QToolButton::InstantPopup); + basicActionsMenu->addAction(m_actionCollection->action(KStandardAction::name(KStandardAction::Cut))); + basicActionsMenu->addAction(m_actionCollection->action(KStandardAction::name(KStandardAction::Copy))); + basicActionsMenu->addAction(m_actionCollection->action(KStandardAction::name(KStandardAction::Paste))); + basicActionsMenu->addSeparator(); + basicActionsMenu->addAction(m_actionCollection->action(KStandardAction::name(KStandardAction::RenameFile))); + basicActionsMenu->addAction(m_actionCollection->action(KStandardAction::name(KStandardAction::MoveToTrash))); + basicActionsMenu->addSeparator(); + basicActionsMenu->addAction(m_actionCollection->action(QStringLiteral("properties"))); + basicActionsMenu->addSeparator(); // We add one more separator because we sometimes add contextual + // actions in slotSelectionChanged() after the static ones above. // View menu KToggleAction* iconsAction = iconsModeAction(); @@ -208,6 +231,14 @@ void DolphinViewActionHandler::createActions() m_actionCollection); zoomOutAction->setWhatsThis(i18nc("@info:whatsthis zoom out", "This reduces the icon size.")); + KActionMenu* zoomMenu = m_actionCollection->add<KActionMenu>(QStringLiteral("zoom")); + zoomMenu->setText(i18nc("@action:inmenu menu of zoom actions", "Zoom")); + zoomMenu->setIcon(QIcon::fromTheme(QStringLiteral("zoom"))); + zoomMenu->setPopupMode(QToolButton::InstantPopup); + zoomMenu->addAction(zoomInAction); + zoomMenu->addAction(zoomResetAction); + zoomMenu->addAction(zoomOutAction); + KToggleAction* showPreview = m_actionCollection->add<KToggleAction>(QStringLiteral("show_preview")); showPreview->setText(i18nc("@action:intoolbar", "Show Previews")); showPreview->setToolTip(i18nc("@info", "Show preview of files and folders")); @@ -709,3 +740,69 @@ void DolphinViewActionHandler::slotCopyPath() { m_currentView->copyPathToClipboard(); } + +void DolphinViewActionHandler::slotSelectionChanged(const KFileItemList& selection) +{ + QString basicActionsMenuText; + switch (selection.count()) { + case 0: + basicActionsMenuText = + i18nc("@action:inmenu menu with actions like copy, paste, rename. The user's selection is empty when this text is shown.", + "Actions for Current View"); + break; + case 1: + basicActionsMenuText = + i18nc("@action:inmenu menu with actions like copy, paste, rename. %1 is the name of the singular selected file/folder.", + "Actions for \"%1\"", selection.first().name()); + break; + case 2: + basicActionsMenuText = + i18nc("@action:inmenu menu with actions like copy, paste, rename. %1 and %2 are names of files/folders.", + "Actions for \"%1\" and \"%2\"", selection.first().name(), selection.last().name()); + break; + case 3: + basicActionsMenuText = + i18nc("@action:inmenu menu with actions like copy, paste, rename. %1, %2 and %3 are names of files/folders.", + "Actions for \"%1\", \"%2\" and \"%3\"", + selection.first().name(), selection.at(1).name(), selection.last().name()); + break; + default: + basicActionsMenuText = QString(); + break; + } + + // At some point the added clarity from the text starts being less important than the menu width. + if (basicActionsMenuText.isEmpty() || basicActionsMenuText.length() > 40) { + const KFileItemListProperties properties(selection); + if (properties.isFile()) { + basicActionsMenuText = + i18ncp("@action:inmenu menu with actions like copy, paste, rename. %1 is the amount of selected files/folders.", + "Actions for One Selected File", "Actions for %1 Selected Files", selection.count()); + } else if (properties.isDirectory()) { + basicActionsMenuText = + i18ncp("@action:inmenu menu with actions like copy, paste, rename. %1 is the amount of selected files/folders.", + "Actions for One Selected Folder", "Actions for %1 Selected Folders", selection.count()); + } else { + basicActionsMenuText = + i18ncp("@action:inmenu menu with actions like copy, paste, rename. %1 is the amount of selected files/folders.", + "Actions for One Selected Item", "Actions for %1 Selected Items", selection.count()); + } + } + + QAction *basicActionsMenu = m_actionCollection->action(QStringLiteral("basic_actions")); + basicActionsMenu->setText(basicActionsMenuText); + + // Add or remove contextual actions + auto basicActionsMenuActions = basicActionsMenu->menu()->actions(); + while (!basicActionsMenu->menu()->actions().constLast()->isSeparator()) { + basicActionsMenu->menu()->removeAction(basicActionsMenu->menu()->actions().last()); + } + if (selection.count() == 1) { + if (selection.first().isLink()) { + basicActionsMenu->menu()->addAction(m_actionCollection->action(QStringLiteral("show_target"))); + } + if (selection.first().isDir()) { + basicActionsMenu->menu()->addAction(m_actionCollection->action(QStringLiteral("add_to_places"))); + } + } +} diff --git a/src/views/dolphinviewactionhandler.h b/src/views/dolphinviewactionhandler.h index 23b4e5f1a..3f73153ea 100644 --- a/src/views/dolphinviewactionhandler.h +++ b/src/views/dolphinviewactionhandler.h @@ -19,6 +19,7 @@ class QAction; class QActionGroup; class DolphinView; class KActionCollection; +class KFileItemList; /** * @short Handles all actions for DolphinView @@ -211,6 +212,13 @@ private Q_SLOTS: */ void slotCopyPath(); + /** + * Changes the name of the menu that contains basic actions like "Copy", "Rename", ... + * The name is changed to something like "Actions for 3 Selected Items" to be extra + * explicit of how these basic actions are used. + */ + void slotSelectionChanged(const KFileItemList& selection); + private: /** * Create all the actions. diff --git a/src/views/versioncontrol/fileviewversioncontrolplugin.desktop b/src/views/versioncontrol/fileviewversioncontrolplugin.desktop index 4c33b3b2c..5cffe9aac 100644 --- a/src/views/versioncontrol/fileviewversioncontrolplugin.desktop +++ b/src/views/versioncontrol/fileviewversioncontrolplugin.desktop @@ -43,6 +43,7 @@ Comment[sr@ijekavian]=Прикључак управљања верзијама � Comment[sr@ijekavianlatin]=Priključak upravljanja verzijama za fajl prikaze Comment[sr@latin]=Priključak upravljanja verzijama za fajl prikaze Comment[sv]=Insticksprogram för versionskontroll i filvyer +Comment[ta]=கோப்புக் காட்சிகளுக்கான பதிப்புக் கட்டுப்பாட்டு (version control) செருகுநிரல் Comment[tr]=Dosya Görünümleri için Sürüm Kontrol Eklentisi Comment[uk]=Додаток керування версіями для панелей перегляду файлів Comment[vi]=Phần cài cắm "Quản lí phiên bản" cho khung xem tệp diff --git a/src/views/versioncontrol/kversioncontrolplugin.h b/src/views/versioncontrol/kversioncontrolplugin.h index aeac5ad29..c908be247 100644 --- a/src/views/versioncontrol/kversioncontrolplugin.h +++ b/src/views/versioncontrol/kversioncontrolplugin.h @@ -23,14 +23,15 @@ class KFileItem; * steps are required (in the example below it is assumed that a plugin for * Subversion will be written): * - * - Create a fileviewsvnplugin.desktop file with the following content: + * - Create a fileviewsvnplugin.json file with the following content: * <code> - * [Desktop Entry] - * Type=Service - * Name=Subversion - * X-KDE-ServiceTypes=FileViewVersionControlPlugin - * MimeType=text/plain; - * X-KDE-Library=fileviewsvnplugin + * { + * "KPlugin": { + * "Description": "The svn plugin", + * "Name": "Svn" + * } + * } + * </code> * * - Create a class FileViewSvnPlugin derived from KVersionControlPlugin and @@ -45,15 +46,13 @@ class KFileItem; * <code> * #include <KPluginFactory> * #include <KPluginLoader> - * K_PLUGIN_FACTORY(FileViewSvnPluginFactory, registerPlugin<FileViewSvnPlugin>();) - * K_EXPORT_PLUGIN(FileViewSvnPluginFactory("fileviewsvnplugin")) + * K_PLUGIN_CLASS_WITH_JSON(FileViewSvnPlugin, "fileviewsvnplugin.json") * </code> * * - Add the following lines to your CMakeLists.txt file: * <code> - * kde4_add_plugin(fileviewsvnplugin fileviewsvnplugin.cpp) - * target_link_libraries(fileviewsvnplugin konq) - * install(FILES fileviewsvnplugin.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + * kcoreaddons_add_plugin(fileviewsvnplugin SOURCES fileviewsvnplugin.cpp INSTALL_NAMESPACE "dolphin/vcs") + * target_link_libraries(fileviewsvnplugin DolphinVcs) * </code> * * General implementation notes: diff --git a/src/views/versioncontrol/versioncontrolobserver.cpp b/src/views/versioncontrol/versioncontrolobserver.cpp index cf5be3c91..9c18c6794 100644 --- a/src/views/versioncontrol/versioncontrolobserver.cpp +++ b/src/views/versioncontrol/versioncontrolobserver.cpp @@ -15,6 +15,8 @@ #include <KLocalizedString> #include <KService> #include <KServiceTypeTrader> +#include <KPluginLoader> +#include <KPluginMetaData> #include <QTimer> @@ -279,24 +281,33 @@ void VersionControlObserver::initPlugins() // all fileview version control plugins and remember them in 'plugins'. const QStringList enabledPlugins = VersionControlSettings::enabledPlugins(); - const KService::List pluginServices = KServiceTypeTrader::self()->query(QStringLiteral("FileViewVersionControlPlugin")); - for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) { - if (enabledPlugins.contains((*it)->name())) { - KVersionControlPlugin* plugin = (*it)->createInstance<KVersionControlPlugin>(this); - if (plugin) { - connect(plugin, &KVersionControlPlugin::itemVersionsChanged, - this, &VersionControlObserver::silentDirectoryVerification); - connect(plugin, &KVersionControlPlugin::infoMessage, - this, &VersionControlObserver::infoMessage); - connect(plugin, &KVersionControlPlugin::errorMessage, - this, &VersionControlObserver::errorMessage); - connect(plugin, &KVersionControlPlugin::operationCompletedMessage, - this, &VersionControlObserver::operationCompletedMessage); + const QVector<KPluginMetaData> plugins = KPluginLoader::findPlugins(QStringLiteral("dolphin/vcs")); + + QSet<QString> loadedPlugins; + for (const auto &p : plugins) { + if (enabledPlugins.contains(p.name())) { + KPluginLoader loader(p.fileName()); + KPluginFactory *factory = loader.factory(); + KVersionControlPlugin *plugin = factory->create<KVersionControlPlugin>(); + if (plugin) { m_plugins.append(plugin); + loadedPlugins += p.name(); } } } + + for (auto &plugin : qAsConst(m_plugins)) { + connect(plugin, &KVersionControlPlugin::itemVersionsChanged, + this, &VersionControlObserver::silentDirectoryVerification); + connect(plugin, &KVersionControlPlugin::infoMessage, + this, &VersionControlObserver::infoMessage); + connect(plugin, &KVersionControlPlugin::errorMessage, + this, &VersionControlObserver::errorMessage); + connect(plugin, &KVersionControlPlugin::operationCompletedMessage, + this, &VersionControlObserver::operationCompletedMessage); + } + m_pluginsInitialized = true; } } |
