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