]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Merge branch 'release/19.12'
authorAlexander Saoutkin <a.saoutkin@gmail.com>
Sun, 1 Mar 2020 17:22:46 +0000 (17:22 +0000)
committerAlexander Saoutkin <a.saoutkin@gmail.com>
Sun, 1 Mar 2020 17:22:46 +0000 (17:22 +0000)
79 files changed:
CMakeLists.txt
cmake/DbusInterfaceMacros.cmake
doc/index.docbook
src/CMakeLists.txt
src/dolphinbookmarkhandler.cpp
src/dolphinbookmarkhandler.h
src/dolphincontextmenu.cpp
src/dolphincontextmenu.h
src/dolphindockwidget.h
src/dolphinmainwindow.cpp
src/dolphinmainwindow.h
src/dolphinpart.cpp
src/dolphinpart.h
src/dolphinpart.rc
src/dolphinui.rc
src/dolphinviewcontainer.cpp
src/global.cpp
src/kitemviews/kfileitemmodel.cpp
src/kitemviews/kfileitemmodel.h
src/kitemviews/kitemlistcontainer.cpp
src/kitemviews/kitemlistcontainer.h
src/kitemviews/kitemlistcontroller.cpp
src/kitemviews/kitemlistcontroller.h
src/kitemviews/kitemlistgroupheader.cpp
src/kitemviews/kitemlistselectionmanager.cpp
src/kitemviews/kitemlistselectionmanager.h
src/kitemviews/kitemliststyleoption.cpp
src/kitemviews/kitemliststyleoption.h
src/kitemviews/kitemlistview.cpp
src/kitemviews/kitemlistview.h
src/kitemviews/kitemlistwidget.cpp
src/kitemviews/kitemlistwidget.h
src/kitemviews/kitemmodelbase.cpp
src/kitemviews/kitemmodelbase.h
src/kitemviews/kitemrange.h
src/kitemviews/kstandarditemlistgroupheader.cpp
src/kitemviews/private/kbaloorolesprovider.cpp
src/kitemviews/private/kdirectorycontentscounter.cpp
src/kitemviews/private/kfileitemclipboard.cpp
src/kitemviews/private/kitemlistkeyboardsearchmanager.cpp
src/kitemviews/private/kitemlistkeyboardsearchmanager.h
src/kitemviews/private/kitemlistselectiontoggle.cpp
src/org.kde.dolphin.appdata.xml
src/panels/folders/folderspanel.cpp
src/panels/folders/treeviewcontextmenu.cpp
src/panels/information/informationpanel.cpp
src/panels/information/informationpanelcontent.cpp
src/panels/information/phononwidget.cpp
src/panels/places/placesitemlistgroupheader.cpp
src/panels/places/placespanel.cpp
src/panels/terminal/terminalpanel.cpp
src/panels/terminal/terminalpanel.h
src/search/dolphinfacetswidget.cpp
src/search/dolphinfacetswidget.h
src/search/dolphinquery.cpp
src/search/dolphinquery.h
src/search/dolphinsearchbox.cpp
src/settings/dolphin_generalsettings.kcfg
src/settings/general/behaviorsettingspage.cpp
src/settings/general/configurepreviewplugindialog.cpp
src/settings/general/confirmationssettingspage.cpp
src/settings/general/generalsettingspage.cpp
src/settings/kcm/kcmdolphingeneral.cpp
src/settings/kcm/kcmdolphingeneral.desktop
src/settings/kcm/kcmdolphinnavigation.cpp
src/settings/kcm/kcmdolphinservices.cpp
src/settings/kcm/kcmdolphinviewmodes.cpp
src/settings/kcm/kcmdolphinviewmodes.desktop
src/settings/viewmodes/viewsettingspage.cpp
src/settings/viewmodes/viewsettingstab.cpp
src/settings/viewpropertiesdialog.cpp
src/tests/dolphinquerytest.cpp
src/views/dolphinview.cpp
src/views/dolphinviewactionhandler.cpp
src/views/renamedialog.cpp [deleted file]
src/views/renamedialog.h [deleted file]
src/views/versioncontrol/fileviewversioncontrolplugin.desktop
src/views/versioncontrol/versioncontrolobserver.cpp
src/views/versioncontrol/versioncontrolobserver.h

index da63349356246da1531b31d4d21993f9f406612b..0ab79e643c7707618e1fbdafaef89f716fbe07d2 100644 (file)
@@ -1,14 +1,14 @@
 cmake_minimum_required(VERSION 3.0)
 
 # KDE Application Version, managed by release script
-set (KDE_APPLICATIONS_VERSION_MAJOR "19")
-set (KDE_APPLICATIONS_VERSION_MINOR "12")
-set (KDE_APPLICATIONS_VERSION_MICRO "3")
-set (KDE_APPLICATIONS_VERSION "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}.${KDE_APPLICATIONS_VERSION_MICRO}")
-project(Dolphin VERSION ${KDE_APPLICATIONS_VERSION})
+set (RELEASE_SERVICE_VERSION_MAJOR "20")
+set (RELEASE_SERVICE_VERSION_MINOR "03")
+set (RELEASE_SERVICE_VERSION_MICRO "70")
+set (RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
+project(Dolphin VERSION ${RELEASE_SERVICE_VERSION})
 
 set(QT_MIN_VERSION "5.11.0")
-set(KF5_MIN_VERSION "5.63.0")
+set(KF5_MIN_VERSION "5.67.0")
 
 # ECM setup
 find_package(ECM ${KF5_MIN_VERSION} CONFIG REQUIRED)
@@ -24,7 +24,7 @@ include(KDECMakeSettings)
 include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE)
 include(ECMQtDeclareLoggingCategory)
 
-ecm_setup_version(${KDE_APPLICATIONS_VERSION} VARIABLE_PREFIX DOLPHIN
+ecm_setup_version(${RELEASE_SERVICE_VERSION} VARIABLE_PREFIX DOLPHIN
                   VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/src/dolphin_version.h"
 )
 
@@ -70,7 +70,7 @@ find_package(KF5 ${KF5_MIN_VERSION} OPTIONAL_COMPONENTS
     Activities
 )
 set_package_properties(KF5Activities PROPERTIES DESCRIPTION "KActivities libraries"
-                       URL "http://www.kde.org"
+                       URL "https://www.kde.org"
                        TYPE OPTIONAL
                        PURPOSE "For tracking which folders are frequently accessed on a Plasma desktop"
                       )
@@ -79,14 +79,14 @@ find_package(Phonon4Qt5 CONFIG REQUIRED)
 
 find_package(KF5Baloo ${KF5_MIN_VERSION})
 set_package_properties(KF5Baloo PROPERTIES DESCRIPTION "Baloo Core libraries"
-                       URL "http://www.kde.org"
+                       URL "https://www.kde.org"
                        TYPE OPTIONAL
                        PURPOSE "For adding desktop-wide search and tagging support to dolphin"
                       )
 
 find_package(KF5BalooWidgets 19.07.70)
 set_package_properties(KF5BalooWidgets PROPERTIES DESCRIPTION "Baloos Widgets"
-                       URL "http://www.kde.org"
+                       URL "https://www.kde.org"
                        TYPE OPTIONAL
                       )
 
@@ -148,7 +148,7 @@ install(FILES
 configure_file(org.kde.dolphin.FileManager1.service.in
                ${CMAKE_CURRENT_BINARY_DIR}/org.kde.dolphin.FileManager1.service)
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.dolphin.FileManager1.service
-        DESTINATION ${DBUS_SERVICES_INSTALL_DIR})
+        DESTINATION ${KDE_INSTALL_DBUSSERVICEDIR})
 install(FILES dolphin.categories  DESTINATION  ${KDE_INSTALL_LOGGINGCATEGORIESDIR})
 
 feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
index 1083dfd443aa93090b478728ab09535d100b10ac..b5f6a80b0b6f0a3fd417eda9ff280ed13c259268 100644 (file)
@@ -9,7 +9,7 @@ macro (generate_and_install_dbus_interface main_project_target header_file outpu
     )
     install(
         FILES ${CMAKE_CURRENT_BINARY_DIR}/${output_xml_file}
-        DESTINATION ${DBUS_INTERFACES_INSTALL_DIR}
+        DESTINATION ${KDE_INSTALL_DBUSINTERFACEDIR}
     )
     add_dependencies(
         ${main_project_target}
index d2c06c6a0287ec3dc1b96139fb8f25b3f5ebc1c8..7dcf9ec1742fe3456078d52902a31d43c29f6ecc 100644 (file)
@@ -312,7 +312,7 @@ The buttons in the toolbar which control the appearance of the view.
 All the settings discussed below and other options concerning, &eg; the
 sorting of the files in the current folder, can also be modified in the
 <guimenu>View</guimenu> menu and in the
-<link linkend="view-properties-dialog">View Properties dialog</link>. By
+<link linkend="view-properties-dialog">View Display Style dialog</link>. By
 default, these settings are remembered for each folder separately. This
 behavior can be changed in the
 <link linkend="preferences-dialog-general"><quote>General</quote></link> section of the settings.
@@ -610,11 +610,11 @@ programs built into &kde; which add support for many different protocols to
 used to manage files and folders on a remote host that is accessible 
 via <acronym>SSH</acronym>. To do this you would type <userinput>fish://username@remotehost</userinput> 
 into the location bar. Similar remote file management can be done on 
-remote hosts accessible via the &FTP;, NFS, SFTP, SMB (CIFS) or webdav protocols.</para>
+remote hosts accessible via the &FTP;, &NFS;, SFTP, &SMB; (&CIFS;) or webdav protocols.</para>
 
-<para>It is also possible to use the kioslaves drop down list to access 
+<para>It is also possible to use the kioslaves drop down box to access 
 &systemsettings;, fonts, trash, other programs and devices attached to your computer. 
-See the drop down list for the full list of capabilities available from kioslaves on your system.
+See the drop down box for the full list of capabilities available from kioslaves on your system.
 </para>
 <screenshot>
 <screeninfo>Screenshot of the list of kioslaves</screeninfo>
@@ -951,11 +951,11 @@ using the <link linkend="preferences-dialog">Preferences Dialog</link>.
 
 <listitem><para>
 Settings which determine how the contents of a folder are displayed in &dolphin;.
-These settings are called <link linkend="view-properties">View Properties</link>
+These settings are called <link linkend="view-properties">View Display Styles</link>
 and can be controlled with toolbar buttons, via the <guimenu>View</guimenu> menu,
-and with the <link linkend="view-properties-dialog">View Properties Dialog</link>.
-In the default configuration, the view properties are remembered for each folder,
-but &dolphin; can also be configured to use common view properties for all folders
+and with the <link linkend="view-properties-dialog">View Display Style dialog</link>.
+In the default configuration, all folders use the same display style,
+but &dolphin; can also be configured to remember each folder's display style separately
 in the <link linkend="preferences-dialog-general-behavior"><quote>General</quote>
 section of the settings</link>.
 </para></listitem>
@@ -1008,9 +1008,9 @@ tab bar at the top.
 <itemizedlist>
 
 <listitem><para>
-In the <guilabel>View</guilabel> section, you can configure whether the
-<link linkend="view-properties"> view properties</link> are stored for each
-folder or if common view properties are to be used for all folders.
+In the <guilabel>View</guilabel> section, you can configure whether the same
+<link linkend="view-properties">view display style</link> is shared among all folders
+or folders remember their own individual view display styles.
 </para></listitem>
 
 <listitem><para>
@@ -1085,7 +1085,7 @@ It is also possible to choose the default action <guilabel>When opening an execu
 </para>
 <warning><para>The confirmation settings for <guilabel>Moving files or folders to trash</guilabel> and
 <guilabel>Deleting files or folders</guilabel> affect file operations in &dolphin;, &konqueror;, 
-<application>Gwenview</application> and all &kde; applications using the default &kde; file dialog, 
+&gwenview; and all &kde; applications using the default &kde; file dialog, 
 whereas <guilabel>Closing Dolphin windows
 with multiple tabs</guilabel> is a &dolphin; specific setting.</para></warning>
 </sect3>
@@ -1412,7 +1412,7 @@ largest files can be deleted automatically.
 </sect1>
 <!-- begin copy to konqueror filemanager.docbook -->
 <sect1 id="view-properties">
-<title>Folder View Properties</title>
+<title>Folder View Display Style</title>
 
 <para>
 The following settings control how the contents of a folder are displayed in the
@@ -1454,31 +1454,31 @@ What additional information (besides the name) is shown in the Icons or Details
 
 </itemizedlist>
 <para>
-The view properties can be configured in the
+The view display style can be configured in the
 <menuchoice><guimenu>View</guimenu></menuchoice> menu, some (such as the view
 mode) can also be changed using toolbar buttons.
 </para>
 
 <sect2 id="view-properties-dialog">
-<title>The View Properties Dialog</title>
+<title>The View Display Style dialog</title>
 
 <para>
 
 <screenshot>
-<screeninfo>Screenshot of the View Properties dialog</screeninfo>
+<screeninfo>Screenshot of the View Display Style dialog</screeninfo>
 <mediaobject>
 <imageobject>
 <imagedata fileref="viewproperties-dialog.png" format="PNG"/>
 </imageobject>
 <textobject>
-<phrase>The View Properties dialog.</phrase>
+<phrase>The View Display Style dialog.</phrase>
 </textobject>
-<caption><para>The View Properties Dialog.</para></caption>
+<caption><para>The View Display Style Dialog.</para></caption>
 </mediaobject>
 </screenshot>
 
-The <guilabel>View Properties</guilabel> dialog can be used to quickly modify
-several view properties at once. This is done for the current folder, for the
+The <guilabel>View Display Style</guilabel> dialog can be used to quickly modify
+the view display styles for many folders at once. This is done for the current folder, for the
 current folder including all subfolders, or even for all folders, depending on
 the choice made in the <guilabel>Apply to</guilabel> section.
 </para>
@@ -1917,9 +1917,9 @@ if necessary, and selects the location such that it can be replaced quickly.
 <varlistentry>
 <term><menuchoice>
 <guimenu>View</guimenu>
-<guimenuitem>Adjust View Properties...</guimenuitem>
+<guimenuitem>Adjust View Display Style...</guimenuitem>
 </menuchoice></term>
-<listitem><para><action>Opens the <link linkend="view-properties-dialog">View Properties
+<listitem><para><action>Opens the <link linkend="view-properties-dialog">View Display Style
 Dialog</link>.</action></para></listitem>
 </varlistentry>
 </variablelist>
@@ -2018,6 +2018,17 @@ for this action.</para></listitem>
 <listitem><para><action>Opens &konsole; within the current folder.</action></para></listitem>
 </varlistentry>
 
+<varlistentry>
+<term><menuchoice>
+<shortcut>
+<keycombo action="simul">&Ctrl;&Shift;<keycap>F</keycap></keycombo>
+</shortcut>
+<guimenu>Tools</guimenu>
+<guimenuitem>Open Preferred Search Tool</guimenuitem>
+</menuchoice></term>
+<listitem><para><action>Opens preferred search tool in the current folder.</action></para></listitem>
+</varlistentry>
+
 <varlistentry>
 <term><menuchoice>
 <guimenu>Tools</guimenu>
@@ -2043,8 +2054,8 @@ connection manually.</action></para></listitem>
 <title>The Settings and Help Menu</title> 
 <para>
 &dolphin; has the common &kde; <guimenu>Settings</guimenu> and <guimenu>Help</guimenu>
-menu items, for more information read the sections about the <ulink url="help:/fundamentals/ui.html#menus-settings"
->Settings Menu</ulink> and <ulink url="help:/fundamentals/ui.html#menus-help">Help Menu</ulink>
+menu items, for more information read the sections about the <ulink url="help:/fundamentals/menus.html#menus-settings"
+>Settings Menu</ulink> and <ulink url="help:/fundamentals/menus.html#menus-help">Help Menu</ulink>
 of the &kde; Fundamentals.
 </para>
 </sect2>
index 617d59480794d5477d91f98545d5ec342dfad035..e8d623d2f2320fc0aa64955b144c50c8e96fb53a 100644 (file)
@@ -99,7 +99,6 @@ set(dolphinprivate_LIB_SRCS
     views/dolphinview.cpp
     views/dolphinviewactionhandler.cpp
     views/draganddrophelper.cpp
-    views/renamedialog.cpp
     views/versioncontrol/updateitemstatesthread.cpp
     views/versioncontrol/versioncontrolobserver.cpp
     views/viewmodecontroller.cpp
@@ -301,9 +300,10 @@ ecm_add_app_icon(dolphin_SRCS ICONS ${ICONS_SRCS})
 kf5_add_kdeinit_executable(dolphin ${dolphin_SRCS})
 
 
-target_link_libraries(kdeinit_dolphin PRIVATE
-    dolphinstatic
+target_link_libraries(kdeinit_dolphin PUBLIC
     dolphinprivate
+    PRIVATE
+    dolphinstatic
     KF5::Crash
 )
 
index bb8f641ec091a13b3e99df0b61a8c78dc6dc0191..ded83d6bb9c87967a95980e1403be1825166201e 100644 (file)
@@ -54,11 +54,6 @@ DolphinBookmarkHandler::~DolphinBookmarkHandler()
 {
 }
 
-void DolphinBookmarkHandler::fillControlMenu(QMenu* menu, KActionCollection* collection)
-{
-    m_bookmarkControlMenu.reset(new KBookmarkMenu(m_bookmarkManager, this, menu, collection));
-}
-
 QString DolphinBookmarkHandler::currentTitle() const
 {
     return title(m_mainWindow->activeViewContainer());
index 6fd511d8025f4fba70f2eb4814d819fbcc9cdd97..bafef41f8afc357b22de51deefb1b8e93f772e9a 100644 (file)
@@ -36,7 +36,7 @@ class DolphinBookmarkHandler : public QObject, public KBookmarkOwner
 public:
     DolphinBookmarkHandler(DolphinMainWindow *mainWindow, KActionCollection *collection, QMenu *menu, QObject *parent);
     ~DolphinBookmarkHandler() override;
-    void fillControlMenu(QMenu *menu, KActionCollection *collection);
+
 private:
     QString currentTitle() const override;
     QUrl currentUrl() const override;
@@ -55,7 +55,6 @@ private:
     DolphinMainWindow* m_mainWindow;
     KBookmarkManager *m_bookmarkManager;
     QScopedPointer<KBookmarkMenu> m_bookmarkMenu;
-    QScopedPointer<KBookmarkMenu> m_bookmarkControlMenu;
 };
 
 #endif // DOLPHINBOOKMARKHANDLER_H
index c8e9629c3a2d883d29d6e8c5e6ee7dee1601bada..9f396719971da3170005edd6cc1a5228e938f75a 100644 (file)
@@ -32,7 +32,6 @@
 #include "views/dolphinview.h"
 #include "views/viewmodecontroller.h"
 
-#include <KAbstractFileItemActionPlugin>
 #include <KActionCollection>
 #include <KFileItemActions>
 #include <KFileItemListProperties>
@@ -95,8 +94,13 @@ void DolphinContextMenu::setCustomActions(const QList<QAction*>& actions)
 DolphinContextMenu::Command DolphinContextMenu::open()
 {
     // get the context information
-    if (m_baseUrl.scheme() == QLatin1String("trash")) {
+    const auto scheme = m_baseUrl.scheme();
+    if (scheme == QLatin1String("trash")) {
         m_context |= TrashContext;
+    } else if (scheme.contains(QLatin1String("search"))) {
+        m_context |= SearchContext;
+    } else if (scheme.contains(QLatin1String("timeline"))) {
+        m_context |= TimelineContext;
     }
 
     if (!m_fileInfo.isNull() && !m_selectedItems.isEmpty()) {
@@ -184,6 +188,36 @@ void DolphinContextMenu::openTrashItemContextMenu()
     }
 }
 
+void DolphinContextMenu::addDirectoryItemContextMenu(KFileItemActions &fileItemActions)
+{
+    // insert 'Open in new window' and 'Open in new tab' entries
+
+    const KFileItemListProperties& selectedItemsProps = selectedItemsProperties();
+
+    addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_new_tab")));
+    addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_new_window")));
+
+    // Insert 'Open With' entries
+    addOpenWithActions(fileItemActions);
+
+    // set up 'Create New' menu
+     DolphinNewFileMenu* newFileMenu = new DolphinNewFileMenu(m_mainWindow->actionCollection(), m_mainWindow);
+     const DolphinView* view = m_mainWindow->activeViewContainer()->view();
+     newFileMenu->setViewShowsHiddenFiles(view->hiddenFilesShown());
+     newFileMenu->checkUpToDate();
+     newFileMenu->setPopupFiles(QList<QUrl>() << m_fileInfo.url());
+     newFileMenu->setEnabled(selectedItemsProps.supportsWriting());
+     connect(newFileMenu, &DolphinNewFileMenu::fileCreated, newFileMenu, &DolphinNewFileMenu::deleteLater);
+     connect(newFileMenu, &DolphinNewFileMenu::directoryCreated, newFileMenu, &DolphinNewFileMenu::deleteLater);
+
+     QMenu* menu = newFileMenu->menu();
+     menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
+     menu->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
+     addMenu(menu);
+
+     addSeparator();
+}
+
 void DolphinContextMenu::openItemContextMenu()
 {
     Q_ASSERT(!m_fileInfo.isNull());
@@ -198,31 +232,10 @@ void DolphinContextMenu::openItemContextMenu()
     fileItemActions.setItemListProperties(selectedItemsProps);
 
     if (m_selectedItems.count() == 1) {
+        // single files
         if (m_fileInfo.isDir()) {
-            // insert 'Open in new window' and 'Open in new tab' entries
-            addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_new_window")));
-            addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_new_tab")));
-
-            // Insert 'Open With' entries
-            addOpenWithActions(fileItemActions);
-
-            // set up 'Create New' menu
-             DolphinNewFileMenu* newFileMenu = new DolphinNewFileMenu(m_mainWindow->actionCollection(), m_mainWindow);
-             const DolphinView* view = m_mainWindow->activeViewContainer()->view();
-             newFileMenu->setViewShowsHiddenFiles(view->hiddenFilesShown());
-             newFileMenu->checkUpToDate();
-             newFileMenu->setPopupFiles(m_fileInfo.url());
-             newFileMenu->setEnabled(selectedItemsProps.supportsWriting());
-             connect(newFileMenu, &DolphinNewFileMenu::fileCreated, newFileMenu, &DolphinNewFileMenu::deleteLater);
-             connect(newFileMenu, &DolphinNewFileMenu::directoryCreated, newFileMenu, &DolphinNewFileMenu::deleteLater);
-
-             QMenu* menu = newFileMenu->menu();
-             menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
-             menu->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
-             addMenu(menu);
-
-             addSeparator();
-        } else if (m_baseUrl.scheme().contains(QLatin1String("search")) || m_baseUrl.scheme().contains(QLatin1String("timeline"))) {
+            addDirectoryItemContextMenu(fileItemActions);
+        } else if (m_context & TimelineContext || m_context & SearchContext) {
             addOpenWithActions(fileItemActions);
 
             openParentAction = new QAction(QIcon::fromTheme(QStringLiteral("document-open-folder")),
@@ -253,8 +266,9 @@ void DolphinContextMenu::openItemContextMenu()
             addSeparator();
         }
     } else {
+        // multiple files
         bool selectionHasOnlyDirs = true;
-        foreach (const KFileItem& item, m_selectedItems) {
+        for (const auto &item : qAsConst(m_selectedItems)) {
             const QUrl& url = DolphinView::openItemAsFolderUrl(item);
             if (url.isEmpty()) {
                 selectionHasOnlyDirs = false;
@@ -328,19 +342,19 @@ void DolphinContextMenu::openViewportContextMenu()
     fileItemActions.setParentWidget(m_mainWindow);
     fileItemActions.setItemListProperties(baseUrlProperties);
 
-    // Don't show "Open With" menu items if the current dir is empty, because there's
-    // generally no app that can do anything interesting with an empty directory
-    if (view->itemsCount() != 0) {
-        addOpenWithActions(fileItemActions);
-    }
-
     // Set up and insert 'Create New' menu
     KNewFileMenu* newFileMenu = m_mainWindow->newFileMenu();
     newFileMenu->setViewShowsHiddenFiles(view->hiddenFilesShown());
     newFileMenu->checkUpToDate();
-    newFileMenu->setPopupFiles(m_baseUrl);
+    newFileMenu->setPopupFiles(QList<QUrl>() << m_baseUrl);
     addMenu(newFileMenu->menu());
 
+    // Don't show "Open With" menu items if the current dir is empty, because there's
+    // generally no app that can do anything interesting with an empty directory
+    if (view->itemsCount() != 0) {
+        addOpenWithActions(fileItemActions);
+    }
+
     QAction* pasteAction = createPasteAction();
     addAction(pasteAction);
 
index bf0cf2c97c8935cc51711001855b3c9ea69a9eff..3f36895ec0b62a09cc19e5ec390c8e089fd80576 100644 (file)
@@ -146,7 +146,9 @@ private:
     {
         NoContext = 0,
         ItemContext = 1,
-        TrashContext = 2
+        TrashContext = 2,
+        TimelineContext = 4,
+        SearchContext = 8,
     };
 
     QPoint m_pos;
@@ -167,6 +169,8 @@ private:
     Command m_command;
 
     DolphinRemoveAction* m_removeAction; // Action that represents either 'Move To Trash' or 'Delete'
+    void addDirectoryItemContextMenu(KFileItemActions &fileItemActions);
+
 };
 
 #endif
index 0b745f0836784a6d0597c984ec6f25988155fa28..fd38826122b1a95ffb4a2ecfc7e03604c2f8efd3 100644 (file)
@@ -30,7 +30,7 @@ class DolphinDockWidget : public QDockWidget
     Q_OBJECT
 
 public:
-    explicit DolphinDockWidget(const QString& title = QString(), QWidget* parent = nullptr, Qt::WindowFlags flags = nullptr);
+    explicit DolphinDockWidget(const QString& title = QString(), QWidget* parent = nullptr, Qt::WindowFlags flags = {});
     ~DolphinDockWidget() override;
 
     /**
index 56ea93e1043e8408f925d2a4cece8615d8f53f73..642c24e60d30adb3cd289e482d6e25364e6707b3 100644 (file)
@@ -57,6 +57,7 @@
 #include <KJobWidgets>
 #include <KLocalizedString>
 #include <KMessageBox>
+#include <KNS3/KMoreToolsMenuFactory>
 #include <KProtocolInfo>
 #include <KProtocolManager>
 #include <KRun>
@@ -197,6 +198,8 @@ DolphinMainWindow::DolphinMainWindow() :
     toolBar()->installEventFilter(middleClickEventFilter);
 
     setupWhatsThis();
+
+    QTimer::singleShot(0, this, &DolphinMainWindow::setupUpdateOpenPreferredSearchToolAction);
 }
 
 DolphinMainWindow::~DolphinMainWindow()
@@ -592,13 +595,13 @@ void DolphinMainWindow::updateNewMenu()
 {
     m_newFileMenu->setViewShowsHiddenFiles(activeViewContainer()->view()->hiddenFilesShown());
     m_newFileMenu->checkUpToDate();
-    m_newFileMenu->setPopupFiles(activeViewContainer()->url());
+    m_newFileMenu->setPopupFiles(QList<QUrl>() << activeViewContainer()->url());
 }
 
 void DolphinMainWindow::createDirectory()
 {
     m_newFileMenu->setViewShowsHiddenFiles(activeViewContainer()->view()->hiddenFilesShown());
-    m_newFileMenu->setPopupFiles(activeViewContainer()->url());
+    m_newFileMenu->setPopupFiles(QList<QUrl>() << activeViewContainer()->url());
     m_newFileMenu->createDirectory();
 }
 
@@ -933,23 +936,88 @@ void DolphinMainWindow::toggleShowMenuBar()
     }
 }
 
-void DolphinMainWindow::openTerminal()
+QString DolphinMainWindow::activeContainerLocalPath()
 {
-    QString dir(QDir::homePath());
-
-    // If the given directory is not local, it can still be the URL of an
-    // ioslave using UDS_LOCAL_PATH which to be converted first.
     KIO::StatJob* statJob = KIO::mostLocalUrl(m_activeViewContainer->url());
     KJobWidgets::setWindow(statJob, this);
     statJob->exec();
     QUrl url = statJob->mostLocalUrl();
-
-    //If the URL is local after the above conversion, set the directory.
     if (url.isLocalFile()) {
-        dir = url.toLocalFile();
+        return url.toLocalFile();
+    }
+    return QDir::homePath();
+}
+
+QPointer<QAction> DolphinMainWindow::preferredSearchTool()
+{
+    m_searchTools.clear();
+    KMoreToolsMenuFactory("dolphin/search-tools").fillMenuFromGroupingNames(
+        &m_searchTools, { "files-find" }, QUrl::fromLocalFile(activeContainerLocalPath())
+    );
+    QList<QAction*> actions = m_searchTools.actions();
+    if (actions.isEmpty()) {
+        return nullptr;
+    }
+    QAction* action = actions.first();
+    if (action->isSeparator()) {
+        return nullptr;
+    }
+    return action;
+}
+
+void DolphinMainWindow::setupUpdateOpenPreferredSearchToolAction()
+{
+    QAction* openPreferredSearchTool = actionCollection()->action(QStringLiteral("open_preferred_search_tool"));
+    const QList<QWidget*> widgets = openPreferredSearchTool->associatedWidgets();
+    for (QWidget* widget : widgets) {
+        QMenu* menu = qobject_cast<QMenu*>(widget);
+        if (menu) {
+            connect(menu, &QMenu::aboutToShow, this, &DolphinMainWindow::updateOpenPreferredSearchToolAction);
+        }
     }
 
-    KToolInvocation::invokeTerminal(QString(), dir);
+    // Update the open_preferred_search_tool action *before* the Configure Shortcuts window is shown,
+    // since this action is then listed in that window and it should be up-to-date when it is displayed.
+    // This update is instantaneous if user made no changes to the search tools in the meantime.
+    // Maybe all KStandardActions should defer calls to their slots, so that we could simply connect() to trigger()?
+    connect(
+        actionCollection()->action(KStandardAction::name(KStandardAction::KeyBindings)), &QAction::hovered,
+        this, &DolphinMainWindow::updateOpenPreferredSearchToolAction
+    );
+
+    updateOpenPreferredSearchToolAction();
+}
+
+void DolphinMainWindow::updateOpenPreferredSearchToolAction()
+{
+    QAction* openPreferredSearchTool = actionCollection()->action(QStringLiteral("open_preferred_search_tool"));
+    if (!openPreferredSearchTool) {
+        return;
+    }
+    QPointer<QAction> tool = preferredSearchTool();
+    if (tool) {
+        openPreferredSearchTool->setVisible(true);
+        openPreferredSearchTool->setText(i18nc("@action:inmenu Tools", "Open %1", tool->text()));
+        openPreferredSearchTool->setIcon(tool->icon());
+    } else {
+        openPreferredSearchTool->setVisible(false);
+        // still visible in Shortcuts configuration window
+        openPreferredSearchTool->setText(i18nc("@action:inmenu Tools", "Open Preferred Search Tool"));
+        openPreferredSearchTool->setIcon(QIcon::fromTheme(QStringLiteral("search")));
+    }
+}
+
+void DolphinMainWindow::openPreferredSearchTool()
+{
+    QPointer<QAction> tool = preferredSearchTool();
+    if (tool) {
+        tool->trigger();
+    }
+}
+
+void DolphinMainWindow::openTerminal()
+{
+    KToolInvocation::invokeTerminal(QString(), activeContainerLocalPath());
 }
 
 void DolphinMainWindow::editSettings()
@@ -1091,7 +1159,9 @@ void DolphinMainWindow::updateControlMenu()
 
     // Add a curated assortment of items from the "Tools" menu
     addActionToMenu(ac->action(QStringLiteral("show_filter_bar")), menu);
+    addActionToMenu(ac->action(QStringLiteral("open_preferred_search_tool")), menu);
     addActionToMenu(ac->action(QStringLiteral("open_terminal")), menu);
+    connect(menu, &QMenu::aboutToShow, this, &DolphinMainWindow::updateOpenPreferredSearchToolAction);
 
     menu->addSeparator();
 
@@ -1247,6 +1317,7 @@ void DolphinMainWindow::setupActions()
 
     QAction* addToPlaces = actionCollection()->addAction(QStringLiteral("add_to_places"));
     addToPlaces->setIcon(QIcon::fromTheme(QStringLiteral("bookmark-new")));
+    addToPlaces->setText(i18nc("@action:inmenu Add current folder to places", "Add to Places"));
     addToPlaces->setWhatsThis(xi18nc("@info:whatsthis", "This adds the selected folder "
         "to the Places panel."));
     connect(addToPlaces, &QAction::triggered, this, &DolphinMainWindow::addToPlaces);
@@ -1465,6 +1536,15 @@ void DolphinMainWindow::setupActions()
     compareFiles->setEnabled(false);
     connect(compareFiles, &QAction::triggered, this, &DolphinMainWindow::compareFiles);
 
+    QAction* openPreferredSearchTool = actionCollection()->addAction(QStringLiteral("open_preferred_search_tool"));
+    openPreferredSearchTool->setText(i18nc("@action:inmenu Tools", "Open Preferred Search Tool"));
+    openPreferredSearchTool->setWhatsThis(xi18nc("@info:whatsthis",
+        "<para>This opens a preferred search tool for the viewed location.</para>"
+        "<para>Use <emphasis>More Search Tools</emphasis> menu to configure it.</para>"));
+    openPreferredSearchTool->setIcon(QIcon::fromTheme(QStringLiteral("search")));
+    actionCollection()->setDefaultShortcut(openPreferredSearchTool, Qt::CTRL + Qt::SHIFT + Qt::Key_F);
+    connect(openPreferredSearchTool, &QAction::triggered, this, &DolphinMainWindow::openPreferredSearchTool);
+
 #ifdef HAVE_TERMINAL
     if (KAuthorized::authorize(QStringLiteral("shell_access"))) {
         QAction* openTerminal = actionCollection()->addAction(QStringLiteral("open_terminal"));
@@ -1475,6 +1555,12 @@ void DolphinMainWindow::setupActions()
         openTerminal->setIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts")));
         actionCollection()->setDefaultShortcut(openTerminal, Qt::SHIFT + Qt::Key_F4);
         connect(openTerminal, &QAction::triggered, this, &DolphinMainWindow::openTerminal);
+
+        QAction* focusTerminalPanel = actionCollection()->addAction(QStringLiteral("focus_terminal_panel"));
+        focusTerminalPanel->setText(i18nc("@action:inmenu Tools", "Focus Terminal Panel"));
+        focusTerminalPanel->setIcon(QIcon::fromTheme(QStringLiteral("swap-panels")));
+        actionCollection()->setDefaultShortcut(focusTerminalPanel, Qt::CTRL + Qt::SHIFT + Qt::Key_F4);
+        connect(focusTerminalPanel, &QAction::triggered, this, &DolphinMainWindow::focusTerminalPanel);
     }
 #endif
 
@@ -1810,7 +1896,6 @@ void DolphinMainWindow::updateFileAndEditActions()
         stateChanged(QStringLiteral("has_no_selection"));
 
         addToPlacesAction->setEnabled(true);
-        addToPlacesAction->setText(i18nc("@action:inmenu Add current folder to places", "Add '%1' to Places", m_activeViewContainer->placesText()));
     } else {
         stateChanged(QStringLiteral("has_selection"));
 
@@ -1823,10 +1908,8 @@ void DolphinMainWindow::updateFileAndEditActions()
 
         if (list.length() == 1 && list.first().isDir()) {
             addToPlacesAction->setEnabled(true);
-            addToPlacesAction->setText(i18nc("@action:inmenu Add current folder to places", "Add '%1' to Places", list.first().name()));
         } else {
             addToPlacesAction->setEnabled(false);
-            addToPlacesAction->setText(i18nc("@action:inmenu Add current folder to places", "Add to Places"));
         }
 
         KFileItemListProperties capabilities(list);
@@ -2208,6 +2291,8 @@ bool DolphinMainWindow::event(QEvent *event)
         QWhatsThisClickedEvent* whatsThisEvent = dynamic_cast<QWhatsThisClickedEvent*>(event);
         QDesktopServices::openUrl(QUrl(whatsThisEvent->href()));
         return true;
+    } else if (event->type() == QEvent::WindowActivate) {
+        updateOpenPreferredSearchToolAction();
     }
     return KXmlGuiWindow::event(event);
 }
@@ -2224,6 +2309,22 @@ bool DolphinMainWindow::eventFilter(QObject* obj, QEvent* event)
     return false;
 }
 
+void DolphinMainWindow::focusTerminalPanel()
+{
+    if (m_terminalPanel->isVisible()) {
+        if (m_terminalPanel->terminalHasFocus()) {
+            m_activeViewContainer->view()->setFocus(Qt::FocusReason::ShortcutFocusReason);
+            actionCollection()->action(QStringLiteral("focus_terminal_panel"))->setText(i18nc("@action:inmenu Tools", "Focus Terminal Panel"));
+        } else {
+            m_terminalPanel->setFocus(Qt::FocusReason::ShortcutFocusReason);
+            actionCollection()->action(QStringLiteral("focus_terminal_panel"))->setText(i18nc("@action:inmenu Tools", "Defocus Terminal Panel"));
+        }
+    } else {
+        actionCollection()->action(QStringLiteral("show_terminal_panel"))->trigger();
+        actionCollection()->action(QStringLiteral("focus_terminal_panel"))->setText(i18nc("@action:inmenu Tools", "Defocus Terminal Panel"));
+    }
+}
+
 DolphinMainWindow::UndoUiInterface::UndoUiInterface() :
     KIO::FileUndoManager::UiInterface()
 {
index 3d86340d6a9ed4b11dcc4d8489a9a04953bd06f2..940a03d83d13623eeb414450858d1b8d21044e6e 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <QIcon>
 #include <QList>
+#include <QMenu>
 #include <QPointer>
 #include <QUrl>
 #include <QVector>
@@ -352,9 +353,21 @@ private slots:
      */
     void toggleShowMenuBar();
 
+    /** Sets up updates for "Open Preferred Search Tool" action. */
+    void setupUpdateOpenPreferredSearchToolAction();
+
+    /** Updates "Open Preferred Search Tool" action. */
+    void updateOpenPreferredSearchToolAction();
+
+    /** Opens preferred search tool for the current location. */
+    void openPreferredSearchTool();
+
     /** Opens a terminal window for the current location. */
     void openTerminal();
 
+    /** Focus a Terminal Panel. */
+    void focusTerminalPanel();
+
     /** Opens the settings dialog for Dolphin. */
     void editSettings();
 
@@ -597,6 +610,15 @@ private:
     /** Adds "What's This?" texts to many widgets and StandardActions. */
     void setupWhatsThis();
 
+    /**
+     * Returns the KIO::StatJob::mostLocalUrl() for the active container URL
+     * if it's a local file. Otherwise returns the user's home path.
+     */
+    QString activeContainerLocalPath();
+
+    /** Returns preferred search tool as configured in "More Search Tools" menu. */
+    QPointer<QAction> preferredSearchTool();
+
 private:
     /**
      * Implements a custom error handling for the undo manager. This
@@ -633,6 +655,9 @@ private:
 
     KToolBarPopupAction* m_backAction;
     KToolBarPopupAction* m_forwardAction;
+
+    QMenu m_searchTools;
+
 };
 
 inline DolphinViewContainer* DolphinMainWindow::activeViewContainer() const
index 607917f9a1ca152a87381f1ee2cfbe719242fad3..7e7425121ca81105c7016630a2b6d9289550d5d6 100644 (file)
@@ -40,6 +40,7 @@
 #include <KLocalizedString>
 #include <KMessageBox>
 #include <KMimeTypeEditor>
+#include <KNS3/KMoreToolsMenuFactory>
 #include <KPluginFactory>
 #include <KRun>
 #include <KSharedConfig>
@@ -532,28 +533,21 @@ void DolphinPart::setNameFilter(const QString& nameFilter)
 
 void DolphinPart::slotOpenTerminal()
 {
-    QString dir(QDir::homePath());
-
-    QUrl u(url());
-
-    // If the given directory is not local, it can still be the URL of an
-    // ioslave using UDS_LOCAL_PATH which to be converted first.
-    KIO::StatJob* statJob = KIO::mostLocalUrl(u);
-    KJobWidgets::setWindow(statJob, widget());
-    statJob->exec();
-    u = statJob->mostLocalUrl();
-
-    //If the URL is local after the above conversion, set the directory.
-    if (u.isLocalFile()) {
-        dir = u.toLocalFile();
-    }
-
-    KToolInvocation::invokeTerminal(QString(), dir);
+    KToolInvocation::invokeTerminal(QString(), KParts::ReadOnlyPart::localFilePath());
 }
 
 void DolphinPart::slotFindFile()
 {
-    KRun::run(QStringLiteral("kfind"), {url()}, widget());
+    QMenu searchTools;
+    KMoreToolsMenuFactory("dolphin/search-tools").fillMenuFromGroupingNames(
+        &searchTools, { "files-find" }, QUrl::fromLocalFile(KParts::ReadOnlyPart::localFilePath())
+    );
+    QList<QAction*> actions = searchTools.actions();
+    if (!(actions.isEmpty())) {
+        actions.first()->trigger();
+    } else {
+        KRun::run(QStringLiteral("kfind"), {url()}, widget());
+    }
 }
 
 void DolphinPart::updateNewMenu()
@@ -562,7 +556,7 @@ void DolphinPart::updateNewMenu()
     m_newFileMenu->checkUpToDate();
     m_newFileMenu->setViewShowsHiddenFiles(m_view->hiddenFilesShown());
     // And set the files that the menu apply on :
-    m_newFileMenu->setPopupFiles(url());
+    m_newFileMenu->setPopupFiles(QList<QUrl>() << url());
 }
 
 void DolphinPart::updateStatusBar()
@@ -579,7 +573,7 @@ void DolphinPart::updateProgress(int percent)
 void DolphinPart::createDirectory()
 {
     m_newFileMenu->setViewShowsHiddenFiles(m_view->hiddenFilesShown());
-    m_newFileMenu->setPopupFiles(url());
+    m_newFileMenu->setPopupFiles(QList<QUrl>() << url());
     m_newFileMenu->createDirectory();
 }
 
index 864c08344e11a20535248b94fe77bf46df29e006..fe8f2d14ead2b3940640fe0f2409a939fbb2f744 100644 (file)
@@ -194,7 +194,7 @@ private Q_SLOTS:
     void slotOpenTerminal();
 
     /**
-     * Open KFind with the current path.
+     * Open preferred search tool in the current directory to find files.
      */
     void slotFindFile();
 
index afd3838e3b5018417e0e622a9854d1fa101ea454..df152fb20e4a30ebba0e234c747321f2ff3e7eeb 100644 (file)
@@ -1,5 +1,5 @@
 <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="dolphinpart" version="14" translationDomain="dolphin">
+<kpartgui name="dolphinpart" version="15" translationDomain="dolphin">
  <MenuBar>
   <Menu name="edit"><text>&amp;Edit</text>
    <Action name="new_menu"/>
@@ -39,6 +39,7 @@
   </Menu>
   <Menu name="tools"><text context="@title:menu">Tools</text>
     <Action name="open_terminal"/>
+    <Action name="focus_terminal_panel"/>
     <Action name="find_file" />
     <Action name="show_filter_bar" />
     <Action name="compare_files" />
index dcacc56c4982877eb1f70ba54ca457579288cd69..e1bb9ee58daa0ad0c8b2f556a1a7358d96a4ce6b 100644 (file)
@@ -1,5 +1,5 @@
 <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="dolphin" version="27">
+<kpartgui name="dolphin" version="29">
     <MenuBar>
         <Menu name="file">
             <Action name="new_menu" />
@@ -54,7 +54,9 @@
         </Menu>
         <Menu name="tools">
             <Action name="show_filter_bar" />
+            <Action name="open_preferred_search_tool" />
             <Action name="open_terminal" />
+            <Action name="focus_terminal_panel"/>
             <Action name="compare_files" />
             <Action name="change_remote_encoding" />
         </Menu>
index 9ed7654fafaf9388e9a4e4cd368aa15044dbe0da..bd3c8ed20f1d18f05ab15a61e8f86b2038f700b8 100644 (file)
@@ -50,6 +50,7 @@
 #include <QTimer>
 #include <QUrl>
 #include <QVBoxLayout>
+#include <QDesktopServices>
 
 DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) :
     QWidget(parent),
@@ -691,30 +692,18 @@ void DolphinViewContainer::slotUrlNavigatorLocationChanged(const QUrl& url)
             QTimer::singleShot(0, this, &DolphinViewContainer::requestFocus);
         }
     } else if (KProtocolManager::isSourceProtocol(url)) {
-        QString app = QStringLiteral("konqueror");
         if (url.scheme().startsWith(QLatin1String("http"))) {
             showMessage(i18nc("@info:status", // krazy:exclude=qmethods
                               "Dolphin does not support web pages, the web browser has been launched"),
                         Information);
-
-            const KConfigGroup config(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), "General");
-            const QString browser = config.readEntry("BrowserApplication");
-            if (!browser.isEmpty()) {
-                app = browser;
-                if (app.startsWith('!')) {
-                    // a literal command has been configured, remove the '!' prefix
-                    app.remove(0, 1);
-                }
-            }
         } else {
             showMessage(i18nc("@info:status",
-                              "Protocol not supported by Dolphin, Konqueror has been launched"),
+                              "Protocol not supported by Dolphin, default application has been launched"),
                         Information);
         }
 
-        const QString secureUrl = KShell::quoteArg(url.toDisplayString(QUrl::PreferLocalFile));
-        const QString command = app + ' ' + secureUrl;
-        KRun::runCommand(command, app, app, this);
+        QDesktopServices::openUrl(url);
+        redirect(QUrl(), m_urlNavigator->locationUrl(1));
     } else {
         showMessage(i18nc("@info:status", "Invalid protocol"), Error);
     }
index 3b81c536aea0613a2363a43aecb731d2bd652610..9aff25b26d6fc36ea984ff508ac4e23c87473b4a 100644 (file)
@@ -77,39 +77,39 @@ bool Dolphin::attachToExistingInstance(const QList<QUrl>& inputUrls, bool openFi
         return false;
     }
 
-    QVector<QPair<QSharedPointer<QDBusInterface>, QStringList>> dolphinServices;
+    QVector<QPair<QSharedPointer<QDBusInterface>, QStringList>> dolphinInterfaces;
     if (!preferredService.isEmpty()) {
-        QSharedPointer<QDBusInterface> preferred(
+        QSharedPointer<QDBusInterface> preferredInterface(
             new QDBusInterface(preferredService,
             QStringLiteral("/dolphin/Dolphin_1"),
             QString()) // #414402: use empty interface name to prevent QtDBus from caching the interface.
         );
-        if (preferred->isValid() && !preferred->lastError().isValid()) {
-            dolphinServices.append(qMakePair(preferred, QStringList()));
+        if (preferredInterface->isValid() && !preferredInterface->lastError().isValid()) {
+            dolphinInterfaces.append(qMakePair(preferredInterface, QStringList()));
         }
     }
 
-    // find all dolphin instances
-    const QStringList services = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
+    // Look for dolphin instances among all available dbus services.
+    const QStringList dbusServices = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
     // Don't match the service without trailing "-" (unique instance)
     const QString pattern = QStringLiteral("org.kde.dolphin-");
     // Don't match the pid without leading "-"
     const QString myPid = QLatin1Char('-') + QString::number(QCoreApplication::applicationPid());
-    for (const QString& service : services) {
+    for (const QString& service : dbusServices) {
         if (service.startsWith(pattern) && !service.endsWith(myPid)) {
             // Check if instance can handle our URLs
-            QSharedPointer<QDBusInterface> instance(
+            QSharedPointer<QDBusInterface> interface(
                 new QDBusInterface(service,
                 QStringLiteral("/dolphin/Dolphin_1"),
                 QStringLiteral("org.kde.dolphin.MainWindow"))
             );
-            if (instance->isValid() && !instance->lastError().isValid()) {
-                dolphinServices.append(qMakePair(instance, QStringList()));
+            if (interface->isValid() && !interface->lastError().isValid()) {
+                dolphinInterfaces.append(qMakePair(interface, QStringList()));
             }
         }
     }
 
-    if (dolphinServices.isEmpty()) {
+    if (dolphinInterfaces.isEmpty()) {
         return false;
     }
 
@@ -119,10 +119,10 @@ bool Dolphin::attachToExistingInstance(const QList<QUrl>& inputUrls, bool openFi
     const auto urls = QUrl::toStringList(inputUrls);
     for (const QString& url : urls) {
         bool urlFound = false;
-        for (auto& service: dolphinServices) {
-            QDBusReply<bool> isUrlOpen = service.first->call(QStringLiteral("isUrlOpen"), url);
-            if (isUrlOpen.isValid() && isUrlOpen.value()) {
-                service.second.append(url);
+        for (auto& interface: dolphinInterfaces) {
+            QDBusReply<bool> isUrlOpenReply = interface.first->call(QStringLiteral("isUrlOpen"), url);
+            if (isUrlOpenReply.isValid() && isUrlOpenReply.value()) {
+                interface.second.append(url);
                 urlFound = true;
                 break;
             }
@@ -131,12 +131,12 @@ bool Dolphin::attachToExistingInstance(const QList<QUrl>& inputUrls, bool openFi
             newUrls.append(url);
         }
     }
-    dolphinServices.front().second << newUrls;
+    dolphinInterfaces.front().second << newUrls;
 
-    for (const auto& service: dolphinServices) {
-        if (!service.second.isEmpty()) {
-            service.first->call(openFiles ? QStringLiteral("openFiles") : QStringLiteral("openDirectories"), service.second, splitView);
-            service.first->call(QStringLiteral("activateWindow"));
+    for (const auto& interface: dolphinInterfaces) {
+        if (!interface.second.isEmpty()) {
+            interface.first->call(openFiles ? QStringLiteral("openFiles") : QStringLiteral("openDirectories"), interface.second, splitView);
+            interface.first->call(QStringLiteral("activateWindow"));
         }
     }
     return true;
index 51ffb21406203a495be91f54a191abf579ced347..4b35a0248a5e07f976451fc2b5f80792bc64d5d5 100644 (file)
@@ -267,7 +267,7 @@ QMimeData* KFileItemModel::createMimeData(const KItemSet& indexes) const
             urls << item.url();
 
             bool isLocal;
-            mostLocalUrls << item.mostLocalUrl(isLocal);
+            mostLocalUrls << item.mostLocalUrl(&isLocal);
         }
     }
 
@@ -1187,12 +1187,20 @@ void KFileItemModel::insertItems(QList<ItemData*>& newItems)
     m_groups.clear();
     prepareItemsForSorting(newItems);
 
-    if (m_sortRole == NameRole && m_naturalSorting) {
-        // Natural sorting of items can be very slow. However, it becomes much
-        // faster if the input sequence is already mostly sorted. Therefore, we
-        // first sort 'newItems' according to the QStrings returned by
-        // KFileItem::text() using QString::operator<(), which is quite fast.
-        parallelMergeSort(newItems.begin(), newItems.end(), nameLessThan, QThread::idealThreadCount());
+    // Natural sorting of items can be very slow. However, it becomes much faster
+    // if the input sequence is already mostly sorted. Therefore, we first sort
+    // 'newItems' according to the QStrings using QString::operator<(), which is quite fast.
+    if (m_naturalSorting) {
+        if (m_sortRole == NameRole) {
+            parallelMergeSort(newItems.begin(), newItems.end(), nameLessThan, QThread::idealThreadCount());
+        } else if (isRoleValueNatural(m_sortRole)) {
+            auto lambdaLessThan = [&] (const KFileItemModel::ItemData* a, const KFileItemModel::ItemData* b)
+            {
+                const QByteArray role = roleForType(m_sortRole);
+                return a->values.value(role).toString() < b->values.value(role).toString();
+            };
+            parallelMergeSort(newItems.begin(), newItems.end(), lambdaLessThan, QThread::idealThreadCount());
+        }
     }
 
     sort(newItems.begin(), newItems.end());
@@ -1726,8 +1734,8 @@ void KFileItemModel::sort(const QList<KFileItemModel::ItemData*>::iterator &begi
         return lessThan(a, b, m_collator);
     };
 
-    if (m_sortRole == NameRole) {
-        // Sorting by name can be expensive, in particular if natural sorting is
+    if (m_sortRole == NameRole || isRoleValueNatural(m_sortRole)) {
+        // Sorting by string can be expensive, in particular if natural sorting is
         // enabled. Use all CPU cores to speed up the sorting process.
         static const int numberOfThreads = QThread::idealThreadCount();
         parallelMergeSort(begin, end, lambdaLessThan, numberOfThreads);
@@ -1835,6 +1843,8 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const
             result = -1;
         } else if (roleValueA.isEmpty() && !roleValueB.isEmpty()) {
             result = +1;
+        } else if (isRoleValueNatural(m_sortRole)) {
+            result = stringCompare(roleValueA, roleValueB, collator);
         } else {
             result = QString::compare(roleValueA, roleValueB);
         }
@@ -2309,38 +2319,38 @@ const KFileItemModel::RoleInfoMap* KFileItemModel::rolesInfoMap(int& count)
     static const RoleInfoMap rolesInfoMap[] = {
     //  |         role           |        roleType        |                role translation                     |            group translation               | requires Baloo | requires indexer
         { nullptr,               NoRole,                  nullptr, nullptr,                                     nullptr, nullptr,                            false,           false },
-        { "text",                NameRole,                I18N_NOOP2_NOSTRIP("@label", "Name"),                 nullptr, nullptr,                            false,           false },
-        { "size",                SizeRole,                I18N_NOOP2_NOSTRIP("@label", "Size"),                 nullptr, nullptr,                            false,           false },
-        { "modificationtime",    ModificationTimeRole,    I18N_NOOP2_NOSTRIP("@label", "Modified"),             nullptr, nullptr,                            false,           false },
-        { "creationtime",        CreationTimeRole,        I18N_NOOP2_NOSTRIP("@label", "Created"),              nullptr, nullptr,                            false,           false },
-        { "accesstime",          AccessTimeRole,          I18N_NOOP2_NOSTRIP("@label", "Accessed"),             nullptr, nullptr,                            false,           false },
-        { "type",                TypeRole,                I18N_NOOP2_NOSTRIP("@label", "Type"),                 nullptr, nullptr,                            false,           false },
-        { "rating",              RatingRole,              I18N_NOOP2_NOSTRIP("@label", "Rating"),               nullptr, nullptr,                            true,            false },
-        { "tags",                TagsRole,                I18N_NOOP2_NOSTRIP("@label", "Tags"),                 nullptr, nullptr,                            true,            false },
-        { "comment",             CommentRole,             I18N_NOOP2_NOSTRIP("@label", "Comment"),              nullptr, nullptr,                            true,            false },
-        { "title",               TitleRole,               I18N_NOOP2_NOSTRIP("@label", "Title"),                I18N_NOOP2_NOSTRIP("@label", "Document"),    true,            true  },
-        { "wordCount",           WordCountRole,           I18N_NOOP2_NOSTRIP("@label", "Word Count"),           I18N_NOOP2_NOSTRIP("@label", "Document"),    true,            true  },
-        { "lineCount",           LineCountRole,           I18N_NOOP2_NOSTRIP("@label", "Line Count"),           I18N_NOOP2_NOSTRIP("@label", "Document"),    true,            true  },
-        { "imageDateTime",       ImageDateTimeRole,       I18N_NOOP2_NOSTRIP("@label", "Date Photographed"),    I18N_NOOP2_NOSTRIP("@label", "Image"),       true,            true  },
-        { "width",               WidthRole,               I18N_NOOP2_NOSTRIP("@label", "Width"),                I18N_NOOP2_NOSTRIP("@label", "Image"),       true,            true  },
-        { "height",              HeightRole,              I18N_NOOP2_NOSTRIP("@label", "Height"),               I18N_NOOP2_NOSTRIP("@label", "Image"),       true,            true  },
-        { "orientation",         OrientationRole,         I18N_NOOP2_NOSTRIP("@label", "Orientation"),          I18N_NOOP2_NOSTRIP("@label", "Image"),       true,            true  },
-        { "artist",              ArtistRole,              I18N_NOOP2_NOSTRIP("@label", "Artist"),               I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "genre",               GenreRole,               I18N_NOOP2_NOSTRIP("@label", "Genre"),                I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "album",               AlbumRole,               I18N_NOOP2_NOSTRIP("@label", "Album"),                I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "duration",            DurationRole,            I18N_NOOP2_NOSTRIP("@label", "Duration"),             I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "bitrate",             BitrateRole,             I18N_NOOP2_NOSTRIP("@label", "Bitrate"),              I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "track",               TrackRole,               I18N_NOOP2_NOSTRIP("@label", "Track"),                I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "releaseYear",         ReleaseYearRole,         I18N_NOOP2_NOSTRIP("@label", "Release Year"),         I18N_NOOP2_NOSTRIP("@label", "Audio"),       true,            true  },
-        { "aspectRatio",         AspectRatioRole,         I18N_NOOP2_NOSTRIP("@label", "Aspect Ratio"),         I18N_NOOP2_NOSTRIP("@label", "Video"),       true,            true  },
-        { "frameRate",           FrameRateRole,           I18N_NOOP2_NOSTRIP("@label", "Frame Rate"),           I18N_NOOP2_NOSTRIP("@label", "Video"),       true,            true  },
-        { "path",                PathRole,                I18N_NOOP2_NOSTRIP("@label", "Path"),                 I18N_NOOP2_NOSTRIP("@label", "Other"),       false,           false },
-        { "deletiontime",        DeletionTimeRole,        I18N_NOOP2_NOSTRIP("@label", "Deletion Time"),        I18N_NOOP2_NOSTRIP("@label", "Other"),       false,           false },
-        { "destination",         DestinationRole,         I18N_NOOP2_NOSTRIP("@label", "Link Destination"),     I18N_NOOP2_NOSTRIP("@label", "Other"),       false,           false },
-        { "originUrl",           OriginUrlRole,           I18N_NOOP2_NOSTRIP("@label", "Downloaded From"),      I18N_NOOP2_NOSTRIP("@label", "Other"),       true,            false },
-        { "permissions",         PermissionsRole,         I18N_NOOP2_NOSTRIP("@label", "Permissions"),          I18N_NOOP2_NOSTRIP("@label", "Other"),       false,           false },
-        { "owner",               OwnerRole,               I18N_NOOP2_NOSTRIP("@label", "Owner"),                I18N_NOOP2_NOSTRIP("@label", "Other"),       false,           false },
-        { "group",               GroupRole,               I18N_NOOP2_NOSTRIP("@label", "User Group"),           I18N_NOOP2_NOSTRIP("@label", "Other"),       false,           false },
+        { "text",                NameRole,                I18NC_NOOP("@label", "Name"),                 nullptr, nullptr,                            false,           false },
+        { "size",                SizeRole,                I18NC_NOOP("@label", "Size"),                 nullptr, nullptr,                            false,           false },
+        { "modificationtime",    ModificationTimeRole,    I18NC_NOOP("@label", "Modified"),             nullptr, nullptr,                            false,           false },
+        { "creationtime",        CreationTimeRole,        I18NC_NOOP("@label", "Created"),              nullptr, nullptr,                            false,           false },
+        { "accesstime",          AccessTimeRole,          I18NC_NOOP("@label", "Accessed"),             nullptr, nullptr,                            false,           false },
+        { "type",                TypeRole,                I18NC_NOOP("@label", "Type"),                 nullptr, nullptr,                            false,           false },
+        { "rating",              RatingRole,              I18NC_NOOP("@label", "Rating"),               nullptr, nullptr,                            true,            false },
+        { "tags",                TagsRole,                I18NC_NOOP("@label", "Tags"),                 nullptr, nullptr,                            true,            false },
+        { "comment",             CommentRole,             I18NC_NOOP("@label", "Comment"),              nullptr, nullptr,                            true,            false },
+        { "title",               TitleRole,               I18NC_NOOP("@label", "Title"),                I18NC_NOOP("@label", "Document"),    true,            true  },
+        { "wordCount",           WordCountRole,           I18NC_NOOP("@label", "Word Count"),           I18NC_NOOP("@label", "Document"),    true,            true  },
+        { "lineCount",           LineCountRole,           I18NC_NOOP("@label", "Line Count"),           I18NC_NOOP("@label", "Document"),    true,            true  },
+        { "imageDateTime",       ImageDateTimeRole,       I18NC_NOOP("@label", "Date Photographed"),    I18NC_NOOP("@label", "Image"),       true,            true  },
+        { "width",               WidthRole,               I18NC_NOOP("@label", "Width"),                I18NC_NOOP("@label", "Image"),       true,            true  },
+        { "height",              HeightRole,              I18NC_NOOP("@label", "Height"),               I18NC_NOOP("@label", "Image"),       true,            true  },
+        { "orientation",         OrientationRole,         I18NC_NOOP("@label", "Orientation"),          I18NC_NOOP("@label", "Image"),       true,            true  },
+        { "artist",              ArtistRole,              I18NC_NOOP("@label", "Artist"),               I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "genre",               GenreRole,               I18NC_NOOP("@label", "Genre"),                I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "album",               AlbumRole,               I18NC_NOOP("@label", "Album"),                I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "duration",            DurationRole,            I18NC_NOOP("@label", "Duration"),             I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "bitrate",             BitrateRole,             I18NC_NOOP("@label", "Bitrate"),              I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "track",               TrackRole,               I18NC_NOOP("@label", "Track"),                I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "releaseYear",         ReleaseYearRole,         I18NC_NOOP("@label", "Release Year"),         I18NC_NOOP("@label", "Audio"),       true,            true  },
+        { "aspectRatio",         AspectRatioRole,         I18NC_NOOP("@label", "Aspect Ratio"),         I18NC_NOOP("@label", "Video"),       true,            true  },
+        { "frameRate",           FrameRateRole,           I18NC_NOOP("@label", "Frame Rate"),           I18NC_NOOP("@label", "Video"),       true,            true  },
+        { "path",                PathRole,                I18NC_NOOP("@label", "Path"),                 I18NC_NOOP("@label", "Other"),       false,           false },
+        { "deletiontime",        DeletionTimeRole,        I18NC_NOOP("@label", "Deletion Time"),        I18NC_NOOP("@label", "Other"),       false,           false },
+        { "destination",         DestinationRole,         I18NC_NOOP("@label", "Link Destination"),     I18NC_NOOP("@label", "Other"),       false,           false },
+        { "originUrl",           OriginUrlRole,           I18NC_NOOP("@label", "Downloaded From"),      I18NC_NOOP("@label", "Other"),       true,            false },
+        { "permissions",         PermissionsRole,         I18NC_NOOP("@label", "Permissions"),          I18NC_NOOP("@label", "Other"),       false,           false },
+        { "owner",               OwnerRole,               I18NC_NOOP("@label", "Owner"),                I18NC_NOOP("@label", "Other"),       false,           false },
+        { "group",               GroupRole,               I18NC_NOOP("@label", "User Group"),           I18NC_NOOP("@label", "Other"),       false,           false },
     };
 
     count = sizeof(rolesInfoMap) / sizeof(RoleInfoMap);
index c2dfd01670a96680beb9c0730b860682b1d2dedc..132a76e461cd216860524dfa25094e87dd21c38a 100644 (file)
@@ -355,6 +355,11 @@ private:
 
     QHash<QByteArray, QVariant> retrieveData(const KFileItem& item, const ItemData* parent) const;
 
+    /**
+     * @return True if role values benefit from natural or case insensitive sorting.
+     */
+    static bool isRoleValueNatural(const RoleType roleType);
+
     /**
      * @return True if \a a has a KFileItem whose text is 'less than' the one
      *         of \a b according to QString::operator<(const QString&).
@@ -504,12 +509,27 @@ private:
     friend class DolphinPart;                  // Accesses m_dirLister
 };
 
+inline bool KFileItemModel::isRoleValueNatural(RoleType roleType)
+{
+    return (roleType == TypeRole ||
+            roleType == TagsRole ||
+            roleType == CommentRole ||
+            roleType == TitleRole ||
+            roleType == ArtistRole ||
+            roleType == GenreRole ||
+            roleType == AlbumRole ||
+            roleType == PathRole ||
+            roleType == DestinationRole ||
+            roleType == OriginUrlRole ||
+            roleType == OwnerRole ||
+            roleType == GroupRole);
+}
+
 inline bool KFileItemModel::nameLessThan(const ItemData* a, const ItemData* b)
 {
     return a->item.text() < b->item.text();
 }
 
-
 inline bool KFileItemModel::isChildItem(int index) const
 {
     if (m_itemData.at(index)->parent) {
index b274e75e2f0c18617f193a7a07cacb3f00046e80..6279b15a994baf8f0f7579f57aa47a981ccf584d 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index c5ef855634f8eb0424f1eead19c580265b905b73..9fcb8896911a776d8e133f0b2cf1141786f2c4b0 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index a80869dfcb8a09f6e99761e30e0cd882dd0becc2..65c42b547d090d65be3fdb26d2289914aa3483ed 100644 (file)
@@ -2,8 +2,7 @@
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *   Copyright (C) 2012 by Frank Reininghaus <frank78ac@googlemail.com>    *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index b21e50735c59ab19ed6ee39f58cb7c5eacaeef74..6d9b2ac6ab3644f6d9feb6f4e443ea79fd2444be 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index 9689180d12965f610f5e1aba530a381a0a326e9e..0c495693cb6317c632dc29fcb8844b9e72190e6c 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
@@ -29,7 +28,7 @@
 #include <QStyleOptionGraphicsItem>
 
 KItemListGroupHeader::KItemListGroupHeader(QGraphicsWidget* parent) :
-    QGraphicsWidget(parent, nullptr),
+    QGraphicsWidget(parent),
     m_dirtyCache(true),
     m_role(),
     m_data(),
index 1b4f7db45fe6c9aa507b2778014356a6b66a3c16..6bee19414ce1b7736d2a9d380287cc532837919c 100644 (file)
@@ -2,8 +2,7 @@
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *   Copyright (C) 2011 by Frank Reininghaus <frank78ac@googlemail.com>    *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index 6f57100066029ee9704da3a6b41f2fb028aeae37..6b043513992c1d2457261edcc8dbee6a5092b9c3 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index bcfb86064b39182175d0234ed5d414efb87e4d49..84054aaacc0051c572ecfbaef4c327b6fd92980f 100644 (file)
@@ -35,21 +35,6 @@ KItemListStyleOption::KItemListStyleOption() :
 {
 }
 
-KItemListStyleOption::KItemListStyleOption(const KItemListStyleOption& other) :
-    rect(other.rect),
-    font(other.font),
-    fontMetrics(other.fontMetrics),
-    palette(other.palette),
-    padding(other.padding),
-    horizontalMargin(other.horizontalMargin),
-    verticalMargin(other.verticalMargin),
-    iconSize(other.iconSize),
-    extendedSelectionRegion(other.extendedSelectionRegion),
-    maxTextLines(other.maxTextLines),
-    maxTextWidth(other.maxTextWidth)
-{
-}
-
 KItemListStyleOption::~KItemListStyleOption()
 {
 }
index 93aafac1f53a9b3c027c97f0f68c47f572ec2eb8..381f4bbe50430c96776ea664834402d1abc6b638 100644 (file)
@@ -31,7 +31,6 @@ class DOLPHIN_EXPORT KItemListStyleOption
 {
 public:
     KItemListStyleOption();
-    KItemListStyleOption(const KItemListStyleOption& other);
     virtual ~KItemListStyleOption();
 
     QRect rect;
@@ -48,8 +47,6 @@ public:
 
     bool operator==(const KItemListStyleOption& other) const;
     bool operator!=(const KItemListStyleOption& other) const;
-
-
 };
 #endif
 
index 21cb2ae9889625f9dfa2f33a5b6a17cb73e0362e..f00805242f9a706138a91ef8ba3672d11d5713b1 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index 3dff35a63276f4a0c493838708d4453ef2849a8f..2a3b7ada27569f3e4544936b158a801384d398f3 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index c33335ae635412994f3aab44af3dbfc8c985222e..49a13f68fa096ef549a069d6d30147602f673bb9 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
@@ -39,7 +38,7 @@ KItemListWidgetInformant::~KItemListWidgetInformant()
 }
 
 KItemListWidget::KItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) :
-    QGraphicsWidget(parent, nullptr),
+    QGraphicsWidget(parent),
     m_informant(informant),
     m_index(-1),
     m_selected(false),
index 433048aa029e049bcabbfd06850dd19af0f89c1d..66b2da069cecb173ede4b51329ce4dbc745aeb80 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index 9cbcbf3c0d36340a2f38f153def4cae1e1647457..faabdbe1dccbac882b18d6a66b3e9107ec39379c 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index f1945de06c1df6cf47ee5eee47be80e6d5a95cc2..a6ba3f7c4ec888adb461bd5b893afc1862dda13d 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index 6453f2154a15c338fa8ce970816091709f2d6d54..f62305a393cc08097cdf5d6657932bd6d0a54502 100644 (file)
@@ -2,8 +2,7 @@
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *   Copyright (C) 2013 by Frank Reininghaus <frank78ac@googlemail.com>    *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index 015362e3fa9229062b00b2003e217c08e911dc68..062b20e905ce02c84fdb9943afa71c71714d1c42 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index 8a2a64b31d5fdce3044cb7f193787fb6c03e09fd..0f7100faae197d6217bf700d90d82ca149e4bf1c 100644 (file)
@@ -81,7 +81,12 @@ QHash<QByteArray, QVariant> KBalooRolesProvider::roleValues(const Baloo::File& f
             std::for_each(rangeBegin, rangeEnd, [&list](const entry& s) { list.append(s.second); });
             values.insert(role, propertyInfo.formatAsDisplayString(list));
         } else {
-            values.insert(role, propertyInfo.formatAsDisplayString((*rangeBegin).second));
+            if (propertyInfo.valueType() == QVariant::DateTime) {
+                // Let dolphin format later Dates
+                values.insert(role, (*rangeBegin).second);
+            } else {
+                values.insert(role, propertyInfo.formatAsDisplayString((*rangeBegin).second));
+            }
         }
         rangeBegin = rangeEnd;
     }
index 977a83d5dd28b7f16a1938b26dde9f9ed0b679e4..bd204fe8e24a353a16a0dccdc6ff821b668c8474 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <KDirWatch>
 
+#include <QFileInfo>
 #include <QThread>
 
 KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObject* parent) :
@@ -85,9 +86,11 @@ void KDirectoryContentsCounter::addDirectory(const QString& path)
 
 int KDirectoryContentsCounter::countDirectoryContentsSynchronously(const QString& path)
 {
-    if (!m_dirWatcher->contains(path)) {
-        m_dirWatcher->addDir(path);
-        m_watchedDirs.insert(path);
+    const QString resolvedPath = QFileInfo(path).canonicalFilePath();
+
+    if (!m_dirWatcher->contains(resolvedPath)) {
+        m_dirWatcher->addDir(resolvedPath);
+        m_watchedDirs.insert(resolvedPath);
     }
 
     KDirectoryContentsCounterWorker::Options options;
@@ -107,9 +110,11 @@ void KDirectoryContentsCounter::slotResult(const QString& path, int count)
 {
     m_workerIsBusy = false;
 
-    if (!m_dirWatcher->contains(path)) {
-        m_dirWatcher->addDir(path);
-        m_watchedDirs.insert(path);
+    const QString resolvedPath = QFileInfo(path).canonicalFilePath();
+
+    if (!m_dirWatcher->contains(resolvedPath)) {
+        m_dirWatcher->addDir(resolvedPath);
+        m_watchedDirs.insert(resolvedPath);
     }
 
     if (!m_queue.isEmpty()) {
index 2bc96a0fac33862cceda4a647f217861dd1eae6d..d6cc87e1d9a0e261487cbcf0aea7036655e06bd8 100644 (file)
@@ -46,7 +46,7 @@ bool KFileItemClipboard::isCut(const QUrl& url) const
 
 QList<QUrl> KFileItemClipboard::cutItems() const
 {
-    return m_cutItems.toList();
+    return m_cutItems.values();
 }
 
 KFileItemClipboard::~KFileItemClipboard()
index 5256f69cad4ebe06ca6d67eae968483e7c9cea8d..1fa6f7a7b0045eee7f5af16e7e766edb03efb8b1 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  * Copyright (C) 2011 by Tirtha Chatterjee <tirtha.p.chatterjee@gmail.com> *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index 9995c16b0114d6f26b42888f782e9bfc6783099a..d0161f927c985996ecbdb65d20fb7c6fbfbfc33c 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  * Copyright (C) 2011 by Tirtha Chatterjee <tirtha.p.chatterjee@gmail.com> *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
@@ -76,7 +75,7 @@ signals:
      *                           current item.
      */
     // TODO: Think about getting rid of the bool parameter
-    // (see http://doc.qt.nokia.com/qq/qq13-apis.html#thebooleanparametertrap)
+    // (see https://doc.qt.io/archives/qq/qq13-apis.html#thebooleanparametertrap)
     void changeCurrentItem(const QString& string, bool searchFromNextItem);
 
 private:
index 6bdd18da5306a7be3ec17edeebbf05e67e7493eb..48c6854aad94d6bf816a44eff15232a223a031ad 100644 (file)
@@ -25,7 +25,7 @@
 #include <QPainter>
 
 KItemListSelectionToggle::KItemListSelectionToggle(QGraphicsItem* parent) :
-    QGraphicsWidget(parent, nullptr),
+    QGraphicsWidget(parent),
     m_checked(false),
     m_hovered(false)
 {
index 77b1e8ce67d60267c2fdd5fccd4d7bfd7cef6f04..c80fe81fa3cae65700fa2aa6bc466ac4b7ca8721 100644 (file)
@@ -26,6 +26,7 @@
   <name xml:lang="it">Dolphin</name>
   <name xml:lang="ko">Dolphin</name>
   <name xml:lang="lt">Dolphin</name>
+  <name xml:lang="ml">ഡോൾഫിൻ</name>
   <name xml:lang="nb">Dolphin</name>
   <name xml:lang="nds">Dolphin</name>
   <name xml:lang="nl">Dolphin</name>
@@ -72,6 +73,7 @@
   <summary xml:lang="it">Gestore file</summary>
   <summary xml:lang="ko">파일 관리자</summary>
   <summary xml:lang="lt">Failų tvarkytuvė</summary>
+  <summary xml:lang="ml">ഫയല്‍ കാര്യസ്ഥന്‍</summary>
   <summary xml:lang="nb">Filbehandler</summary>
   <summary xml:lang="nds">Dateipleger</summary>
   <summary xml:lang="nl">Bestandsbeheerder</summary>
     <p xml:lang="id">Dolphin adalah pengelola file yang ringan. Ini telah dirancang dengan kemudahan penggunaan dan kesederhanaan dalam hal, sementara masih memungkinkan fleksibilitas dan kustomisasi. Ini berarti kamu bisa melakukan pengelolaan file-mu persis seperti yang kamu inginkan.</p>
     <p xml:lang="it">Dolphin è un gestore file leggero. È stato progettato per essere facile da utilizzare e pensando alla semplicità, garantendo al contempo flessibilità e personalizzazione. Ciò significa che puoi gestire i tuoi file come meglio desideri.</p>
     <p xml:lang="ko">Dolphin은 가벼운 파일 관리자입니다. 사용 편의성과 단순함을 염두에 두고 설계되었으며, 유연성과 사용자 지정을 여전히 허용합니다. 즉, 파일 관리를 원하는 방식으로 정확하게 수행할 수 있습니다.</p>
+    <p xml:lang="lt">Dolphin yra supaprastinta failų tvarkytuvė. Ji buvo sukurta taip, kad ją būtų lengva naudoti, susitelkiant į paprastumą, tačiau įgalinant lankstumą ir tinkinimą. Tai reiškia, kad galite tvarkyti failus būtent taip, kaip norite.</p>
+    <p xml:lang="ml">ഡോൾഫിൻ ഒരു ഭാരം കുറഞ്ഞ ഫയൽ മാനേജറാണ്. ഇത് നിർമ്മിച്ചിരിക്കുന്നത് ഉപയോഗിക്കുന്നതിനുള്ള എളുപ്പത്തിനും , മാനസികമായിയുള്ള എളുപ്പത്തിനുമാണ്, ഒപ്പം തന്നെ അഭിരുചിക്കനുസൃതമാക്കുന്നതിനും വഴക്കം നൽകുന്നതിനും അനുവദിക്കുന്നു. അതായത് നിങ്ങൾക്ക് നിങ്ങളുടെ ഫയലുകൾ  എങ്ങനെയൊക്കെ കൈകാര്യം ചെയ്യണോ അങ്ങനെ കൈകാര്യം ചെയ്യാവുന്നതാണ്.</p>
     <p xml:lang="nb">Dolphin er en lettvekts filbehandler. Den er laget for å være enkel og lett å bruke, samtidig som den er fleksibel og kan tilpasses. Det betyr at du kan utføre dine filbehandlingsoppgaver akkurat slik du vil gjøre det.</p>
     <p xml:lang="nds">Dolphin is en slank Dateipleger. Dat wöör buut mit de Idee vun't eenfache Bedenen vör Ogen, bides dat liekers flexibel un topassbor wesen schull. Du kannst Dien Dateien also jüst so plegen, as Du dat wullt.</p>
     <p xml:lang="nl">Dolphin is een lichtgewicht bestandsbeheerder. Het is ontworpen met gebruiksgemak en eenvoud in gedachte en staat toch flexibiliteit en aan te passen toe. Dit betekent dat u uw bestandsbeheer kunt doen precies op de manier zoals u dat wilt.</p>
     <p xml:lang="id">Fitur:</p>
     <p xml:lang="it">Funzionalità:</p>
     <p xml:lang="ko">기능:</p>
-    <p xml:lang="lt">Galimybės</p>
+    <p xml:lang="lt">Ypatybės:</p>
+    <p xml:lang="ml">വിശേഷതകൾ:</p>
     <p xml:lang="nb">Egenskaper:</p>
     <p xml:lang="nds">Markmalen:</p>
     <p xml:lang="nl">Mogelijkheden:</p>
       <li xml:lang="id">Bilah navigasi (atau breadcrumb) untuk URL-URL, memungkinkan kamu secara cepat bernavigasi melalui hirerarki file-file dan folder-folder.</li>
       <li xml:lang="it">La barra di navigazione per gli URL, che ti consente di navigare rapidamente attraverso la struttura di file e cartelle.</li>
       <li xml:lang="ko">URL에 대한 탐색(또는 이동 경로) 표시줄을 사용하면 파일 및 폴더의 계층 구조를 빠르게 탐색할 수 있습니다.</li>
+      <li xml:lang="lt">Naršymo (arba trupinių) juosta, skirta URL adresams, leidžianti greitai naršyti per failų ar aplankų hierarchiją.</li>
+      <li xml:lang="ml">ഫയലുകളുടെയും അറകളുടെയും ശ്രേണി കണ്ടുപിടിക്കുന്നതിന് URL കൾക്ക്  നാവിഗേഷൻ (അല്ലെങ്കിൽ വഴി കാട്ടുന്നതിനുള്ള) സ്ഥലം.</li>
       <li xml:lang="nb">Navigasjonslinje (brødsmulelinje) for URL-er slik at du raskt kan navigere gjennom hierarkiet av filer og mapper.</li>
       <li xml:lang="nds">Steed- (oder Krömelspoor-)Balken för URLs, mit de Du Di fix dör de Hierarchie ut Dateien un Ornern bewegen kannst</li>
       <li xml:lang="nl">Navigatie- (of broodkruimel)balk voor URL's, waarmee u snel kunt navigeren door de hiërarchie van bestanden en mappen.</li>
       <li xml:lang="id">Mendukung beberapa jenis gaya tampilan dan properti yang berbeda dan memungkinkanmu untuk mengonfigurasi tampilan persis seperti yang kamu inginkan.</li>
       <li xml:lang="it">Supporta diversi stili di visualizzazione e proprietà e ti consente di configurare la vista come desideri.</li>
       <li xml:lang="ko">여러 종류의 보기 스타일 및 속성을 지원하며 원하는 방식으로 보기를 구성할 수 있습니다.</li>
+      <li xml:lang="lt">Palaiko kelias įvairias stilių ir savybių rūšis ir leidžia konfigūruoti rodinį būtent taip, kaip norite.</li>
+      <li xml:lang="ml">നിങ്ങൾക്ക് ഇഷ്ടമുള്ള രീതിയിൽ കാണുന്നതിന് ആവശ്യമായിട്ടുള്ള വിവിധ അലങ്കാര രീതികള്‍ക്ക് പിന്തുണ നൽകുന്നു.</li>
       <li xml:lang="nb">Støtter flere forskjellige visningsstiler og kan sette opp visningen akkurat slik du vil ha den.</li>
       <li xml:lang="nds">Ünnerstütt en Reeg verscheden Ansichtstilen un -egenschappen un lett Di de Ansicht jüst so topassen, as Du dat bruukst.</li>
       <li xml:lang="nl">Ondersteunt een aantal verschillende soorten stijlen van weergave en eigenschappen en biedt u de mogelijkheid de weergave in te stellen precies zoals u dat wilt.</li>
       <li xml:lang="id">Tampilan belah, memungkinkanmu untuk menyalin atau memindah file antar lokasi dengan mudah.</li>
       <li xml:lang="it">La vista divisa, che ti consente di copiare o spostare i file tra le diverse posizioni in maniera semplice.</li>
       <li xml:lang="ko">분할 보기를 통해 위치간에 파일을 쉽게 복사하거나 이동할 수 있습니다.</li>
+      <li xml:lang="lt">Padalytas rodinys, leidžiantis lengvai kopijuoti ar perkelti failus tarp įvairių vietų.</li>
+      <li xml:lang="ml">എളുപ്പത്തിൽ ഫയലുകൾ പക‍‍ർത്തുന്നതിനും നീക്കുന്നതിനും സഹായിക്കുന്ന വേർതിരിച്ച കാഴ്ച</li>
       <li xml:lang="nb">Delt visning, så du lett kan kopiere eller flytte filer mellom steder.</li>
       <li xml:lang="nds">Deelt Ansicht, mit De Du Dateien eenfach twischen Steden koperen oder bewegen kannst.</li>
       <li xml:lang="nl">Gesplitst beeld, waarmee u gemakkelijk bestanden kunt kopiëren of verplaatsen tussen locaties.</li>
       <li xml:lang="id">Informasi tambahan dan pintasan tersedia sebagai panel yang bisa di-dock, memungkinkanmu untuk memindahkannya secara bebas dan menampilkan apa yang kamu inginkan.</li>
       <li xml:lang="it">Informazioni aggiuntive e scorciatoie sono disponibili come pannelli agganciabili, che possono essere spostati liberamente e visualizzare esattamente ciò che desideri.</li>
       <li xml:lang="ko">추가 정보 및 바로 가기는 도킹 가능한 패널로 제공되므로 자유롭게 이동할 수 있고 원하는 대로 정확히 표시할 수 있습니다.</li>
+      <li xml:lang="lt">Papildoma informacija ir šaukiniai yra prieinami kaip pritvirtinami skydeliai, leidžiantys juos laisvai perkelinėti ir atvaizduoti būtent tai, ką norite.</li>
+      <li xml:lang="ml">നിങ്ങൾക്ക് ആവശ്യമായിട്ടുള്ള കുറുക്കുവഴികളും വിവരങ്ങളും എളുപ്പത്തിൽ തുറക്കാവുന്ന ഭാഗങ്ങളായി ലഭ്യമാണ്.</li>
       <li xml:lang="nb">Mer informasjon og snarveier er tilgjengelige som dokkbare ruter, som du kan flytte fritt rundt og bruke til å vise akkurat hva du vil.</li>
       <li xml:lang="nds">Bito-Infos un Leestekens laat sik as Paneels andocken, Du kannst ehr verschuven un se jüst dat wiesen laten, wat Du weten wullt.</li>
       <li xml:lang="nl">Extra informatie en sneltoetsen zijn beschikbaar als vast te zetten panelen, die u vrij kunt verplaatsen en precies kunt tonen wat u wilt.</li>
       <li xml:lang="it">Supporto di schede multiple</li>
       <li xml:lang="ko">다중 탭 지원</li>
       <li xml:lang="lt">Daugelio kortelių palaikymas</li>
+      <li xml:lang="ml">അനേക  ടാബുകളുടെ പിൻതുണ</li>
       <li xml:lang="nb">Støtte for flere faner</li>
       <li xml:lang="nds">Ünnerstütten för Paneels</li>
       <li xml:lang="nl">Ondersteuning voor meerdere tabbladen</li>
       <li xml:lang="id">Dialog informasi ditampilkan dengan cara yang tidak mengganggu.</li>
       <li xml:lang="it">Le finestre informative sono visualizzate in modo molto discreto.</li>
       <li xml:lang="ko">정보 대화 상자는 눈에 거슬리지 않는 방식으로 표시됩니다.</li>
+      <li xml:lang="lt">Informaciniai dialogai yra rodomi neįkyriai.</li>
+      <li xml:lang="ml">വിവരങ്ങൾ അച്ചടക്കമുള്ള രീതിയിൽ ദൃശ്യമാകുന്നു.</li>
       <li xml:lang="nb">Informasjonsdialoger vises på en lite påtrengende måte.</li>
       <li xml:lang="nds">Informatschoondialogen kaamt Di nich in'n Weg.</li>
       <li xml:lang="nl">Informatiedialogen worden op een prettige manier getoond.</li>
       <li xml:lang="id">Dukungan urungkan/lanjurkan</li>
       <li xml:lang="it">Supporto di annulla/rifai</li>
       <li xml:lang="ko">실행 취소/다시 실행 지원</li>
+      <li xml:lang="lt">Atšaukimo/grąžinimo palaikymas</li>
+      <li xml:lang="ml">നിഷ്ക്രിയമാക്കുക/വീണ്ടും ചെയ്യുക പിന്തുണയ്ക്കുന്നു</li>
       <li xml:lang="nb">Støtte for angring/omgjøring</li>
       <li xml:lang="nds">Ünnerstütten för Torüchnehmen un Wedderherstellen</li>
       <li xml:lang="nl">Ondersteuning ongedaan maken/opnieuw</li>
       <li xml:lang="id">Akses jaringan transparan melalui sistem KIO.</li>
       <li xml:lang="it">Accesso trasparente alla rete tramite il sistema KIO.</li>
       <li xml:lang="ko">KIO 시스템을 통한 투명한 네트워크 액세스.</li>
+      <li xml:lang="lt">Skaidri tinklo prieiga per KIO sistemą.</li>
+      <li xml:lang="ml">KIO സിസ്റ്റത്തിലൂടെ ശൃംഖലയെ സമീപിക്കുന്നു.</li>
       <li xml:lang="nb">Gjennomsiktig nettverkstilgang via KIO-systemet.</li>
       <li xml:lang="nds">Direkt Nettwarktogriep över dat KDE-In-/Utgaav-(KIO-)Moduulsysteem</li>
       <li xml:lang="nl">Transparante toegang tot het netwerk via het KIO systeem.</li>
       <caption xml:lang="id">Pengelolaan file di Dolphin</caption>
       <caption xml:lang="it">Gestione dei file in Dolphin</caption>
       <caption xml:lang="ko">Dolphin의 파일 관리</caption>
+      <caption xml:lang="lt">Failų tvarkymas Dolphin programoje</caption>
+      <caption xml:lang="ml">ഡോൾഫിനിലെ ഫയൽ കൈകാര്യം ചെയ്യൽ</caption>
       <caption xml:lang="nl">Bestandsbeheer in Dolphin</caption>
       <caption xml:lang="nn">Filhandsaming i Dolphin</caption>
       <caption xml:lang="pl">Zarządzanie plikami w Dolphinie</caption>
index 01f338461f0d8990651ed615612cab5d239fa589..2e7e4dc28c1ee8d88a511044efec48bed940af37 100644 (file)
 #include "kitemviews/kitemlistselectionmanager.h"
 #include "treeviewcontextmenu.h"
 #include "views/draganddrophelper.h"
-#include "views/renamedialog.h"
 
 #include <KJobWidgets>
 #include <KJobUiDelegate>
 #include <KIO/CopyJob>
 #include <KIO/DropJob>
 #include <KIO/FileUndoManager>
+#include <KIO/RenameFileDialog>
 
 #include <QApplication>
 #include <QBoxLayout>
@@ -104,7 +104,7 @@ void FoldersPanel::rename(const KFileItem& item)
         const int index = m_model->index(item);
         m_controller->view()->editRole(index, "text");
     } else {
-        RenameDialog* dialog = new RenameDialog(this, KFileItemList() << item);
+        KIO::RenameFileDialog* dialog = new KIO::RenameFileDialog(KFileItemList({item}), this);
         dialog->open();
     }
 }
index df9b9d62e5aba15270814b27907a83b1ce71dd4a..6c4adf8836b95dbda1a5e51f16117305ae60eed0 100644 (file)
@@ -173,7 +173,7 @@ void TreeViewContextMenu::populateMimeData(QMimeData* mimeData, bool cut)
     kdeUrls.append(m_fileItem.url());
     QList<QUrl> mostLocalUrls;
     bool dummy;
-    mostLocalUrls.append(m_fileItem.mostLocalUrl(dummy));
+    mostLocalUrls.append(m_fileItem.mostLocalUrl(&dummy));
     KIO::setClipboardDataCut(mimeData, cut);
     KUrlMimeData::setUrls(kdeUrls, mostLocalUrls, mimeData);
 }
index e6c3bf32ad5610247baf32f858bcfd6ef542a6ae..23e7f1922b0b0625d719a60c26781d39721f509c 100644 (file)
@@ -290,8 +290,8 @@ void InformationPanel::reset()
 
 void InformationPanel::slotFileRenamed(const QString& source, const QString& dest)
 {
-    if (m_shownUrl == QUrl::fromLocalFile(source)) {
-        m_shownUrl = QUrl::fromLocalFile(dest);
+    if (m_shownUrl == QUrl::fromUserInput(source)) {
+        m_shownUrl = QUrl::fromUserInput(dest);
         m_fileItem = KFileItem(m_shownUrl);
 
         if ((m_selection.count() == 1) && (m_selection[0].url() == QUrl::fromLocalFile(source))) {
@@ -308,10 +308,10 @@ void InformationPanel::slotFileRenamed(const QString& source, const QString& des
 
 void InformationPanel::slotFilesAdded(const QString& directory)
 {
-    if (m_shownUrl == QUrl::fromLocalFile(directory)) {
+    if (m_shownUrl == QUrl::fromUserInput(directory)) {
         // If the 'trash' icon changes because the trash has been emptied or got filled,
         // the signal filesAdded("trash:/") will be emitted.
-        KFileItem item(QUrl::fromLocalFile(directory));
+        KFileItem item(QUrl::fromUserInput(directory));
         requestDelayedItemInfo(item);
     }
 }
@@ -319,7 +319,7 @@ void InformationPanel::slotFilesAdded(const QString& directory)
 void InformationPanel::slotFilesChanged(const QStringList& files)
 {
     for (const QString& fileName : files) {
-        if (m_shownUrl == QUrl::fromLocalFile(fileName)) {
+        if (m_shownUrl == QUrl::fromUserInput(fileName)) {
             showItemInfo();
             break;
         }
@@ -329,7 +329,7 @@ void InformationPanel::slotFilesChanged(const QStringList& files)
 void InformationPanel::slotFilesRemoved(const QStringList& files)
 {
     for (const QString& fileName : files) {
-        if (m_shownUrl == QUrl::fromLocalFile(fileName)) {
+        if (m_shownUrl == QUrl::fromUserInput(fileName)) {
             // the currently shown item has been removed, show
             // the parent directory as fallback
             markUrlAsInvalid();
@@ -340,15 +340,15 @@ void InformationPanel::slotFilesRemoved(const QStringList& files)
 
 void InformationPanel::slotEnteredDirectory(const QString& directory)
 {
-    if (m_shownUrl == QUrl::fromLocalFile(directory)) {
-        KFileItem item(QUrl::fromLocalFile(directory));
+    if (m_shownUrl == QUrl::fromUserInput(directory)) {
+        KFileItem item(QUrl::fromUserInput(directory));
         requestDelayedItemInfo(item);
     }
 }
 
 void InformationPanel::slotLeftDirectory(const QString& directory)
 {
-    if (m_shownUrl == QUrl::fromLocalFile(directory)) {
+    if (m_shownUrl == QUrl::fromUserInput(directory)) {
         // The signal 'leftDirectory' is also emitted when a media
         // has been unmounted. In this case no directory change will be
         // done in Dolphin, but the Information Panel must be updated to
index 417ca709cf0c2a1dcbb538ce11345b541ee38ef8..5c1b7ae2240c227d12b5bc9881d413f78c592a8b 100644 (file)
@@ -166,12 +166,13 @@ InformationPanelContent::~InformationPanelContent()
 
 void InformationPanelContent::showItem(const KFileItem& item)
 {
-    if (item != m_item) {
+    // compares item entries, comparing items only compares urls
+    if (m_item.entry() != item.entry()) {
         m_item = item;
-
         m_preview->stopAnimatedImage();
         refreshMetaData();
     }
+
     refreshPreview();
 }
 
index 6911f79bd16cf8e9318f035d7e5827ceff7f33a1..f815b4bd043bfef51a0a2d2d08c38e8486e5e8f6 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "phononwidget.h"
 
-#include <KIconLoader>
 #include <KLocalizedString>
 #include <Phonon/AudioOutput>
 #include <Phonon/MediaObject>
@@ -28,6 +27,7 @@
 #include <Phonon/VideoWidget>
 
 #include <QShowEvent>
+#include <QStyle>
 #include <QToolButton>
 #include <QVBoxLayout>
 
@@ -161,7 +161,7 @@ void PhononWidget::showEvent(QShowEvent *event)
 
         m_topLayout->addLayout(controlsLayout);
 
-        const int smallIconSize = IconSize(KIconLoader::Small);
+        const int smallIconSize = style()->pixelMetric(QStyle::PM_SmallIconSize);
         const QSize buttonSize(smallIconSize, smallIconSize);
 
         m_playButton->setToolTip(i18n("play"));
index 884859d5bfa4b8f220e502e50068ccd66a2a7aa9..dbd055f367679a5b066e7e1f8277e893123d452e 100644 (file)
@@ -1,8 +1,7 @@
 /***************************************************************************
  *   Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com>             *
  *                                                                         *
- *   Based on the Itemviews NG project from Trolltech Labs:                *
- *   http://qt.gitorious.org/qt-labs/itemviews-ng                          *
+ *   Based on the Itemviews NG project from Trolltech Labs                 *
  *                                                                         *
  *   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  *
index 8469399a7ff98bcca3cd7f7c467d22be3f525c91..d90a20fa6cfdc275f91361370d4173227e977893 100644 (file)
@@ -181,8 +181,8 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
         menu.addSeparator();
     }
 
-    QAction* openInNewWindowAction = menu.addAction(QIcon::fromTheme(QStringLiteral("window-new")), i18nc("@item:inmenu", "Open in New Window"));
     QAction* openInNewTabAction = menu.addAction(QIcon::fromTheme(QStringLiteral("tab-new")), i18nc("@item:inmenu", "Open in New Tab"));
+    QAction* openInNewWindowAction = menu.addAction(QIcon::fromTheme(QStringLiteral("window-new")), i18nc("@item:inmenu", "Open in New Window"));
     QAction* propertiesAction = nullptr;
     if (item->url().isLocalFile()) {
         propertiesAction = menu.addAction(QIcon::fromTheme(QStringLiteral("document-properties")), i18nc("@action:inmenu", "Properties"));
@@ -309,10 +309,10 @@ void PlacesPanel::slotViewContextMenuRequested(const QPointF& pos)
 
     const int iconSizeCount = 4;
     static const IconSizeInfo iconSizes[iconSizeCount] = {
-        {KIconLoader::SizeSmall,        I18N_NOOP2_NOSTRIP("Small icon size", "Small (%1x%2)")},
-        {KIconLoader::SizeSmallMedium,  I18N_NOOP2_NOSTRIP("Medium icon size", "Medium (%1x%2)")},
-        {KIconLoader::SizeMedium,       I18N_NOOP2_NOSTRIP("Large icon size", "Large (%1x%2)")},
-        {KIconLoader::SizeLarge,        I18N_NOOP2_NOSTRIP("Huge icon size", "Huge (%1x%2)")}
+        {KIconLoader::SizeSmall,        I18NC_NOOP("Small icon size", "Small (%1x%2)")},
+        {KIconLoader::SizeSmallMedium,  I18NC_NOOP("Medium icon size", "Medium (%1x%2)")},
+        {KIconLoader::SizeMedium,       I18NC_NOOP("Large icon size", "Large (%1x%2)")},
+        {KIconLoader::SizeLarge,        I18NC_NOOP("Huge icon size", "Huge (%1x%2)")}
     };
 
     QHash<QAction*, int> iconSizeActionMap;
index 86974d200e4d23190222367c07b86d226037e813..861afebee0330fa2fd5c9ffc4917630a29809f6b 100644 (file)
@@ -147,6 +147,7 @@ void TerminalPanel::showEvent(QShowEvent* event)
         if (m_konsolePart) {
             connect(m_konsolePart, &KParts::ReadOnlyPart::destroyed, this, &TerminalPanel::terminalExited);
             m_terminalWidget = m_konsolePart->widget();
+            setFocusProxy(m_terminalWidget);
             m_layout->addWidget(m_terminalWidget);
             if (m_konsolePartMissingMessage) {
                 m_layout->removeWidget(m_konsolePartMissingMessage);
@@ -263,3 +264,8 @@ void TerminalPanel::slotKonsolePartCurrentDirectoryChanged(const QString& dir)
     const QUrl url(QUrl::fromLocalFile(dir));
     emit changeUrl(url);
 }
+
+bool TerminalPanel::terminalHasFocus() const
+{
+    return m_terminalWidget->hasFocus();
+}
index f5d66e548ece30e5ed2fa4aaea250f2fa049f559..6ab205fe32cb01828dff012bdfb49e6b8d59ad5e 100644 (file)
@@ -56,6 +56,7 @@ public:
     void goHome();
     QString currentWorkingDirectory();
     bool isHiddenInVisibleWindow() const;
+    bool terminalHasFocus() const;
     bool hasProgramRunning() const;
     QString runningProgramName() const;
 
index ae05509e77fc6ffe8894ce4fd6a6d453b0163a17..d9943abcd4867ea425629fc6b9bb74710b4f2a49 100644 (file)
 #include <QEvent>
 #include <QHBoxLayout>
 #include <QIcon>
+#include <QMenu>
+#include <QToolButton>
 
 DolphinFacetsWidget::DolphinFacetsWidget(QWidget* parent) :
     QWidget(parent),
     m_typeSelector(nullptr),
     m_dateSelector(nullptr),
-    m_ratingSelector(nullptr)
+    m_ratingSelector(nullptr),
+    m_tagsSelector(nullptr)
 {
     m_typeSelector = new QComboBox(this);
     m_typeSelector->addItem(QIcon::fromTheme(QStringLiteral("none")), i18nc("@item:inlistbox", "Any Type"), QString());
@@ -63,13 +66,27 @@ DolphinFacetsWidget::DolphinFacetsWidget(QWidget* parent) :
     m_ratingSelector->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "Highest Rating"), 5);
     initComboBox(m_ratingSelector);
 
+    m_tagsSelector = new QToolButton(this);
+    m_tagsSelector->setIcon(QIcon::fromTheme(QStringLiteral("tag")));
+    m_tagsSelector->setMenu(new QMenu(this));
+    m_tagsSelector->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+    m_tagsSelector->setPopupMode(QToolButton::MenuButtonPopup);
+    m_tagsSelector->setAutoRaise(true);
+    updateTagsSelector();
+
+    connect(m_tagsSelector, &QToolButton::clicked, m_tagsSelector, &QToolButton::showMenu);
+    connect(m_tagsSelector->menu(), &QMenu::aboutToShow, this, &DolphinFacetsWidget::updateTagsMenu);
+    connect(&m_tagsLister, &KCoreDirLister::itemsAdded, this, &DolphinFacetsWidget::updateTagsMenuItems);
+    updateTagsMenu();
+
     QHBoxLayout* topLayout = new QHBoxLayout(this);
     topLayout->setContentsMargins(0, 0, 0, 0);
     topLayout->addWidget(m_typeSelector);
     topLayout->addWidget(m_dateSelector);
     topLayout->addWidget(m_ratingSelector);
+    topLayout->addWidget(m_tagsSelector);
 
-    resetOptions();
+    resetSearchTerms();
 }
 
 DolphinFacetsWidget::~DolphinFacetsWidget()
@@ -78,19 +95,27 @@ DolphinFacetsWidget::~DolphinFacetsWidget()
 
 void DolphinFacetsWidget::changeEvent(QEvent *event)
 {
-    if (event->type() == QEvent::EnabledChange && !isEnabled()) {
-        resetOptions();
+    if (event->type() == QEvent::EnabledChange) {
+        if (isEnabled()) {
+            updateTagsSelector();
+        } else {
+            resetSearchTerms();
+        }
     }
 }
 
-void DolphinFacetsWidget::resetOptions()
+void DolphinFacetsWidget::resetSearchTerms()
 {
     m_typeSelector->setCurrentIndex(0);
     m_dateSelector->setCurrentIndex(0);
     m_ratingSelector->setCurrentIndex(0);
+
+    m_searchTags = QStringList();
+    updateTagsSelector();
+    updateTagsMenu();
 }
 
-QString DolphinFacetsWidget::ratingTerm() const
+QStringList DolphinFacetsWidget::searchTerms() const
 {
     QStringList terms;
 
@@ -104,7 +129,17 @@ QString DolphinFacetsWidget::ratingTerm() const
         terms << QStringLiteral("modified>=%1").arg(date.toString(Qt::ISODate));
     }
 
-    return terms.join(QLatin1String(" AND "));
+    if (!m_searchTags.isEmpty()) {
+        for (auto const &tag : m_searchTags) {
+            if (tag.contains(QLatin1Char(' '))) {
+                terms << QStringLiteral("tag:\"%1\"").arg(tag);
+            } else {
+                terms << QStringLiteral("tag:%1").arg(tag);
+            }
+        }
+    }
+
+    return terms;
 }
 
 QString DolphinFacetsWidget::facetType() const
@@ -112,42 +147,36 @@ QString DolphinFacetsWidget::facetType() const
     return m_typeSelector->currentData().toString();
 }
 
-bool DolphinFacetsWidget::isRatingTerm(const QString& term) const
+bool DolphinFacetsWidget::isSearchTerm(const QString& term) const
 {
-    const QStringList subTerms = term.split(' ', QString::SkipEmptyParts);
-
-    // If term has sub terms, then sone of the sub terms are always "rating" and "modified" terms.
-    bool containsRating = false;
-    bool containsModified = false;
+    static const QLatin1String searchTokens[] {
+        QLatin1String("modified>="),
+        QLatin1String("rating>="),
+        QLatin1String("tag:"), QLatin1String("tag=")
+    };
 
-    foreach (const QString& subTerm, subTerms) {
-        if (subTerm.startsWith(QLatin1String("rating>="))) {
-            containsRating = true;
-        } else if (subTerm.startsWith(QLatin1String("modified>="))) {
-            containsModified = true;
+    for (const auto &searchToken : searchTokens) {
+        if (term.startsWith(searchToken)) {
+            return true;
         }
     }
-
-    return containsModified || containsRating;
+    return false;
 }
 
-void DolphinFacetsWidget::setRatingTerm(const QString& term)
+void DolphinFacetsWidget::setSearchTerm(const QString& term)
 {
-    // If term has sub terms, then the sub terms are always "rating" and "modified" terms.
-    // If term has no sub terms, then the term itself is either a "rating" term or a "modified"
-    // term. To avoid code duplication we add term to subTerms list, if the list is empty.
-    QStringList subTerms = term.split(' ', QString::SkipEmptyParts);
-
-    foreach (const QString& subTerm, subTerms) {
-        if (subTerm.startsWith(QLatin1String("modified>="))) {
-            const QString value = subTerm.mid(10);
-            const QDate date = QDate::fromString(value, Qt::ISODate);
-            setTimespan(date);
-        } else if (subTerm.startsWith(QLatin1String("rating>="))) {
-            const QString value = subTerm.mid(8);
-            const int stars = value.toInt() / 2;
-            setRating(stars);
-        }
+    if (term.startsWith(QLatin1String("modified>="))) {
+        const QString value = term.mid(10);
+        const QDate date = QDate::fromString(value, Qt::ISODate);
+        setTimespan(date);
+    } else if (term.startsWith(QLatin1String("rating>="))) {
+        const QString value = term.mid(8);
+        const int stars = value.toInt() / 2;
+        setRating(stars);
+    } else if (term.startsWith(QLatin1String("tag:")) ||
+               term.startsWith(QLatin1String("tag="))) {
+        const QString value = term.mid(4);
+        addSearchTag(value);
     }
 }
 
@@ -183,6 +212,25 @@ void DolphinFacetsWidget::setTimespan(const QDate& date)
     }
 }
 
+void DolphinFacetsWidget::addSearchTag(const QString& tag)
+{
+    if (tag.isEmpty() || m_searchTags.contains(tag)) {
+        return;
+    }
+    m_searchTags.append(tag);
+    m_searchTags.sort();
+    updateTagsSelector();
+}
+
+void DolphinFacetsWidget::removeSearchTag(const QString& tag)
+{
+    if (tag.isEmpty() || !m_searchTags.contains(tag)) {
+        return;
+    }
+    m_searchTags.removeAll(tag);
+    updateTagsSelector();
+}
+
 void DolphinFacetsWidget::initComboBox(QComboBox* combo)
 {
     combo->setFrame(false);
@@ -191,3 +239,55 @@ void DolphinFacetsWidget::initComboBox(QComboBox* combo)
     connect(combo, QOverload<int>::of(&QComboBox::activated), this, &DolphinFacetsWidget::facetChanged);
 }
 
+void DolphinFacetsWidget::updateTagsSelector()
+{
+    const bool hasListedTags = !m_tagsSelector->menu()->isEmpty();
+    const bool hasSelectedTags = !m_searchTags.isEmpty();
+
+    if (hasSelectedTags) {
+        const QString tagsText = m_searchTags.join(i18nc("String list separator", ", "));
+        m_tagsSelector->setText(i18ncp("@action:button %2 is a list of tags",
+                                       "Tag: %2", "Tags: %2",m_searchTags.count(), tagsText));
+    } else {
+        m_tagsSelector->setText(i18nc("@action:button", "Add Tags"));
+    }
+
+    m_tagsSelector->setEnabled(isEnabled() && (hasListedTags || hasSelectedTags));
+}
+
+void DolphinFacetsWidget::updateTagsMenu()
+{
+    updateTagsMenuItems({}, {});
+    m_tagsLister.openUrl(QUrl(QStringLiteral("tags:/")), KCoreDirLister::OpenUrlFlag::Reload);
+}
+
+void DolphinFacetsWidget::updateTagsMenuItems(const QUrl&, const KFileItemList& items)
+{
+    m_tagsSelector->menu()->clear();
+
+    QStringList allTags = QStringList(m_searchTags);
+    for (const KFileItem &item: items) {
+        allTags.append(item.name());
+    }
+    allTags.sort(Qt::CaseInsensitive);
+    allTags.removeDuplicates();
+
+    for (const QString& tagName : qAsConst(allTags)) {
+        QAction* action = m_tagsSelector->menu()->addAction(QIcon::fromTheme(QStringLiteral("tag")), tagName);
+        action->setCheckable(true);
+        action->setChecked(m_searchTags.contains(tagName));
+
+        connect(action, &QAction::triggered, this, [this, tagName](bool isChecked) {
+            if (isChecked) {
+                addSearchTag(tagName);
+            } else {
+                removeSearchTag(tagName);
+            }
+            emit facetChanged();
+
+            m_tagsSelector->menu()->show();
+        });
+    }
+
+    updateTagsSelector();
+}
index 0a8a5161f177529cf61cd3619cf8271aa6a801ef..2e91bcc9676a8165973607aace4e96cc285ebd96 100644 (file)
 #define DOLPHINFACETSWIDGET_H
 
 #include <QWidget>
+#include <KCoreDirLister>
 
 class QComboBox;
 class QDate;
 class QEvent;
+class QToolButton;
 
 /**
  * @brief Allows to filter search-queries by facets.
@@ -50,13 +52,12 @@ public:
     explicit DolphinFacetsWidget(QWidget* parent = nullptr);
     ~DolphinFacetsWidget() override;
 
-    void resetOptions();
-
-    QString ratingTerm() const;
+    QStringList searchTerms() const;
     QString facetType() const;
 
-    bool isRatingTerm(const QString& term) const;
-    void setRatingTerm(const QString& term);
+    bool isSearchTerm(const QString& term) const;
+    void setSearchTerm(const QString& term);
+    void resetSearchTerms();
 
     void setFacetType(const QString& type);
 
@@ -66,15 +67,27 @@ signals:
 protected:
     void changeEvent(QEvent* event) override;
 
+private slots:
+    void updateTagsMenu();
+    void updateTagsMenuItems(const QUrl&, const KFileItemList& items);
+
 private:
     void setRating(const int stars);
     void setTimespan(const QDate& date);
+    void addSearchTag(const QString& tag);
+    void removeSearchTag(const QString& tag);
+
     void initComboBox(QComboBox* combo);
+    void updateTagsSelector();
 
 private:
     QComboBox* m_typeSelector;
     QComboBox* m_dateSelector;
     QComboBox* m_ratingSelector;
+    QToolButton* m_tagsSelector;
+
+    QStringList m_searchTags;
+    KCoreDirLister m_tagsLister;
 };
 
 #endif
index 8f8cb09ec121c96e52cff9aa4333d7430bb5fb99..ab107f43fab736e3a39407017dd5a7dd28f2abbf 100644 (file)
 
 #include "dolphinquery.h"
 
+#include <QRegularExpression>
+
 #include <config-baloo.h>
 #ifdef HAVE_BALOO
 #include <Baloo/Query>
 #endif
 
 namespace {
-    /** Checks if a given term in the Baloo::Query::searchString() is a special search term.
-     * This is a copy of `DolphinFacetsWidget::isRatingTerm()` method.
+    /** Checks if a given term in the Baloo::Query::searchString() is a special search term
+     * @return: the specific search token of the term, or an empty QString() if none is found
      */
-    bool isSearchTerm(const QString& term)
+    QString searchTermToken(const QString& term)
     {
         static const QLatin1String searchTokens[] {
+            QLatin1String("filename:"),
             QLatin1String("modified>="),
-            QLatin1String("rating>=")
+            QLatin1String("rating>="),
+            QLatin1String("tag:"), QLatin1String("tag=")
         };
 
         for (const auto &searchToken : searchTokens) {
             if (term.startsWith(searchToken)) {
-                return true;
+                return searchToken;
             }
         }
-        return false;
+        return QString();
+    }
+
+    QString stripQuotes(const QString& text)
+    {
+        if (text.length() >= 2 && text.at(0) == QLatin1Char('"')
+                               && text.back() == QLatin1Char('"')) {
+            return text.mid(1, text.size() - 2);
+        }
+        return text;
+    }
+
+    QStringList splitOutsideQuotes(const QString& text)
+    {
+        const QRegularExpression subTermsRegExp("(\\S*?\"[^\"]*?\"|(?<=\\s|^)\\S+(?=\\s|$))");
+        auto subTermsMatchIterator = subTermsRegExp.globalMatch(text);
+
+        QStringList textParts;
+        while (subTermsMatchIterator.hasNext()) {
+            textParts << subTermsMatchIterator.next().captured(0);
+        }
+        return textParts;
     }
 }
 
@@ -58,29 +83,35 @@ DolphinQuery DolphinQuery::fromBalooSearchUrl(const QUrl& searchUrl)
     model.m_fileType = types.isEmpty() ? QString() : types.first();
 
     QStringList textParts;
+    QString fileName;
 
-    const QStringList subTerms = query.searchString().split(' ', QString::SkipEmptyParts);
+    const QStringList subTerms = splitOutsideQuotes(query.searchString());
     foreach (const QString& subTerm, subTerms) {
-        QString value;
-        if (subTerm.startsWith(QLatin1String("filename:"))) {
-            value = subTerm.mid(9);
-        } else if (isSearchTerm(subTerm)) {
-            model.m_searchTerms << subTerm;
+        const QString token = searchTermToken(subTerm);
+        const QString value = stripQuotes(subTerm.mid(token.length()));
+
+        if (token == QLatin1String("filename:")) {
+            if (!value.isEmpty()) {
+                fileName = value;
+                model.m_hasFileName = true;
+            }
+            continue;
+        } else if (!token.isEmpty()) {
+            model.m_searchTerms << token + value;
             continue;
         } else if (subTerm == QLatin1String("AND") && subTerm != subTerms.at(0) && subTerm != subTerms.back()) {
             continue;
-        } else {
-            value = subTerm;
+        } else if (!value.isEmpty()) {
+            textParts << value;
+            model.m_hasContentSearch = true;
         }
+    }
 
-        if (!value.isEmpty() && value.at(0) == QLatin1Char('"')) {
-            value = value.mid(1);
-        }
-        if (!value.isEmpty() && value.back() == QLatin1Char('"')) {
-            value = value.mid(0, value.size() - 1);
-        }
-        if (!value.isEmpty()) {
-            textParts << value;
+    if (model.m_hasFileName) {
+        if (model.m_hasContentSearch) {
+            textParts << QStringLiteral("filename:\"%1\"").arg(fileName);
+        } else {
+            textParts << fileName;
         }
     }
 
@@ -114,3 +145,13 @@ QString DolphinQuery::includeFolder() const
 {
     return m_includeFolder;
 }
+
+bool DolphinQuery::hasContentSearch() const
+{
+    return m_hasContentSearch;
+}
+
+bool DolphinQuery::hasFileName() const
+{
+    return m_hasFileName;
+}
index e60008e3bf8ca7d23f3fd42b171afe59318d70fe..544f246bcfe6bea0b184c982fead5df359d011c6 100644 (file)
@@ -48,6 +48,10 @@ public:
     /** @return Baloo::Query::includeFolder(), that is, the initial directory
      * for the query or an empty string if its a global search" */
     QString includeFolder() const;
+    /** @return whether the query includes search in file content */
+    bool hasContentSearch() const;
+    /** @return whether the query includes a filter by fileName */
+    bool hasFileName() const;
 
 private:
     QUrl m_searchUrl;
@@ -55,6 +59,8 @@ private:
     QString m_fileType;
     QStringList m_searchTerms;
     QString m_includeFolder;
+    bool m_hasContentSearch = false;
+    bool m_hasFileName = false;
 };
 
 #endif //DOLPHINQUERY_H
index 16f17bbcdd323c6e4b2dd3c153e2618fc0368dfc..23f520de148a3f1ba710cb652828bb2de5830f81 100644 (file)
@@ -477,11 +477,7 @@ QUrl DolphinSearchBox::balooUrlForSearching() const
     Baloo::Query query;
     query.addType(m_facetsWidget->facetType());
 
-    QStringList queryStrings;
-    QString ratingQuery = m_facetsWidget->ratingTerm();
-    if (!ratingQuery.isEmpty()) {
-        queryStrings << ratingQuery;
-    }
+    QStringList queryStrings = m_facetsWidget->searchTerms();
 
     if (m_contentButton->isChecked()) {
         queryStrings << text;
@@ -517,11 +513,17 @@ void DolphinSearchBox::updateFromQuery(const DolphinQuery& query)
 
     setText(query.text());
 
-    m_facetsWidget->resetOptions();
+    if (query.hasContentSearch()) {
+        m_contentButton->setChecked(true);
+    } else if (query.hasFileName())  {
+        m_fileNameButton->setChecked(true);
+    }
+
+    m_facetsWidget->resetSearchTerms();
     m_facetsWidget->setFacetType(query.type());
     const QStringList searchTerms = query.searchTerms();
     for (const QString& searchTerm : searchTerms) {
-        m_facetsWidget->setRatingTerm(searchTerm);
+        m_facetsWidget->setSearchTerm(searchTerm);
     }
 
     m_startSearchTimer->stop();
index 5a7bb1a01d582b0ca5952085131fcc3073dae308..fca70656d0dc651df1d058599db1fe11abe8de5c 100644 (file)
@@ -16,7 +16,7 @@
         </entry>
         <entry name="UrlCompletionMode" type="Enum">
             <label>Text completion mode of the URL Navigator</label>
-            <default>KCompletion::CompletionPopup</default>
+            <default>KCompletion::CompletionPopupAuto</default>
         </entry>
         <entry name="ShowFullPath" type="Bool">
             <label>Should the full path be shown inside the location bar</label>
index df7ea21135f62b55e6d224ab3d0ad9bd5f610d36..30883c5dade1bb3c52fbf03f52ef8b5afc8af9ac 100644 (file)
@@ -48,8 +48,8 @@ BehaviorSettingsPage::BehaviorSettingsPage(const QUrl& url, QWidget* parent) :
 
 
     // View properties
-    m_globalViewProps = new QRadioButton(i18nc("@option:radio", "Use common properties for all folders"));
-    m_localViewProps = new QRadioButton(i18nc("@option:radio", "Remember properties for each folder"));
+    m_globalViewProps = new QRadioButton(i18nc("@option:radio", "Use common display style for all folders"));
+    m_localViewProps = new QRadioButton(i18nc("@option:radio", "Remember display style for each folder"));
     m_localViewProps->setToolTip(i18nc("@info", "Dolphin will create a hidden .directory file in each folder you change view properties for."));
 
     QButtonGroup* viewGroup = new QButtonGroup(this);
index 60e814c13dcb77a4456cae64719651c6121993f7..bc3cca706803c3c1d6494306086f085812ae4f38 100644 (file)
@@ -66,7 +66,7 @@ ConfigurePreviewPluginDialog::ConfigurePreviewPluginDialog(const QString& plugin
             // delete the whole thumbnails directory.
             previewPlugin->writeConfiguration(configurationWidget);
 
-            // http://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html#DIRECTORY
+            // https://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html#DIRECTORY
             const QString thumbnailsPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1String("/thumbnails/");
             KIO::del(QUrl::fromLocalFile(thumbnailsPath), KIO::HideProgressInfo);
         });
index dd4d60f3b10fe24526098b8544fc6179867afdb7..58d49062f5d4bbe2ef19bab24389a4d5bbb48312 100644 (file)
@@ -110,7 +110,11 @@ ConfirmationsSettingsPage::ConfirmationsSettingsPage(QWidget* parent) :
     connect(m_confirmMoveToTrash, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
     connect(m_confirmEmptyTrash, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
     connect(m_confirmDelete, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
     connect(m_confirmScriptExecution, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ConfirmationsSettingsPage::changed);
+#else
+    connect(m_confirmScriptExecution, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), this, &ConfirmationsSettingsPage::changed);
+#endif
     connect(m_confirmClosingMultipleTabs, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
 
 #ifdef HAVE_TERMINAL
index daa74aff1dd1e2d7f1231c99922a72aba7df0592..6e0a1d4743c16bc5e623b410871aa97de5657f93 100644 (file)
@@ -64,7 +64,7 @@ GeneralSettingsPage::GeneralSettingsPage(const QUrl& url, QWidget* parent) :
     m_pages.append(confirmationsPage);
     m_pages.append(statusBarPage);
 
-    topLayout->addWidget(tabWidget, 0, nullptr);
+    topLayout->addWidget(tabWidget, 0, {});
 }
 
 GeneralSettingsPage::~GeneralSettingsPage()
index ccc32a8a658ec5ec6a8fa445f463b5bcfb968e3f..a82cb3858c409609fedb07b468ed34a7a427d39e 100644 (file)
@@ -26,6 +26,7 @@
 #include <KLocalizedString>
 #include <KPluginFactory>
 #include <KPluginLoader>
+#include <kconfigwidgets_version.h>
 
 #include <QTabWidget>
 #include <QVBoxLayout>
@@ -48,23 +49,34 @@ DolphinGeneralConfigModule::DolphinGeneralConfigModule(QWidget* parent, const QV
     // initialize 'Behavior' tab
     BehaviorSettingsPage* behaviorPage = new BehaviorSettingsPage(QUrl::fromLocalFile(QDir::homePath()), tabWidget);
     tabWidget->addTab(behaviorPage, i18nc("@title:tab Behavior settings", "Behavior"));
+#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0)
     connect(behaviorPage, &BehaviorSettingsPage::changed, this, QOverload<>::of(&DolphinGeneralConfigModule::changed));
+#else
+    connect(behaviorPage, &BehaviorSettingsPage::changed, this, &DolphinGeneralConfigModule::markAsChanged);
+#endif
 
     // initialize 'Previews' tab
     PreviewsSettingsPage* previewsPage = new PreviewsSettingsPage(tabWidget);
     tabWidget->addTab(previewsPage, i18nc("@title:tab Previews settings", "Previews"));
+#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0)
     connect(previewsPage, &PreviewsSettingsPage::changed, this, QOverload<>::of(&DolphinGeneralConfigModule::changed));
+#else
+    connect(previewsPage, &PreviewsSettingsPage::changed, this, &DolphinGeneralConfigModule::markAsChanged);
+#endif
 
     // initialize 'Confirmations' tab
     ConfirmationsSettingsPage* confirmationsPage = new ConfirmationsSettingsPage(tabWidget);
     tabWidget->addTab(confirmationsPage,  i18nc("@title:tab Confirmations settings", "Confirmations"));
+#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0)
     connect(confirmationsPage, &ConfirmationsSettingsPage::changed, this, QOverload<>::of(&DolphinGeneralConfigModule::changed));
-
+#else
+    connect(confirmationsPage, &ConfirmationsSettingsPage::changed, this, &DolphinGeneralConfigModule::markAsChanged);
+#endif
     m_pages.append(behaviorPage);
     m_pages.append(previewsPage);
     m_pages.append(confirmationsPage);
 
-    topLayout->addWidget(tabWidget, 0, nullptr);
+    topLayout->addWidget(tabWidget, 0, {});
 }
 
 DolphinGeneralConfigModule::~DolphinGeneralConfigModule()
index d3f19539a45fda03c941b30b09a650b6581378f5..c8eb36c720d3255c222ceca2ef9c341917ef97e7 100644 (file)
@@ -22,7 +22,7 @@ Name[ja]=Dolphin 全般
 Name[ko]=Dolphin 일반
 Name[lt]=Dolphin bendrosios
 Name[lv]=Dolphin vispārējs
-Name[ml]=à´ªàµ\86ാതàµ\81 à´¸à´\9càµ\8dà´\9càµ\80à´\95à´°à´£à´\99àµ\8dà´\99à´³àµ\8dâ\80\8d
+Name[ml]=à´¡àµ\8bൾഫിൻ à´\9cനറൽ
 Name[nb]=Dolphin generelt
 Name[nl]=Dolphin algemeen
 Name[nn]=Generelt for Dolphin
index 6b88dadacb0559fe13d183fc9c52d1c5248709af..2cdabdeee0e22d124cb65b58356f1c4328a59f18 100644 (file)
@@ -20,6 +20,7 @@
 #include "kcmdolphinnavigation.h"
 
 #include "settings/navigation/navigationsettingspage.h"
+#include <kconfigwidgets_version.h>
 
 #include <KPluginFactory>
 #include <KPluginLoader>
@@ -40,8 +41,12 @@ DolphinNavigationConfigModule::DolphinNavigationConfigModule(QWidget* parent, co
     topLayout->setContentsMargins(0, 0, 0, 0);
 
     m_navigation = new NavigationSettingsPage(this);
+#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0)
     connect(m_navigation, &NavigationSettingsPage::changed, this, QOverload<>::of(&DolphinNavigationConfigModule::changed));
-    topLayout->addWidget(m_navigation, 0, nullptr);
+#else
+    connect(m_navigation, &NavigationSettingsPage::changed, this, &DolphinNavigationConfigModule::markAsChanged);
+#endif
+    topLayout->addWidget(m_navigation, 0, {});
 }
 
 DolphinNavigationConfigModule::~DolphinNavigationConfigModule()
index d5457f1fda699ac9a71bbeeef6e823c00511336b..e6a8867d7dde1754f0d9f88d368e308d0f098d14 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "settings/services/servicessettingspage.h"
 
+#include <kconfigwidgets_version.h>
 #include <KPluginFactory>
 #include <KPluginLoader>
 
@@ -40,8 +41,12 @@ DolphinServicesConfigModule::DolphinServicesConfigModule(QWidget* parent, const
     topLayout->setContentsMargins(0, 0, 0, 0);
 
     m_services = new ServicesSettingsPage(this);
+#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0)
     connect(m_services, &ServicesSettingsPage::changed, this, QOverload<>::of(&DolphinServicesConfigModule::changed));
-    topLayout->addWidget(m_services, 0, nullptr);
+#else
+    connect(m_services, &ServicesSettingsPage::changed, this, &DolphinServicesConfigModule::markAsChanged);
+#endif
+    topLayout->addWidget(m_services, 0, {});
 }
 
 DolphinServicesConfigModule::~DolphinServicesConfigModule()
index 12a2056c1edb3eaf14298220a3305861e5459182..4fac1160073a7128d47ee0258fcf06a33b8f3c2a 100644 (file)
@@ -65,7 +65,7 @@ DolphinViewModesConfigModule::DolphinViewModesConfigModule(QWidget* parent, cons
     m_tabs.append(compactTab);
     m_tabs.append(detailsTab);
 
-    topLayout->addWidget(tabWidget, 0, nullptr);
+    topLayout->addWidget(tabWidget, 0, {});
 }
 
 DolphinViewModesConfigModule::~DolphinViewModesConfigModule()
index 996e8410981156ab3db060e8c9ed08d598191c37..486e63ca582e10fcd63e031ce63ea22a5fee754e 100644 (file)
@@ -61,7 +61,7 @@ Comment[fi]=Tällä palvelulla voi muokata Dolphinin katselutilojen asetuksia.
 Comment[fr]=Ce service permet de configurer les modes d'affichage de Dolphin.
 Comment[gl]=Este servizo permite configurar os modos de vista de Dolphin.
 Comment[hu]=Ez a szolgáltatás lehetővé teszi a Dolphin nézetmódjainak beállítását.
-Comment[ia]=Iste servicio permitte configuration de le modos de vista de Dolphin
+Comment[ia]=Iste servicio permitte configuration del modos de vista de Dolphin
 Comment[id]=Layanan ini memungkinkan konfigurasi mode tampilan Dolphin.
 Comment[it]=Questo servizio permette di configurare le viste di Dolphin.
 Comment[ja]=Dolphin の表示モードを設定します
@@ -124,7 +124,7 @@ Name[ja]=表示モード
 Name[ko]=보기 모드
 Name[lt]=Rodinio veiksenos
 Name[lv]=Skata režīmi
-Name[ml]=à´\85വതരണ à´¦à´¶കള്‍
+Name[ml]=à´\85വതരണ à´°àµ\80തികള്‍
 Name[nb]=Visningsmåter
 Name[nl]=Weergavemodi
 Name[nn]=Visingsmodusar
index be2226db6ebee63ab7a7205c1cca32a018b5b743..d2e291a3bc7b551014fe8918c11f6060f84a4cf9 100644 (file)
@@ -56,7 +56,7 @@ ViewSettingsPage::ViewSettingsPage(QWidget* parent) :
     m_tabs.append(compactTab);
     m_tabs.append(detailsTab);
 
-    topLayout->addWidget(tabWidget, 0, nullptr);
+    topLayout->addWidget(tabWidget, 0);
 }
 
 ViewSettingsPage::~ViewSettingsPage()
index 06b0b8cf5ca191d80b5e2faef4560eb1374de559..2175f75c85247ec9277aa665e7cb1b667a686cf1 100644 (file)
@@ -120,11 +120,23 @@ ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget* parent) :
 
     switch (m_mode) {
     case IconsMode:
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
         connect(m_widthBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ViewSettingsTab::changed);
+#else
+        connect(m_widthBox, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), this, &ViewSettingsTab::changed);
+#endif
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
         connect(m_maxLinesBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ViewSettingsTab::changed);
+#else
+        connect(m_maxLinesBox, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), this, &ViewSettingsTab::changed);
+#endif
         break;
     case CompactMode:
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
         connect(m_widthBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ViewSettingsTab::changed);
+#else
+        connect(m_widthBox, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged), this, &ViewSettingsTab::changed);
+#endif
         break;
     case DetailsMode:
         connect(m_expandableFolders, &QCheckBox::toggled, this, &ViewSettingsTab::changed);
index a1f9718feaceccf70faee9e6784457a7d1cea332..2f5d55523dc14b147f94cd28181fef5f22ab1e74 100644 (file)
@@ -68,7 +68,7 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) :
     Q_ASSERT(dolphinView);
     const bool useGlobalViewProps = GeneralSettings::globalViewProps();
 
-    setWindowTitle(i18nc("@title:window", "View Properties"));
+    setWindowTitle(i18nc("@title:window", "View Display Style"));
 
     const QUrl& url = dolphinView->url();
     m_viewProps = new ViewProperties(url);
@@ -163,11 +163,23 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) :
     layout->addRow(QString(), m_showInGroups);
     layout->addRow(QString(), m_showHiddenFiles);
 
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
     connect(m_viewMode, QOverload<int>::of(&QComboBox::currentIndexChanged),
+#else
+    connect(m_viewMode, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
+#endif
             this, &ViewPropertiesDialog::slotViewModeChanged);
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
     connect(m_sorting, QOverload<int>::of(&QComboBox::currentIndexChanged),
+#else
+    connect(m_sorting, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
+#endif
             this, &ViewPropertiesDialog::slotSortingChanged);
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
     connect(m_sortOrder, QOverload<int>::of(&QComboBox::currentIndexChanged),
+#else
+    connect(m_sortOrder, QOverload<int, const QString &>::of(&QComboBox::currentIndexChanged),
+#endif
             this, &ViewPropertiesDialog::slotSortOrderChanged);
     connect(m_sortFoldersFirst, &QCheckBox::clicked,
             this, &ViewPropertiesDialog::slotSortFoldersFirstChanged);
index 1c6b39e267a5391f58d7ae604a50f4ef84eb4cb6..b65ee037fdcc343c6fc3af31589f074574fc0603 100644 (file)
@@ -41,38 +41,80 @@ private slots:
  */
 void DolphinSearchBoxTest::testBalooSearchParsing_data()
 {
-    const QString text = QStringLiteral("xyz");
-    const QString filename = QStringLiteral("filename:\"xyz\"");
+    const QString text = QStringLiteral("abc");
+    const QString textS = QStringLiteral("abc xyz");
+    const QString filename = QStringLiteral("filename:\"%1\"").arg(text);
+    const QString filenameS = QStringLiteral("filename:\"%1\"").arg(textS);
+
     const QString rating = QStringLiteral("rating>=2");
-    const QString modified = QString("modified>=2019-08-07");
+    const QString modified = QStringLiteral("modified>=2019-08-07");
+
+    const QString tag = QStringLiteral("tag:tagA");
+    const QString tagS = QStringLiteral("tag:\"tagB with spaces\"");  // in search url
+    const QString tagR = QStringLiteral("tag:tagB with spaces");      // in result term
 
     QTest::addColumn<QString>("searchString");
     QTest::addColumn<QString>("expectedText");
     QTest::addColumn<QStringList>("expectedTerms");
+    QTest::addColumn<bool>("hasContent");
+    QTest::addColumn<bool>("hasFileName");
 
     // Test for "Content"
-    QTest::newRow("content")              << text    << text << QStringList();
-    QTest::newRow("content/empty")        << ""      << ""   << QStringList();
-    QTest::newRow("content/singleQuote")  << "\""    << ""   << QStringList();
-    QTest::newRow("content/doubleQuote")  << "\"\""  << ""   << QStringList();
-    // Test for empty `filename`
-    QTest::newRow("filename")             << filename         << text << QStringList();
-    QTest::newRow("filename/empty")       << "filename:"      << ""   << QStringList();
-    QTest::newRow("filename/singleQuote") << "filename:\""    << ""   << QStringList();
-    QTest::newRow("filename/doubleQuote") << "filename:\"\""  << ""   << QStringList();
+    QTest::newRow("content")              << text    << text  << QStringList() << true  << false;
+    QTest::newRow("content/space")        << textS   << textS << QStringList() << true  << false;
+    QTest::newRow("content/empty")        << ""      << ""    << QStringList() << false << false;
+    QTest::newRow("content/single_quote") << "\""    << "\""  << QStringList() << true  << false;
+    QTest::newRow("content/double_quote") << "\"\""  << ""    << QStringList() << false << false;
+
+    // Test for "FileName"
+    QTest::newRow("filename")              << filename        << text  << QStringList() << false << true;
+    QTest::newRow("filename/space")        << filenameS       << textS << QStringList() << false << true;
+    QTest::newRow("filename/empty")        << "filename:"     << ""    << QStringList() << false << false;
+    QTest::newRow("filename/single_quote") << "filename:\""   << "\""  << QStringList() << false << true;
+    QTest::newRow("filename/double_quote") << "filename:\"\"" << ""    << QStringList() << false << false;
+
+    // Combined content and filename search
+    QTest::newRow("content+filename")
+        << text + " " + filename
+        << text + " " + filename << QStringList() << true << true;
 
     // Test for rating
-    QTest::newRow("rating")          << rating                  << ""   << QStringList({rating});
-    QTest::newRow("rating+content")  << rating + " " + text     << text << QStringList({rating});
-    QTest::newRow("rating+filename") << rating + " " + filename << text << QStringList({rating});
+    QTest::newRow("rating")          << rating                  << ""   << QStringList({rating}) << false << false;
+    QTest::newRow("rating+content")  << rating + " " + text     << text << QStringList({rating}) << true  << false;
+    QTest::newRow("rating+filename") << rating + " " + filename << text << QStringList({rating}) << false << true;
+
     // Test for modified date
-    QTest::newRow("modified")          << modified                  << ""   << QStringList({modified});
-    QTest::newRow("modified+content")  << modified + " " + text     << text << QStringList({modified});
-    QTest::newRow("modified+filename") << modified + " " + filename << text << QStringList({modified});
-    // Combined tests
-    QTest::newRow("rating+modified")          << rating + " AND " + modified                  << ""   << QStringList({modified, rating});
-    QTest::newRow("rating+modified+content")  << rating + " AND " + modified + " " + text     << text << QStringList({modified, rating});
-    QTest::newRow("rating+modified+filename") << rating + " AND " + modified + " " + filename << text << QStringList({modified, rating});
+    QTest::newRow("modified")          << modified                  << ""   << QStringList({modified}) << false << false;
+    QTest::newRow("modified+content")  << modified + " " + text     << text << QStringList({modified}) << true  << false;
+    QTest::newRow("modified+filename") << modified + " " + filename << text << QStringList({modified}) << false << true;
+
+    // Test for tags
+    QTest::newRow("tag")          << tag                  << ""   << QStringList({tag})       << false << false;
+    QTest::newRow("tag/space" )   << tagS                 << ""   << QStringList({tagR})      << false << false;
+    QTest::newRow("tag/double")   << tag + " " + tagS     << ""   << QStringList({tag, tagR}) << false << false;
+    QTest::newRow("tag+content")  << tag + " " + text     << text << QStringList({tag})       << true  << false;
+    QTest::newRow("tag+filename") << tag + " " + filename << text << QStringList({tag})       << false << true;
+
+    // Combined search terms
+    QTest::newRow("searchTerms")
+        << rating + " AND " + modified + " AND " + tag + " AND " + tagS
+        << "" << QStringList({modified, rating, tag, tagR}) << false << false;
+
+    QTest::newRow("searchTerms+content")
+        << rating + " AND " + modified + " " + text + " " + tag + " AND " + tagS
+        << text << QStringList({modified, rating, tag, tagR}) << true << false;
+
+    QTest::newRow("searchTerms+filename")
+        << rating + " AND " + modified + " " + filename + " " + tag + " AND " + tagS
+        << text << QStringList({modified, rating, tag, tagR}) << false << true;
+
+    QTest::newRow("allTerms")
+        << text + " " + filename + " " + rating + " AND " + modified + " AND " + tag
+        << text + " " + filename << QStringList({modified, rating, tag}) << true << true;
+
+    QTest::newRow("allTerms/space")
+        << textS + " " + filenameS + " " + rating + " AND " + modified + " AND " + tagS
+        << textS + " " + filenameS << QStringList({modified, rating, tagR}) << true << true;
 }
 
 /**
@@ -107,6 +149,8 @@ void DolphinSearchBoxTest::testBalooSearchParsing()
     QFETCH(QString, searchString);
     QFETCH(QString, expectedText);
     QFETCH(QStringList, expectedTerms);
+    QFETCH(bool, hasContent);
+    QFETCH(bool, hasFileName);
 
     const QUrl testUrl = composeQueryUrl(searchString);
     const DolphinQuery query = DolphinQuery::fromBalooSearchUrl(testUrl);
@@ -122,6 +166,10 @@ void DolphinSearchBoxTest::testBalooSearchParsing()
     for (int i = 0; i < expectedTerms.count(); i++) {
         QCOMPARE(searchTerms.at(i), expectedTerms.at(i));
     }
+
+    // Check for filename and content detection
+    QCOMPARE(query.hasContentSearch(), hasContent);
+    QCOMPARE(query.hasFileName(), hasFileName);
 }
 
 QTEST_MAIN(DolphinSearchBoxTest)
index 3437db7a76da37f93b818160863c77b233592b78..cfece0fe6b7f1e0b17349269fe340a888ec36b01 100644 (file)
@@ -31,7 +31,6 @@
 #include "kitemviews/kitemlistcontroller.h"
 #include "kitemviews/kitemlistheader.h"
 #include "kitemviews/kitemlistselectionmanager.h"
-#include "renamedialog.h"
 #include "versioncontrol/versioncontrolobserver.h"
 #include "viewproperties.h"
 #include "views/tooltips/tooltipmanager.h"
@@ -52,6 +51,7 @@
 #include <KIO/Paste>
 #include <KIO/PasteJob>
 #include <KIO/PreviewJob>
+#include <KIO/RenameFileDialog>
 #include <KJobWidgets>
 #include <KLocalizedString>
 #include <KMessageBox>
@@ -637,8 +637,9 @@ void DolphinView::renameSelectedItems()
         connect(m_view, &DolphinItemListView::roleEditingFinished,
                 this, &DolphinView::slotRoleEditingFinished);
     } else {
-        RenameDialog* dialog = new RenameDialog(this, items);
-        connect(dialog, &RenameDialog::renamingFinished, this, &DolphinView::slotRenameDialogRenamingFinished);
+        KIO::RenameFileDialog* dialog = new KIO::RenameFileDialog(items, this);
+        connect(dialog, &KIO::RenameFileDialog::renamingFinished,
+                this, &DolphinView::slotRenameDialogRenamingFinished);
 
         dialog->open();
     }
index 0d9f9f81cc8bdd1a47c05b2d7ecb279e9f68a42c..ef9f317ee16d20e3399d6e46b41d1bd33d0ef4b2 100644 (file)
@@ -280,7 +280,7 @@ void DolphinViewActionHandler::createActions()
     connect(showHiddenFiles, &KToggleAction::triggered, this, &DolphinViewActionHandler::toggleShowHiddenFiles);
 
     QAction* adjustViewProps = m_actionCollection->addAction(QStringLiteral("view_properties"));
-    adjustViewProps->setText(i18nc("@action:inmenu View", "Adjust View Properties..."));
+    adjustViewProps->setText(i18nc("@action:inmenu View", "Adjust View Display Style..."));
     adjustViewProps->setIcon(QIcon::fromTheme(QStringLiteral("view-choose")));
     adjustViewProps->setWhatsThis(i18nc("@info:whatsthis", "This opens a window "
         "in which all folder view properties can be adjusted."));
diff --git a/src/views/renamedialog.cpp b/src/views/renamedialog.cpp
deleted file mode 100644 (file)
index 9606856..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2006-2010 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 <KGuiItem>
-#include <KIO/BatchRenameJob>
-#include <KIO/CopyJob>
-#include <KIO/FileUndoManager>
-#include <KJobUiDelegate>
-#include <KJobWidgets>
-#include <KLocalizedString>
-
-#include <QDialogButtonBox>
-#include <QHBoxLayout>
-#include <QLabel>
-#include <QLineEdit>
-#include <QMimeDatabase>
-#include <QPushButton>
-#include <QSpinBox>
-
-RenameDialog::RenameDialog(QWidget *parent, const KFileItemList& items) :
-    QDialog(parent),
-    m_renameOneItem(false),
-    m_newName(),
-    m_lineEdit(nullptr),
-    m_items(items),
-    m_allExtensionsDifferent(true),
-    m_spinBox(nullptr)
-{
-    const QSize minSize = minimumSize();
-    setMinimumSize(QSize(320, minSize.height()));
-
-    const int itemCount = items.count();
-    Q_ASSERT(itemCount >= 1);
-    m_renameOneItem = (itemCount == 1);
-
-    setWindowTitle(m_renameOneItem ?
-               i18nc("@title:window", "Rename Item") :
-               i18nc("@title:window", "Rename Items"));
-    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
-    QVBoxLayout *mainLayout = new QVBoxLayout;
-    setLayout(mainLayout);
-    m_okButton = buttonBox->button(QDialogButtonBox::Ok);
-    m_okButton->setDefault(true);
-    m_okButton->setShortcut(Qt::CTRL + Qt::Key_Return);
-    connect(buttonBox, &QDialogButtonBox::accepted, this, &RenameDialog::slotAccepted);
-    connect(buttonBox, &QDialogButtonBox::rejected, this, &RenameDialog::reject);
-    connect(buttonBox, &QDialogButtonBox::rejected, this, &QObject::deleteLater);
-    m_okButton->setDefault(true);
-
-    KGuiItem::assign(m_okButton, KGuiItem(i18nc("@action:button", "&Rename"), QStringLiteral("dialog-ok-apply")));
-
-    QWidget* page = new QWidget(this);
-    mainLayout->addWidget(page);
-    mainLayout->addWidget(buttonBox);
-
-    QVBoxLayout* topLayout = new QVBoxLayout(page);
-
-    QLabel* editLabel = nullptr;
-    if (m_renameOneItem) {
-        m_newName = items.first().name();
-        editLabel = new QLabel(xi18nc("@label:textbox", "Rename the item <filename>%1</filename> to:", m_newName),
-                               page);
-        editLabel->setTextFormat(Qt::PlainText);
-    } else {
-        m_newName = i18nc("@info:status", "New name #");
-        editLabel = new QLabel(i18ncp("@label:textbox",
-                                      "Rename the %1 selected item to:",
-                                      "Rename the %1 selected items to:", itemCount),
-                               page);
-    }
-
-    m_lineEdit = new QLineEdit(page);
-    mainLayout->addWidget(m_lineEdit);
-    connect(m_lineEdit, &QLineEdit::textChanged, this, &RenameDialog::slotTextChanged);
-
-    int selectionLength = m_newName.length();
-    if (m_renameOneItem) {
-        const QString fileName = items.first().url().toDisplayString();
-        QMimeDatabase db;
-        const QString extension = db.suffixForFileName(fileName.toLower());
-
-        // If the current item is a directory, select the whole file name.
-        if ((extension.length() > 0) && !items.first().isDir()) {
-            // Don't select the extension
-            selectionLength -= extension.length() + 1;
-        }
-    } else {
-         // Don't select the # character
-        --selectionLength;
-    }
-
-    m_lineEdit->setText(m_newName);
-    m_lineEdit->setSelection(0, selectionLength);
-
-    topLayout->addWidget(editLabel);
-    topLayout->addWidget(m_lineEdit);
-
-    if (!m_renameOneItem) {
-        QSet<QString> extensions;
-        foreach (const KFileItem& item, m_items) {
-            QMimeDatabase db;
-            const QString extension = db.suffixForFileName(item.url().toDisplayString().toLower());
-
-            if (extensions.contains(extension)) {
-                m_allExtensionsDifferent = false;
-                break;
-            }
-
-            extensions.insert(extension);
-        }
-
-        QLabel* infoLabel = new QLabel(i18nc("@info", "# will be replaced by ascending numbers starting with:"), page);
-        mainLayout->addWidget(infoLabel);
-        m_spinBox = new QSpinBox(page);
-        m_spinBox->setMaximum(10000);
-        m_spinBox->setMinimum(0);
-        m_spinBox->setSingleStep(1);
-        m_spinBox->setValue(1);
-        m_spinBox->setDisplayIntegerBase(10);
-
-        QHBoxLayout* horizontalLayout = new QHBoxLayout(page);
-        horizontalLayout->setContentsMargins(0, 0, 0, 0);
-        horizontalLayout->addWidget(infoLabel);
-        horizontalLayout->addWidget(m_spinBox);
-
-        topLayout->addLayout(horizontalLayout);
-    }
-}
-
-RenameDialog::~RenameDialog()
-{
-}
-
-void RenameDialog::slotAccepted()
-{
-    QWidget* widget = parentWidget();
-    if (!widget) {
-        widget = this;
-    }
-
-    const QList<QUrl> srcList = m_items.urlList();
-    const QString newName = m_lineEdit->text();
-    KIO::FileUndoManager::CommandType cmdType;
-    KIO::Job *job = nullptr;
-    if (m_renameOneItem) {
-        Q_ASSERT(m_items.count() == 1);
-        cmdType = KIO::FileUndoManager::Rename;
-        const QUrl oldUrl = m_items.constFirst().url();
-        QUrl newUrl = oldUrl.adjusted(QUrl::RemoveFilename);
-        newUrl.setPath(newUrl.path() + KIO::encodeFileName(newName));
-        m_renamedItems << newUrl;
-        job = KIO::moveAs(oldUrl, newUrl, KIO::HideProgressInfo);
-    } else {
-        cmdType = KIO::FileUndoManager::BatchRename;
-        job = KIO::batchRename(srcList, newName, m_spinBox->value(), QLatin1Char('#'));
-        connect(qobject_cast<KIO::BatchRenameJob*>(job), &KIO::BatchRenameJob::fileRenamed, this, &RenameDialog::slotFileRenamed);
-    }
-
-    KJobWidgets::setWindow(job, widget);
-    const QUrl parentUrl = srcList.first().adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash);
-    KIO::FileUndoManager::self()->recordJob(cmdType, srcList, parentUrl, job);
-
-    connect(job, &KJob::result, this, &RenameDialog::slotResult);
-    connect(job, &KJob::result, this, &QObject::deleteLater);
-
-    job->uiDelegate()->setAutoErrorHandlingEnabled(true);
-
-    accept();
-}
-
-void RenameDialog::slotTextChanged(const QString& newName)
-{
-    bool enable = !newName.isEmpty() && (newName != QLatin1String("..")) && (newName != QLatin1Char('.'));
-    if (enable && !m_renameOneItem) {
-        const int count = newName.count(QLatin1Char('#'));
-        if (count == 0) {
-            // Renaming multiple files without '#' will only work if all extensions are different.
-            enable = m_allExtensionsDifferent;
-        } else {
-            // Assure that the new name contains exactly one # (or a connected sequence of #'s)
-            const int first = newName.indexOf(QLatin1Char('#'));
-            const int last = newName.lastIndexOf(QLatin1Char('#'));
-            enable = (last - first + 1 == count);
-        }
-    }
-    m_okButton->setEnabled(enable);
-}
-
-void RenameDialog::slotFileRenamed(const QUrl &oldUrl, const QUrl &newUrl)
-{
-    Q_UNUSED(oldUrl)
-    m_renamedItems << newUrl;
-}
-
-void RenameDialog::slotResult(KJob *job)
-{
-    if (!job->error()) {
-        emit renamingFinished(m_renamedItems);
-    }
-}
-
-void RenameDialog::showEvent(QShowEvent* event)
-{
-    m_lineEdit->setFocus();
-
-    QDialog::showEvent(event);
-}
diff --git a/src/views/renamedialog.h b/src/views/renamedialog.h
deleted file mode 100644 (file)
index 08571cd..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2006-2010 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 "dolphin_export.h"
-
-#include <KFileItem>
-
-#include <QDialog>
-#include <QString>
-
-class QLineEdit;
-class QSpinBox;
-class QPushButton;
-class KJob;
-/**
- * @brief Dialog for renaming a variable number of files.
- *
- * The dialog deletes itself when accepted or rejected.
- */
-class DOLPHIN_EXPORT RenameDialog : public QDialog
-{
-    Q_OBJECT
-
-public:
-    explicit RenameDialog(QWidget* parent, const KFileItemList& items);
-    ~RenameDialog() override;
-
-signals:
-    void renamingFinished(const QList<QUrl>& urls);
-
-private slots:
-    void slotAccepted();
-    void slotTextChanged(const QString& newName);
-    void slotFileRenamed(const QUrl& oldUrl, const QUrl& newUrl);
-    void slotResult(KJob* job);
-
-protected:
-    void showEvent(QShowEvent* event) override;
-
-private:
-    bool m_renameOneItem;
-    QList<QUrl> m_renamedItems;
-    QString m_newName;
-    QLineEdit* m_lineEdit;
-    KFileItemList m_items;
-    bool m_allExtensionsDifferent;
-    QSpinBox* m_spinBox;
-    QPushButton* m_okButton;
-};
-
-#endif
index a04f1cc6075b26978dce0a6169f7b2fe70bcb4de..c3d4d1837a1bc76ca44e698cf970e9d3ac792b8e 100644 (file)
@@ -25,7 +25,7 @@ Comment[ja]=ファイルビューのためのバージョン管理プラグイ
 Comment[ko]=파일 보기용 버전 제어 플러그인
 Comment[lt]=Failo rodinių versijų tvarkymo papildinys
 Comment[lv]=Versiju kontroles spraudnis priekš datņu skata
-Comment[ml]=ഫയലàµ\8dâ\80\8d à´\85വതരണദിശà´\95ൾà´\95àµ\8dà´\95àµ\81à´³àµ\8dà´³ à´ªà´¤à´¿à´ªàµ\8dà´ªàµ\8d à´¨à´¿à´¯à´¨àµ\8dà´¤àµ\8dà´°à´£ à´¸à´\82à´¯àµ\8bà´\9cà´\95à´\82
+Comment[ml]=ഫയൽ à´\95ാഴàµ\8dâ\80\8cà´\9aà´\95ൾà´\95àµ\8dà´\95ായàµ\81à´³àµ\8dà´³ à´ªà´¤à´¿à´ªàµ\8dà´ªàµ\8d à´¨à´¿à´¯à´¨àµ\8dà´¤àµ\8dà´°à´£ à´ªàµ\8dà´²à´\97ിൻ
 Comment[nb]=Versjonskontrollmodul for filvisninger
 Comment[nl]=Plugin voor versiecontrole op bestandoverzichten
 Comment[nn]=Versjonskontroll-tillegg for filvisingar
index fc74390a9999978f2f9dc18f68fe4abbf78afa64..2d801686e259099a249a301b613f49109d41ca03 100644 (file)
@@ -69,7 +69,7 @@ void VersionControlObserver::setModel(KFileItemModel* model)
         disconnect(m_model, &KFileItemModel::itemsInserted,
                    this, &VersionControlObserver::delayedDirectoryVerification);
         disconnect(m_model, &KFileItemModel::itemsChanged,
-                   this, &VersionControlObserver::delayedDirectoryVerification);
+                   this, &VersionControlObserver::slotItemsChanged);
     }
 
     m_model = model;
@@ -78,7 +78,7 @@ void VersionControlObserver::setModel(KFileItemModel* model)
         connect(m_model, &KFileItemModel::itemsInserted,
                 this, &VersionControlObserver::delayedDirectoryVerification);
         connect(m_model, &KFileItemModel::itemsChanged,
-                this, &VersionControlObserver::delayedDirectoryVerification);
+                this, &VersionControlObserver::slotItemsChanged);
     }
 }
 
@@ -137,6 +137,18 @@ void VersionControlObserver::silentDirectoryVerification()
     m_dirVerificationTimer->start();
 }
 
+void VersionControlObserver::slotItemsChanged(const KItemRangeList& itemRanges, const QSet<QByteArray>& roles)
+{
+    Q_UNUSED(itemRanges)
+
+    // Because "version" role is emitted by VCS plugin (ourselfs) we don't need to
+    // analyze it and update directory item states information. So lets check if
+    // there is only "version".
+    if ( !(roles.count() == 1 && roles.contains("version")) ) {
+        delayedDirectoryVerification();
+    }
+}
+
 void VersionControlObserver::verifyDirectory()
 {
     if (!m_model) {
@@ -291,7 +303,7 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const QUrl& director
             if (enabledPlugins.contains((*it)->name())) {
                 KVersionControlPlugin* plugin = (*it)->createInstance<KVersionControlPlugin>(this);
                 if (plugin) {
-                    m_plugins.append(plugin);
+                    m_plugins.append( qMakePair(plugin, plugin->fileName()) );
                 }
             }
         }
@@ -311,12 +323,12 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const QUrl& director
 
     // Verify whether the current directory contains revision information
     // like .svn, .git, ...
-    foreach (KVersionControlPlugin* plugin, m_plugins) {
-        const QString fileName = directory.path() + '/' + plugin->fileName();
+    for (const auto &it : qAsConst(m_plugins)) {
+        const QString fileName = directory.path() + '/' + it.second;
         if (QFile::exists(fileName)) {
             // The score of this plugin is 0 (best), so we can just return this plugin,
             // instead of going through the plugin scoring procedure, we can't find a better one ;)
-            return plugin;
+            return it.first;
         }
 
         // Version control systems like Git provide the version information
@@ -330,10 +342,10 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const QUrl& director
             QUrl upUrl = KIO::upUrl(dirUrl);
             int upUrlCounter = 1;
             while ((upUrlCounter < bestScore) && (upUrl != dirUrl)) {
-                const QString fileName = dirUrl.path() + '/' + plugin->fileName();
+                const QString fileName = dirUrl.path() + '/' + it.second;
                 if (QFile::exists(fileName)) {
                     if (upUrlCounter < bestScore) {
-                        bestPlugin = plugin;
+                        bestPlugin = it.first;
                         bestScore = upUrlCounter;
                     }
                     break;
index 08279dc8663e7042ba4932bae81a382df7858c52..66f992963c3532d5080f00844d01ea01d7a25798 100644 (file)
@@ -33,6 +33,7 @@
 
 class KFileItemList;
 class KFileItemModel;
+class KItemRangeList;
 class QAction;
 class QTimer;
 class UpdateItemStatesThread;
@@ -97,6 +98,12 @@ private slots:
      */
     void silentDirectoryVerification();
 
+    /**
+     * Invokes delayedDirectoryVerification() only if the itemsChanged() signal has not
+     * been triggered by the VCS plugin itself.
+     */
+    void slotItemsChanged(const KItemRangeList& itemRanges, const QSet<QByteArray>& roles);
+
     void verifyDirectory();
 
     /**
@@ -107,6 +114,7 @@ private slots:
 
 private:
     typedef QPair<KFileItem, KVersionControlPlugin::ItemVersion> ItemState;
+    typedef QPair<KVersionControlPlugin*, QString> VCSPlugin;
 
     void updateItemStates();
 
@@ -150,7 +158,7 @@ private:
 
     bool m_pluginsInitialized;
     KVersionControlPlugin* m_plugin;
-    QList<KVersionControlPlugin*> m_plugins;
+    QList<VCSPlugin> m_plugins;
     UpdateItemStatesThread* m_updateItemStatesThread;
 
     friend class UpdateItemStatesThread;