CMakeLists.txt.user
.directory
*.kdev4
+/build*/
# KDE Application Version, managed by release script
set (KDE_APPLICATIONS_VERSION_MAJOR "19")
-set (KDE_APPLICATIONS_VERSION_MINOR "08")
-set (KDE_APPLICATIONS_VERSION_MICRO "2")
+set (KDE_APPLICATIONS_VERSION_MINOR "11")
+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})
-set(QT_MIN_VERSION "5.8.0")
-set(KF5_MIN_VERSION "5.57.0")
+set(QT_MIN_VERSION "5.11.0")
+set(KF5_MIN_VERSION "5.61.0")
# ECM setup
find_package(ECM ${KF5_MIN_VERSION} CONFIG REQUIRED)
${CMAKE_CURRENT_BINARY_DIR}/org.kde.dolphin.FileManager1.service)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.dolphin.FileManager1.service
DESTINATION ${DBUS_SERVICES_INSTALL_DIR})
-
-if (NOT ECM_VERSION VERSION_LESS "5.59.0")
- install(FILES dolphin.categories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR})
-else()
- install(FILES dolphin.categories DESTINATION ${KDE_INSTALL_CONFDIR})
-endif()
+install(FILES dolphin.categories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR})
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
<legalnotice>&FDLNotice;</legalnotice>
-<date>2019-06-26</date>
-<releaseinfo>Applications 19.08</releaseinfo>
+<date>2019-09-30</date>
+<releaseinfo>Applications 19.12</releaseinfo>
<abstract>
<para>
<para>
&dolphin; allows a number of panels to be placed next to the view. These can
-be enabled in <menuchoice><guimenu>View</guimenu><guisubmenu>Panels</guisubmenu></menuchoice>.
+be enabled in <menuchoice><guimenu>View</guimenu><guisubmenu>Show Panels</guisubmenu></menuchoice>.
By unlocking the panels and clicking and dragging a panel title, the panel can be moved
to a different position, even outside the window.
</para>
<title>Confirmations Tab</title>
<para>
In the ask for confirmation section, you can enable warning dialogs that
-are shown before potentially harmful actions .
+are shown before potentially harmful actions.
+</para>
+<para>
+It is also possible to choose the default action <guilabel>When opening an executable file</guilabel>. There are three options, namely <guimenuitem>Always ask</guimenuitem>, <guimenuitem>Open in application</guimenuitem>, and <guimenuitem>Run script</guimenuitem>.
</para>
<warning><para>The confirmation settings for <guilabel>Moving files or folders to trash</guilabel> and
<guilabel>Deleting files or folders</guilabel> affect file operations in &dolphin;, &konqueror;,
<listitem><para><action>Decreases the size of icons in the view.</action></para></listitem>
</varlistentry>
+<varlistentry>
+<term><menuchoice>
+<shortcut>
+<keycombo action="simul">&Ctrl;<keycap>0</keycap></keycombo>
+</shortcut>
+<guimenu>View</guimenu>
+<guimenuitem>Zoom Reset</guimenuitem>
+</menuchoice></term>
+<listitem><para><action>Resets the size of icons in the view to default.</action></para></listitem>
+</varlistentry>
+
<varlistentry>
<term><menuchoice>
<guimenu>View</guimenu>
<varlistentry>
<term><menuchoice>
<guimenu>View</guimenu>
-<guisubmenu>Additional Information</guisubmenu>
+<guisubmenu>Show Additional Information</guisubmenu>
</menuchoice></term>
<listitem><para><action>Displays additional information</action>
described in <link linkend="dolphin-view-information">Information in the View</link>.
<varlistentry>
<term><menuchoice>
<guimenu>View</guimenu>
-<guimenuitem>Preview</guimenuitem>
+<guimenuitem>Show Previews</guimenuitem>
</menuchoice></term>
<listitem><para><action>Displays a symbolic preview of the file contents </action> in the different
view modes.</para></listitem>
<keycombo action="simul">&Alt;<keycap>.</keycap></keycombo>
</shortcut>
<guimenu>View</guimenu>
-<guimenuitem>Hidden Files</guimenuitem>
+<guimenuitem>Show Hidden Files</guimenuitem>
</menuchoice></term>
<listitem><para><action>Shows all the hidden files and sub-folders within the current
folder.</action>There is an alternate shortcut <keycombo action="simul">&Ctrl;<keycap>H</keycap></keycombo>
<varlistentry>
<term><menuchoice>
<guimenu>View</guimenu>
-<guisubmenu>Panels</guisubmenu>
+<guisubmenu>Show Panels</guisubmenu>
</menuchoice></term>
<listitem><para><action>Enables and disables</action> the different <link linkend="panels">panels</link>:
<guimenuitem>Places</guimenuitem> (<keycap>F9</keycap>), <guimenuitem>Information</guimenuitem>
-/***************************************************************************
+ /***************************************************************************
* Copyright (C) 2006 by Peter Penz (peter.penz@gmx.at) and *
* Cvetoslav Ludmiloff *
* *
QAction* openParentAction = nullptr;
QAction* openParentInNewWindowAction = nullptr;
QAction* openParentInNewTabAction = nullptr;
- QAction* addToPlacesAction = nullptr;
const KFileItemListProperties& selectedItemsProps = selectedItemsProperties();
KFileItemActions fileItemActions;
// 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());
- newFileMenu->checkUpToDate();
- newFileMenu->setPopupFiles(m_fileInfo.url());
- newFileMenu->setEnabled(selectedItemsProps.supportsWriting());
- connect(newFileMenu, &DolphinNewFileMenu::fileCreated, newFileMenu, &DolphinNewFileMenu::deleteLater);
- connect(newFileMenu, &DolphinNewFileMenu::directoryCreated, newFileMenu, &DolphinNewFileMenu::deleteLater);
-
- QMenu* menu = newFileMenu->menu();
- menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
- menu->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
- addMenu(menu);
-
- addSeparator();
- } else if (m_baseUrl.scheme().contains(QStringLiteral("search")) || m_baseUrl.scheme().contains(QStringLiteral("timeline"))) {
+ DolphinNewFileMenu* newFileMenu = new DolphinNewFileMenu(m_mainWindow->actionCollection(), m_mainWindow);
+ const DolphinView* view = m_mainWindow->activeViewContainer()->view();
+ newFileMenu->setViewShowsHiddenFiles(view->hiddenFilesShown());
+ newFileMenu->checkUpToDate();
+ newFileMenu->setPopupFiles(m_fileInfo.url());
+ newFileMenu->setEnabled(selectedItemsProps.supportsWriting());
+ connect(newFileMenu, &DolphinNewFileMenu::fileCreated, newFileMenu, &DolphinNewFileMenu::deleteLater);
+ connect(newFileMenu, &DolphinNewFileMenu::directoryCreated, newFileMenu, &DolphinNewFileMenu::deleteLater);
+
+ QMenu* menu = newFileMenu->menu();
+ menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
+ menu->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
+ addMenu(menu);
+
+ addSeparator();
+ } else if (m_baseUrl.scheme().contains(QLatin1String("search")) || m_baseUrl.scheme().contains(QLatin1String("timeline"))) {
addOpenWithActions(fileItemActions);
openParentAction = new QAction(QIcon::fromTheme(QStringLiteral("document-open-folder")),
this);
addAction(openParentInNewTabAction);
- 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
insertDefaultItemActions(selectedItemsProps);
+ // insert 'Add to Places' entry if appropriate
+ if (m_selectedItems.count() == 1) {
+ if (m_fileInfo.isDir()) {
+ if (!placeExists(m_fileInfo.url())) {
+ addAction(m_mainWindow->actionCollection()->action(QStringLiteral("add_to_places")));
+ }
+ }
+ }
+
addSeparator();
fileItemActions.addServiceActionsTo(this);
QAction* activatedAction = exec(m_pos);
if (activatedAction) {
- if (activatedAction == addToPlacesAction) {
- const QUrl selectedUrl(m_fileInfo.url());
- if (selectedUrl.isValid()) {
- PlacesItemModel model;
- const QString text = selectedUrl.fileName();
- model.createPlacesItem(text, selectedUrl, KIO::iconNameForUrl(selectedUrl));
- }
- } else if (activatedAction == openParentAction) {
+ if (activatedAction == openParentAction) {
m_command = OpenParentFolder;
} else if (activatedAction == openParentInNewWindowAction) {
m_command = OpenParentFolderInNewWindow;
void DolphinContextMenu::openViewportContextMenu()
{
- // setup 'Create New' menu
- KNewFileMenu* newFileMenu = m_mainWindow->newFileMenu();
const DolphinView* view = m_mainWindow->activeViewContainer()->view();
- newFileMenu->setViewShowsHiddenFiles(view->hiddenFilesShown());
- newFileMenu->checkUpToDate();
- newFileMenu->setPopupFiles(m_baseUrl);
- addMenu(newFileMenu->menu());
- addSeparator();
// Insert 'Open With' entries
KFileItem baseItem = view->rootItem();
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("file_new")));
- addAction(m_mainWindow->actionCollection()->action(QStringLiteral("new_tab")));
-
- // Insert 'Add to Places' entry if exactly one item is selected
- QAction* addToPlacesAction = nullptr;
- if (!placeExists(m_mainWindow->activeViewContainer()->url())) {
- addToPlacesAction = addAction(QIcon::fromTheme(QStringLiteral("bookmark-new")),
- i18nc("@action:inmenu Add current folder to places", "Add to Places"));
- }
-
- addSeparator();
+ // Set up and insert 'Create New' menu
+ KNewFileMenu* newFileMenu = m_mainWindow->newFileMenu();
+ newFileMenu->setViewShowsHiddenFiles(view->hiddenFilesShown());
+ newFileMenu->checkUpToDate();
+ newFileMenu->setPopupFiles(m_baseUrl);
+ addMenu(newFileMenu->menu());
QAction* pasteAction = createPasteAction();
addAction(pasteAction);
+
+ // Insert 'Add to Places' entry if it's not already in the places panel
+ if (!placeExists(m_mainWindow->activeViewContainer()->url())) {
+ addAction(m_mainWindow->actionCollection()->action(QStringLiteral("add_to_places")));
+ }
addSeparator();
// Insert 'Sort By' and 'View Mode'
addCustomActions();
+ addSeparator();
+
QAction* propertiesAction = m_mainWindow->actionCollection()->action(QStringLiteral("properties"));
addAction(propertiesAction);
addShowMenuBarAction();
- QAction* action = exec(m_pos);
- if (addToPlacesAction && (action == addToPlacesAction)) {
- const DolphinViewContainer* container = m_mainWindow->activeViewContainer();
- const QUrl url = container->url();
- if (url.isValid()) {
- PlacesItemModel model;
- QString icon;
- if (container->isSearchModeEnabled()) {
- icon = QStringLiteral("folder-saved-search-symbolic");
- } else {
- icon = KIO::iconNameForUrl(url);
- }
- model.createPlacesItem(container->placesText(), url, icon);
- }
- }
+ exec(m_pos);
}
void DolphinContextMenu::insertDefaultItemActions(const KFileItemListProperties& properties)
#include "dolphintabpage.h"
#include "middleclickactioneventfilter.h"
#include "panels/folders/folderspanel.h"
+#include "panels/places/placesitemmodel.h"
#include "panels/places/placespanel.h"
#include "panels/information/informationpanel.h"
#include "panels/terminal/terminalpanel.h"
#include <KStartupInfo>
#include <KToggleAction>
#include <KToolBar>
+#include <KToolBarPopupAction>
#include <KToolInvocation>
#include <KUrlComboBox>
#include <KUrlNavigator>
// Used for GeneralSettings::version() to determine whether
// an updated version of Dolphin is running.
const int CurrentDolphinVersion = 200;
+ // The maximum number of entries in the back/forward popup menu
+ const int MaxNumberOfNavigationentries = 12;
}
DolphinMainWindow::DolphinMainWindow() :
- KXmlGuiWindow(nullptr, Qt::WindowContextHelpButtonHint),
+ KXmlGuiWindow(nullptr),
m_newFileMenu(nullptr),
m_helpMenu(nullptr),
m_tabWidget(nullptr),
m_lastHandleUrlStatJob(nullptr),
m_terminalPanel(nullptr),
m_placesPanel(nullptr),
- m_tearDownFromPlacesRequested(false)
+ m_tearDownFromPlacesRequested(false),
+ m_backAction(nullptr),
+ m_forwardAction(nullptr)
{
Q_INIT_RESOURCE(dolphin);
+#ifndef Q_OS_WIN
+ setWindowFlags(Qt::WindowContextHelpButtonHint);
+#endif
setComponentName(QStringLiteral("dolphin"), QGuiApplication::applicationDisplayName());
setObjectName(QStringLiteral("Dolphin#"));
}
m_activeViewContainer->setUrl(url);
- updateEditActions();
+ updateFileAndEditActions();
updatePasteAction();
updateViewActions();
updateGoActions();
void DolphinMainWindow::slotSelectionChanged(const KFileItemList& selection)
{
- updateEditActions();
+ updateFileAndEditActions();
const int selectedUrlsCount = m_tabWidget->currentTabPage()->selectedItemsCount();
m_tabWidget->openNewActivatedTab();
}
+void DolphinMainWindow::addToPlaces()
+{
+ QUrl url;
+ QString name;
+
+ // If nothing is selected, act on the current dir
+ if (m_activeViewContainer->view()->selectedItems().isEmpty()) {
+ url = m_activeViewContainer->url();
+ name = m_activeViewContainer->placesText();
+ } else {
+ const auto dirToAdd = m_activeViewContainer->view()->selectedItems().first();
+ url = dirToAdd.url();
+ name = dirToAdd.name();
+ }
+ if (url.isValid()) {
+ PlacesItemModel model;
+ QString icon;
+ if (m_activeViewContainer->isSearchModeEnabled()) {
+ icon = QStringLiteral("folder-saved-search-symbolic");
+ } else {
+ icon = KIO::iconNameForUrl(url);
+ }
+ model.createPlacesItem(name, url, icon);
+ }
+}
+
void DolphinMainWindow::openNewTab(const QUrl& url, DolphinTabWidget::TabPlacement tabPlacement)
{
m_tabWidget->openNewTab(url, QUrl(), tabPlacement);
}
}
- if (m_terminalPanel->hasProgramRunning() && GeneralSettings::confirmClosingTerminalRunningProgram() && closedByUser) {
+ if (m_terminalPanel && m_terminalPanel->hasProgramRunning() && GeneralSettings::confirmClosingTerminalRunningProgram() && closedByUser) {
// Ask if the user really wants to quit Dolphin with a program that is still running in the Terminal panel
// Open a confirmation dialog with 3 buttons:
// QDialogButtonBox::Yes -> Quit
if (!m_terminalPanel->isVisible()) {
KGuiItem::assign(
buttons->button(QDialogButtonBox::No),
- KGuiItem(i18n("Show &Terminal Panel"), QIcon::fromTheme(QStringLiteral("utilities-terminal"))));
+ KGuiItem(i18n("Show &Terminal Panel"), QIcon::fromTheme(QStringLiteral("dialog-scripts"))));
}
KGuiItem::assign(buttons->button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel());
m_activeViewContainer->setSearchModeEnabled(true);
}
+void DolphinMainWindow::updateSearchAction()
+{
+ QAction* toggleSearchAction = actionCollection()->action(QStringLiteral("toggle_search"));
+ toggleSearchAction->setChecked(m_activeViewContainer->isSearchModeEnabled());
+}
+
void DolphinMainWindow::updatePasteAction()
{
QAction* pasteAction = actionCollection()->action(KStandardAction::name(KStandardAction::Paste));
}
}
+void DolphinMainWindow::slotAboutToShowBackPopupMenu()
+{
+ KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
+ int entries = 0;
+ m_backAction->menu()->clear();
+ for (int i = urlNavigator->historyIndex() + 1; i < urlNavigator->historySize() && entries < MaxNumberOfNavigationentries; ++i, ++entries) {
+ QAction* action = new QAction(urlNavigator->locationUrl(i).toString(QUrl::PreferLocalFile), m_backAction->menu());
+ action->setData(i);
+ m_backAction->menu()->addAction(action);
+ }
+}
+
+void DolphinMainWindow::slotGoBack(QAction* action)
+{
+ int gotoIndex = action->data().value<int>();
+ KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
+ for (int i = gotoIndex - urlNavigator->historyIndex(); i > 0; --i) {
+ goBack();
+ }
+}
+
+void DolphinMainWindow::slotBackForwardActionMiddleClicked(QAction* action)
+{
+ if (action) {
+ KUrlNavigator* urlNavigator = activeViewContainer()->urlNavigator();
+ openNewTabAfterCurrentTab(urlNavigator->locationUrl(action->data().value<int>()));
+ }
+}
+
+void DolphinMainWindow::slotAboutToShowForwardPopupMenu()
+{
+ KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
+ int entries = 0;
+ m_forwardAction->menu()->clear();
+ for (int i = urlNavigator->historyIndex() - 1; i >= 0 && entries < MaxNumberOfNavigationentries; --i, ++entries) {
+ QAction* action = new QAction(urlNavigator->locationUrl(i).toString(QUrl::PreferLocalFile), m_forwardAction->menu());
+ action->setData(i);
+ m_forwardAction->menu()->addAction(action);
+ }
+}
+
+void DolphinMainWindow::slotGoForward(QAction* action)
+{
+ int gotoIndex = action->data().value<int>();
+ KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
+ for (int i = urlNavigator->historyIndex() - gotoIndex; i > 0; --i) {
+ goForward();
+ }
+}
+
void DolphinMainWindow::selectAll()
{
clearStatusBar();
void DolphinMainWindow::slotTerminalPanelVisibilityChanged()
{
- if (m_terminalPanel->isHiddenInVisibleWindow()) {
+ if (m_terminalPanel->isHiddenInVisibleWindow() && m_activeViewContainer) {
m_activeViewContainer->view()->setFocus();
}
}
KActionCollection* ac = actionCollection();
- // Add "Create New" menu
menu->addMenu(m_newFileMenu->menu());
+ addActionToMenu(ac->action(QStringLiteral("file_new")), menu);
+ addActionToMenu(ac->action(QStringLiteral("new_tab")), menu);
+ addActionToMenu(ac->action(QStringLiteral("closed_tabs")), menu);
menu->addSeparator();
- // Overwrite Find action to Search action
- QAction *searchAction = ac->action(KStandardAction::name(KStandardAction::Find));
- searchAction->setText(i18n("Search..."));
-
// Add "Edit" actions
bool added = addActionToMenu(ac->action(KStandardAction::name(KStandardAction::Undo)), menu) |
- addActionToMenu(searchAction, menu) |
addActionToMenu(ac->action(KStandardAction::name(KStandardAction::SelectAll)), menu) |
addActionToMenu(ac->action(QStringLiteral("invert_selection")), menu);
// Add "View" actions
if (!GeneralSettings::showZoomSlider()) {
addActionToMenu(ac->action(KStandardAction::name(KStandardAction::ZoomIn)), menu);
+ addActionToMenu(ac->action(QStringLiteral("view_zoom_reset")), menu);
addActionToMenu(ac->action(KStandardAction::name(KStandardAction::ZoomOut)), menu);
menu->addSeparator();
}
- added = addActionToMenu(ac->action(QStringLiteral("sort")), menu) |
- addActionToMenu(ac->action(QStringLiteral("view_mode")), menu) |
- addActionToMenu(ac->action(QStringLiteral("additional_info")), menu) |
- addActionToMenu(ac->action(QStringLiteral("show_preview")), menu) |
+ added = addActionToMenu(ac->action(QStringLiteral("show_preview")), menu) |
addActionToMenu(ac->action(QStringLiteral("show_in_groups")), menu) |
- addActionToMenu(ac->action(QStringLiteral("show_hidden_files")), menu);
-
- if (added) {
- menu->addSeparator();
- }
-
- added = addActionToMenu(ac->action(QStringLiteral("split_view")), menu) |
- addActionToMenu(ac->action(KStandardAction::name(KStandardAction::Redisplay)), menu) |
+ addActionToMenu(ac->action(QStringLiteral("show_hidden_files")), menu) |
+ addActionToMenu(ac->action(QStringLiteral("additional_info")), menu) |
addActionToMenu(ac->action(QStringLiteral("view_properties")), menu);
+
if (added) {
menu->addSeparator();
}
- addActionToMenu(ac->action(QStringLiteral("panels")), menu);
- QMenu* locationBarMenu = new QMenu(i18nc("@action:inmenu", "Location Bar"), menu);
- locationBarMenu->addAction(ac->action(QStringLiteral("editable_location")));
- locationBarMenu->addAction(ac->action(QStringLiteral("replace_location")));
- menu->addMenu(locationBarMenu);
+ // Add a curated assortment of items from the "Tools" menu
+ addActionToMenu(ac->action(QStringLiteral("show_filter_bar")), menu);
+ addActionToMenu(ac->action(QStringLiteral("open_terminal")), menu);
menu->addSeparator();
- // Add "Go" menu
- QMenu* goMenu = new QMenu(i18nc("@action:inmenu", "Go"), menu);
- goMenu->addAction(ac->action(KStandardAction::name(KStandardAction::Back)));
- goMenu->addAction(ac->action(KStandardAction::name(KStandardAction::Forward)));
- goMenu->addAction(ac->action(KStandardAction::name(KStandardAction::Up)));
- goMenu->addAction(ac->action(KStandardAction::name(KStandardAction::Home)));
- goMenu->addAction(ac->action(QStringLiteral("closed_tabs")));
- KActionMenu *bookmarkMenu = new KActionMenu(i18nc("@title:menu", "&Bookmarks"), goMenu);
- m_bookmarkHandler->fillControlMenu(bookmarkMenu->menu(), ac);
- goMenu->addAction(bookmarkMenu);
- menu->addMenu(goMenu);
-
- // Add "Tool" menu
- QMenu* toolsMenu = new QMenu(i18nc("@action:inmenu", "Tools"), menu);
- toolsMenu->addAction(ac->action(QStringLiteral("show_filter_bar")));
- toolsMenu->addAction(ac->action(QStringLiteral("compare_files")));
- toolsMenu->addAction(ac->action(QStringLiteral("open_terminal")));
- toolsMenu->addAction(ac->action(QStringLiteral("change_remote_encoding")));
- menu->addMenu(toolsMenu);
+ // Add "Show Panels" menu
+ addActionToMenu(ac->action(QStringLiteral("panels")), menu);
// Add "Settings" menu entries
addActionToMenu(ac->action(KStandardAction::name(KStandardAction::KeyBindings)), menu);
addActionToMenu(ac->action(KStandardAction::name(KStandardAction::ConfigureToolbars)), menu);
addActionToMenu(ac->action(KStandardAction::name(KStandardAction::Preferences)), menu);
+ addActionToMenu(ac->action(KStandardAction::name(KStandardAction::ShowMenubar)), menu);
// Add "Help" menu
- menu->addMenu(m_helpMenu->menu());
-
- menu->addSeparator();
- addActionToMenu(ac->action(KStandardAction::name(KStandardAction::ShowMenubar)), menu);
+ auto helpMenu = m_helpMenu->menu();
+ helpMenu->setIcon(QIcon::fromTheme(QStringLiteral("system-help")));
+ menu->addMenu(helpMenu);
}
void DolphinMainWindow::updateToolBar()
m_activeViewContainer = viewContainer;
if (oldViewContainer) {
+ const QAction* toggleSearchAction = actionCollection()->action(QStringLiteral("toggle_search"));
+ toggleSearchAction->disconnect(oldViewContainer);
+
// Disconnect all signals between the old view container (container,
// view and url navigator) and main window.
oldViewContainer->disconnect(this);
m_actionHandler->setCurrentView(viewContainer->view());
updateHistory();
- updateEditActions();
+ updateFileAndEditActions();
updatePasteAction();
updateViewActions();
updateGoActions();
+ updateSearchAction();
const QUrl url = viewContainer->url();
emit urlChanged(url);
void DolphinMainWindow::slotStorageTearDownFromPlacesRequested(const QString& mountPath)
{
- if (m_terminalPanel->currentWorkingDirectory().startsWith(mountPath)) {
+ if (m_terminalPanel && m_terminalPanel->currentWorkingDirectory().startsWith(mountPath)) {
m_tearDownFromPlacesRequested = true;
m_terminalPanel->goHome();
// m_placesPanel->proceedWithTearDown() will be called in slotTerminalDirectoryChanged
void DolphinMainWindow::slotStorageTearDownExternallyRequested(const QString& mountPath)
{
- if (m_terminalPanel->currentWorkingDirectory().startsWith(mountPath)) {
+ if (m_terminalPanel && m_terminalPanel->currentWorkingDirectory().startsWith(mountPath)) {
m_tearDownFromPlacesRequested = false;
m_terminalPanel->goHome();
}
QAction* newWindow = KStandardAction::openNew(this, &DolphinMainWindow::openNewMainWindow, actionCollection());
newWindow->setText(i18nc("@action:inmenu File", "New &Window"));
+ newWindow->setToolTip(i18nc("@info", "Open a new Dolphin window"));
newWindow->setWhatsThis(xi18nc("@info:whatsthis", "This opens a new "
"window just like this one with the current location and view."
"<nl/>You can drag and drop items between windows."));
actionCollection()->setDefaultShortcuts(newTab, {Qt::CTRL + Qt::Key_T, Qt::CTRL + Qt::SHIFT + Qt::Key_N});
connect(newTab, &QAction::triggered, this, &DolphinMainWindow::openNewActivatedTab);
+ QAction* addToPlaces = actionCollection()->addAction(QStringLiteral("add_to_places"));
+ addToPlaces->setIcon(QIcon::fromTheme(QStringLiteral("bookmark-new")));
+ addToPlaces->setWhatsThis(xi18nc("@info:whatsthis", "This adds the selected folder "
+ "to the Places panel."));
+ connect(addToPlaces, &QAction::triggered, this, &DolphinMainWindow::addToPlaces);
+
QAction* closeTab = KStandardAction::close(m_tabWidget, QOverload<>::of(&DolphinTabWidget::closeTab), actionCollection());
closeTab->setText(i18nc("@action:inmenu File", "Close Tab"));
closeTab->setWhatsThis(i18nc("@info:whatsthis", "This closes the "
"the find bar so we can have a look at it while the settings are "
"explained.</para>"));
+ // toggle_search acts as a copy of the main searchAction to be used mainly
+ // in the toolbar, with no default shortcut attached, to avoid messing with
+ // existing workflows (search bar always open and Ctrl-F to focus)
+ QAction *toggleSearchAction = actionCollection()->addAction(QStringLiteral("toggle_search"));
+ toggleSearchAction->setText(i18nc("@action:inmenu", "Toggle Search Bar"));
+ toggleSearchAction->setIconText(i18nc("@action:intoolbar", "Search"));
+ toggleSearchAction->setIcon(searchAction->icon());
+ toggleSearchAction->setToolTip(searchAction->toolTip());
+ toggleSearchAction->setWhatsThis(searchAction->whatsThis());
+ toggleSearchAction->setCheckable(true);
+
QAction* selectAllAction = KStandardAction::selectAll(this, &DolphinMainWindow::selectAll, actionCollection());
selectAllAction->setWhatsThis(xi18nc("@info:whatsthis", "This selects all "
"files and folders in the current location."));
connect(replaceLocation, &QAction::triggered, this, &DolphinMainWindow::replaceLocation);
// setup 'Go' menu
- QAction* backAction = KStandardAction::back(this, &DolphinMainWindow::goBack, actionCollection());
- auto backShortcuts = backAction->shortcuts();
+ {
+ QScopedPointer<QAction> backAction(KStandardAction::back(nullptr, nullptr, nullptr));
+ m_backAction = new KToolBarPopupAction(backAction->icon(), backAction->text(), actionCollection());
+ m_backAction->setObjectName(backAction->objectName());
+ m_backAction->setShortcuts(backAction->shortcuts());
+ }
+ m_backAction->setDelayed(true);
+ m_backAction->setStickyMenu(false);
+ connect(m_backAction, &QAction::triggered, this, &DolphinMainWindow::goBack);
+ connect(m_backAction->menu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowBackPopupMenu);
+ connect(m_backAction->menu(), &QMenu::triggered, this, &DolphinMainWindow::slotGoBack);
+ actionCollection()->addAction(m_backAction->objectName(), m_backAction);
+
+ auto backShortcuts = m_backAction->shortcuts();
backShortcuts.append(QKeySequence(Qt::Key_Backspace));
- actionCollection()->setDefaultShortcuts(backAction, backShortcuts);
+ actionCollection()->setDefaultShortcuts(m_backAction, backShortcuts);
DolphinRecentTabsMenu* recentTabsMenu = new DolphinRecentTabsMenu(this);
actionCollection()->addAction(QStringLiteral("closed_tabs"), recentTabsMenu);
"be undone will ask for your confirmation."));
undoAction->setEnabled(false); // undo should be disabled by default
- KStandardAction::forward(this, &DolphinMainWindow::goForward, actionCollection());
+ {
+ QScopedPointer<QAction> forwardAction(KStandardAction::forward(nullptr, nullptr, nullptr));
+ m_forwardAction = new KToolBarPopupAction(forwardAction->icon(), forwardAction->text(), actionCollection());
+ m_forwardAction->setObjectName(forwardAction->objectName());
+ m_forwardAction->setShortcuts(forwardAction->shortcuts());
+ }
+ m_forwardAction->setDelayed(true);
+ m_forwardAction->setStickyMenu(false);
+ connect(m_forwardAction, &QAction::triggered, this, &DolphinMainWindow::goForward);
+ connect(m_forwardAction->menu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowForwardPopupMenu);
+ connect(m_forwardAction->menu(), &QMenu::triggered, this, &DolphinMainWindow::slotGoForward);
+ actionCollection()->addAction(m_forwardAction->objectName(), m_forwardAction);
+ actionCollection()->setDefaultShortcuts(m_forwardAction, m_forwardAction->shortcuts());
+
+ // enable middle-click to open in a new tab
+ auto *middleClickEventFilter = new MiddleClickActionEventFilter(this);
+ connect(middleClickEventFilter, &MiddleClickActionEventFilter::actionMiddleClicked, this, &DolphinMainWindow::slotBackForwardActionMiddleClicked);
+ m_backAction->menu()->installEventFilter(middleClickEventFilter);
+ m_forwardAction->menu()->installEventFilter(middleClickEventFilter);
KStandardAction::up(this, &DolphinMainWindow::goUp, actionCollection());
QAction* homeAction = KStandardAction::home(this, &DolphinMainWindow::goHome, actionCollection());
homeAction->setWhatsThis(xi18nc("@info:whatsthis", "Go to your "
openTerminal->setWhatsThis(xi18nc("@info:whatsthis",
"<para>This opens a <emphasis>terminal</emphasis> application for the viewed location.</para>"
"<para>To learn more about terminals use the help in the terminal application.</para>"));
- openTerminal->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal")));
+ openTerminal->setIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts")));
actionCollection()->setDefaultShortcut(openTerminal, Qt::SHIFT + Qt::Key_F4);
connect(openTerminal, &QAction::triggered, this, &DolphinMainWindow::openTerminal);
}
this, &DolphinMainWindow::slotTerminalPanelVisibilityChanged);
QAction* terminalAction = terminalDock->toggleViewAction();
- createPanelAction(QIcon::fromTheme(QStringLiteral("utilities-terminal")), Qt::Key_F4, terminalAction, QStringLiteral("show_terminal_panel"));
+ createPanelAction(QIcon::fromTheme(QStringLiteral("dialog-scripts")), Qt::Key_F4, terminalAction, QStringLiteral("show_terminal_panel"));
addDockWidget(Qt::BottomDockWidgetArea, terminalDock);
connect(this, &DolphinMainWindow::urlChanged,
this, &DolphinMainWindow::slotStorageTearDownExternallyRequested);
m_tabWidget->slotPlacesPanelVisibilityChanged(m_placesPanel->isVisible());
- auto actionShowAllPlaces = new QAction(QIcon::fromTheme(QStringLiteral("hint")), i18nc("@item:inmenu", "Show Hidden Places"), this);
+ auto actionShowAllPlaces = new QAction(QIcon::fromTheme(QStringLiteral("view-hidden")), i18nc("@item:inmenu", "Show Hidden Places"), this);
actionShowAllPlaces->setCheckable(true);
actionShowAllPlaces->setDisabled(true);
actionShowAllPlaces->setWhatsThis(i18nc("@info:whatsthis", "This displays "
"appear semi-transparent unless you uncheck their hide property."));
connect(actionShowAllPlaces, &QAction::triggered, this, [actionShowAllPlaces, this](bool checked){
- actionShowAllPlaces->setIcon(QIcon::fromTheme(checked ? QStringLiteral("visibility") : QStringLiteral("hint")));
+ actionShowAllPlaces->setIcon(QIcon::fromTheme(checked ? QStringLiteral("view-visible") : QStringLiteral("view-hidden")));
m_placesPanel->showHiddenEntries(checked);
});
connect(m_placesPanel, &PlacesPanel::showHiddenEntriesChanged, this, [actionShowAllPlaces] (bool checked){
actionShowAllPlaces->setChecked(checked);
- actionShowAllPlaces->setIcon(QIcon::fromTheme(checked ? QStringLiteral("visibility") : QStringLiteral("hint")));
+ actionShowAllPlaces->setIcon(QIcon::fromTheme(checked ? QStringLiteral("view-visible") : QStringLiteral("view-hidden")));
});
actionCollection()->action(QStringLiteral("show_places_panel"))
"</interface> to display it again.</para>") + panelWhatsThis);
// Add actions into the "Panels" menu
- KActionMenu* panelsMenu = new KActionMenu(i18nc("@action:inmenu View", "Panels"), this);
+ KActionMenu* panelsMenu = new KActionMenu(i18nc("@action:inmenu View", "Show Panels"), this);
actionCollection()->addAction(QStringLiteral("panels"), panelsMenu);
+ panelsMenu->setIcon(QIcon::fromTheme(QStringLiteral("view-sidetree")));
panelsMenu->setDelayed(false);
const KActionCollection* ac = actionCollection();
panelsMenu->addAction(ac->action(QStringLiteral("show_places_panel")));
});
}
-void DolphinMainWindow::updateEditActions()
+
+void DolphinMainWindow::updateFileAndEditActions()
{
const KFileItemList list = m_activeViewContainer->view()->selectedItems();
+ const KActionCollection* col = actionCollection();
+ QAction* addToPlacesAction = col->action(QStringLiteral("add_to_places"));
+
if (list.isEmpty()) {
stateChanged(QStringLiteral("has_no_selection"));
+
+ addToPlacesAction->setText(i18nc("@action:inmenu Add current folder to places", "Add '%1' to Places", m_activeViewContainer->placesText()));
} else {
stateChanged(QStringLiteral("has_selection"));
- KActionCollection* col = actionCollection();
QAction* renameAction = col->action(KStandardAction::name(KStandardAction::RenameFile));
QAction* moveToTrashAction = col->action(KStandardAction::name(KStandardAction::MoveToTrash));
QAction* deleteAction = col->action(KStandardAction::name(KStandardAction::DeleteFile));
QAction* deleteWithTrashShortcut = col->action(QStringLiteral("delete_shortcut")); // see DolphinViewActionHandler
QAction* showTarget = col->action(QStringLiteral("show_target"));
+ if (list.length() == 1 && list.first().isDir()) {
+ addToPlacesAction->setEnabled(true);
+ addToPlacesAction->setText(i18nc("@action:inmenu Add current folder to places", "Add '%1' to Places", list.first().name()));
+ } else {
+ addToPlacesAction->setEnabled(false);
+ addToPlacesAction->setText(i18nc("@action:inmenu Add current folder to places", "Add to Places"));
+ }
+
KFileItemListProperties capabilities(list);
const bool enableMoveToTrash = capabilities.isLocal() && capabilities.supportsMoving();
m_controlButton = new QToolButton(this);
m_controlButton->setIcon(QIcon::fromTheme(QStringLiteral("application-menu")));
- m_controlButton->setText(i18nc("@action", "Control"));
+ m_controlButton->setToolTip(i18nc("@action", "Show menu"));
m_controlButton->setAttribute(Qt::WidgetAttribute::WA_CustomWhatsThis);
m_controlButton->setPopupMode(QToolButton::InstantPopup);
- m_controlButton->setToolButtonStyle(toolBar()->toolButtonStyle());
QMenu* controlMenu = new QMenu(m_controlButton);
connect(controlMenu, &QMenu::aboutToShow, this, &DolphinMainWindow::updateControlMenu);
toolBar()->addWidget(m_controlButton);
connect(toolBar(), &KToolBar::iconSizeChanged,
m_controlButton, &QToolButton::setIconSize);
- connect(toolBar(), &KToolBar::toolButtonStyleChanged,
- m_controlButton, &QToolButton::setToolButtonStyle);
// The added widgets are owned by the toolbar and may get deleted when e.g. the toolbar
// gets edited. In this case we must add them again. The adding is done asynchronously by
this, &DolphinMainWindow::updateFilterBarAction);
connect(container, &DolphinViewContainer::writeStateChanged,
this, &DolphinMainWindow::slotWriteStateChanged);
+ connect(container, &DolphinViewContainer::searchModeEnabledChanged,
+ this, &DolphinMainWindow::updateSearchAction);
+
+ const QAction* toggleSearchAction = actionCollection()->action(QStringLiteral("toggle_search"));
+ connect(toggleSearchAction, &QAction::triggered, container, &DolphinViewContainer::setSearchModeEnabled);
const DolphinView* view = container->view();
connect(view, &DolphinView::selectionChanged,
bool DolphinMainWindow::isUrlOpen(const QString& url)
{
- if (m_tabWidget->getIndexByUrl(QUrl::fromUserInput((url))).first >= 0) {
- return true;
- } else {
- return false;
- }
+ return m_tabWidget->isUrlOpen(QUrl::fromUserInput((url)));
}
class KJob;
class KNewFileMenu;
class KHelpMenu;
+class KToolBarPopupAction;
class QToolButton;
class QIcon;
class PlacesPanel;
/** Replaces the URL navigator by a search box to find files. */
void find();
+ /** Updates the state of the search action according to the view container. */
+ void updateSearchAction();
+
/**
* Updates the text of the paste action dependent on
* the number of items which are in the clipboard.
*/
void openNewActivatedTab();
+ /**
+ * Adds the current URL as an entry to the Places panel
+ */
+ void addToPlaces();
+
/**
* Opens a new tab in the background showing the URL \a url.
*/
*/
void slotToolBarActionMiddleClicked(QAction *action);
+ /**
+ * Is called before the Back popup menu is shown. This slot will populate
+ * the menu with history data
+ */
+ void slotAboutToShowBackPopupMenu();
+
+ /**
+ * This slot is used by the Back Popup Menu to go back to a specific
+ * history index. The QAction::data will carry an int with the index
+ * to go to.
+ */
+ void slotGoBack(QAction* action);
+
+ /**
+ * Middle clicking Back/Forward will open the resulting folder in a new tab.
+ */
+ void slotBackForwardActionMiddleClicked(QAction *action);
+
+ /**
+ * Is called before the Forward popup menu is shown. This slot will populate
+ * the menu with history data
+ */
+ void slotAboutToShowForwardPopupMenu();
+
+ /**
+ * This slot is used by the Forward Popup Menu to go forward to a specific
+ * history index. The QAction::data will carry an int with the index
+ * to go to.
+ */
+ void slotGoForward(QAction* action);
private:
/**
* Sets up the various menus and actions and connects them.
*/
void setupDockWidgets();
- void updateEditActions();
+ void updateFileAndEditActions();
void updateViewActions();
void updateGoActions();
TerminalPanel* m_terminalPanel;
PlacesPanel* m_placesPanel;
bool m_tearDownFromPlacesRequested;
+
+ KToolBarPopupAction* m_backAction;
+ KToolBarPopupAction* m_forwardAction;
};
inline DolphinViewContainer* DolphinMainWindow::activeViewContainer() const
#ifndef Q_OS_WIN
if (KAuthorized::authorize(QStringLiteral("shell_access"))) {
m_openTerminalAction = actionCollection()->addAction(QStringLiteral("open_terminal"));
- m_openTerminalAction->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal")));
+ m_openTerminalAction->setIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts")));
m_openTerminalAction->setText(i18nc("@action:inmenu Tools", "Open &Terminal"));
connect(m_openTerminalAction, &QAction::triggered, this, &DolphinPart::slotOpenTerminal);
actionCollection()->setDefaultShortcut(m_openTerminalAction, Qt::Key_F4);
Name[it]=Vista di Dolphin
Name[ja]=Dolphin ビュー
Name[ko]=Dolphin 보기
-Name[lt]=Dolphin žiūryklė
+Name[lt]=Dolphin rodinys
Name[ml]=ഡോള്ഫിന് അവതരണരീതി
Name[nb]=Dolphin visning
Name[nl]=Dolphin-weergave
Name[it]=Icone
Name[ja]=アイコン
Name[ko]=아이콘
-Name[lt]=Ženkliukai
+Name[lt]=Piktogramos
Name[ml]=സൂചനാചിത്രങ്ങള്
Name[nb]=Ikoner
Name[nl]=Pictogrammen
Name[it]=Dettagli
Name[ja]=詳細
Name[ko]=자세히
-Name[lt]=Informacija
+Name[lt]=Išsamus
Name[ml]=വിശദമായി
Name[nb]=Detaljer
Name[nl]=Details
}
}
+bool DolphinTabWidget::isUrlOpen(const QUrl &url) const
+{
+ return indexByUrl(url).first >= 0;
+}
+
void DolphinTabWidget::openNewActivatedTab()
{
const DolphinViewContainer* oldActiveViewContainer = currentTabPage()->activeViewContainer();
QWidget* focusWidget = QApplication::focusWidget();
DolphinTabPage* tabPage = new DolphinTabPage(primaryUrl, secondaryUrl, this);
+ tabPage->setActive(false);
tabPage->setPlacesSelectorVisible(m_placesSelectorVisible);
connect(tabPage, &DolphinTabPage::activeViewChanged,
this, &DolphinTabWidget::activeViewChanged);
if (tabPlacement == AfterCurrentTab) {
newTabIndex = currentIndex() + 1;
}
- insertTab(newTabIndex, tabPage, QIcon::fromTheme(KIO::iconNameForUrl(primaryUrl)), tabName(tabPage));
+ insertTab(newTabIndex, tabPage, QIcon() /* loaded in tabInserted */, tabName(tabPage));
if (focusWidget) {
// The DolphinViewContainer grabbed the keyboard focus. As the tab is opened
QList<QUrl>::const_iterator it = dirs.constBegin();
while (it != dirs.constEnd()) {
const QUrl& primaryUrl = *(it++);
- const QPair<int, bool> viewLocation = getIndexByUrl(primaryUrl);
- if (viewLocation.first >= 0) {
- setCurrentIndex(viewLocation.first);
- const auto tabPage = tabPageAt(viewLocation.first);
- if (viewLocation.second) {
+ const QPair<int, bool> indexInfo = indexByUrl(primaryUrl);
+ const int index = indexInfo.first;
+ const bool isInPrimaryView = indexInfo.second;
+ if (index >= 0) {
+ setCurrentIndex(index);
+ const auto tabPage = tabPageAt(index);
+ if (isInPrimaryView) {
tabPage->primaryViewContainer()->setActive(true);
} else {
tabPage->secondaryViewContainer()->setActive(true);
const int index = indexOf(qobject_cast<QWidget*>(sender()));
if (index >= 0) {
tabBar()->setTabText(index, tabName(tabPageAt(index)));
- tabBar()->setTabIcon(index, QIcon::fromTheme(KIO::iconNameForUrl(url)));
+ if (tabBar()->isVisible()) {
+ tabBar()->setTabIcon(index, QIcon::fromTheme(KIO::iconNameForUrl(url)));
+ } else {
+ // Mark as dirty, actually load once the tab bar actually gets shown
+ tabBar()->setTabIcon(index, QIcon());
+ }
// Emit the currentUrlChanged signal if the url of the current tab has been changed.
if (index == currentIndex()) {
QTabWidget::tabInserted(index);
if (count() > 1) {
+ // Resolve all pending tab icons
+ for (int i = 0; i < count(); ++i) {
+ if (tabBar()->tabIcon(i).isNull()) {
+ tabBar()->setTabIcon(i, QIcon::fromTheme(KIO::iconNameForUrl(tabPageAt(i)->activeViewContainer()->url())));
+ }
+ }
+
tabBar()->show();
}
return name.replace('&', QLatin1String("&&"));
}
-QPair<int, bool> DolphinTabWidget::getIndexByUrl(const QUrl& url) const
+QPair<int, bool> DolphinTabWidget::indexByUrl(const QUrl& url) const
{
for (int i = 0; i < count(); i++) {
const auto tabPage = tabPageAt(i);
void refreshViews();
/**
- * @param url The URL that we would like
- * @return a QPair with first containing the index of the tab with the
- * desired URL or -1 if not found. Second says true if URL is in primary
- * view container, false otherwise. False means the URL is in the secondary
- * view container, unless first == -1. In that case the value of second
- * is meaningless.
+ * @return Whether any of the tab pages contains @p url in their primary
+ * or secondary view.
*/
- QPair<int, bool> getIndexByUrl(const QUrl& url) const;
+ bool isUrlOpen(const QUrl& url) const;
signals:
/**
*/
QString tabName(DolphinTabPage* tabPage) const;
+ /**
+ * @param url The URL that we would like
+ * @return a QPair with first containing the index of the tab with the
+ * desired URL or -1 if not found. Second says true if URL is in primary
+ * view container, false otherwise. False means the URL is in the secondary
+ * view container, unless first == -1. In that case the value of second
+ * is meaningless.
+ */
+ QPair<int, bool> indexByUrl(const QUrl& url) const;
+
private:
/** Caches the (negated) places panel visibility */
bool m_placesSelectorVisible;
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="dolphin" version="22">
+<kpartgui name="dolphin" version="27">
<MenuBar>
<Menu name="file">
<Action name="new_menu" />
<Action name="file_close" />
<Action name="undo_close_tab" />
<Separator/>
+ <Action name="add_to_places" />
+ <Separator/>
<Action name="renamefile" />
<Action name="movetotrash" />
<Action name="deletefile" />
<Action name="invert_selection" />
</Menu>
<Menu name="view">
+ <Action name="view_zoom_in"/>
+ <Action name="view_zoom_reset"/>
+ <Action name="view_zoom_out"/>
+ <Separator/>
<Action name="sort" />
<Action name="view_mode" />
<Action name="additional_info" />
<Action name="stop" />
<Separator/>
<Action name="panels" />
- <Menu name="location_bar">
+ <Menu name="location_bar" icon="edit-select-text">
<text context="@title:menu">Location Bar</text>
<Action name="editable_location" />
<Action name="replace_location" />
<Action name="compact" />
<Action name="details" />
<Separator name="separator_0" />
- <Action name="edit_find"/>
- <Action name="show_preview" />
+ <Action name="sort" />
+ <Spacer name="spacer_0" />
<Action name="split_view" />
<Action name="split_stash" />
+ <Action name="toggle_search" />
</ToolBar>
<ActionProperties scheme="Default">
<Action priority="0" name="go_back"/>
<Action priority="0" name="compact"/>
<Action priority="0" name="details"/>
<Action priority="0" name="view_zoom_in"/>
+ <Action priority="0" name="view_zoom_reset"/>
<Action priority="0" name="view_zoom_out"/>
<Action priority="0" name="edit_cut"/>
<Action priority="0" name="edit_copy"/>
<Action priority="0" name="edit_paste"/>
+ <Action priority="0" name="toggle_search"/>
</ActionProperties>
</kpartgui>
}
m_searchModeEnabled = enabled;
+
+ emit searchModeEnabledChanged(enabled);
}
bool DolphinViewContainer::isSearchModeEnabled() const
}
KFilePlacesModel *placesModel = DolphinPlacesModelSingleton::instance().placesModel();
- const auto& matchedPlaces = placesModel->match(placesModel->index(0,0), KFilePlacesModel::UrlRole, url(), 1, Qt::MatchExactly);
+ const auto& matchedPlaces = placesModel->match(placesModel->index(0,0), KFilePlacesModel::UrlRole, QUrl(url().adjusted(QUrl::StripTrailingSlash).toString(QUrl::FullyEncoded).append("/?")), 1, Qt::MatchRegExp);
if (!matchedPlaces.isEmpty()) {
return placesModel->text(matchedPlaces.first());
app = browser;
if (app.startsWith('!')) {
// a literal command has been configured, remove the '!' prefix
- app = app.mid(1);
+ app.remove(0, 1);
}
}
} else {
bool DolphinViewContainer::isSearchUrl(const QUrl& url) const
{
- return url.scheme().contains(QStringLiteral("search"));
+ return url.scheme().contains(QLatin1String("search"));
}
void DolphinViewContainer::saveViewState()
/** Returns true, if the filter bar is visible. */
bool isFilterBarVisible() const;
- /**
- * Enables the search mode, if \p enabled is true. In the search mode the URL navigator
- * will be hidden and replaced by a line editor that allows to enter a search term.
- */
- void setSearchModeEnabled(bool enabled);
+
+ /** Returns true if the search mode is enabled. */
bool isSearchModeEnabled() const;
/**
*/
void setFilterBarVisible(bool visible);
+ /**
+ * Enables the search mode, if \p enabled is true. In the search mode the URL navigator
+ * will be hidden and replaced by a line editor that allows to enter a search term.
+ */
+ void setSearchModeEnabled(bool enabled);
+
signals:
/**
* Is emitted whenever the filter bar has changed its visibility state.
*/
void showFilterBarChanged(bool shown);
+ /**
+ * Is emitted whenever the search mode has changed its state.
+ */
+ void searchModeEnabledChanged(bool enabled);
/**
* Is emitted when the write state of the folder has been changed. The application
return false;
}
- const QStringList services = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
-
- // Don't match the service without trailing "-" (unique instance)
- const QString pattern = QStringLiteral("org.kde.dolphin-");
- // Don't match the pid without leading "-"
- const QString myPid = QStringLiteral("-") + QString::number(QCoreApplication::applicationPid());
QVector<QPair<QSharedPointer<QDBusInterface>, QStringList>> dolphinServices;
if (!preferredService.isEmpty()) {
QSharedPointer<QDBusInterface> preferred(
QStringLiteral("org.kde.dolphin.MainWindow"))
);
if (preferred->isValid() && !preferred->lastError().isValid()) {
- dolphinServices.append(qMakePair(preferred, QStringList() ));
+ dolphinServices.append(qMakePair(preferred, QStringList()));
}
}
// find all dolphin instances
+ const QStringList services = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
+ // Don't match the service without trailing "-" (unique instance)
+ const QString pattern = QStringLiteral("org.kde.dolphin-");
+ // Don't match the pid without leading "-"
+ const QString myPid = QLatin1Char('-') + QString::number(QCoreApplication::applicationPid());
for (const QString& service : services) {
if (service.startsWith(pattern) && !service.endsWith(myPid)) {
// Check if instance can handle our URLs
QStringLiteral("/dolphin/Dolphin_1"),
QStringLiteral("org.kde.dolphin.MainWindow"))
);
- if (!instance->isValid() || instance->lastError().isValid()) {
- continue;
+ if (instance->isValid() && !instance->lastError().isValid()) {
+ dolphinServices.append(qMakePair(instance, QStringList()));
}
- dolphinServices.append(qMakePair(instance, QStringList()));
}
}
for (auto& service: dolphinServices) {
QDBusReply<bool> isUrlOpen = service.first->call(QStringLiteral("isUrlOpen"), url);
if (isUrlOpen.isValid() && isUrlOpen.value()) {
- service.second.append(url);
- urlFound = true;
- break;
+ service.second.append(url);
+ urlFound = true;
+ break;
}
}
if (!urlFound) {
void KFileItemModel::slotCompleted()
{
+ m_maximumUpdateIntervalTimer->stop();
dispatchPendingItemsToInsert();
if (!m_urlsToExpand.isEmpty()) {
}
}
- if (useMaximumUpdateInterval() && !m_maximumUpdateIntervalTimer->isActive()) {
+ if (!m_maximumUpdateIntervalTimer->isActive()) {
// Assure that items get dispatched if no completed() or canceled() signal is
// emitted during the maximum update interval.
m_maximumUpdateIntervalTimer->start();
if (m_requestRole[DestinationRole]) {
QString destination = item.linkDest();
if (destination.isEmpty()) {
- destination = QStringLiteral("-");
+ destination = QLatin1Char('-');
}
data.insert(sharedValue("destination"), destination);
}
default: {
const QByteArray role = roleForType(m_sortRole);
- result = QString::compare(a->values.value(role).toString(),
- b->values.value(role).toString());
+ const QString roleValueA = a->values.value(role).toString();
+ const QString roleValueB = b->values.value(role).toString();
+ if (!roleValueA.isEmpty() && roleValueB.isEmpty()) {
+ result = -1;
+ } else if (roleValueA.isEmpty() && !roleValueB.isEmpty()) {
+ result = +1;
+ } else {
+ result = QString::compare(roleValueA, roleValueB);
+ }
break;
}
return QString::compare(a, b, Qt::CaseSensitive);
}
-bool KFileItemModel::useMaximumUpdateInterval() const
-{
- return !m_dirLister->url().isLocalFile();
-}
-
QList<QPair<int, QVariant> > KFileItemModel::nameRoleGroups() const
{
Q_ASSERT(!m_itemData.isEmpty());
if (firstChar != newFirstChar) {
QString newGroupValue;
if (newFirstChar.isLetter()) {
- // Try to find a matching group in the range 'A' to 'Z'.
- static std::vector<QChar> lettersAtoZ;
- lettersAtoZ.reserve('Z' - 'A' + 1);
- if (lettersAtoZ.empty()) {
- for (char c = 'A'; c <= 'Z'; ++c) {
- lettersAtoZ.push_back(QLatin1Char(c));
+
+ if (m_collator.compare(newFirstChar, QChar(QLatin1Char('A'))) >= 0 && m_collator.compare(newFirstChar, QChar(QLatin1Char('Z'))) <= 0) {
+ // WARNING! Symbols based on latin 'Z' like 'Z' with acute are treated wrong as non Latin and put in a new group.
+
+ // Try to find a matching group in the range 'A' to 'Z'.
+ static std::vector<QChar> lettersAtoZ;
+ lettersAtoZ.reserve('Z' - 'A' + 1);
+ if (lettersAtoZ.empty()) {
+ for (char c = 'A'; c <= 'Z'; ++c) {
+ lettersAtoZ.push_back(QLatin1Char(c));
+ }
}
- }
- auto localeAwareLessThan = [this](QChar c1, QChar c2) -> bool {
- return m_collator.compare(c1, c2) < 0;
- };
+ auto localeAwareLessThan = [this](QChar c1, QChar c2) -> bool {
+ return m_collator.compare(c1, c2) < 0;
+ };
- std::vector<QChar>::iterator it = std::lower_bound(lettersAtoZ.begin(), lettersAtoZ.end(), newFirstChar, localeAwareLessThan);
- if (it != lettersAtoZ.end()) {
- if (localeAwareLessThan(newFirstChar, *it) && it != lettersAtoZ.begin()) {
- // newFirstChar belongs to the group preceding *it.
- // Example: for an umlaut 'A' in the German locale, *it would be 'B' now.
- --it;
+ std::vector<QChar>::iterator it = std::lower_bound(lettersAtoZ.begin(), lettersAtoZ.end(), newFirstChar, localeAwareLessThan);
+ if (it != lettersAtoZ.end()) {
+ if (localeAwareLessThan(newFirstChar, *it)) {
+ // newFirstChar belongs to the group preceding *it.
+ // Example: for an umlaut 'A' in the German locale, *it would be 'B' now.
+ --it;
+ }
+ newGroupValue = *it;
}
- newGroupValue = *it;
+
} else {
+ // Symbols from non Latin-based scripts
newGroupValue = newFirstChar;
}
} else if (newFirstChar >= QLatin1Char('0') && newFirstChar <= QLatin1Char('9')) {
int stringCompare(const QString& a, const QString& b, const QCollator& collator) const;
- bool useMaximumUpdateInterval() const;
-
QList<QPair<int, QVariant> > nameRoleGroups() const;
QList<QPair<int, QVariant> > sizeRoleGroups() const;
QList<QPair<int, QVariant> > timeRoleGroups(const std::function<QDateTime(const ItemData *)> &fileTimeCb) const;
do {
QString lastTextLine = nameText.mid(line.textStart());
lastTextLine = m_customizedFontMetrics.elidedText(lastTextLine,
- Qt::ElideRight,
+ Qt::ElideMiddle,
elidingWidth);
const QString elidedText = nameText.left(line.textStart()) + lastTextLine;
nameTextInfo->staticText.setText(elidedText);
textLine.setLineWidth(maxWidth);
requiredWidth = textLine.naturalTextWidth();
if (requiredWidth > maxWidth) {
- const QString elidedText = m_customizedFontMetrics.elidedText(text, Qt::ElideRight, maxWidth);
+ const QString elidedText = m_customizedFontMetrics.elidedText(text, Qt::ElideMiddle, maxWidth);
textInfo->staticText.setText(elidedText);
requiredWidth = m_customizedFontMetrics.width(elidedText);
} else if (role == "rating") {
qreal requiredWidth = m_customizedFontMetrics.width(text);
if (requiredWidth > maxWidth) {
requiredWidth = maxWidth;
- const QString elidedText = m_customizedFontMetrics.elidedText(text, Qt::ElideRight, maxWidth);
+ const QString elidedText = m_customizedFontMetrics.elidedText(text, Qt::ElideMiddle, maxWidth);
textInfo->staticText.setText(elidedText);
}
}
if (requiredWidth > availableTextWidth) {
- text = m_customizedFontMetrics.elidedText(text, Qt::ElideRight, availableTextWidth);
+ text = m_customizedFontMetrics.elidedText(text, Qt::ElideMiddle, availableTextWidth);
requiredWidth = m_customizedFontMetrics.width(text);
}
{
static const QIcon fallbackIcon = QIcon::fromTheme(QStringLiteral("unknown"));
- int requestedSize = size;
- if (size <= KIconLoader::SizeSmall) {
- requestedSize = KIconLoader::SizeSmall;
- } else if (size <= KIconLoader::SizeSmallMedium) {
- requestedSize = KIconLoader::SizeSmallMedium;
- } else if (size <= KIconLoader::SizeMedium) {
- requestedSize = KIconLoader::SizeMedium;
- } else if (size <= KIconLoader::SizeLarge) {
- requestedSize = KIconLoader::SizeLarge;
- } else if (size <= KIconLoader::SizeHuge) {
- requestedSize = KIconLoader::SizeHuge;
- } else if (size <= KIconLoader::SizeEnormous) {
- requestedSize = KIconLoader::SizeEnormous;
- } else if (size <= KIconLoader::SizeEnormous * 2) {
- requestedSize = KIconLoader::SizeEnormous * 2;
- }
size *= qApp->devicePixelRatio();
- requestedSize *= qApp->devicePixelRatio();
- const QString key = "KStandardItemListWidget:" % name % ":" % overlays.join(QStringLiteral(":")) % ":" % QString::number(size) % ":" % QString::number(mode);
+ const QString key = "KStandardItemListWidget:" % name % ":" % overlays.join(QLatin1Char(':')) % ":" % QString::number(size) % ":" % QString::number(mode);
QPixmap pixmap;
if (!QPixmapCache::find(key, pixmap)) {
const QIcon icon = QIcon::fromTheme(name, fallbackIcon);
- pixmap = icon.pixmap(requestedSize / qApp->devicePixelRatio(), requestedSize / qApp->devicePixelRatio(), mode);
- if (requestedSize != size) {
+ pixmap = icon.pixmap(size / qApp->devicePixelRatio(), size / qApp->devicePixelRatio(), mode);
+ if (pixmap.width() != size || pixmap.height() != size) {
KPixmapModifier::scale(pixmap, QSize(size, size));
}
QCollator coll;
coll.setNumericMode(true);
std::sort(alphabeticalOrderTags.begin(), alphabeticalOrderTags.end(), [&](const QString& s1, const QString& s2){ return coll.compare(s1, s2) < 0; });
- return alphabeticalOrderTags.join(QStringLiteral(", "));
+ return alphabeticalOrderTags.join(QLatin1String(", "));
}
{
foreach (const QByteArray& role, roles) {
if (!m_columnWidths.contains(role)) {
- m_columnWidths.remove(role);
m_preferredColumnWidths.remove(role);
}
}
// Do not start a new search if the user pressed Space. Only add
// it to the search string if a search is in progress already.
- if (newSearch && keys == QLatin1String(" ")) {
+ if (newSearch && keys == QLatin1Char(' ')) {
return;
}
#include <QAction>
#include <QEvent>
+#include <QMenu>
#include <QMouseEvent>
#include <QToolBar>
if (me->button() == Qt::MiddleButton) {
QToolBar *toolBar = qobject_cast<QToolBar *>(watched);
-
- QAction *action = toolBar->actionAt(me->pos());
- if (action) {
- if (event->type() == QEvent::MouseButtonPress) {
- m_lastMiddlePressedAction = action;
- } else if (event->type() == QEvent::MouseButtonRelease) {
- if (m_lastMiddlePressedAction == action) {
- emit actionMiddleClicked(action);
+ if (toolBar) {
+ QAction *action = toolBar->actionAt(me->pos());
+ if (action) {
+ if (event->type() == QEvent::MouseButtonPress) {
+ m_lastMiddlePressedAction = action;
+ } else if (event->type() == QEvent::MouseButtonRelease) {
+ if (m_lastMiddlePressedAction == action) {
+ emit actionMiddleClicked(action);
+ }
+ m_lastMiddlePressedAction = nullptr;
+ }
+ }
+ }
+ QMenu *menu = qobject_cast<QMenu *>(watched);
+ if (menu) {
+ QAction *action = menu->actionAt(me->pos());
+ if (action) {
+ if (event->type() == QEvent::MouseButtonPress) {
+ m_lastMiddlePressedAction = action;
+ } else if (event->type() == QEvent::MouseButtonRelease) {
+ if (m_lastMiddlePressedAction == action) {
+ emit actionMiddleClicked(action);
+ return true;
+ }
+ m_lastMiddlePressedAction = nullptr;
}
- m_lastMiddlePressedAction = nullptr;
}
}
}
GenericName[it]=Gestore dei file
GenericName[ja]=ファイルマネージャ
GenericName[ko]=파일 관리자
-GenericName[lt]=Failų tvarkyklė
+GenericName[lt]=Failų tvarkytuvė
GenericName[ml]=ഫയല് മാനേജര്
GenericName[nb]=Filbehandler
GenericName[nl]=Bestandsbeheerder
bool FoldersPanel::urlChanged()
{
- if (!url().isValid() || url().scheme().contains(QStringLiteral("search"))) {
+ if (!url().isValid() || url().scheme().contains(QLatin1String("search"))) {
// Skip results shown by a search, as possible identical
// directory names are useless without parent-path information.
return false;
if (role == "text") {
const KFileItem item = m_model->fileItem(index);
const QString newName = value.toString();
- if (!newName.isEmpty() && newName != item.text() && newName != QLatin1String(".") && newName != QLatin1String("..")) {
+ if (!newName.isEmpty() && newName != item.text() && newName != QLatin1Char('.') && newName != QLatin1String("..")) {
const QUrl oldUrl = item.url();
QUrl newUrl = oldUrl.adjusted(QUrl::RemoveFilename);
newUrl.setPath(newUrl.path() + KIO::encodeFileName(newName));
#include <QTimer>
#include <QVBoxLayout>
#include <QStyle>
+#include <QPainter>
+#include <QBitmap>
+#include <QLinearGradient>
+#include <QPolygon>
#include "dolphin_informationpanelsettings.h"
#include "phononwidget.h"
#include "pixmapviewer.h"
+const int PLAY_ARROW_SIZE = 24;
+const int PLAY_ARROW_BORDER_SIZE = 2;
+
InformationPanelContent::InformationPanelContent(QWidget* parent) :
QWidget(parent),
m_item(),
m_nameLabel(nullptr),
m_metaDataWidget(nullptr),
m_metaDataArea(nullptr),
- m_placesItemModel(nullptr)
+ m_placesItemModel(nullptr),
+ m_isVideo(false)
{
parent->installEventFilter(this);
if (item != m_item) {
m_item = item;
+ m_preview->stopAnimatedImage();
refreshMetaData();
}
refreshPreview();
}
+void InformationPanelContent::refreshPixmapView()
+{
+ // If there is a preview job, kill it to prevent that we have jobs for
+ // multiple items running, and thus a race condition (bug 250787).
+ if (m_previewJob) {
+ m_previewJob->kill();
+ }
+
+ // 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 (!m_item.isDir()) {
+ m_outdatedPreviewTimer->start();
+ }
+
+ QStringList plugins = KIO::PreviewJob::availablePlugins();
+ m_previewJob = new KIO::PreviewJob(KFileItemList() << m_item,
+ QSize(m_preview->width(), m_preview->height()),
+ &plugins);
+ m_previewJob->setScaleType(KIO::PreviewJob::Unscaled);
+ m_previewJob->setIgnoreMaximumSize(m_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);
+}
+
void InformationPanelContent::refreshPreview()
{
// If there is a preview job, kill it to prevent that we have jobs for
m_previewJob->kill();
}
+ m_preview->setCursor(Qt::ArrowCursor);
+ bool usePhonon = false;
setNameLabelText(m_item.text());
if (InformationPanelSettings::previewsShown()) {
const QUrl itemUrl = m_item.url();
- const bool isSearchUrl = itemUrl.scheme().contains(QStringLiteral("search")) && m_item.localPath().isEmpty();
+ const bool isSearchUrl = itemUrl.scheme().contains(QLatin1String("search")) && m_item.localPath().isEmpty();
if (isSearchUrl) {
m_preview->show();
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 (!m_item.isDir()) {
- m_outdatedPreviewTimer->start();
- }
-
- QStringList plugins = KIO::PreviewJob::availablePlugins();
- m_previewJob = new KIO::PreviewJob(KFileItemList() << m_item,
- QSize(m_preview->width(), m_preview->height()),
- &plugins);
- m_previewJob->setScaleType(KIO::PreviewJob::Unscaled);
- m_previewJob->setIgnoreMaximumSize(m_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);
+ refreshPixmapView();
const QString mimeType = m_item.mimetype();
- const bool isVideo = mimeType.startsWith(QLatin1String("video/"));
- const bool usePhonon = mimeType.startsWith(QLatin1String("audio/")) || isVideo;
+ const bool isAnimatedImage = m_preview->isAnimatedImage(itemUrl.toLocalFile());
+ m_isVideo = !isAnimatedImage && mimeType.startsWith(QLatin1String("video/"));
+ usePhonon = m_isVideo || mimeType.startsWith(QLatin1String("audio/"));
if (usePhonon) {
-
- if (InformationPanelSettings::previewsAutoPlay() && isVideo) {
- // hides the preview now to avoid flickering when the autoplay video starts
- m_preview->hide();
- } else {
- // the video won't play before the preview is displayed
- m_preview->show();
+ // change the cursor of the preview
+ m_preview->setCursor(Qt::PointingHandCursor);
+ m_preview->installEventFilter(m_phononWidget);
+
+ // if the video is playing, has been paused or stopped
+ // we don't need to update the preview/phonon widget states
+ // unless the previewed file has changed,
+ // or the setting previewshown has changed
+ if ((m_phononWidget->state() != Phonon::State::PlayingState &&
+ m_phononWidget->state() != Phonon::State::PausedState &&
+ m_phononWidget->state() != Phonon::State::StoppedState) ||
+ m_item.targetUrl() != m_phononWidget->url() ||
+ (!m_preview->isVisible() &&! m_phononWidget->isVisible())) {
+
+ if (InformationPanelSettings::previewsAutoPlay() && m_isVideo) {
+ // hides the preview now to avoid flickering when the autoplay video starts
+ m_preview->hide();
+ } else {
+ // the video won't play before the preview is displayed
+ m_preview->show();
+ }
+
+ m_phononWidget->show();
+ m_phononWidget->setUrl(m_item.targetUrl(), m_isVideo ? PhononWidget::MediaKind::Video : PhononWidget::MediaKind::Audio);
+ adjustWidgetSizes(parentWidget()->width());
}
-
- m_phononWidget->show();
- m_phononWidget->setUrl(m_item.targetUrl(), isVideo ? PhononWidget::MediaKind::Video : PhononWidget::MediaKind::Audio);
- m_phononWidget->setVideoSize(m_preview->size());
} else {
+ if (isAnimatedImage) {
+ m_preview->setAnimatedImageFileName(itemUrl.toLocalFile());
+ }
// When we don't need it, hide the phonon widget first to avoid flickering
m_phononWidget->hide();
m_preview->show();
+ m_preview->removeEventFilter(m_phononWidget);
+ m_phononWidget->clearUrl();
}
}
} else {
+ m_preview->stopAnimatedImage();
m_preview->hide();
m_phononWidget->hide();
}
m_previewJob->kill();
}
+ m_preview->stopAnimatedImage();
+
m_preview->setPixmap(
QIcon::fromTheme(QStringLiteral("dialog-information")).pixmap(KIconLoader::SizeEnormous, KIconLoader::SizeEnormous)
);
const QPixmap& pixmap)
{
m_outdatedPreviewTimer->stop();
- Q_UNUSED(item);
QPixmap p = pixmap;
KIconLoader::global()->drawOverlays(item.overlays(), p, KIconLoader::Desktop);
+
+ if (m_isVideo) {
+ // adds a play arrow
+
+ // compute relative pixel positions
+ const int zeroX = static_cast<int>(p.width() / 2 - PLAY_ARROW_SIZE / 2 / devicePixelRatio());
+ const int zeroY = static_cast<int>(p.height() / 2 - PLAY_ARROW_SIZE / 2 / devicePixelRatio());
+
+ QPolygon arrow;
+ arrow << QPoint(zeroX, zeroY);
+ arrow << QPoint(zeroX, zeroY + PLAY_ARROW_SIZE);
+ arrow << QPoint(zeroX + PLAY_ARROW_SIZE, zeroY + PLAY_ARROW_SIZE / 2);
+
+ QPainterPath path;
+ path.addPolygon(arrow);
+
+ QLinearGradient gradient(QPointF(zeroX, zeroY),
+ QPointF(zeroX + PLAY_ARROW_SIZE,zeroY + PLAY_ARROW_SIZE));
+
+ QColor whiteColor = Qt::white;
+ QColor blackColor = Qt::black;
+ gradient.setColorAt(0, whiteColor);
+ gradient.setColorAt(1, blackColor);
+
+ QBrush brush(gradient);
+
+ QPainter painter(&p);
+
+ QPen pen(blackColor, PLAY_ARROW_BORDER_SIZE, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
+ painter.setPen(pen);
+
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.drawPolygon(arrow);
+ painter.fillPath(path, brush);
+ }
+
m_preview->setPixmap(p);
}
void InformationPanelContent::slotHasVideoChanged(bool hasVideo)
{
m_preview->setVisible(InformationPanelSettings::previewsShown() && !hasVideo);
+ if (m_preview->isVisible() && m_preview->size().width() != m_preview->pixmap().size().width()) {
+ // in case the information panel has been resized when the preview was not displayed
+ // we need to refresh its content
+ refreshPixmapView();
+ }
}
void InformationPanelContent::setPreviewAutoPlay(bool autoPlay) {
*/
void adjustWidgetSizes(int width);
+ /**
+ * Refreshes the image in the PixmapViewer
+ */
+ void refreshPixmapView();
+
private:
KFileItem m_item;
QDialogButtonBox* m_configureButtons;
PlacesItemModel* m_placesItemModel;
+ bool m_isVideo;
};
#endif // INFORMATIONPANELCONTENT_H
: QWidget(parent),
m_url(),
m_playButton(nullptr),
- m_stopButton(nullptr),
+ m_pauseButton(nullptr),
m_topLayout(nullptr),
m_media(nullptr),
m_seekSlider(nullptr),
return m_url;
}
+void PhononWidget::clearUrl()
+{
+ m_url.clear();
+}
+
+void PhononWidget::togglePlayback()
+{
+ if (m_media && m_media->state() == Phonon::State::PlayingState) {
+ m_media->pause();
+ } else {
+ play();
+ }
+}
+
+bool PhononWidget::eventFilter(QObject *object, QEvent *event)
+{
+ Q_UNUSED(object)
+ if (event->type() == QEvent::MouseButtonPress) {
+ const QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+ if (mouseEvent->button() == Qt::LeftButton) {
+ // toggle playback
+ togglePlayback();
+ return true;
+ }
+ }
+ return false;
+}
+
void PhononWidget::setVideoSize(const QSize& size)
{
if (m_videoSize != size) {
controlsLayout->setSpacing(0);
m_playButton = new QToolButton(this);
- m_stopButton = new QToolButton(this);
+ m_pauseButton = new QToolButton(this);
m_seekSlider = new Phonon::SeekSlider(this);
controlsLayout->addWidget(m_playButton);
- controlsLayout->addWidget(m_stopButton);
+ controlsLayout->addWidget(m_pauseButton);
controlsLayout->addWidget(m_seekSlider);
m_topLayout->addLayout(controlsLayout);
m_playButton->setAutoRaise(true);
connect(m_playButton, &QToolButton::clicked, this, &PhononWidget::play);
- m_stopButton->setToolTip(i18n("stop"));
- m_stopButton->setIconSize(buttonSize);
- m_stopButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-stop")));
- m_stopButton->setAutoRaise(true);
- m_stopButton->hide();
- connect(m_stopButton, &QToolButton::clicked, this, &PhononWidget::stop);
+ m_pauseButton->setToolTip(i18n("pause"));
+ m_pauseButton->setIconSize(buttonSize);
+ m_pauseButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause")));
+ m_pauseButton->setAutoRaise(true);
+ m_pauseButton->hide();
+ connect(m_pauseButton, &QToolButton::clicked, this, &PhononWidget::togglePlayback);
m_seekSlider->setIconVisible(false);
switch (newstate) {
case Phonon::PlayingState:
case Phonon::BufferingState:
- m_stopButton->show();
m_playButton->hide();
+ m_pauseButton->show();
break;
default:
- m_stopButton->hide();
+ m_pauseButton->hide();
m_playButton->show();
break;
}
if (!m_videoPlayer) {
m_videoPlayer = new EmbeddedVideoPlayer(this);
+ m_videoPlayer->setCursor(Qt::PointingHandCursor);
m_videoPlayer->installEventFilter(this);
m_topLayout->insertWidget(0, m_videoPlayer);
Phonon::createPath(m_media, m_videoPlayer);
}
}
+Phonon::State PhononWidget::state() const
+{
+ return m_media == nullptr ? Phonon::State::StoppedState : m_media->state();
+}
+
void PhononWidget::stop()
{
if (m_media) {
void setUrl(const QUrl &url, MediaKind kind);
QUrl url() const;
+ void clearUrl();
void setVideoSize(const QSize& size);
QSize videoSize() const;
+ Phonon::State state() const;
void setAutoPlay(bool autoPlay);
+ bool eventFilter(QObject *object, QEvent *event) override;
signals:
/**
void applyVideoSize();
private:
+ void togglePlayback();
+
QUrl m_url;
QSize m_videoSize;
QToolButton *m_playButton;
- QToolButton *m_stopButton;
+ QToolButton *m_pauseButton;
QVBoxLayout *m_topLayout;
Phonon::MediaObject *m_media;
#include <KIconLoader>
+#include <QImageReader>
+#include <QMovie>
#include <QPainter>
#include <QStyle>
PixmapViewer::PixmapViewer(QWidget* parent, Transition transition) :
QWidget(parent),
+ m_animatedImage(nullptr),
m_transition(transition),
m_animationStep(0),
- m_sizeHint()
+ m_sizeHint(),
+ m_hasAnimatedImage(false)
{
setMinimumWidth(KIconLoader::SizeEnormous);
setMinimumHeight(KIconLoader::SizeEnormous);
return;
}
+ // Avoid flicker with static pixmap if an animated image is running
+ if (m_animatedImage && m_animatedImage->state() == QMovie::Running) {
+ return;
+ }
+
if ((m_transition != NoTransition) && (m_animation.state() == QTimeLine::Running)) {
m_pendingPixmaps.enqueue(pixmap);
if (m_pendingPixmaps.count() > 5) {
m_pixmap = pixmap;
update();
- const bool animate = (m_transition != NoTransition) &&
- (m_pixmap.size() != m_oldPixmap.size());
- if (animate) {
+ const bool animateTransition = (m_transition != NoTransition) &&
+ (m_pixmap.size() != m_oldPixmap.size());
+ if (animateTransition) {
m_animation.start();
+ } else if (m_hasAnimatedImage) {
+ // If there is no transition animation but an animatedImage
+ // and it is not already running, start animating now
+ if (m_animatedImage->state() != QMovie::Running) {
+ m_animatedImage->setScaledSize(m_pixmap.size());
+ m_animatedImage->start();
+ }
}
}
void PixmapViewer::setSizeHint(const QSize& size)
{
+ if (m_animatedImage && size != m_sizeHint) {
+ m_animatedImage->stop();
+ }
+
m_sizeHint = size;
updateGeometry();
}
return m_sizeHint;
}
+void PixmapViewer::setAnimatedImageFileName(const QString &fileName)
+{
+ if (!m_animatedImage) {
+ m_animatedImage = new QMovie(this);
+ connect(m_animatedImage, &QMovie::frameChanged, this, &PixmapViewer::updateAnimatedImageFrame);
+ }
+
+ if (m_animatedImage->fileName() != fileName) {
+ m_animatedImage->stop();
+ m_animatedImage->setFileName(fileName);
+ }
+
+ m_hasAnimatedImage = m_animatedImage->isValid() && (m_animatedImage->frameCount() > 1);
+}
+
+
+QString PixmapViewer::animatedImageFileName() const
+{
+ if (!m_hasAnimatedImage) {
+ return QString();
+ }
+ return m_animatedImage->fileName();
+}
+
void PixmapViewer::paintEvent(QPaintEvent* event)
{
QWidget::paintEvent(event);
QPainter painter(this);
- if (m_transition != NoTransition) {
+ if (m_transition != NoTransition || (m_hasAnimatedImage && m_animatedImage->state() != QMovie::Running)) {
const float value = m_animation.currentValue();
const int scaledWidth = static_cast<int>((m_oldPixmap.width() * (1.0 - value)) + (m_pixmap.width() * value));
const int scaledHeight = static_cast<int>((m_oldPixmap.height() * (1.0 - value)) + (m_pixmap.height() * value));
m_pixmap = pixmap;
update();
m_animation.start();
+ } else if (m_hasAnimatedImage) {
+ m_animatedImage->setScaledSize(m_pixmap.size());
+ m_animatedImage->start();
} else {
m_oldPixmap = m_pixmap;
}
}
+void PixmapViewer::updateAnimatedImageFrame()
+{
+ Q_ASSERT (m_animatedImage);
+
+ m_pixmap = m_animatedImage->currentPixmap();
+ update();
+}
+
+void PixmapViewer::stopAnimatedImage()
+{
+ if (m_hasAnimatedImage) {
+ m_animatedImage->stop();
+ m_hasAnimatedImage = false;
+ }
+}
+
+bool PixmapViewer::isAnimatedImage(const QString &fileName)
+{
+ const QByteArray imageFormat = QImageReader::imageFormat(fileName);
+ return !imageFormat.isEmpty() && QMovie::supportedFormats().contains(imageFormat);
+}
#include <QWidget>
class QPaintEvent;
+class QMovie;
/**
* @brief Widget which shows a pixmap centered inside the boundaries.
void setSizeHint(const QSize& size);
QSize sizeHint() const override;
+ void setAnimatedImageFileName(const QString& fileName);
+ QString animatedImageFileName() const;
+
+ void stopAnimatedImage();
+
+ /**
+ * Checks if \a fileName contains an animated image supported by QMovie.
+ */
+ static bool isAnimatedImage(const QString &fileName);
+
protected:
void paintEvent(QPaintEvent* event) override;
private Q_SLOTS:
void checkPendingPixmaps();
+ void updateAnimatedImageFrame();
private:
QPixmap m_pixmap;
QPixmap m_oldPixmap;
+ QMovie* m_animatedImage;
QQueue<QPixmap> m_pendingPixmaps;
QTimeLine m_animation;
Transition m_transition;
int m_animationStep;
QSize m_sizeHint;
+ bool m_hasAnimatedImage;
};
inline QPixmap PixmapViewer::pixmap() const
bool PlacesPanel::urlChanged()
{
- if (!url().isValid() || url().scheme().contains(QStringLiteral("search"))) {
+ if (!url().isValid() || url().scheme().contains(QLatin1String("search"))) {
// Skip results shown by a search, as possible identical
// directory names are useless without parent-path information.
return false;
removeAction = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18nc("@item:inmenu", "Remove"));
}
- QAction* hideAction = menu.addAction(QIcon::fromTheme(QStringLiteral("hint")), i18nc("@item:inmenu", "Hide"));
+ QAction* hideAction = menu.addAction(QIcon::fromTheme(QStringLiteral("view-hidden")), i18nc("@item:inmenu", "Hide"));
hideAction->setCheckable(true);
hideAction->setChecked(item->isHidden());
QAction* showAllAction = menu.addAction(i18nc("@item:inmenu", "Show Hidden Places"));
showAllAction->setCheckable(true);
showAllAction->setChecked(m_model->hiddenItemsShown());
- showAllAction->setIcon(QIcon::fromTheme(m_model->hiddenItemsShown() ? QStringLiteral("visibility") : QStringLiteral("hint")));
+ showAllAction->setIcon(QIcon::fromTheme(m_model->hiddenItemsShown() ? QStringLiteral("view-visible") : QStringLiteral("view-hidden")));
showAllAction->setEnabled(m_model->hiddenCount());
buildGroupContextMenu(&menu, m_controller->indexCloseToMousePressedPosition());
}
KFilePlacesModel::GroupType groupType = m_model->groupType(index);
- QAction *hideGroupAction = menu->addAction(QIcon::fromTheme(QStringLiteral("hint")), i18nc("@item:inmenu", "Hide Section '%1'", m_model->item(index)->group()));
+ QAction *hideGroupAction = menu->addAction(QIcon::fromTheme(QStringLiteral("view-hidden")), i18nc("@item:inmenu", "Hide Section '%1'", m_model->item(index)->group()));
hideGroupAction->setCheckable(true);
hideGroupAction->setChecked(m_model->isGroupHidden(groupType));
bool TerminalPanel::isHiddenInVisibleWindow() const
{
return parentWidget()
- && parentWidget()->isHidden()
- && m_terminal
- && !hasProgramRunning();
+ && parentWidget()->isHidden();
}
void TerminalPanel::dockVisibilityChanged()
{
// Only react when the DockWidget itself (not some parent) is hidden. This way we don't
// respond when e.g. Dolphin is minimized.
- if (isHiddenInVisibleWindow()) {
+ if (isHiddenInVisibleWindow() && m_terminal && !hasProgramRunning()) {
// Make sure that the following "cd /" command will not affect the view.
disconnect(m_konsolePart, SIGNAL(currentDirectoryChanged(QString)),
this, SLOT(slotKonsolePartCurrentDirectoryChanged(QString)));
terms << QStringLiteral("modified>=%1").arg(date.toString(Qt::ISODate));
}
- return terms.join(QStringLiteral(" AND "));
+ return terms.join(QLatin1String(" AND "));
}
QString DolphinFacetsWidget::facetType() const
query.setIncludeFolder(m_searchPath.toLocalFile());
}
- query.setSearchString(queryStrings.join(QStringLiteral(" ")));
+ query.setSearchString(queryStrings.join(QLatin1Char(' ')));
return query.toSearchUrl(i18nc("@title UDS_DISPLAY_NAME for a KIO directory listing. %1 is the query the user entered.",
"Query Results from '%1'", text));
{
foreach (const KIO::UDSEntry& entry, list) {
const QString name = entry.stringValue(KIO::UDSEntry::UDS_NAME);
- if (name != QLatin1String(".") && name != QLatin1String("..") && entry.isDir()) {
+ if (name != QLatin1Char('.') && name != QLatin1String("..") && entry.isDir()) {
++m_progress;
QUrl url(m_dir);
GeneralSettingsPage* generalSettingsPage = new GeneralSettingsPage(url, this);
KPageWidgetItem* generalSettingsFrame = addPage(generalSettingsPage,
i18nc("@title:group General settings", "General"));
- generalSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("view-preview")));
+ generalSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("system-file-manager")));
connect(generalSettingsPage, &GeneralSettingsPage::changed, this, &DolphinSettingsDialog::enableApply);
// Startup
StartupSettingsPage* startupSettingsPage = new StartupSettingsPage(url, this);
KPageWidgetItem* startupSettingsFrame = addPage(startupSettingsPage,
i18nc("@title:group", "Startup"));
- startupSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("go-home")));
+ startupSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-launch-feedback")));
connect(startupSettingsPage, &StartupSettingsPage::changed, this, &DolphinSettingsDialog::enableApply);
// View Modes
ViewSettingsPage* viewSettingsPage = new ViewSettingsPage(this);
KPageWidgetItem* viewSettingsFrame = addPage(viewSettingsPage,
i18nc("@title:group", "View Modes"));
- viewSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("view-choose")));
+ viewSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-icons")));
connect(viewSettingsPage, &ViewSettingsPage::changed, this, &DolphinSettingsDialog::enableApply);
// Navigation
NavigationSettingsPage* navigationSettingsPage = new NavigationSettingsPage(this);
KPageWidgetItem* navigationSettingsFrame = addPage(navigationSettingsPage,
i18nc("@title:group", "Navigation"));
- navigationSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("edit-select")));
+ navigationSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-navigation")));
connect(navigationSettingsPage, &NavigationSettingsPage::changed, this, &DolphinSettingsDialog::enableApply);
// Services
ServicesSettingsPage* servicesSettingsPage = new ServicesSettingsPage(this);
KPageWidgetItem* servicesSettingsFrame = addPage(servicesSettingsPage,
i18nc("@title:group", "Services"));
- servicesSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("flag")));
+ servicesSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("preferences-system-services")));
connect(servicesSettingsPage, &ServicesSettingsPage::changed, this, &DolphinSettingsDialog::enableApply);
// Trash
if (trashSettingsPage) {
KPageWidgetItem* trashSettingsFrame = addPage(trashSettingsPage,
i18nc("@title:group", "Trash"));
- trashSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("trash-empty")));
+ trashSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("user-trash")));
connect(trashSettingsPage, &TrashSettingsPage::changed, this, &DolphinSettingsDialog::enableApply);
}
// View properties
m_globalViewProps = new QRadioButton(i18nc("@option:radio", "Use common properties for all folders"));
m_localViewProps = new QRadioButton(i18nc("@option:radio", "Remember properties for each folder"));
- m_localViewProps->setToolTip(i18nc("@info", "Dolphin will create an hidden .directory file in each folder you change view properties for."));
+ m_localViewProps->setToolTip(i18nc("@info", "Dolphin will create a hidden .directory file in each folder you change view properties for."));
QButtonGroup* viewGroup = new QButtonGroup(this);
viewGroup->addButton(m_globalViewProps);
#include <KLocalizedString>
#include <QCheckBox>
+#include <QComboBox>
#include <QLabel>
+#include <QHBoxLayout>
#include <QVBoxLayout>
namespace {
+ enum ScriptExecution
+ {
+ AlwaysAsk = 0,
+ Open = 1,
+ Execute = 2
+ };
+
const bool ConfirmEmptyTrash = true;
const bool ConfirmTrash = false;
const bool ConfirmDelete = true;
- const bool ConfirmScriptExecution = true;
+ const int ConfirmScriptExecution = ScriptExecution::AlwaysAsk;
}
ConfirmationsSettingsPage::ConfirmationsSettingsPage(QWidget* parent) :
"Emptying trash"), this);
m_confirmDelete = new QCheckBox(i18nc("@option:check Ask for confirmation when",
"Deleting files or folders"), this);
- m_confirmScriptExecution = new QCheckBox(i18nc("@option:check Ask for confirmation when",
- "Executing scripts or desktop files"), this);
QLabel* confirmLabelDolphin = new QLabel(i18nc("@title:group", "Ask for confirmation in Dolphin when:"), this);
confirmLabelDolphin->setWordWrap(true);
"Closing windows with a program running in the Terminal panel"), this);
#endif
+ QHBoxLayout* executableScriptLayout = new QHBoxLayout();
+ QLabel* executableScriptLabel = new QLabel(i18nc("@title:group", "When opening an executable file:"), this);
+ confirmLabelKde->setWordWrap(true);
+ executableScriptLayout->addWidget(executableScriptLabel);
+
+ m_confirmScriptExecution = new QComboBox(this);
+ m_confirmScriptExecution->addItems({i18n("Always ask"), i18n("Open in application"), i18n("Run script")});
+ executableScriptLayout->addWidget(m_confirmScriptExecution);
+
topLayout->addWidget(confirmLabelKde);
topLayout->addWidget(m_confirmMoveToTrash);
topLayout->addWidget(m_confirmEmptyTrash);
topLayout->addWidget(m_confirmDelete);
- topLayout->addWidget(m_confirmScriptExecution);
topLayout->addSpacing(Dolphin::VERTICAL_SPACER_HEIGHT);
topLayout->addWidget(confirmLabelDolphin);
topLayout->addWidget(m_confirmClosingMultipleTabs);
topLayout->addWidget(m_confirmClosingTerminalRunningProgram);
#endif
+ topLayout->addSpacing(Dolphin::VERTICAL_SPACER_HEIGHT);
+ topLayout->addLayout(executableScriptLayout);
+
topLayout->addStretch();
loadSettings();
connect(m_confirmMoveToTrash, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
connect(m_confirmEmptyTrash, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
connect(m_confirmDelete, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
- connect(m_confirmScriptExecution, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
+ connect(m_confirmScriptExecution, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ConfirmationsSettingsPage::changed);
connect(m_confirmClosingMultipleTabs, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
#ifdef HAVE_TERMINAL
confirmationGroup.writeEntry("ConfirmDelete", m_confirmDelete->isChecked());
KConfigGroup scriptExecutionGroup(kioConfig, "Executable scripts");
- if (m_confirmScriptExecution->isChecked()) {
+ const int index = m_confirmScriptExecution->currentIndex();
+ switch (index) {
+ case ScriptExecution::AlwaysAsk:
scriptExecutionGroup.writeEntry("behaviourOnLaunch", "alwaysAsk");
- } else {
+ break;
+ case ScriptExecution::Open:
scriptExecutionGroup.writeEntry("behaviourOnLaunch", "dontAsk");
+ break;
+ case ScriptExecution::Execute:
+ scriptExecutionGroup.writeEntry("behaviourOnLaunch", "execute");
+ break;
}
kioConfig->sync();
m_confirmMoveToTrash->setChecked(ConfirmTrash);
m_confirmEmptyTrash->setChecked(ConfirmEmptyTrash);
m_confirmDelete->setChecked(ConfirmDelete);
- m_confirmScriptExecution->setChecked(ConfirmScriptExecution);
+ m_confirmScriptExecution->setCurrentIndex(ConfirmScriptExecution);
}
void ConfirmationsSettingsPage::loadSettings()
const KConfigGroup scriptExecutionGroup(KSharedConfig::openConfig(QStringLiteral("kiorc")), "Executable scripts");
const QString value = scriptExecutionGroup.readEntry("behaviourOnLaunch", "alwaysAsk");
- m_confirmScriptExecution->setChecked(value == QLatin1String("alwaysAsk"));
+ if (value == QLatin1String("dontAsk")) {
+ m_confirmScriptExecution->setCurrentIndex(ScriptExecution::Open);
+ } else if (value == QLatin1String("execute")) {
+ m_confirmScriptExecution->setCurrentIndex(ScriptExecution::Execute);
+ } else /* if (value == QLatin1String("alwaysAsk"))*/ {
+ m_confirmScriptExecution->setCurrentIndex(ScriptExecution::AlwaysAsk);
+ }
m_confirmClosingMultipleTabs->setChecked(GeneralSettings::confirmClosingMultipleTabs());
#include "settings/settingspagebase.h"
class QCheckBox;
+class QComboBox;
/**
* @brief Page for the enabling or disabling confirmation dialogs.
#endif
QCheckBox* m_confirmClosingMultipleTabs;
- QCheckBox* m_confirmScriptExecution;
+ QComboBox* m_confirmScriptExecution;
};
#endif
Name[it]=Impostazioni generali di Dolphin
Name[ja]=Dolphin 全般
Name[ko]=Dolphin 일반
-Name[lt]=Dolphin bendrieji
+Name[lt]=Dolphin bendrosios
Name[ml]=പൊതു സജ്ജീകരണങ്ങള്
Name[nb]=Dolphin generelt
Name[nl]=Dolphin algemeen
Comment[it]=Questo servizio permette di configurare le impostazioni generali di Dolphin.
Comment[ja]=Dolphin の全般的な設定を行います
Comment[ko]=이 서비스는 일반 Dolphin 설정을 담당합니다.
-Comment[lt]=Ši tarnyba leidžia konfigūruoti Dolphin bendrąsias nuostatas.
+Comment[lt]=Ši paslauga leidžia bendrųjų Dolphin nuostatų konfigūravimą.
Comment[ml]=പൊതുവായ ഡോള്ഫിന് സജ്ജീകരണങ്ങള് ക്രമീകരിയ്ക്കാന് ഈ സേവനം അനുവദിക്കുന്നു.
Comment[nb]=Med denne tjenesten kan du sette opp generelle innstillinger for Dolphin.
Comment[nl]=Met deze dienst kunt u algemene Dolphin-instellingen configureren.
Comment[zh_TW]=此服務允許設定 Dolphin 的一般設定。
[Desktop Entry]
-Icon=system-run
+Icon=system-file-manager
Type=Service
X-KDE-ServiceTypes=KCModule
Exec=kcmshell5 kcmdolphingeneral
Name[it]=Generale
Name[ja]=全般
Name[ko]=일반
-Name[lt]=Bendra
+Name[lt]=Bendrosios
Name[ml]=പൊതുവായതു്
Name[nb]=Generelt
Name[nl]=Algemeen
Comment[it]=Configura le impostazioni generali del gestore dei file
Comment[ja]=ファイルマネージャの全般的な設定を行います
Comment[ko]=일반 파일 관리자 설정
-Comment[lt]=Bendrųjų failų tvarkyklės nuostatų konfigūravimas
+Comment[lt]=Konfigūruoti bendras failų tvarkytuvės nuostatas
Comment[ml]=ഫയൽ മാനേജറിന്റെ പൊതുവായ സജ്ജീകരണങ്ങള് ക്രമീകരിയ്ക്കുക
Comment[nb]=Sett opp generelle innstillinger for filbehandleren
Comment[nl]=Algemene bestandsbeheerderinstellingen configureren
X-KDE-Keywords[it]=gestore dei file
X-KDE-Keywords[ja]=ファイルマネージャ
X-KDE-Keywords[ko]=파일 관리자
-X-KDE-Keywords[lt]=Failų tvarkyklė
+X-KDE-Keywords[lt]=failų tvarkytuvė
X-KDE-Keywords[ml]=ഫയൽ മാനേജർ
X-KDE-Keywords[nb]=filbehandler
X-KDE-Keywords[nl]=bestandsbeheerder
Name[it]=Navigazione di Dolphin
Name[ja]=Dolphin ナビゲーション
Name[ko]=Dolphin 탐색
-Name[lt]=Dolphin navigacija
+Name[lt]=Dolphin naršymas
Name[ml]=ഡോള്ഫിന് നാവിഗേഷന്
Name[nb]=Navigasjon i Dolphin
Name[nl]=Dolphin-navigatie
Comment[it]=Questo servizio permette di configurare la navigazione con Dolphin.
Comment[ja]=Dolphin でのナビゲーションを設定します
Comment[ko]=이 서비스는 Dolphin 탐색을 설정합니다.
-Comment[lt]=Ši tarnyba leidžia konfigūruoti Dolphin navigaciją.
+Comment[lt]=Ši paslauga leidžia Dolphin naršymo konfigūravimą.
Comment[ml]=ഡോള്ഫിന് നാവിഗേഷൻ ക്രമീകരിയ്ക്കാന് ഈ സേവനം അനുവദിയ്ക്കുന്നു.
Comment[nb]=Med denne tjenesten kan du sette opp navigasjon for Dolphin.
Comment[nl]=Met deze dienst kunt u Dolphin-navigatie configureren.
Comment[zh_TW]=此服務允許設定 Dolphin 的導覽。
[Desktop Entry]
-Icon=input-mouse
+Icon=preferences-desktop-navigation
Type=Service
X-KDE-ServiceTypes=KCModule
Exec=kcmshell5 kcmdolphinnavigation
Name[it]=Navigazione
Name[ja]=ナビゲーション
Name[ko]=탐색
-Name[lt]=Navigacija
+Name[lt]=Naršymas
Name[ml]=നാവിഗേഷന്
Name[nb]=Navigasjon
Name[nl]=Navigatie
Comment[it]=Configura la navigazione col gestore dei file
Comment[ja]=ファイルマネージャでのナビゲーションを設定します
Comment[ko]=파일 관리자 탐색 설정
-Comment[lt]=Konfigūruokite failų tvarkyklės navigaciją
+Comment[lt]=Konfigūruoti failų tvarkytuvės naršymą
Comment[ml]=ഫയല് മാനേജർ നാവിഗേഷൻ ക്രമീകരിയ്ക്കുക
Comment[nb]=Sett opp navigasjon i filbehandleren
Comment[nl]=Bestandsbeheerdernavigatie configureren
X-KDE-Keywords[it]=gestore dei file
X-KDE-Keywords[ja]=ファイルマネージャ
X-KDE-Keywords[ko]=파일 관리자
-X-KDE-Keywords[lt]=Failų tvarkyklė
+X-KDE-Keywords[lt]=failų tvarkytuvė
X-KDE-Keywords[ml]=ഫയൽ മാനേജർ
X-KDE-Keywords[nb]=filbehandler
X-KDE-Keywords[nl]=bestandsbeheerder
Name[it]=Servizi di Dolphin
Name[ja]=Dolphin サービス
Name[ko]=Dolphin 서비스
-Name[lt]=Dolphin tarnybos
+Name[lt]=Dolphin paslaugos
Name[ml]=ഡോള്ഫിന് സേവനങ്ങള്
Name[nb]=Dolphin-tjenester
Name[nl]=Dolphin-services
Name[zh_TW]=Dolphin 服務
[Desktop Entry]
-Icon=services
+Icon=preferences-system-services
Type=Service
X-KDE-ServiceTypes=KCModule
Exec=kcmshell5 kcmdolphinservices
Comment[it]=Configura i servizi del gestore dei file
Comment[ja]=ファイルマネージャのサービスを設定します
Comment[ko]=파일 관리자 서비스 설정
-Comment[lt]=Konfigūruokite failų tvarkyklės tarnybas
+Comment[lt]=Konfigūruoti failų tvarkytuvės paslaugas
Comment[ml]=ഫയല് മാനേജർ സേവനങ്ങള് ക്രമീകരിയ്ക്കുക
Comment[nb]=Sett opp tjenester i filbehandleren
Comment[nl]=Bestandsbeheerderservices configureren
X-KDE-Keywords[it]=gestore dei file
X-KDE-Keywords[ja]=ファイルマネージャ
X-KDE-Keywords[ko]=파일 관리자
-X-KDE-Keywords[lt]=Failų tvarkyklė
+X-KDE-Keywords[lt]=failų tvarkytuvė
X-KDE-Keywords[ml]=ഫയൽ മാനേജർ
X-KDE-Keywords[nb]=filbehandler
X-KDE-Keywords[nl]=bestandsbeheerder
Name[it]=Viste di Dolphin
Name[ja]=Dolphin 表示モード
Name[ko]=Dolphin 보기 모드
-Name[lt]=Dolphin rodymo būdai
+Name[lt]=Dolphin rodinio veiksenos
Name[ml]=ഡോള്ഫിന് അവതരണദശകള്
Name[nb]=Dolphin visningsmåter
Name[nl]=Dolphin-weergavemodussen
Comment[it]=Questo servizio permette di configurare le viste di Dolphin.
Comment[ja]=Dolphin の表示モードを設定します
Comment[ko]=이 서비스는 Dolphin 보기 모드를 설정합니다.
-Comment[lt]=Ši tarnyba leidžia konfigūruoti Dolphin rodymo būdus.
+Comment[lt]=Ši paslauga leidžia Dolphin rodinio veiksenų konfigūravimą.
Comment[ml]=ഡോള്ഫിന് അവതരണദശകള് ക്രമീകരിയ്ക്കാന് ഈ സേവനം അനുവദിയ്ക്കുന്നു.
Comment[nb]=Med denne tjenesten kan du sette opp Dolphins visningsmåter.
Comment[nl]=Met deze dienst kunt u Dolphin-weergavemodussen configureren.
Comment[zh_TW]=此服務允許設定 Dolphin 的檢視模式。
[Desktop Entry]
-Icon=view-choose
+Icon=preferences-desktop-icons
Type=Service
X-KDE-ServiceTypes=KCModule
Exec=kcmshell5 kcmdolphinviewmodes
Name[it]=Viste
Name[ja]=表示モード
Name[ko]=보기 모드
-Name[lt]=Rodymo būdai
+Name[lt]=Rodinio veiksenos
Name[ml]=അവതരണ ദശകള്
Name[nb]=Visningsmåter
Name[nl]=Weergavemodi
Comment[it]=Configura le viste del gestore dei file
Comment[ja]=ファイルマネージャの表示モードを設定します
Comment[ko]=파일 관리자 보기 모드 설정
-Comment[lt]=Failų tvarkyklės rodymo būdų konfigūravimas
+Comment[lt]=Konfigūruoti failų tvarkytuvės rodinio veiksenas
Comment[ml]=ഫയല് മാനേജറിന്റെ അവതരണ ദശകള് ക്രമീകരിയ്ക്കുക
Comment[nb]=Tilpass filbehandlerens visningsmåter
Comment[nl]=Bestandsbeheerderweergavemodussen configureren
X-KDE-Keywords[it]=gestore dei file
X-KDE-Keywords[ja]=ファイルマネージャ
X-KDE-Keywords[ko]=파일 관리자
-X-KDE-Keywords[lt]=Failų tvarkyklė
+X-KDE-Keywords[lt]=failų tvarkytuvė
X-KDE-Keywords[ml]=ഫയൽ മാനേജർ
X-KDE-Keywords[nb]=filbehandler
X-KDE-Keywords[nl]=bestandsbeheerder
#include <QDir>
#include <QDirIterator>
#include <QCommandLineParser>
+#include <QMimeDatabase>
#include <KLocalizedString>
exit(1);
}
-bool evaluateShell(const QString &program, const QStringList &arguments, QString &output, QString &errorText)
-{
- QProcess process;
- process.start(program, arguments, QIODevice::ReadOnly);
- if (!process.waitForStarted()) {
- fail(i18n("Failed to run process: %1 %2", program, arguments.join(" ")));
- }
-
- if (!process.waitForFinished()) {
- fail(i18n("Process did not finish in reasonable time: %1 %2", program, arguments.join(" ")));
- }
-
- const auto stdoutResult = QString::fromUtf8(process.readAllStandardOutput()).trimmed();
- const auto stderrResult = QString::fromUtf8(process.readAllStandardError()).trimmed();
-
- if (process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0) {
- output = stdoutResult;
- return true;
- } else {
- errorText = stderrResult + stdoutResult;
- return false;
- }
-}
-
-QString mimeType(const QString &path)
-{
- QString result;
- QString errorText;
- if (evaluateShell("xdg-mime", QStringList{"query", "filetype", path}, result, errorText)) {
- return result;
- } else {
- fail(i18n("Failed to run xdg-mime %1: %2", path, errorText));
- }
-}
-
QString getServiceMenusDir()
{
const QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
"multipart/x-zip"},
UncompressCommand{"unzip", QStringList{}, QStringList{"-d"}}});
- const auto mime = mimeType(inputPath);
+ const auto mime = QMimeDatabase().mimeTypeForFile(inputPath).name();
UncompressCommand command{};
for (const auto &pair : mimeTypeToCommand) {
// Load JSON-based plugins that implement the KFileItemActionPlugin interface
const auto jsonPlugins = KPluginLoader::findPlugins(QStringLiteral("kf5/kfileitemaction"), [](const KPluginMetaData& metaData) {
- return metaData.serviceTypes().contains(QStringLiteral("KFileItemAction/Plugin"));
+ return metaData.serviceTypes().contains(QLatin1String("KFileItemAction/Plugin"));
});
foreach (const auto& jsonMetadata, jsonPlugins) {
ecm_add_test(draganddrophelpertest.cpp LINK_LIBRARIES dolphinprivate Qt5::Test)
# PlacesItemModelTest
-if (KF5_VERSION VERSION_GREATER_EQUAL "5.60.0")
+if (KF5_VERSION VERSION_GREATER_EQUAL 5.63.0)
ecm_add_test(placesitemmodeltest.cpp
TEST_NAME placesitemmodeltest
LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test)
void testOpenInNewTabTitle();
void testNewFileMenuEnabled_data();
void testNewFileMenuEnabled();
+ void testWindowTitle_data();
+ void testWindowTitle();
+
private:
QTRY_COMPARE(newFileMenu->isEnabled(), expectedEnabled);
}
+void DolphinMainWindowTest::testWindowTitle_data()
+{
+ QTest::addColumn<QUrl>("activeViewUrl");
+ QTest::addColumn<QString>("expectedWindowTitle");
+
+ // TODO: this test should enforce the english locale.
+ QTest::newRow("home") << QUrl::fromLocalFile(QDir::homePath()) << QStringLiteral("Home");
+ QTest::newRow("home with trailing slash") << QUrl::fromLocalFile(QStringLiteral("%1/").arg(QDir::homePath())) << QStringLiteral("Home");
+ QTest::newRow("trash") << QUrl::fromUserInput(QStringLiteral("trash:/")) << QStringLiteral("Trash");
+}
+
+void DolphinMainWindowTest::testWindowTitle()
+{
+ QFETCH(QUrl, activeViewUrl);
+ m_mainWindow->openDirectories({ activeViewUrl }, false);
+ m_mainWindow->show();
+ QVERIFY(QTest::qWaitForWindowExposed(m_mainWindow.data()));
+ QVERIFY(m_mainWindow->isVisible());
+
+ QFETCH(QString, expectedWindowTitle);
+ QCOMPARE(m_mainWindow->windowTitle(), expectedWindowTitle);
+}
+
QTEST_MAIN(DolphinMainWindowTest)
#include "dolphinmainwindowtest.moc"
}
m_model->m_dirLister->updateDirectory(m_testDir->url());
- if (itemsInsertedSpy.count() == 0) {
+ if (itemsInsertedSpy.isEmpty()) {
QVERIFY(itemsInsertedSpy.wait());
}
QVERIFY(itemSet.isValid());
QVERIFY(itemSet.count() == itemsQVector.count());
- if (itemSet.count() == 0) {
+ if (itemSet.isEmpty()) {
QVERIFY(itemSet.isEmpty());
QVERIFY(itemSet.begin() == itemSet.end());
QVERIFY(itemSet.constBegin() == itemSet.constEnd());
int min;
int max;
- if (itemSet.count() == 0) {
+ if (itemSet.isEmpty()) {
// Use some arbitrary values for the upcoming tests.
min = 0;
max = 5;
int min;
int max;
- if (itemSet.count() == 0) {
+ if (itemSet.isEmpty()) {
// Use some arbitrary values for the upcoming tests.
min = 0;
max = 5;
#include <KConfigGroup>
#include <KAboutData>
#include <KFilePlacesModel>
+#include <KProtocolInfo>
#include "dolphin_generalsettings.h"
#include "panels/places/placesitemmodel.h"
PlacesItemModel* m_model;
QSet<int> m_tobeRemoved;
QMap<QString, QDBusInterface *> m_interfacesMap;
- int m_expectedModelCount = 14;
+ int m_expectedModelCount = qEnvironmentVariableIsSet("KDE_FULL_SESSION") && KProtocolInfo::isKnownProtocol(QStringLiteral("recentlyused")) ? 16 : 14;
bool m_hasDesktopFolder = false;
bool m_hasDocumentsFolder = false;
bool m_hasDownloadsFolder = false;
urls << QStringLiteral("trash:/")
<< QStringLiteral("remote:/")
- << QStringLiteral("/media/nfs")
- << QStringLiteral("timeline:/today") << QStringLiteral("timeline:/yesterday")
+ << QStringLiteral("/media/nfs");
+
+ if (qEnvironmentVariableIsSet("KDE_FULL_SESSION") && KProtocolInfo::isKnownProtocol(QStringLiteral("recentlyused"))) {
+ urls << QStringLiteral("recentlyused:/files");
+ urls << QStringLiteral("recentlyused:/locations");
+ }
+
+ urls << QStringLiteral("timeline:/today") << QStringLiteral("timeline:/yesterday")
<< QStringLiteral("search:/documents") << QStringLiteral("search:/images") << QStringLiteral("search:/audio") << QStringLiteral("search:/videos")
<< QStringLiteral("/foreign")
<< QStringLiteral("/media/floppy0") << QStringLiteral("/media/XO-Y4") << QStringLiteral("/media/cdrom");
QCOMPARE(groups.at(1).second.toString(), QStringLiteral("Remote"));
QCOMPARE(groups.at(2).first, expectedRemoteIndex + 2);
- QCOMPARE(groups.at(2).second.toString(), QStringLiteral("Recently Saved"));
+ QCOMPARE(groups.at(2).second.toString(), QStringLiteral("Recent"));
+
+ if (qEnvironmentVariableIsSet("KDE_FULL_SESSION") && KProtocolInfo::isKnownProtocol(QStringLiteral("recentlyused"))) {
+ expectedRemoteIndex += 2;
+ }
QCOMPARE(groups.at(3).first, expectedRemoteIndex + 4);
QCOMPARE(groups.at(3).second.toString(), QStringLiteral("Search For"));
QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << false << true << QStringLiteral("Search For") << false;
// baloo - timeline
- QTest::newRow("Baloo - Today") << QUrl("timeline:/today") << false << true << QStringLiteral("Recently Saved") << false;
+ QTest::newRow("Baloo - Today") << QUrl("timeline:/today") << false << true << QStringLiteral("Recent") << false;
// devices
QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << false << false << QStringLiteral("Removable Devices") << false;
#include <QPixmapCache>
#include <QPointer>
#include <QScrollBar>
+#include <QSize>
#include <QTimer>
#include <QVBoxLayout>
m_container = new KItemListContainer(controller, this);
m_container->installEventFilter(this);
setFocusProxy(m_container);
- connect(m_container->horizontalScrollBar(), &QScrollBar::valueChanged, this, &DolphinView::hideToolTip);
- connect(m_container->verticalScrollBar(), &QScrollBar::valueChanged, this, &DolphinView::hideToolTip);
+ connect(m_container->horizontalScrollBar(), &QScrollBar::valueChanged, this, [=] { hideToolTip(); });
+ connect(m_container->verticalScrollBar(), &QScrollBar::valueChanged, this, [=] { hideToolTip(); });
controller->setSelectionBehavior(KItemListController::MultiSelection);
connect(controller, &KItemListController::itemActivated, this, &DolphinView::slotItemActivated);
break;
case QEvent::KeyPress:
+ hideToolTip(ToolTipManager::HideBehavior::Instantly);
if (GeneralSettings::useTabForSwitchingSplitView()) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Tab && keyEvent->modifiers() == Qt::NoModifier) {
return QUrl();
}
+void DolphinView::resetZoomLevel()
+{
+ ViewModeSettings::ViewMode mode;
+
+ switch (m_mode) {
+ case IconsView: mode = ViewModeSettings::IconsMode; break;
+ case CompactView: mode = ViewModeSettings::CompactMode; break;
+ case DetailsView: mode = ViewModeSettings::DetailsMode; break;
+ }
+ const ViewModeSettings settings(mode);
+ const QSize iconSize = QSize(settings.iconSize(), settings.iconSize());
+ setZoomLevel(ZoomLevelInfo::zoomLevelForIconSize(iconSize));
+}
+
void DolphinView::observeCreatedItem(const QUrl& url)
{
if (m_active) {
}
}
-void DolphinView::hideToolTip()
+void DolphinView::hideToolTip(const ToolTipManager::HideBehavior behavior)
{
#ifdef HAVE_BALOO
if (GeneralSettings::showToolTips()) {
- m_toolTipManager->hideToolTip();
+ m_toolTipManager->hideToolTip(behavior);
}
#endif
}
#include "dolphintabwidget.h"
#include "dolphin_export.h"
+#include "tooltips/tooltipmanager.h"
#include <KFileItem>
#include <KIO/Job>
void setZoomLevel(int level);
int zoomLevel() const;
+ /**
+ * Resets the view's icon size to the default value
+ */
+ void resetZoomLevel();
+
void setSortRole(const QByteArray& role);
QByteArray sortRole() const;
*/
void updateViewState();
- void hideToolTip();
-
/**
* Calculates the number of currently shown files into
* \a fileCount and the number of folders into \a folderCount.
*/
void applyModeToView();
+ /**
+ * Hides tooltip displayed over element.
+ */
+ void hideToolTip(const ToolTipManager::HideBehavior behavior = ToolTipManager::HideBehavior::Later);
+
/**
* Helper method for DolphinView::paste() and DolphinView::pasteIntoFolder().
* Pastes the clipboard data into the URL \a url.
"</interface> option is enabled.</para>"));
compactAction->setWhatsThis(xi18nc("@info:whatsthis Compact view mode",
"<para>This switches to a compact view mode that lists the folders "
- "and files in columns with the names beside the icons. <para></para>"
+ "and files in columns with the names beside the icons.</para><para>"
"This helps to keep the overview in folders with many items.</para>"));
detailsAction->setWhatsThis(xi18nc("@info:whatsthis Details view mode",
"<para>This switches to a list view mode that focuses on folder "
m_actionCollection);
zoomInAction->setWhatsThis(i18nc("@info:whatsthis zoom in", "This increases the icon size."));
+ QAction* zoomResetAction = m_actionCollection->addAction(QStringLiteral("view_zoom_reset"));
+ zoomResetAction->setText(i18nc("@action:inmenu View", "Reset Zoom Level"));
+ zoomResetAction->setToolTip(i18n("Zoom To Default"));
+ zoomResetAction->setWhatsThis(i18nc("@info:whatsthis zoom reset", "This resets the icon size to default."));
+ zoomResetAction->setIcon(QIcon::fromTheme(QStringLiteral("zoom-original")));
+ m_actionCollection->setDefaultShortcuts(zoomResetAction, {Qt::CTRL + Qt::Key_0});
+ connect(zoomResetAction, &QAction::triggered, this, &DolphinViewActionHandler::zoomReset);
+
QAction* zoomOutAction = KStandardAction::zoomOut(this,
&DolphinViewActionHandler::zoomOut,
m_actionCollection);
- zoomOutAction->setWhatsThis(i18nc("@info:whatsthis zoom in", "This reduces the icon size."));
+ zoomOutAction->setWhatsThis(i18nc("@info:whatsthis zoom out", "This reduces the icon size."));
KToggleAction* showPreview = m_actionCollection->add<KToggleAction>(QStringLiteral("show_preview"));
- showPreview->setText(i18nc("@action:intoolbar", "Preview"));
+ showPreview->setText(i18nc("@action:intoolbar", "Show Previews"));
showPreview->setToolTip(i18nc("@info", "Show preview of files and folders"));
showPreview->setWhatsThis(xi18nc("@info:whatsthis", "When this is "
"enabled, the icons are based on the actual file or folder "
QActionGroup* visibleRolesGroup = createFileItemRolesActionGroup(QStringLiteral("show_"));
KActionMenu* visibleRolesMenu = m_actionCollection->add<KActionMenu>(QStringLiteral("additional_info"));
- visibleRolesMenu->setText(i18nc("@action:inmenu View", "Additional Information"));
+ visibleRolesMenu->setText(i18nc("@action:inmenu View", "Show Additional Information"));
+ visibleRolesMenu->setIcon(QIcon::fromTheme(QStringLiteral("documentinfo")));
visibleRolesMenu->setDelayed(false);
foreach (QAction* action, visibleRolesGroup->actions()) {
connect(showInGroups, &KToggleAction::triggered, this, &DolphinViewActionHandler::toggleGroupedSorting);
KToggleAction* showHiddenFiles = m_actionCollection->add<KToggleAction>(QStringLiteral("show_hidden_files"));
- showHiddenFiles->setText(i18nc("@action:inmenu View", "Hidden Files"));
+ showHiddenFiles->setText(i18nc("@action:inmenu View", "Show Hidden Files"));
showHiddenFiles->setToolTip(i18nc("@info", "Visibility of hidden files and folders"));
showHiddenFiles->setWhatsThis(xi18nc("@info:whatsthis", "<para>When "
"this is enabled <emphasis>hidden</emphasis> files and folders "
QAction* adjustViewProps = m_actionCollection->addAction(QStringLiteral("view_properties"));
adjustViewProps->setText(i18nc("@action:inmenu View", "Adjust View Properties..."));
+ adjustViewProps->setIcon(QIcon::fromTheme(QStringLiteral("view-choose")));
adjustViewProps->setWhatsThis(i18nc("@info:whatsthis", "This opens a window "
"in which all folder view properties can be adjusted."));
connect(adjustViewProps, &QAction::triggered, this, &DolphinViewActionHandler::slotAdjustViewProperties);
QActionGroup* DolphinViewActionHandler::createFileItemRolesActionGroup(const QString& groupPrefix)
{
const bool isSortGroup = (groupPrefix == QLatin1String("sort_by_"));
- Q_ASSERT(isSortGroup || (!isSortGroup && groupPrefix == QLatin1String("show_")));
+ Q_ASSERT(isSortGroup || groupPrefix == QLatin1String("show_"));
QActionGroup* rolesActionGroup = new QActionGroup(m_actionCollection);
rolesActionGroup->setExclusive(isSortGroup);
{
Q_UNUSED(shown);
// It is not enough to update the 'Show Preview' action, also
- // the 'Zoom In' and 'Zoom Out' actions must be adapted.
+ // the 'Zoom In', 'Zoom Out' and 'Zoom Reset' actions must be adapted.
updateViewActions();
}
updateViewActions();
}
+void DolphinViewActionHandler::zoomReset()
+{
+ m_currentView->resetZoomLevel();
+ updateViewActions();
+}
+
void DolphinViewActionHandler::toggleSortFoldersFirst()
{
const bool sortFirst = m_currentView->sortFoldersFirst();
// #374508: don't overwrite custom icons.
const QString iconName = showHiddenFilesAction->icon().name();
- if (!iconName.isEmpty() && iconName != QLatin1String("visibility") && iconName != QLatin1String("hint")) {
+ if (!iconName.isEmpty() && iconName != QLatin1String("view-visible") && iconName != QLatin1String("view-hidden")) {
return;
}
- showHiddenFilesAction->setIcon(QIcon::fromTheme(shown ? QStringLiteral("visibility") : QStringLiteral("hint")));
+ showHiddenFilesAction->setIcon(QIcon::fromTheme(shown ? QStringLiteral("view-visible") : QStringLiteral("view-hidden")));
}
void DolphinViewActionHandler::slotWriteStateChanged(bool isFolderWritable)
// actions and the sub-menu-actions. If an action gets checked, it must
// be assured that all other actions get unchecked, except the ascending/
// descending actions
- QAction* sortByMenu = m_actionCollection->action(QStringLiteral("sort"));
for (QAction *groupAction : qAsConst(m_sortByActions)) {
KActionMenu* actionMenu = qobject_cast<KActionMenu*>(groupAction);
if (actionMenu) {
/** Decreases the size of the current set view mode. */
void zoomOut();
+
+ /** Resets the size of the current set view mode to default. */
+ void zoomReset();
/** Switches between a separate sorting and a mixed sorting of files and folders. */
void toggleSortFoldersFirst();
void RenameDialog::slotTextChanged(const QString& newName)
{
- bool enable = !newName.isEmpty() && (newName != QLatin1String("..")) && (newName != QLatin1String("."));
+ bool enable = !newName.isEmpty() && (newName != QLatin1String("..")) && (newName != QLatin1Char('.'));
if (enable && !m_renameOneItem) {
const int count = newName.count(QLatin1Char('#'));
if (count == 0) {
Q_ASSERT(!m_metaDataRequested);
}
-void ToolTipManager::hideToolTip()
+void ToolTipManager::hideToolTip(const HideBehavior behavior)
{
if (m_appliedWaitCursor) {
QApplication::restoreOverrideCursor();
m_showToolTipTimer->stop();
m_contentRetrievalTimer->stop();
if (m_tooltipWidget) {
- m_tooltipWidget->hideLater();
+ switch (behavior) {
+ case HideBehavior::Instantly:
+ m_tooltipWidget->hide();
+ break;
+ case HideBehavior::Later:
+ m_tooltipWidget->hideLater();
+ break;
+ }
}
}
Q_OBJECT
public:
+ enum class HideBehavior {
+ Instantly,
+ Later
+ };
+
explicit ToolTipManager(QWidget* parent);
~ToolTipManager() override;
/**
* Hides the currently shown tooltip.
*/
- void hideToolTip();
+ void hideToolTip(const HideBehavior behavior = HideBehavior::Later);
signals:
/**
Comment[it]=Estensione di controllo delle versioni per le viste dei file
Comment[ja]=ファイルビューのためのバージョン管理プラグイン
Comment[ko]=파일 보기를 위한 버전 관리 플러그인
-Comment[lt]=Versijų kontrolės papildinys failų tvarkyklėms
+Comment[lt]=Failo rodinių versijų tvarkymo papildinys
Comment[ml]=ഫയല് അവതരണദിശകൾക്കുള്ള പതിപ്പ് നിയന്ത്രണ സംയോജകം
Comment[nb]=Versjonskontrollmodul for filvisninger
Comment[nl]=Plugin voor versiecontrole op bestandoverzichten
#include <QCryptographicHash>
+#include <KFileItem>
+
namespace {
const int AdditionalInfoViewPropertiesVersion = 1;
const int NameRolePropertiesVersion = 2;
// we store the properties information in a local file.
if (useGlobalViewProps) {
m_filePath = destinationDir(QStringLiteral("global"));
- } else if (url.scheme().contains(QStringLiteral("search"))) {
+ } else if (url.scheme().contains(QLatin1String("search"))) {
m_filePath = destinationDir(QStringLiteral("search/")) + directoryHashForUrl(url);
useDetailsViewWithPath = true;
} else if (url.scheme() == QLatin1String("trash")) {
m_filePath = url.toLocalFile();
bool useDestinationDir = !isPartOfHome(m_filePath);
+ if (!useDestinationDir) {
+ const KFileItem fileItem(url);
+ useDestinationDir = fileItem.isSlow();
+ }
+
if (!useDestinationDir) {
const QFileInfo dirInfo(m_filePath);
const QFileInfo fileInfo(m_filePath + QDir::separator() + ViewPropertiesFileName);