From: Elvis Angelaccio Date: Sun, 13 May 2018 11:28:00 +0000 (+0200) Subject: Merge branch 'Applications/18.04' X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/6e05c6365eec005caa3198a13bb071c782b8b192?hp=2e1cc199c3c2ef2eea5abd630821f80dfc9e0b16 Merge branch 'Applications/18.04' --- diff --git a/CMakeLists.txt b/CMakeLists.txt index ee77c5a5a..707160f53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/doc/index.docbook b/doc/index.docbook index 44af99503..c2ed2854f 100644 --- a/doc/index.docbook +++ b/doc/index.docbook @@ -70,8 +70,8 @@ &FDLNotice; -2016-06-01 -Applications 16.04 +2018-03-26 +Applications 18.04 @@ -281,6 +281,9 @@ the toolbar can be used to navigate in the history. +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. + @@ -359,8 +362,8 @@ The details view allows you to view the current folder in a tree-like fashion if Expandable folders are enabled: Each subfolder of the current folder can be -expanded or collapsed by clicking on the + -or - icon next to it. +expanded or collapsed by clicking on the > +or v icon next to it. @@ -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. - + @@ -733,9 +736,10 @@ tags, and comments to it. The Folders 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. - - +Use Limit to Home Directory to hide all folders from +the tree view except your Home. + @@ -803,10 +807,6 @@ a KIOSlave is launched to provide the search results. The option from Everywhere with activated Baloo services searches in all indexed folders, without Baloo this option starts the search from the user's Home folder. - Search with More Options @@ -832,6 +832,14 @@ the user to shrink the number of search results. together with the Filter bar to find files using Baloo or limit the search to files matching the filter expression. +Use the Save icon to save a search to the Search For +section in the Places panel to quickly access it again in the future. + + + @@ -856,7 +864,7 @@ in the menu, ⪚ Undo: Rename. - + Renaming A Batch Of Files @@ -864,7 +872,7 @@ in the menu, ⪚ Undo: Rename. will have the file name specified, including a number, ⪚, Image1.jpg, Image2.jpg, Image3.jpg. This can be useful, ⪚, for pictures taken with a digital camera. - + 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 section on the filter bar + +Show full path in title bar makes it easy to distinguish +between files or folders with the same name in different folders. + @@ -1325,6 +1337,10 @@ Enable Rename inline 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. +Use tab for switching between left and right split view +allows to switch without using the mouse. + + @@ -1353,8 +1369,8 @@ are shown before potentially harmful actions . The confirmation settings for Moving files or folders to trash and Deleting files or folders affect file operations in &dolphin;, &konqueror;, Gwenview and all &kde; applications using the default &kde; file dialog, -whereas Closing Dolphin windows - with multiple tabs is a &dolphin; specific setting. +whereas Closing Dolphin windows +with multiple tabs is a &dolphin; specific setting. @@ -1575,6 +1591,15 @@ trash. to the trash and cannot be restored. + + +File +Show Target + +This action highlights a link target in a new &dolphin; window. + + + @@ -1786,7 +1811,8 @@ current folder grouped by the option selected in Sort ByHidden Files Shows all the hidden files and sub-folders within the current -folder. +folder.There is an alternate shortcut &Ctrl;H +for this action. @@ -1954,7 +1980,9 @@ be reopened. Tools Show Filter Bar -Enables and disables the filter bar. +Enables and disables the filter bar. +You can also use the alternate shortcut &Shift;/ +for this action. diff --git a/src/dolphincontextmenu.cpp b/src/dolphincontextmenu.cpp index bedc835c2..befe98677 100644 --- a/src/dolphincontextmenu.cpp +++ b/src/dolphincontextmenu.cpp @@ -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() diff --git a/src/dolphincontextmenu.h b/src/dolphincontextmenu.h index 9ebdb1a56..bf0cf2c97 100644 --- a/src/dolphincontextmenu.h +++ b/src/dolphincontextmenu.h @@ -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. diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index d112007bc..a0509ad47 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -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(&DolphinMainWindow::openNewActivatedTab)); - QAction* closeTab = actionCollection()->addAction(QStringLiteral("close_tab")); - closeTab->setIcon(QIcon::fromTheme(QStringLiteral("tab-close"))); + QAction* closeTab = KStandardAction::close( + m_tabWidget, static_cast(&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(&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")); diff --git a/src/dolphinpart.cpp b/src/dolphinpart.cpp index e0f06bc5f..2e7f7639f 100644 --- a/src/dolphinpart.cpp +++ b/src/dolphinpart.cpp @@ -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"))) { diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index a96c8b6a3..b2bb5c896 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -312,6 +312,9 @@ void DolphinTabPage::slotViewActivated() m_primaryViewActive = !m_primaryViewActive; } else { m_primaryViewActive = true; + if (m_secondaryViewContainer) { + m_secondaryViewContainer->setActive(false); + } } } diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp index 0271ed568..a5c2f8c98 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -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(&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(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) diff --git a/src/dolphintabwidget.h b/src/dolphintabwidget.h index ba2fd4867..b4493f7ed 100644 --- a/src/dolphintabwidget.h +++ b/src/dolphintabwidget.h @@ -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 diff --git a/src/dolphinui.rc b/src/dolphinui.rc index 566f50fc8..ea3609c64 100644 --- a/src/dolphinui.rc +++ b/src/dolphinui.rc @@ -1,11 +1,11 @@ - + - + - + @@ -17,7 +17,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index b6a001642..844954d6a 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -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 }, diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index 75953f0b7..134c50245 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -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: diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp index 6c96a08d1..544d88040 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.cpp +++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp @@ -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"); diff --git a/src/kitemviews/kitemlistgroupheader.cpp b/src/kitemviews/kitemlistgroupheader.cpp index fb9298989..06a32484a 100644 --- a/src/kitemviews/kitemlistgroupheader.cpp +++ b/src/kitemviews/kitemlistgroupheader.cpp @@ -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; diff --git a/src/kitemviews/kitemlistselectionmanager.cpp b/src/kitemviews/kitemlistselectionmanager.cpp index efc256e1e..f5e097c02 100644 --- a/src/kitemviews/kitemlistselectionmanager.cpp +++ b/src/kitemviews/kitemlistselectionmanager.cpp @@ -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); } diff --git a/src/kitemviews/kitemliststyleoption.cpp b/src/kitemviews/kitemliststyleoption.cpp index 1ebcad141..bcfb86064 100644 --- a/src/kitemviews/kitemliststyleoption.cpp +++ b/src/kitemviews/kitemliststyleoption.cpp @@ -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); +} diff --git a/src/kitemviews/kitemliststyleoption.h b/src/kitemviews/kitemliststyleoption.h index 09b787c27..93aafac1f 100644 --- a/src/kitemviews/kitemliststyleoption.h +++ b/src/kitemviews/kitemliststyleoption.h @@ -45,6 +45,11 @@ public: bool extendedSelectionRegion; int maxTextLines; int maxTextWidth; + + bool operator==(const KItemListStyleOption& other) const; + bool operator!=(const KItemListStyleOption& other) const; + + }; #endif diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 489c6f9b6..f0647fb3e 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -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; diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index 61dd7256e..28b374620 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -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(); } diff --git a/src/kitemviews/kstandarditemlistview.cpp b/src/kitemviews/kstandarditemlistview.cpp index ee1c06103..929ee1da8 100644 --- a/src/kitemviews/kstandarditemlistview.cpp +++ b/src/kitemviews/kstandarditemlistview.cpp @@ -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() diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp index 1aca250dd..bc3bb29de 100644 --- a/src/kitemviews/kstandarditemlistwidget.cpp +++ b/src/kitemviews/kstandarditemlistwidget.cpp @@ -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)); diff --git a/src/kitemviews/private/kbaloorolesprovider.cpp b/src/kitemviews/private/kbaloorolesprovider.cpp index bbd0927f2..3d3923b1b 100644 --- a/src/kitemviews/private/kbaloorolesprovider.cpp +++ b/src/kitemviews/private/kbaloorolesprovider.cpp @@ -56,9 +56,6 @@ QHash KBalooRolesProvider::roleValues(const Baloo::File& f { QHash values; - int width = -1; - int height = -1; - QMapIterator it(file.properties()); while (it.hasNext()) { it.next(); @@ -72,23 +69,7 @@ QHash 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" }, diff --git a/src/panels/information/dolphin_informationpanelsettings.kcfg b/src/panels/information/dolphin_informationpanelsettings.kcfg index 53c756d24..dbc1ab6d2 100644 --- a/src/panels/information/dolphin_informationpanelsettings.kcfg +++ b/src/panels/information/dolphin_informationpanelsettings.kcfg @@ -10,5 +10,13 @@ true + + + + + + + 0 + diff --git a/src/panels/information/informationpanelcontent.cpp b/src/panels/information/informationpanelcontent.cpp index f44a3feb7..0cba0cdf0 100644 --- a/src/panels/information/informationpanelcontent.cpp +++ b/src/panels/information/informationpanelcontent.cpp @@ -112,12 +112,13 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) : this, &InformationPanelContent::urlActivated); #else m_metaDataWidget = new Baloo::FileMetaDataWidget(parent); + m_metaDataWidget->setDateFormat(static_cast(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(InformationPanelSettings::dateFormat())); +#endif m_metaDataWidget->show(); m_metaDataWidget->setItems(KFileItemList() << item); } @@ -283,6 +285,12 @@ void InformationPanelContent::configureSettings(const QList& 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(Baloo::DateFormats::ShortFormat)); +#endif popup.addSeparator(); foreach (QAction* action, customContextMenuActions) { popup.addAction(action); @@ -308,16 +316,22 @@ void InformationPanelContent::configureSettings(const QList& customCon dialog->show(); connect(dialog, &FileMetaDataConfigurationDialog::destroyed, this, &InformationPanelContent::refreshMetaData); } +#ifdef HAVE_BALOO + if (action == dateformatAction) { + int dateFormat = static_cast(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; diff --git a/src/panels/information/informationpanelcontent.h b/src/panels/information/informationpanelcontent.h index 80f3c8e22..9223fcc5a 100644 --- a/src/panels/information/informationpanelcontent.h +++ b/src/panels/information/informationpanelcontent.h @@ -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 diff --git a/src/panels/places/placesitemmodel.cpp b/src/panels/places/placesitemmodel.cpp index 3641b3e42..7e313482d 100644 --- a/src/panels/places/placesitemmodel.cpp +++ b/src/panels/places/placesitemmodel.cpp @@ -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); diff --git a/src/panels/places/placespanel.cpp b/src/panels/places/placespanel.cpp index 1f81a1eaa..00d8735c3 100644 --- a/src/panels/places/placespanel.cpp +++ b/src/panels/places/placespanel.cpp @@ -291,7 +291,7 @@ void PlacesPanel::slotViewContextMenuRequested(const QPointF& pos) {KIconLoader::SizeLarge, I18N_NOOP2_NOSTRIP("Huge icon size", "Huge (%1x%2)")} }; - QMap iconSizeActionMap; + QHash iconSizeActionMap; QActionGroup* iconSizeGroup = new QActionGroup(iconSizeSubMenu); for (int i = 0; i < iconSizeCount; ++i) { diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index c656173a8..07e4257a0 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -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 diff --git a/src/tests/dolphinmainwindowtest.cpp b/src/tests/dolphinmainwindowtest.cpp index a31237f3c..70ec8dba0 100644 --- a/src/tests/dolphinmainwindowtest.cpp +++ b/src/tests/dolphinmainwindowtest.cpp @@ -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("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("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()); diff --git a/src/tests/placesitemmodeltest.cpp b/src/tests/placesitemmodeltest.cpp index 3263537f9..fc21ce055 100644 --- a/src/tests/placesitemmodeltest.cpp +++ b/src/tests/placesitemmodeltest.cpp @@ -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); diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp index 2b3a241a3..95c140cc5 100644 --- a/src/views/dolphinviewactionhandler.cpp +++ b/src/views/dolphinviewactionhandler.cpp @@ -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);