]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Merge branch 'Applications/18.04'
authorElvis Angelaccio <elvis.angelaccio@kde.org>
Sun, 13 May 2018 11:28:00 +0000 (13:28 +0200)
committerElvis Angelaccio <elvis.angelaccio@kde.org>
Sun, 13 May 2018 11:28:00 +0000 (13:28 +0200)
31 files changed:
CMakeLists.txt
doc/index.docbook
src/dolphincontextmenu.cpp
src/dolphincontextmenu.h
src/dolphinmainwindow.cpp
src/dolphinpart.cpp
src/dolphintabpage.cpp
src/dolphintabwidget.cpp
src/dolphintabwidget.h
src/dolphinui.rc
src/kitemviews/kfileitemmodel.cpp
src/kitemviews/kfileitemmodel.h
src/kitemviews/kfileitemmodelrolesupdater.cpp
src/kitemviews/kitemlistgroupheader.cpp
src/kitemviews/kitemlistselectionmanager.cpp
src/kitemviews/kitemliststyleoption.cpp
src/kitemviews/kitemliststyleoption.h
src/kitemviews/kitemlistview.cpp
src/kitemviews/kitemlistwidget.cpp
src/kitemviews/kstandarditemlistview.cpp
src/kitemviews/kstandarditemlistwidget.cpp
src/kitemviews/private/kbaloorolesprovider.cpp
src/panels/information/dolphin_informationpanelsettings.kcfg
src/panels/information/informationpanelcontent.cpp
src/panels/information/informationpanelcontent.h
src/panels/places/placesitemmodel.cpp
src/panels/places/placespanel.cpp
src/tests/CMakeLists.txt
src/tests/dolphinmainwindowtest.cpp
src/tests/placesitemmodeltest.cpp
src/views/dolphinviewactionhandler.cpp

index ee77c5a5a21d0c5d85c3c5c126f2f922b6ac8c7f..707160f53cb43335052e7cf315215e414acaf1db 100644 (file)
@@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.0)
 
 # KDE Application Version, managed by release script
 set (KDE_APPLICATIONS_VERSION_MAJOR "18")
-set (KDE_APPLICATIONS_VERSION_MINOR "04")
-set (KDE_APPLICATIONS_VERSION_MICRO "1")
+set (KDE_APPLICATIONS_VERSION_MINOR "07")
+set (KDE_APPLICATIONS_VERSION_MICRO "70")
 set (KDE_APPLICATIONS_VERSION "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}.${KDE_APPLICATIONS_VERSION_MICRO}")
 project(Dolphin VERSION ${KDE_APPLICATIONS_VERSION})
 
@@ -77,7 +77,7 @@ set_package_properties(KF5Baloo PROPERTIES DESCRIPTION "Baloo Core libraries"
                        PURPOSE "For adding desktop-wide search and tagging support to dolphin"
                       )
 
-find_package(KF5BalooWidgets 4.97)
+find_package(KF5BalooWidgets 18.07.70)
 set_package_properties(KF5BalooWidgets PROPERTIES DESCRIPTION "Baloos Widgets"
                        URL "http://www.kde.org"
                        TYPE OPTIONAL
index 44af99503fb301fd23e150a1533d85152259656d..c2ed2854f480a7f6dab47ad9f3b20455e46889db 100644 (file)
@@ -70,8 +70,8 @@
 
 <legalnotice>&FDLNotice;</legalnotice>
 
-<date>2016-06-01</date>
-<releaseinfo>Applications 16.04</releaseinfo>
+<date>2018-03-26</date>
+<releaseinfo>Applications 18.04</releaseinfo>
 
 <abstract>
 <para>
@@ -281,6 +281,9 @@ the toolbar can be used to navigate in the history.
 </mediaobject>
 </screenshot>
 
+<para>If you click with the &MMB; the item in the history is opened in a new tab
+thus keeping the current tab with its content.
+</para>
 </sect2>
 
 <sect2 id="dolphin-view-appearance">
@@ -359,8 +362,8 @@ The details view allows you to view the current folder
 in a tree-like fashion if <link linkend="preferences-dialog-viewmodes-details">
 <guilabel>Expandable folders</guilabel></link> are enabled:
 Each subfolder of the current folder can be
-<quote>expanded</quote> or <quote>collapsed</quote> by clicking on the <guiicon>+</guiicon>
-or <guiicon>-</guiicon> icon next to it.</para></listitem>
+<quote>expanded</quote> or <quote>collapsed</quote> by clicking on the <guiicon>></guiicon>
+or <guiicon>v</guiicon> icon next to it.</para></listitem>
 </itemizedlist>
 </para>
 
@@ -723,7 +726,7 @@ over with the mouse, including size, type, and date of last modification. It als
 features a large preview of the selected item and allows you to assign a rating,
 tags, and comments to it.
 </para>
-
+<!--FIXME panel context menu-->
 </sect2>
 
 <sect2 id="folders-panel">
@@ -733,9 +736,10 @@ tags, and comments to it.
 The <guilabel>Folders</guilabel> panel shows a tree view structure of the file
 system. It only shows folders. Clicking a folder with the &LMB; opens this folder
 in the &dolphin; view.
-
 </para>
-
+<para>Use <guilabel>Limit to Home Directory</guilabel> to hide all folders from
+the tree view except your <guilabel>Home</guilabel>.
+</para>
 </sect2>
 
 <sect2 id="terminal-panel">
@@ -803,10 +807,6 @@ a KIOSlave is launched to provide the search results.</para>
 <para>The option from <guilabel>Everywhere</guilabel> with activated Baloo 
 services searches in all indexed folders, without Baloo this option  
 starts the search from the user's <replaceable>Home</replaceable> folder.</para>
-<!--FIXME 16.12
-https://git.reviewboard.kde.org/r/123883/
-Add prototype of a "More search tools..." button
--->
 <screenshot>
 <screeninfo>Search with More Options</screeninfo>
 <mediaobject>
@@ -832,6 +832,14 @@ the user to shrink the number of search results.</para>
 together with the <guilabel>Filter</guilabel> bar to find files using Baloo or limit 
 the search to files matching the filter expression.</para>
 
+<para>Use the Save icon to save a search to the <guilabel>Search For</guilabel>
+section in the <guilabel>Places</guilabel> panel to quickly access it again in the future.
+</para>
+<!--FIXME 16.12
+https://git.reviewboard.kde.org/r/123883/
+Add prototype of a "More search tools..." button
+-->
+
 </sect2>
 
 <sect2 id="mounting-storage-media">
@@ -856,7 +864,7 @@ in the menu, &eg; <guimenuitem>Undo: Rename</guimenuitem>.
 </para>
 
 </sect2>
-
+<!-- FIXME https://phabricator.kde.org/D10698-->
 <sect2 id="batch-rename">
 <title>Renaming A Batch Of Files</title>
 <para>
@@ -864,7 +872,7 @@ in the menu, &eg; <guimenuitem>Undo: Rename</guimenuitem>.
 will have the file name specified, including a number, &eg;, Image1.jpg,
 Image2.jpg, Image3.jpg. This can be useful, &eg;, for pictures taken with a digital camera.
 </para>
-
+<!--double click-->
 <para>
 If you wish to rename a batch of files, first select the files to be renamed.
 This can be done by pressing the &LMB; and drawing a rectangle around the files
@@ -1024,6 +1032,10 @@ startup or not. See the <link linkend="filter-files">section on the filter bar</
 for details.
 </para></listitem>
 
+<listitem><para>
+<guilabel>Show full path in title bar</guilabel> makes it easy to distinguish
+between files or folders with the same name in different folders.
+</para></listitem>
 </itemizedlist>
 
 </para>
@@ -1325,6 +1337,10 @@ Enable <guilabel>Rename inline</guilabel> to use this mode if only one item is c
 If this option is disabled or several items are selected, a dialog will be displayed for renaming.
 </para></listitem>
 
+<listitem><para><guilabel>Use tab for switching between left and right split view</guilabel>
+allows to switch without using the mouse.
+</para></listitem>
+
 </itemizedlist>
 
 </para>
@@ -1353,8 +1369,8 @@ are shown before potentially harmful actions .
 <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, 
-whereas <guilabel>Closing Dolphin windows 
-  with multiple tabs</guilabel> is a &dolphin; <!--and &konqueror;--> specific setting.</para></warning>
+whereas <guilabel>Closing Dolphin windows
+with multiple tabs</guilabel> is a &dolphin; specific setting.</para></warning>
 </sect3>
 
 <sect3 id="preferences-dialog-general-statusbar">
@@ -1575,6 +1591,15 @@ trash.</action></para></listitem>
 to the trash and cannot be restored.</action></para></listitem>
 </varlistentry>
 
+<varlistentry>
+<term><menuchoice>
+<guimenu>File</guimenu>
+<guimenuitem>Show Target</guimenuitem>
+</menuchoice></term>
+<listitem><para>This action highlights a link target in a new &dolphin; window.
+</para></listitem>
+</varlistentry>
+
 <varlistentry>
 <term><menuchoice>
 <shortcut>
@@ -1786,7 +1811,8 @@ current folder grouped by the option selected in <guimenuitem>Sort By</guimenuit
 <guimenuitem>Hidden Files</guimenuitem>
 </menuchoice></term>
 <listitem><para><action>Shows all the hidden files and sub-folders within the current
-folder.</action></para></listitem>
+folder.</action>There is an alternate shortcut <keycombo action="simul">&Ctrl;<keycap>H</keycap></keycombo>
+for this action.</para></listitem>
 </varlistentry>
 
 <varlistentry>
@@ -1954,7 +1980,9 @@ be reopened.</action></para></listitem>
 <guimenu>Tools</guimenu>
 <guimenuitem>Show Filter Bar</guimenuitem>
 </menuchoice></term>
-<listitem><para><action>Enables and disables the <link linkend="filter-files">filter bar</link>.</action></para></listitem>
+<listitem><para><action>Enables and disables the <link linkend="filter-files">filter bar</link>.</action>
+You can also use the alternate shortcut <keycombo action="simul">&Shift;<keycap>/</keycap></keycombo>
+for this action.</para></listitem>
 </varlistentry>
 
 <varlistentry>
index bedc835c2af7e04c3d9c139956d6f401de26fa7a..befe98677afaca4738f1377573d7f1603900b955 100644 (file)
@@ -192,13 +192,29 @@ void DolphinContextMenu::openItemContextMenu()
     QAction* addToPlacesAction = nullptr;
     const KFileItemListProperties& selectedItemsProps = selectedItemsProperties();
 
+    KFileItemActions fileItemActions;
+    fileItemActions.setParentWidget(m_mainWindow);
+    fileItemActions.setItemListProperties(selectedItemsProps);
+
     if (m_selectedItems.count() == 1) {
-        if (m_fileInfo.isLink()) {
-            addAction(m_mainWindow->actionCollection()->action(QStringLiteral("show_target")));
-            addSeparator();
-        }
         if (m_fileInfo.isDir()) {
-            // setup 'Create New' menu
+            // 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);
+
+            // insert 'Add to Places' entry
+            if (!placeExists(m_fileInfo.url())) {
+                addToPlacesAction = addAction(QIcon::fromTheme(QStringLiteral("bookmark-new")),
+                                                       i18nc("@action:inmenu Add selected folder to places",
+                                                             "Add to Places"));
+            }
+
+            addSeparator();
+
+            // 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());
@@ -212,18 +228,6 @@ void DolphinContextMenu::openItemContextMenu()
             menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
             menu->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
             addMenu(menu);
-            addSeparator();
-
-            // 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 'Add to Places' entry
-            if (!placeExists(m_fileInfo.url())) {
-                addToPlacesAction = addAction(QIcon::fromTheme(QStringLiteral("bookmark-new")),
-                                                       i18nc("@action:inmenu Add selected folder to places",
-                                                             "Add to Places"));
-            }
 
             addSeparator();
         } else if (m_baseUrl.scheme().contains(QStringLiteral("search")) || m_baseUrl.scheme().contains(QStringLiteral("timeline"))) {
@@ -247,10 +251,20 @@ void DolphinContextMenu::openItemContextMenu()
 
             addSeparator();
         } else if (!DolphinView::openItemAsFolderUrl(m_fileInfo).isEmpty()) {
+            // Insert 'Open With" entries
+            addOpenWithActions(fileItemActions);
+
             // 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")));
 
+            addSeparator();
+        } else {
+            // Insert 'Open With" entries
+            addOpenWithActions(fileItemActions);
+        }
+        if (m_fileInfo.isLink()) {
+            addAction(m_mainWindow->actionCollection()->action(QStringLiteral("show_target")));
             addSeparator();
         }
     } else {
@@ -266,18 +280,16 @@ void DolphinContextMenu::openItemContextMenu()
         if (selectionHasOnlyDirs) {
             // insert 'Open in new tab' entry
             addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_new_tabs")));
-            addSeparator();
         }
+        // Insert 'Open With" entries
+        addOpenWithActions(fileItemActions);
     }
 
     insertDefaultItemActions(selectedItemsProps);
 
     addSeparator();
 
-    KFileItemActions fileItemActions;
-    fileItemActions.setItemListProperties(selectedItemsProps);
-    addServiceActions(fileItemActions);
-
+    fileItemActions.addServiceActionsTo(this);
     fileItemActions.addPluginActionsTo(this);
 
     addVersionControlPluginActions();
@@ -324,6 +336,13 @@ void DolphinContextMenu::openViewportContextMenu()
     addMenu(newFileMenu->menu());
     addSeparator();
 
+    // Insert 'Open With' entries
+    const KFileItemListProperties baseUrlProperties(KFileItemList() << baseFileItem());
+    KFileItemActions fileItemActions;
+    fileItemActions.setParentWidget(m_mainWindow);
+    fileItemActions.setItemListProperties(baseUrlProperties);
+    addOpenWithActions(fileItemActions);
+
     // Insert 'New Window' and 'New Tab' entries. Don't use "open_in_new_window" and
     // "open_in_new_tab" here, as the current selection should get ignored.
     addAction(m_mainWindow->actionCollection()->action(QStringLiteral("new_window")));
@@ -343,11 +362,7 @@ void DolphinContextMenu::openViewportContextMenu()
     addSeparator();
 
     // Insert service actions
-    const KFileItemListProperties baseUrlProperties(KFileItemList() << baseFileItem());
-    KFileItemActions fileItemActions;
-    fileItemActions.setItemListProperties(baseUrlProperties);
-    addServiceActions(fileItemActions);
-
+    fileItemActions.addServiceActionsTo(this);
     fileItemActions.addPluginActionsTo(this);
 
     addVersionControlPluginActions();
@@ -469,15 +484,10 @@ KFileItem DolphinContextMenu::baseFileItem()
     return *m_baseFileItem;
 }
 
-void DolphinContextMenu::addServiceActions(KFileItemActions& fileItemActions)
+void DolphinContextMenu::addOpenWithActions(KFileItemActions& fileItemActions)
 {
-    fileItemActions.setParentWidget(m_mainWindow);
-
     // insert 'Open With...' action or sub menu
     fileItemActions.addOpenWithActionsTo(this, QStringLiteral("DesktopEntryName != '%1'").arg(qApp->desktopFileName()));
-
-    // insert 'Actions' sub menu
-    fileItemActions.addServiceActionsTo(this);
 }
 
 void DolphinContextMenu::addVersionControlPluginActions()
index 9ebdb1a566574bc90c779a1e9588bedb9a367d67..bf0cf2c97c8935cc51711001855b3c9ea69a9eff 100644 (file)
@@ -116,10 +116,9 @@ private:
     KFileItem baseFileItem();
 
     /**
-     * Adds actions that have been installed as service-menu.
-     * (see http://techbase.kde.org/index.php?title=Development/Tutorials/Creating_Konqueror_Service_Menus)
+     * Adds "Open With" actions
      */
-    void addServiceActions(KFileItemActions& fileItemActions);
+    void addOpenWithActions(KFileItemActions& fileItemActions);
 
     /**
      * Adds actions that are provided by a KVersionControlPlugin.
index d112007bc542a66fc654f2cc973473c0c8cf7125..a0509ad47da00a77034288efb4653d427afd7897 100644 (file)
@@ -104,7 +104,7 @@ DolphinMainWindow::DolphinMainWindow() :
     m_tearDownFromPlacesRequested(false)
 {
     Q_INIT_RESOURCE(dolphin);
-
+    setComponentName(QStringLiteral("dolphin"), QGuiApplication::applicationDisplayName());
     setObjectName(QStringLiteral("Dolphin#"));
 
     connect(&DolphinNewFileMenuObserver::instance(), &DolphinNewFileMenuObserver::errorMessage,
@@ -287,13 +287,13 @@ void DolphinMainWindow::updateHistory()
     const KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
     const int index = urlNavigator->historyIndex();
 
-    QAction* backAction = actionCollection()->action(QStringLiteral("go_back"));
+    QAction* backAction = actionCollection()->action(KStandardAction::name(KStandardAction::Back));
     if (backAction) {
         backAction->setToolTip(i18nc("@info", "Go back"));
         backAction->setEnabled(index < urlNavigator->historySize() - 1);
     }
 
-    QAction* forwardAction = actionCollection()->action(QStringLiteral("go_forward"));
+    QAction* forwardAction = actionCollection()->action(KStandardAction::name(KStandardAction::Forward));
     if (forwardAction) {
         forwardAction->setToolTip(i18nc("@info", "Go forward"));
         forwardAction->setEnabled(index > 0);
@@ -402,7 +402,7 @@ void DolphinMainWindow::closeEvent(QCloseEvent* event)
         dialog->setWindowTitle(i18nc("@title:window", "Confirmation"));
         dialog->setModal(true);
         QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Yes | QDialogButtonBox::No | QDialogButtonBox::Cancel);
-        KGuiItem::assign(buttons->button(QDialogButtonBox::Yes), KStandardGuiItem::quit());
+        KGuiItem::assign(buttons->button(QDialogButtonBox::Yes), KGuiItem(i18nc("@action:button 'Quit Dolphin' button", "&Quit %1", QGuiApplication::applicationDisplayName()), QIcon::fromTheme(QStringLiteral("application-exit"))));
         KGuiItem::assign(buttons->button(QDialogButtonBox::No), KGuiItem(i18n("C&lose Current Tab"), QIcon::fromTheme(QStringLiteral("tab-close"))));
         KGuiItem::assign(buttons->button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel());
         buttons->button(QDialogButtonBox::Yes)->setDefault(true);
@@ -457,6 +457,10 @@ void DolphinMainWindow::updateNewMenu()
     m_newFileMenu->setViewShowsHiddenFiles(activeViewContainer()->view()->hiddenFilesShown());
     m_newFileMenu->checkUpToDate();
     m_newFileMenu->setPopupFiles(activeViewContainer()->url());
+
+    // If we're in the trash, also disable all the 'create new' items
+    // TODO: remove this once https://phabricator.kde.org/T8234 is implemented
+    slotWriteStateChanged(m_activeViewContainer->view()->url().scheme() != QLatin1String("trash"));
 }
 
 void DolphinMainWindow::createDirectory()
@@ -534,9 +538,9 @@ void DolphinMainWindow::slotDirectoryLoadingCompleted()
 
 void DolphinMainWindow::slotToolBarActionMiddleClicked(QAction *action)
 {
-    if (action == actionCollection()->action(QStringLiteral("go_back"))) {
+    if (action == actionCollection()->action(KStandardAction::name(KStandardAction::Back))) {
         goBackInNewTab();
-    } else if (action == actionCollection()->action(QStringLiteral("go_forward"))) {
+    } else if (action == actionCollection()->action(KStandardAction::name(KStandardAction::Forward))) {
         goForwardInNewTab();
     } else if (action == actionCollection()->action(QStringLiteral("go_up"))) {
         goUpInNewTab();
@@ -804,7 +808,10 @@ void DolphinMainWindow::slotHandleUrlStatFinished(KJob* job)
 
 void DolphinMainWindow::slotWriteStateChanged(bool isFolderWritable)
 {
-    newFileMenu()->setEnabled(isFolderWritable);
+    const auto actions = m_newFileMenu->menu()->actions();
+    for (auto menuItem : actions) {
+        menuItem->setEnabled(isFolderWritable);
+    }
 }
 
 void DolphinMainWindow::openContextMenu(const QPoint& pos,
@@ -819,10 +826,12 @@ void DolphinMainWindow::openContextMenu(const QPoint& pos,
     switch (command) {
     case DolphinContextMenu::OpenParentFolder:
         changeUrl(KIO::upUrl(item.url()));
+        m_activeViewContainer->view()->markUrlsAsSelected({item.url()});
+        m_activeViewContainer->view()->markUrlAsCurrent(item.url());
         break;
 
     case DolphinContextMenu::OpenParentFolderInNewWindow:
-        Dolphin::openNewWindow({KIO::upUrl(item.url())}, this);
+        Dolphin::openNewWindow({item.url()}, this, Dolphin::OpenNewWindowFlag::Select);
         break;
 
     case DolphinContextMenu::OpenParentFolderInNewTab:
@@ -854,7 +863,7 @@ void DolphinMainWindow::updateControlMenu()
     // Add "Edit" actions
     bool added = addActionToMenu(ac->action(KStandardAction::name(KStandardAction::Undo)), menu) |
                  addActionToMenu(ac->action(KStandardAction::name(KStandardAction::Find)), menu) |
-                 addActionToMenu(ac->action(QStringLiteral("select_all")), menu) |
+                 addActionToMenu(ac->action(KStandardAction::name(KStandardAction::SelectAll)), menu) |
                  addActionToMenu(ac->action(QStringLiteral("invert_selection")), menu);
 
     if (added) {
@@ -880,7 +889,7 @@ void DolphinMainWindow::updateControlMenu()
     }
 
     added = addActionToMenu(ac->action(QStringLiteral("split_view")), menu) |
-            addActionToMenu(ac->action(QStringLiteral("reload")), menu) |
+            addActionToMenu(ac->action(KStandardAction::name(KStandardAction::Redisplay)), menu) |
             addActionToMenu(ac->action(QStringLiteral("view_properties")), menu);
     if (added) {
         menu->addSeparator();
@@ -987,7 +996,7 @@ void DolphinMainWindow::activeViewChanged(DolphinViewContainer* viewContainer)
 void DolphinMainWindow::tabCountChanged(int count)
 {
     const bool enableTabActions = (count > 1);
-    actionCollection()->action(QStringLiteral("close_tab"))->setEnabled(enableTabActions);
+    actionCollection()->action(KStandardAction::name(KStandardAction::Close))->setEnabled(enableTabActions);
     actionCollection()->action(QStringLiteral("activate_next_tab"))->setEnabled(enableTabActions);
     actionCollection()->action(QStringLiteral("activate_prev_tab"))->setEnabled(enableTabActions);
 }
@@ -1064,24 +1073,19 @@ void DolphinMainWindow::setupActions()
     connect(menu, &QMenu::aboutToShow,
             this, &DolphinMainWindow::updateNewMenu);
 
-    QAction* newWindow = actionCollection()->addAction(QStringLiteral("new_window"));
-    newWindow->setIcon(QIcon::fromTheme(QStringLiteral("window-new")));
+    QAction* newWindow = KStandardAction::openNew(this, &DolphinMainWindow::openNewMainWindow, actionCollection());
     newWindow->setText(i18nc("@action:inmenu File", "New &Window"));
-    actionCollection()->setDefaultShortcut(newWindow, Qt::CTRL + Qt::Key_N);
-    connect(newWindow, &QAction::triggered, this, &DolphinMainWindow::openNewMainWindow);
 
     QAction* newTab = actionCollection()->addAction(QStringLiteral("new_tab"));
     newTab->setIcon(QIcon::fromTheme(QStringLiteral("tab-new")));
     newTab->setText(i18nc("@action:inmenu File", "New Tab"));
-    actionCollection()->setDefaultShortcuts(newTab, {Qt::CTRL + Qt::Key_T, Qt::CTRL + Qt::SHIFT + Qt::Key_N});
+    actionCollection()->setDefaultShortcuts(newTab, {Qt::CTRL + Qt::Key_T, QKeySequence::AddTab});
     connect(newTab, &QAction::triggered, this, static_cast<void(DolphinMainWindow::*)()>(&DolphinMainWindow::openNewActivatedTab));
 
-    QAction* closeTab = actionCollection()->addAction(QStringLiteral("close_tab"));
-    closeTab->setIcon(QIcon::fromTheme(QStringLiteral("tab-close")));
+    QAction* closeTab = KStandardAction::close(
+            m_tabWidget, static_cast<void(DolphinTabWidget::*)()>(&DolphinTabWidget::closeTab), actionCollection());
     closeTab->setText(i18nc("@action:inmenu File", "Close Tab"));
-    actionCollection()->setDefaultShortcut(closeTab, Qt::CTRL + Qt::Key_W);
     closeTab->setEnabled(false);
-    connect(closeTab, &QAction::triggered, m_tabWidget, static_cast<void(DolphinTabWidget::*)()>(&DolphinTabWidget::closeTab));
 
     KStandardAction::quit(this, &DolphinMainWindow::quit, actionCollection());
 
@@ -1101,11 +1105,7 @@ void DolphinMainWindow::setupActions()
 
     KStandardAction::find(this, &DolphinMainWindow::find, actionCollection());
 
-    QAction* selectAll = actionCollection()->addAction(QStringLiteral("select_all"));
-    selectAll->setText(i18nc("@action:inmenu Edit", "Select All"));
-    selectAll->setIcon(QIcon::fromTheme(QStringLiteral("edit-select-all")));
-    actionCollection()->setDefaultShortcut(selectAll, Qt::CTRL + Qt::Key_A);
-    connect(selectAll, &QAction::triggered, this, &DolphinMainWindow::selectAll);
+    KStandardAction::selectAll(this, &DolphinMainWindow::selectAll, actionCollection());
 
     QAction* invertSelection = actionCollection()->addAction(QStringLiteral("invert_selection"));
     invertSelection->setText(i18nc("@action:inmenu Edit", "Invert Selection"));
@@ -1129,11 +1129,7 @@ void DolphinMainWindow::setupActions()
     stashSplit->setVisible(KProtocolInfo::isKnownProtocol("stash"));
     connect(stashSplit, &QAction::triggered, this, &DolphinMainWindow::toggleSplitStash);
 
-    QAction* reload = actionCollection()->addAction(QStringLiteral("reload"));
-    reload->setText(i18nc("@action:inmenu View", "Reload"));
-    actionCollection()->setDefaultShortcut(reload, Qt::Key_F5);
-    reload->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh")));
-    connect(reload, &QAction::triggered, this, &DolphinMainWindow::reloadView);
+    KStandardAction::redisplay(this, &DolphinMainWindow::reloadView, actionCollection());
 
     QAction* stop = actionCollection()->addAction(QStringLiteral("stop"));
     stop->setText(i18nc("@action:inmenu View", "Stop"));
index e0f06bc5f8deed6beade74d2e541e41101100ddb..2e7f7639f16871d94fb7206ba0214a0f6fae2866 100644 (file)
@@ -180,7 +180,7 @@ void DolphinPart::createActions()
     unselectItemsMatching->setText(i18nc("@action:inmenu Edit", "Unselect Items Matching..."));
     connect(unselectItemsMatching, &QAction::triggered, this, &DolphinPart::slotUnselectItemsMatchingPattern);
 
-    actionCollection()->addAction(KStandardAction::SelectAll, QStringLiteral("select_all"), m_view, SLOT(selectAll()));
+    KStandardAction::selectAll(m_view, &DolphinView::selectAll, actionCollection());
 
     QAction* unselectAll = actionCollection()->addAction(QStringLiteral("unselect_all"));
     unselectAll->setText(i18nc("@action:inmenu Edit", "Unselect All"));
@@ -216,11 +216,8 @@ void DolphinPart::createActions()
                    goActionGroup);
 
     // Tools menu
-    m_findFileAction = actionCollection()->addAction(QStringLiteral("find_file"));
+    m_findFileAction = KStandardAction::find(this, &DolphinPart::slotFindFile, actionCollection());
     m_findFileAction->setText(i18nc("@action:inmenu Tools", "Find File..."));
-    actionCollection()->setDefaultShortcut(m_findFileAction, Qt::CTRL + Qt::Key_F);
-    m_findFileAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-find")));
-    connect(m_findFileAction, &QAction::triggered, this, &DolphinPart::slotFindFile);
 
 #ifndef Q_OS_WIN
     if (KAuthorized::authorize(QStringLiteral("shell_access"))) {
index a96c8b6a32dc6706c6aae1abb90dd465ea2703fb..b2bb5c896d95d720c4cab58a8f4d268c6c46214a 100644 (file)
@@ -312,6 +312,9 @@ void DolphinTabPage::slotViewActivated()
             m_primaryViewActive = !m_primaryViewActive;
         } else {
             m_primaryViewActive = true;
+            if (m_secondaryViewContainer) {
+                m_secondaryViewContainer->setActive(false);
+            }
         }
     }
 
index 0271ed5688af9259b6f999c359a8a4be33b5667c..a5c2f8c98c77e48dd72d02aaec36f5bf92838483 100644 (file)
@@ -34,7 +34,7 @@
 DolphinTabWidget::DolphinTabWidget(QWidget* parent) :
     QTabWidget(parent),
     m_placesSelectorVisible(true),
-    m_previousTab(0)
+    m_lastViewedTab(0)
 {
     connect(this, &DolphinTabWidget::tabCloseRequested,
             this, static_cast<void (DolphinTabWidget::*)(int)>(&DolphinTabWidget::closeTab));
@@ -61,6 +61,18 @@ DolphinTabPage* DolphinTabWidget::currentTabPage() const
     return tabPageAt(currentIndex());
 }
 
+DolphinTabPage* DolphinTabWidget::nextTabPage() const
+{
+    const int index = currentIndex() + 1;
+    return tabPageAt(index < count() ? index : 0);
+}
+
+DolphinTabPage* DolphinTabWidget::prevTabPage() const
+{
+    const int index = currentIndex() - 1;
+    return tabPageAt(index >= 0 ? index : (count() - 1));
+}
+
 DolphinTabPage* DolphinTabWidget::tabPageAt(const int index) const
 {
     return static_cast<DolphinTabPage*>(widget(index));
@@ -305,8 +317,8 @@ void DolphinTabWidget::tabUrlChanged(const QUrl& url)
 
 void DolphinTabWidget::currentTabChanged(int index)
 {
-    // previous tab deactivation
-    if (DolphinTabPage* tabPage = tabPageAt(m_previousTab)) {
+    // last-viewed tab deactivation
+    if (DolphinTabPage* tabPage = tabPageAt(m_lastViewedTab)) {
         tabPage->setActive(false);
     }
     DolphinTabPage* tabPage = tabPageAt(index);
@@ -314,7 +326,7 @@ void DolphinTabWidget::currentTabChanged(int index)
     emit activeViewChanged(viewContainer);
     emit currentUrlChanged(viewContainer->url());
     tabPage->setActive(true);
-    m_previousTab = index;
+    m_lastViewedTab = index;
 }
 
 void DolphinTabWidget::tabInserted(int index)
index ba2fd4867ab109dad2db80a300abb9f4d5be97c9..b4493f7ed82e00e1a82270b0cf9d3e48fe8eaf1c 100644 (file)
@@ -39,6 +39,18 @@ public:
      */
     DolphinTabPage* currentTabPage() const;
 
+    /**
+     * @return the next tab page. If the current active tab is the last tab,
+     * it returns the first tab. If there is only one tab, returns nullptr
+     */
+    DolphinTabPage* nextTabPage() const;
+
+    /**
+     * @return the previous tab page. If the current active tab is the first tab,
+     * it returns the last tab. If there is only one tab, returns nullptr
+     */
+    DolphinTabPage* prevTabPage() const;
+
     /**
      * @return Tab page at the given \a index (can be 0 if the index is out-of-range)
      */
@@ -187,7 +199,7 @@ private:
     /** Caches the (negated) places panel visibility */
     bool m_placesSelectorVisible;
 
-    int m_previousTab;
+    int m_lastViewedTab;
 };
 
 #endif
index 566f50fc846fcd874e4ae459f629c05fc717e1b7..ea3609c6429c255d4f215282f5174c56260b1cfa 100644 (file)
@@ -1,11 +1,11 @@
 <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="dolphin" version="19">
+<kpartgui name="dolphin" version="20">
     <MenuBar>
         <Menu name="file">
             <Action name="new_menu" />
-            <Action name="new_window" />
+            <Action name="file_new" />
             <Action name="new_tab" />
-            <Action name="close_tab" />
+            <Action name="file_close" />
            <Action name="undo_close_tab" />
             <Separator/>
             <Action name="renamefile" />
@@ -17,7 +17,7 @@
             <Action name="properties" />
         </Menu>
         <Menu name="edit">
-            <Action name="select_all" />
+            <Action name="edit_select_all" />
             <Action name="invert_selection" />
         </Menu>
         <Menu name="view">
@@ -30,7 +30,7 @@
             <Separator/>
             <Action name="split_view" />
             <Action name="split_stash" />
-            <Action name="reload" />
+            <Action name="redisplay" />
             <Action name="stop" />
             <Separator/>
             <Action name="panels" />
index b6a0016428a2110ce443e78e113e96784edfc408..844954d6a3e8883239190213f7b4c16f60cf8d81 100644 (file)
@@ -1846,16 +1846,10 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const
         break;
     }
 
-    case RatingRole: {
-        result = a->values.value("rating").toInt() - b->values.value("rating").toInt();
-        break;
-    }
-
-    case ImageSizeRole: {
-        // Alway use a natural comparing to interpret the numbers of a string like
-        // "1600 x 1200" for having a correct sorting.
-        result = collator.compare(a->values.value("imageSize").toString(),
-                                  b->values.value("imageSize").toString());
+    case RatingRole:
+    case WidthRole:
+    case HeightRole: {
+        result = a->values.value(roleForType(m_sortRole)).toInt() - b->values.value(roleForType(m_sortRole)).toInt();
         break;
     }
 
@@ -2305,7 +2299,8 @@ const KFileItemModel::RoleInfoMap* KFileItemModel::rolesInfoMap(int& count)
         { "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  },
-        { "imageSize",   ImageSizeRole,   I18N_NOOP2_NOSTRIP("@label", "Image Size"),       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  },
index 75953f0b7e8ed303c92f4826870377f4fa212ac3..134c50245c897318467bdb4f2a21e5297b1f88d9 100644 (file)
@@ -286,7 +286,7 @@ private:
         NoRole, NameRole, SizeRole, ModificationTimeRole, CreationTimeRole, AccessTimeRole, PermissionsRole, OwnerRole,
         GroupRole, TypeRole, DestinationRole, PathRole, DeletionTimeRole,
         // User visible roles available with Baloo:
-        CommentRole, TagsRole, RatingRole, ImageSizeRole, ImageDateTimeRole, OrientationRole,
+        CommentRole, TagsRole, RatingRole, WidthRole, HeightRole, ImageDateTimeRole, OrientationRole,
         WordCountRole, TitleRole, LineCountRole, ArtistRole, GenreRole, AlbumRole, DurationRole, TrackRole, ReleaseYearRole,
         BitrateRole, OriginUrlRole,
         // Non-visible roles:
index 6c96a08d164c9914938d1b193d9b9dffeb2d28a2..544d88040c8a52246b306b5e9487ee922add2362 100644 (file)
@@ -497,7 +497,7 @@ void KFileItemModelRolesUpdater::slotGotPreview(const KFileItem& item, const QPi
 
     const QString mimeType = item.mimetype();
     const int slashIndex = mimeType.indexOf(QLatin1Char('/'));
-    const bool isFontPreview = mimeType.right(slashIndex).contains(QLatin1String("font"));
+    const bool isFontPreview = mimeType.rightRef(slashIndex).contains(QLatin1String("font"));
     const bool isFolderPreview = item.isDir();
     const bool isWindowsExePreview = mimeType == QLatin1String("application/x-ms-dos-executable") ||
                                      mimeType == QLatin1String("application/x-msdownload");
index fb92989894243f1ef5c6103ee391c3831a698d7e..06a32484aabf3e1be09aeb96713cbd4d99336b63 100644 (file)
@@ -78,6 +78,10 @@ QVariant KItemListGroupHeader::data() const
 
 void KItemListGroupHeader::setStyleOption(const KItemListStyleOption& option)
 {
+    if (m_styleOption == option) {
+        return;
+    }
+
     const KItemListStyleOption previous = m_styleOption;
     m_styleOption = option;
     m_dirtyCache = true;
index efc256e1e6f97186451aa28fcce8ecda0a7e11a8..f5e097c0256eedebb467a828f159732f96f647fa 100644 (file)
@@ -235,6 +235,9 @@ void KItemListSelectionManager::itemsInserted(const KItemRangeList& itemRanges)
         // Calling setCurrentItem would trigger the selectionChanged signal, but we want to
         // emit it only once in this function -> change the current item manually and emit currentChanged
         m_currentItem += inc;
+        if (m_currentItem >= m_model->count()) {
+            m_currentItem = -1;
+        }
         emit currentChanged(m_currentItem, previousCurrent);
     }
 
index 1ebcad141509fc499bc01211c7bc2f98f1b17aa3..bcfb86064b39182175d0234ed5d414efb87e4d49 100644 (file)
@@ -53,3 +53,23 @@ KItemListStyleOption::KItemListStyleOption(const KItemListStyleOption& other) :
 KItemListStyleOption::~KItemListStyleOption()
 {
 }
+
+bool KItemListStyleOption::operator==(const KItemListStyleOption& other) const
+{
+    return 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;
+}
+
+bool KItemListStyleOption::operator!=(const KItemListStyleOption& other) const
+{
+    return !(*this == other);
+}
index 09b787c27d272d71b70f7d3b7d3b3e8c77dbdfcb..93aafac1f53a9b3c027c97f0f68c47f572ec2eb8 100644 (file)
@@ -45,6 +45,11 @@ public:
     bool extendedSelectionRegion;
     int maxTextLines;
     int maxTextWidth;
+
+    bool operator==(const KItemListStyleOption& other) const;
+    bool operator!=(const KItemListStyleOption& other) const;
+
+
 };
 #endif
 
index 489c6f9b69f44522670b946fb72c74f7d886cbe6..f0647fb3eac23fc922532e447a4f20c541cbe3c1 100644 (file)
@@ -752,6 +752,10 @@ void KItemListView::setItemSize(const QSizeF& size)
 
 void KItemListView::setStyleOption(const KItemListStyleOption& option)
 {
+    if (m_styleOption == option) {
+        return;
+    }
+
     const KItemListStyleOption previousOption = m_styleOption;
     m_styleOption = option;
 
index 61dd7256eb98b7e9ac7f61b4981ea52b8f32edf7..28b374620c38ff7fe1122164f8011756a4489faa 100644 (file)
@@ -191,10 +191,13 @@ qreal KItemListWidget::columnWidth(const QByteArray& role) const
 
 void KItemListWidget::setStyleOption(const KItemListStyleOption& option)
 {
+    if (m_styleOption == option) {
+        return;
+    }
+
     const KItemListStyleOption previous = m_styleOption;
     clearHoverCache();
     m_styleOption = option;
-
     styleOptionChanged(option, previous);
     update();
 }
index ee1c061036f7a10c6b90183923a546fc57759f4e..929ee1da80a2db5b56cb589a46b09c876a9362bf 100644 (file)
@@ -146,27 +146,20 @@ void KStandardItemListView::applyDefaultStyleOption(int iconSize,
 {
     KItemListStyleOption option = styleOption();
 
-    bool changed = false;
     if (option.iconSize < 0) {
         option.iconSize = iconSize;
-        changed = true;
     }
     if (option.padding < 0) {
         option.padding = padding;
-        changed = true;
     }
     if (option.horizontalMargin < 0) {
         option.horizontalMargin = horizontalMargin;
-        changed = true;
     }
     if (option.verticalMargin < 0) {
         option.verticalMargin = verticalMargin;
-        changed = true;
     }
 
-    if (changed) {
-        setStyleOption(option);
-    }
+    setStyleOption(option);
 }
 
 void KStandardItemListView::updateLayoutOfVisibleItems()
index 1aca250dd8a46fae60ab06daa5fe22999c292405..bc3bb29de94daf12b115fd18b1579d69ccaa60f9 100644 (file)
@@ -1015,15 +1015,21 @@ void KStandardItemListWidget::updatePixmapCache()
 
     if (iconOnTop) {
         // Center horizontally and align on bottom within the icon-area
-        m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2);
+        m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2.0);
         m_pixmapPos.setY(padding + scaledIconSize - m_scaledPixmapSize.height());
     } else {
         // Center horizontally and vertically within the icon-area
         const TextInfo* textInfo = m_textInfo.value("text");
-        m_pixmapPos.setX(textInfo->pos.x() - 2 * padding
-                         - (scaledIconSize + m_scaledPixmapSize.width()) / 2);
-        m_pixmapPos.setY(padding
-                         + (scaledIconSize - m_scaledPixmapSize.height()) / 2);
+        m_pixmapPos.setX(textInfo->pos.x() - 2.0 * padding
+                      - (scaledIconSize + m_scaledPixmapSize.width()) / 2.0);
+
+        // Derive icon's vertical center from the center of the text frame, including
+        // any necessary adjustment if the font's midline is offset from the frame center
+        const qreal midlineShift = m_customizedFontMetrics.height() / 2.0
+                    - m_customizedFontMetrics.descent()
+                    - m_customizedFontMetrics.capHeight() / 2.0;
+        m_pixmapPos.setY(m_textRect.center().y() + midlineShift - m_scaledPixmapSize.height() / 2.0);
+
     }
 
     m_iconRect = QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize));
index bbd0927f21ef639f9371e568d2e9083ffce63651..3d3923b1b761125c83c6b96ed03ae1a06664344a 100644 (file)
@@ -56,9 +56,6 @@ QHash<QByteArray, QVariant> KBalooRolesProvider::roleValues(const Baloo::File& f
 {
     QHash<QByteArray, QVariant> values;
 
-    int width = -1;
-    int height = -1;
-
     QMapIterator<KFileMetaData::Property::Property, QVariant> it(file.properties());
     while (it.hasNext()) {
         it.next();
@@ -72,23 +69,7 @@ QHash<QByteArray, QVariant> KBalooRolesProvider::roleValues(const Baloo::File& f
 
         const QVariant value = it.value();
 
-        if (role == "imageSize") {
-            // Merge the two properties for width and height
-            // as one string into the "imageSize" role
-            if (property == QLatin1String("width")) {
-                width = value.toInt();
-            }
-            else if (property == QLatin1String("height")) {
-                height = value.toInt();
-            }
-
-            if (width >= 0 && height >= 0) {
-                QString widthAndHeight = QString::number(width);
-                widthAndHeight += QLatin1String(" x ");
-                widthAndHeight += QString::number(height);
-                values.insert(role, widthAndHeight);
-            }
-        } else if (role == "orientation") {
+        if (role == "orientation") {
             const QString orientation = orientationFromValue(value.toInt());
             values.insert(role, orientation);
         } else if (role == "duration") {
@@ -135,8 +116,7 @@ KBalooRolesProvider::KBalooRolesProvider() :
     };
 
     // Mapping from the URIs to the KFileItemModel roles. Note that this must not be
-    // a 1:1 mapping: One role may contain several URI-values (e.g. the URIs for height and
-    // width of an image are mapped to the role "imageSize")
+    // a 1:1 mapping: One role may contain several URI-values
     static const PropertyInfo propertyInfoList[] = {
         { "rating", "rating" },
         { "tag",        "tags" },
@@ -144,8 +124,8 @@ KBalooRolesProvider::KBalooRolesProvider() :
         { "title",         "title" },
         { "wordCount",     "wordCount" },
         { "lineCount",     "lineCount" },
-        { "width",         "imageSize" },
-        { "height",        "imageSize" },
+        { "width",         "width" },
+        { "height",        "height" },
         { "imageDateTime",   "imageDateTime"},
         { "nexif.orientation", "orientation", },
         { "artist",     "artist" },
index 53c756d2404d9bc99363c1d3d6fc8dabb48d1382..dbc1ab6d29f1c73abac34c5d9ebf71847297299d 100644 (file)
             <label>Previews shown</label>
             <default>true</default>
         </entry>
+        <entry name="dateFormat" type="Enum">
+            <label>Date display format</label>
+            <choices>
+                <choice name="LongFormat" />
+                <choice name="ShortFormat" />
+            </choices>
+            <default>0</default>
+        </entry>
     </group>
 </kcfg>
index f44a3feb764050d24cabc95fa38a65fbbb2ad01f..0cba0cdf0687cb86f04c820a09c305fa0c5d5a8d 100644 (file)
@@ -112,12 +112,13 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) :
             this, &InformationPanelContent::urlActivated);
 #else
     m_metaDataWidget = new Baloo::FileMetaDataWidget(parent);
+    m_metaDataWidget->setDateFormat(static_cast<Baloo::DateFormats>(InformationPanelSettings::dateFormat()));
     connect(m_metaDataWidget, &Baloo::FileMetaDataWidget::urlActivated,
             this, &InformationPanelContent::urlActivated);
 #endif
     m_metaDataWidget->setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
     m_metaDataWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
-
     // Encapsulate the MetaDataWidget inside a container that has a dummy widget
     // at the bottom. This prevents that the meta data widget gets vertically stretched
     // in the case where the height of m_metaDataArea > m_metaDataWidget.
@@ -160,41 +161,42 @@ void InformationPanelContent::showItem(const KFileItem& item)
 
     const QUrl itemUrl = item.url();
     const bool isSearchUrl = itemUrl.scheme().contains(QStringLiteral("search")) && item.localPath().isEmpty();
-    if (!applyPlace(itemUrl)) {
-        setNameLabelText(item.text());
-        if (isSearchUrl) {
-            // in the case of a search-URL the URL is not readable for humans
-            // (at least not useful to show in the Information Panel)
-            m_preview->setPixmap(
-                QIcon::fromTheme(QStringLiteral("nepomuk")).pixmap(KIconLoader::SizeEnormous, KIconLoader::SizeEnormous)
-            );
-        } else {
-            // try to get a preview pixmap from the item...
-
-            // Mark the currently shown preview as outdated. This is done
-            // with a small delay to prevent a flickering when the next preview
-            // can be shown within a short timeframe. This timer is not started
-            // for directories, as directory previews might fail and return the
-            // same icon.
-            if (!item.isDir()) {
-                m_outdatedPreviewTimer->start();
-            }
-
-            m_previewJob = new KIO::PreviewJob(KFileItemList() << item, QSize(m_preview->width(), m_preview->height()));
-            m_previewJob->setScaleType(KIO::PreviewJob::Unscaled);
-            m_previewJob->setIgnoreMaximumSize(item.isLocalFile());
-            if (m_previewJob->uiDelegate()) {
-                KJobWidgets::setWindow(m_previewJob, this);
-            }
+    setNameLabelText(item.text());
+    if (isSearchUrl) {
+        // in the case of a search-URL the URL is not readable for humans
+        // (at least not useful to show in the Information Panel)
+        m_preview->setPixmap(
+            QIcon::fromTheme(QStringLiteral("nepomuk")).pixmap(KIconLoader::SizeEnormous, KIconLoader::SizeEnormous)
+        );
+    } else {
+        // try to get a preview pixmap from the item...
+
+        // Mark the currently shown preview as outdated. This is done
+        // with a small delay to prevent a flickering when the next preview
+        // can be shown within a short timeframe. This timer is not started
+        // for directories, as directory previews might fail and return the
+        // same icon.
+        if (!item.isDir()) {
+            m_outdatedPreviewTimer->start();
+        }
 
-            connect(m_previewJob.data(), &KIO::PreviewJob::gotPreview,
-                    this, &InformationPanelContent::showPreview);
-            connect(m_previewJob.data(), &KIO::PreviewJob::failed,
-                    this, &InformationPanelContent::showIcon);
+        m_previewJob = new KIO::PreviewJob(KFileItemList() << item, QSize(m_preview->width(), m_preview->height()));
+        m_previewJob->setScaleType(KIO::PreviewJob::Unscaled);
+        m_previewJob->setIgnoreMaximumSize(item.isLocalFile());
+        if (m_previewJob->uiDelegate()) {
+            KJobWidgets::setWindow(m_previewJob, this);
         }
+
+        connect(m_previewJob.data(), &KIO::PreviewJob::gotPreview,
+                this, &InformationPanelContent::showPreview);
+        connect(m_previewJob.data(), &KIO::PreviewJob::failed,
+                this, &InformationPanelContent::showIcon);
     }
 
     if (m_metaDataWidget) {
+#ifdef HAVE_BALOO
+        m_metaDataWidget->setDateFormat(static_cast<Baloo::DateFormats>(InformationPanelSettings::dateFormat()));
+#endif
         m_metaDataWidget->show();
         m_metaDataWidget->setItems(KFileItemList() << item);
     }
@@ -283,6 +285,12 @@ void InformationPanelContent::configureSettings(const QList<QAction*>& customCon
     QAction* configureAction = popup.addAction(i18nc("@action:inmenu", "Configure..."));
     configureAction->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
 
+#ifdef HAVE_BALOO
+    QAction* dateformatAction = popup.addAction(i18nc("@action:inmenu", "Condensed Date"));
+    dateformatAction->setIcon(QIcon::fromTheme(QStringLiteral("change-date-symbolic")));
+    dateformatAction->setCheckable(true);
+    dateformatAction->setChecked(InformationPanelSettings::dateFormat() == static_cast<int>(Baloo::DateFormats::ShortFormat));
+#endif
     popup.addSeparator();
     foreach (QAction* action, customContextMenuActions) {
         popup.addAction(action);
@@ -308,16 +316,22 @@ void InformationPanelContent::configureSettings(const QList<QAction*>& customCon
         dialog->show();
         connect(dialog, &FileMetaDataConfigurationDialog::destroyed, this, &InformationPanelContent::refreshMetaData);
     }
+#ifdef HAVE_BALOO
+    if (action == dateformatAction) {
+        int dateFormat = static_cast<int>(isChecked ? Baloo::DateFormats::ShortFormat : Baloo::DateFormats::LongFormat);
+
+        InformationPanelSettings::setDateFormat(dateFormat);
+        refreshMetaData();
+    }
+#endif
 }
 
 void InformationPanelContent::showIcon(const KFileItem& item)
 {
     m_outdatedPreviewTimer->stop();
-    if (!applyPlace(item.targetUrl())) {
-        QPixmap pixmap = QIcon::fromTheme(item.iconName()).pixmap(KIconLoader::SizeEnormous, KIconLoader::SizeEnormous);
-        KIconLoader::global()->drawOverlays(item.overlays(), pixmap, KIconLoader::Desktop);
-        m_preview->setPixmap(pixmap);
-    }
+    QPixmap pixmap = QIcon::fromTheme(item.iconName()).pixmap(KIconLoader::SizeEnormous, KIconLoader::SizeEnormous);
+    KIconLoader::global()->drawOverlays(item.overlays(), pixmap, KIconLoader::Desktop);
+    m_preview->setPixmap(pixmap);
 }
 
 void InformationPanelContent::showPreview(const KFileItem& item,
@@ -352,21 +366,6 @@ void InformationPanelContent::refreshMetaData()
     }
 }
 
-bool InformationPanelContent::applyPlace(const QUrl& url)
-{
-    const int count = m_placesItemModel->count();
-    for (int i = 0; i < count; ++i) {
-        const PlacesItem* item = m_placesItemModel->placesItem(i);
-        if (item->url().matches(url, QUrl::StripTrailingSlash)) {
-            setNameLabelText(item->text());
-            m_preview->setPixmap(QIcon::fromTheme(item->icon()).pixmap(128, 128));
-            return true;
-        }
-    }
-
-    return false;
-}
-
 void InformationPanelContent::setNameLabelText(const QString& text)
 {
     QTextOption textOption;
index 80f3c8e22a09a114d1e9814b875d1159df68e872..9223fcc5a2c722f4300b1c07cfc0503dbc94da60 100644 (file)
@@ -115,14 +115,6 @@ private slots:
     void refreshMetaData();
 
 private:
-    /**
-     * Checks whether the an URL is repesented by a place. If yes,
-     * then the place icon and name are shown instead of a preview.
-     * @return True, if the URL represents exactly a place.
-     * @param url The url to check.
-     */
-    bool applyPlace(const QUrl& url);
-
     /**
      * Sets the text for the label \a m_nameLabel and assures that the
      * text is split in a way that it can be wrapped within the
index 3641b3e42a0e4c8cb9ced8d78f4526ef9b6a64f6..7e313482da21455c327ddcf95f171a837be98088 100644 (file)
@@ -453,7 +453,7 @@ void PlacesItemModel::initializeDefaultViewProperties() const
                 } else if (path == QLatin1String("/images")) {
                     props.setViewMode(DolphinView::IconsView);
                     props.setPreviewsShown(true);
-                    props.setVisibleRoles({"text", "imageSize"});
+                    props.setVisibleRoles({"text", "height", "width"});
                 } else if (path == QLatin1String("/audio")) {
                     props.setViewMode(DolphinView::DetailsView);
                     props.setPreviewsShown(false);
@@ -597,7 +597,8 @@ void PlacesItemModel::onSourceModelDataChanged(const QModelIndex &topLeft, const
 
 void PlacesItemModel::onSourceModelGroupHiddenChanged(KFilePlacesModel::GroupType group, bool hidden)
 {
-    for(const QModelIndex &sourceIndex : m_sourceModel->groupIndexes(group)) {
+    const auto groupIndexes = m_sourceModel->groupIndexes(group);
+    for (const QModelIndex &sourceIndex : groupIndexes) {
         PlacesItem *item = placesItem(mapFromSource(sourceIndex));
         if (item) {
             item->setGroupHidden(hidden);
index 1f81a1eaa9977c170e46f61f5399cb7da031e326..00d8735c39020edb929c5947382f5119f5f3565b 100644 (file)
@@ -291,7 +291,7 @@ void PlacesPanel::slotViewContextMenuRequested(const QPointF& pos)
         {KIconLoader::SizeLarge,        I18N_NOOP2_NOSTRIP("Huge icon size", "Huge (%1x%2)")}
     };
 
-    QMap<QAction*, int> iconSizeActionMap;
+    QHash<QAction*, int> iconSizeActionMap;
     QActionGroup* iconSizeGroup = new QActionGroup(iconSizeSubMenu);
 
     for (int i = 0; i < iconSizeCount; ++i) {
index c656173a8d77510a40ddb95ae892010fec56a1f7..07e4257a0becf6f9fb2a4b51619fe56dbebd1e6f 100644 (file)
@@ -54,10 +54,14 @@ TEST_NAME viewpropertiestest
 LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test)
 
 # DolphinMainWindowTest
-ecm_add_test(dolphinmainwindowtest.cpp
+set(dolphinmainwindowtest_SRCS dolphinmainwindowtest.cpp)
+qt5_add_resources(dolphinmainwindowtest_SRCS ${CMAKE_SOURCE_DIR}/src/dolphin.qrc)
+
+ecm_add_test(${dolphinmainwindowtest_SRCS}
 TEST_NAME dolphinmainwindowtest
 LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test)
 
+# DragAndDropHelperTest
 ecm_add_test(draganddrophelpertest.cpp LINK_LIBRARIES dolphinprivate Qt5::Test)
 
 # PlacesItemModelTest
index a31237f3c56f824f0fdae679463e74e4cced3bd6..70ec8dba04dd91f1e624c1002c6a288b4c608c79 100644 (file)
@@ -34,6 +34,8 @@ class DolphinMainWindowTest : public QObject
 private slots:
     void init();
     void testClosingTabsWithSearchBoxVisible();
+    void testActiveViewAfterClosingSplitView_data();
+    void testActiveViewAfterClosingSplitView();
     void testUpdateWindowTitleAfterClosingSplitView();
 
 private:
@@ -68,6 +70,58 @@ void DolphinMainWindowTest::testClosingTabsWithSearchBoxVisible()
     QCOMPARE(tabWidget->count(), 1);
 }
 
+void DolphinMainWindowTest::testActiveViewAfterClosingSplitView_data()
+{
+    QTest::addColumn<bool>("closeLeftView");
+
+    QTest::newRow("close left view") << true;
+    QTest::newRow("close right view") << false;
+}
+
+void DolphinMainWindowTest::testActiveViewAfterClosingSplitView()
+{
+    m_mainWindow->openDirectories({ QUrl::fromLocalFile(QDir::homePath()) }, false);
+    m_mainWindow->show();
+    QVERIFY(QTest::qWaitForWindowExposed(m_mainWindow.data()));
+    QVERIFY(m_mainWindow->isVisible());
+
+    auto tabWidget = m_mainWindow->findChild<DolphinTabWidget*>("tabWidget");
+    QVERIFY(tabWidget);
+    QVERIFY(tabWidget->currentTabPage()->primaryViewContainer());
+    QVERIFY(!tabWidget->currentTabPage()->secondaryViewContainer());
+
+    // Open split view.
+    m_mainWindow->actionCollection()->action(QStringLiteral("split_view"))->trigger();
+    QVERIFY(tabWidget->currentTabPage()->splitViewEnabled());
+    QVERIFY(tabWidget->currentTabPage()->secondaryViewContainer());
+
+    // Make sure the right view is the active one.
+    auto leftViewContainer = tabWidget->currentTabPage()->primaryViewContainer();
+    auto rightViewContainer = tabWidget->currentTabPage()->secondaryViewContainer();
+    QVERIFY(!leftViewContainer->isActive());
+    QVERIFY(rightViewContainer->isActive());
+
+    QFETCH(bool, closeLeftView);
+    if (closeLeftView) {
+        // Activate left view.
+        leftViewContainer->setActive(true);
+        QVERIFY(leftViewContainer->isActive());
+        QVERIFY(!rightViewContainer->isActive());
+
+        // Close left view. The secondary view (which was on the right) will become the primary one and must be active.
+        m_mainWindow->actionCollection()->action(QStringLiteral("split_view"))->trigger();
+        QVERIFY(!leftViewContainer->isActive());
+        QVERIFY(rightViewContainer->isActive());
+        QCOMPARE(rightViewContainer, tabWidget->currentTabPage()->activeViewContainer());
+    } else {
+        // Close right view. The left view will become active.
+        m_mainWindow->actionCollection()->action(QStringLiteral("split_view"))->trigger();
+        QVERIFY(leftViewContainer->isActive());
+        QVERIFY(!rightViewContainer->isActive());
+        QCOMPARE(leftViewContainer, tabWidget->currentTabPage()->activeViewContainer());
+    }
+}
+
 // Test case for bug #385111
 void DolphinMainWindowTest::testUpdateWindowTitleAfterClosingSplitView()
 {
@@ -99,6 +153,7 @@ void DolphinMainWindowTest::testUpdateWindowTitleAfterClosingSplitView()
 
     // Close split view. The secondary view (which was on the right) will become the primary one and must be active.
     m_mainWindow->actionCollection()->action(QStringLiteral("split_view"))->trigger();
+    QVERIFY(!leftViewContainer->isActive());
     QVERIFY(rightViewContainer->isActive());
     QCOMPARE(rightViewContainer, tabWidget->currentTabPage()->activeViewContainer());
 
index 3263537f9e9c36320b28f053fde09cd1defbed28..fc21ce055f9c0d46c0ae59e4a088f6ab489b6aea 100644 (file)
@@ -228,7 +228,8 @@ void PlacesItemModelTest::init()
 
 void PlacesItemModelTest::cleanup()
 {
-    for (int i : m_tobeRemoved) {
+    const auto tobeRemoved = m_tobeRemoved;
+    for (const int i : tobeRemoved) {
         int before = m_model->count();
         m_model->deleteItem(i);
         QTRY_COMPARE(m_model->count(), before - 1);
index 2b3a241a3ea70ef7be6ba3e95c217cb00e722fb2..95c140cc50f79c602eed8a3fffe9258554be4f77 100644 (file)
@@ -122,7 +122,7 @@ void DolphinViewActionHandler::createActions()
     QAction* deleteWithTrashShortcut = m_actionCollection->addAction(QStringLiteral("delete_shortcut"));
     // The descriptive text is just for the shortcuts editor.
     deleteWithTrashShortcut->setText(i18nc("@action \"Move to Trash\" for non-local files, etc.", "Delete (using shortcut for Trash)"));
-    m_actionCollection->setDefaultShortcut(deleteWithTrashShortcut, QKeySequence::Delete);
+    m_actionCollection->setDefaultShortcuts(deleteWithTrashShortcut, KStandardShortcut::moveToTrash());
     deleteWithTrashShortcut->setEnabled(false);
     connect(deleteWithTrashShortcut, &QAction::triggered, this, &DolphinViewActionHandler::slotDeleteItems);