--- /dev/null
+include:
+ - https://invent.kde.org/sysadmin/ci-tooling/raw/master/invent/ci-before.yml
+ - https://invent.kde.org/sysadmin/ci-tooling/raw/master/invent/ci-applications-linux.yml
cmake_minimum_required(VERSION 3.0)
# KDE Application Version, managed by release script
-set (RELEASE_SERVICE_VERSION_MAJOR "20")
-set (RELEASE_SERVICE_VERSION_MINOR "12")
-set (RELEASE_SERVICE_VERSION_MICRO "0")
+set (RELEASE_SERVICE_VERSION_MAJOR "21")
+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.14.0")
-set(KF5_MIN_VERSION "5.73.0")
+set(KF5_MIN_VERSION "5.77.0")
# ECM setup
find_package(ECM ${KF5_MIN_VERSION} CONFIG REQUIRED)
include(ECMSetupVersion)
include(ECMGenerateHeaders)
+include(ECMGenerateDBusServiceFile)
+include(ECMConfiguredInstall)
include(CMakePackageConfigHelpers)
include(GenerateExportHeader)
include(FeatureSummary)
COMPONENT Devel
)
-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 ${KDE_INSTALL_DBUSSERVICEDIR})
+ecm_generate_dbus_service_file(
+ NAME org.freedesktop.FileManager1
+ EXECUTABLE "${KDE_INSTALL_FULL_BINDIR}/dolphin --daemon"
+ SYSTEMD_SERVICE plasma-dolphin.service
+ DESTINATION ${KDE_INSTALL_DBUSSERVICEDIR}
+ RENAME org.kde.dolphin.FileManager1.service
+)
+
+ecm_install_configured_files(INPUT plasma-dolphin.service.in DESTINATION ${SYSTEMD_USER_UNIT_INSTALL_DIR})
+
install(FILES dolphin.categories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR})
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
<listitem><para>
A file or folder can be opened by clicking it with the &LMB; (or
-double-clicking, if <guilabel>Double-click to open files and folders</guilabel>
-is enabled in the &systemsettings; in the <menuchoice><guimenu>Input Devices</guimenu>
-<guimenuitem>Mouse</guimenuitem></menuchoice> module.
+double-clicking, if <guilabel>Open by double-clicking instead</guilabel>
+is enabled in the &systemsettings; in the <menuchoice><guimenu>Workspace</guimenu>
+<guimenuitem>General Behavior</guimenuitem></menuchoice> module).
</para></listitem>
<listitem><para>
</sect2>
+<sect2 id="filter-files">
+<title>Filtering Files</title>
+
+<para>
+&dolphin; is capable of filtering files, &ie; showing only those items in the
+view whose name contains a given text. For example, if you wish to show
+only the <acronym>MP3</acronym> files within a folder, you could filter for <quote>.mp3</quote>.
+This would then filter out all files whose name does not contain <quote>.mp3</quote>.
+</para>
+
+<para>
+To filter files, first enable the filter bar, either by pressing <keycombo action="simul">&Ctrl;<keycap>I</keycap></keycombo>
+or via the menu: <menuchoice> <guimenu>Edit</guimenu> <guimenuitem>Filter...</guimenuitem> </menuchoice>.
+You can then enter the text to be filtered for in the filter bar. The filter bar can
+be disabled either by pressing &Esc;, or with a &LMB; click on the
+<guiicon>Hide Filter Bar</guiicon> icon.
+</para>
+
+</sect2>
+
<sect2 id="finding-searching-in-file">
<title>Finding Files and Searching in Files</title>
<!-- FIXME search in hidden files + folders View -> Show Hidden Files has to be enabled ? -->
</sect2>
-<sect2 id="filter-files">
-<title>Filtering Files</title>
-
-<para>
-&dolphin; is capable of filtering files, &ie; showing only those items in the
-view whose name contains a given text. For example, if you wish to show
-only the <acronym>MP3</acronym> files within a folder, you could filter for <quote>.mp3</quote>.
-This would then filter out all files whose name does not contain <quote>.mp3</quote>.
-</para>
-
-<para>
-To filter files, first enable the filter bar, either by pressing <keycombo action="simul">&Ctrl;<keycap>I</keycap></keycombo>
-or via the menu: <menuchoice> <guimenu>Tools</guimenu> <guimenuitem>Show Filter Bar</guimenuitem> </menuchoice>.
-You can then enter the text to be filtered for in the filter bar. The filter bar can
-be disabled either by pressing &Esc;, or with a &LMB; click on the
-<guiicon>Hide Filter Bar</guiicon> icon.
-</para>
-
-</sect2>
-
</sect1>
</chapter>
<listitem><para>
The option to open items with a single or double mouse click is a system wide setting and can be
-changed in the &systemsettings; in the <menuchoice><guimenu>Input Devices</guimenu>
-<guimenuitem>Mouse</guimenuitem></menuchoice> module.</para>
+changed in the &systemsettings; in the <menuchoice><guimenu>Workspace</guimenu>
+<guimenuitem>General Behavior</guimenuitem></menuchoice> module.</para>
</listitem>
<listitem><para>
Is disabled if the current user does not have write permission on the selected item(s).</action></para></listitem>
</varlistentry>
+<varlistentry>
+<term><menuchoice>
+<shortcut>
+<keycombo action="simul">&Ctrl;<keycap>I</keycap></keycombo>
+</shortcut>
+<guimenu>Edit</guimenu>
+<guimenuitem>Filter...</guimenuitem>
+</menuchoice></term>
+<listitem><para><action>Enables and disables the <link linkend="filter-files">filter bar</link>.</action>
+You can also use the alternate shortcut <keycombo action="simul">&Shift;<keycap>/</keycap></keycombo>
+for this action.</para></listitem>
+</varlistentry>
+
<varlistentry>
<term><menuchoice>
<shortcut>
<para>
<variablelist>
-<varlistentry>
-<term><menuchoice>
-<shortcut>
-<keycombo action="simul">&Ctrl;<keycap>I</keycap></keycombo>
-</shortcut>
-<guimenu>Tools</guimenu>
-<guimenuitem>Show Filter Bar</guimenuitem>
-</menuchoice></term>
-<listitem><para><action>Enables and disables the <link linkend="filter-files">filter bar</link>.</action>
-You can also use the alternate shortcut <keycombo action="simul">&Shift;<keycap>/</keycap></keycombo>
-for this action.</para></listitem>
-</varlistentry>
-
<varlistentry>
<term><menuchoice>
<shortcut>
+++ /dev/null
-[D-BUS Service]
-Name=org.freedesktop.FileManager1
-Exec=@CMAKE_INSTALL_PREFIX@/bin/dolphin --daemon
--- /dev/null
+[Unit]
+Description=Dolphin file manager
+PartOf=graphical-session.target
+
+[Service]
+ExecStart=@KDE_INSTALL_FULL_BINDIR@/dolphin --daemon
+BusName=org.freedesktop.FileManager1
+Slice=background.slice
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dolphin_export.h DESTINATION ${KDE_INSTALL_INCLUDEDIR} COMPONENT Devel)
##########################################
+configure_file(dolphinpart.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/dolphinpart.desktop @ONLY)
set(dolphinpart_SRCS
dolphinpart.cpp
qt5_add_resources(dolphinpart_SRCS dolphinpart.qrc)
add_library(dolphinpart MODULE ${dolphinpart_SRCS})
+kcoreaddons_desktop_to_json(dolphinpart ${CMAKE_CURRENT_BINARY_DIR}/dolphinpart.desktop)
target_link_libraries(dolphinpart
dolphinprivate
)
-install(TARGETS dolphinpart DESTINATION ${KDE_INSTALL_PLUGINDIR})
+install(TARGETS dolphinpart DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/parts)
-install(FILES dolphinpart.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dolphinpart.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
##########################################
// or the items itself. To increase the performance both lists are cached.
const DolphinView* view = m_mainWindow->activeViewContainer()->view();
m_selectedItems = view->selectedItems();
+
+ installEventFilter(this);
}
DolphinContextMenu::~DolphinContextMenu()
return m_command;
}
-void DolphinContextMenu::keyPressEvent(QKeyEvent *ev)
+void DolphinContextMenu::childEvent(QChildEvent* event)
{
- if (m_removeAction && ev->key() == Qt::Key_Shift) {
- m_removeAction->update(DolphinRemoveAction::ShiftState::Pressed);
+ if(event->added()) {
+ event->child()->installEventFilter(this);
}
- QMenu::keyPressEvent(ev);
+ QMenu::childEvent(event);
}
-void DolphinContextMenu::keyReleaseEvent(QKeyEvent *ev)
+bool DolphinContextMenu::eventFilter(QObject* dest, QEvent* event)
{
- if (m_removeAction && ev->key() == Qt::Key_Shift) {
- m_removeAction->update(DolphinRemoveAction::ShiftState::Released);
+ if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
+ QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
+ if(m_removeAction && keyEvent->key() == Qt::Key_Shift) {
+ if(event->type() == QEvent::KeyPress) {
+ m_removeAction->update(DolphinRemoveAction::ShiftState::Pressed);
+ } else {
+ m_removeAction->update(DolphinRemoveAction::ShiftState::Released);
+ }
+ return true;
+ }
}
- QMenu::keyReleaseEvent(ev);
+ return QMenu::eventFilter(dest, event);
}
void DolphinContextMenu::openTrashContextMenu()
QMenu* menu = newFileMenu->menu();
menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
menu->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
+ menu->setParent(this, Qt::Popup);
addMenu(menu);
addSeparator();
const KFileItemListProperties& selectedItemsProps = selectedItemsProperties();
KFileItemActions fileItemActions;
- fileItemActions.setParentWidget(m_mainWindow);
+ fileItemActions.setParentWidget(this);
fileItemActions.setItemListProperties(selectedItemsProps);
if (m_selectedItems.count() == 1) {
insertDefaultItemActions(selectedItemsProps);
- // insert 'Add to Places' entry if appropriate
- if (m_selectedItems.count() == 1) {
- if (m_fileInfo.isDir()) {
- if (!placeExists(m_fileInfo.url())) {
- addAction(m_mainWindow->actionCollection()->action(QStringLiteral("add_to_places")));
- }
- }
- }
-
- addSeparator();
-
- fileItemActions.addServiceActionsTo(this);
- fileItemActions.addPluginActionsTo(this);
-
- addVersionControlPluginActions();
+ addAdditionalActions(fileItemActions, selectedItemsProps);
// insert 'Copy To' and 'Move To' sub menus
if (GeneralSettings::showCopyMoveMenu()) {
addAction(m_mainWindow->actionCollection()->action(QStringLiteral("sort")));
addAction(m_mainWindow->actionCollection()->action(QStringLiteral("view_mode")));
- addSeparator();
-
- // Insert service actions
- fileItemActions.addServiceActionsTo(this);
- fileItemActions.addPluginActionsTo(this);
-
- addVersionControlPluginActions();
-
+ addAdditionalActions(fileItemActions, baseUrlProperties);
addCustomActions();
addSeparator();
}
addAction(m_mainWindow->actionCollection()->action(QStringLiteral("duplicate")));
- addSeparator();
-
// Insert 'Rename'
addAction(collection->action(KStandardAction::name(KStandardAction::RenameFile)));
+ // insert 'Add to Places' entry if appropriate
+ if (m_selectedItems.count() == 1) {
+ if (m_fileInfo.isDir()) {
+ if (!placeExists(m_fileInfo.url())) {
+ addAction(m_mainWindow->actionCollection()->action(QStringLiteral("add_to_places")));
+ }
+ }
+ }
+
+ addSeparator();
+
// Insert 'Move to Trash' and/or 'Delete'
const bool showDeleteAction = (KSharedConfig::openConfig()->group("KDE").readEntry("ShowDeleteCommand", false) ||
!properties.isLocal());
fileItemActions.addOpenWithActionsTo(this, QStringLiteral("DesktopEntryName != '%1'").arg(qApp->desktopFileName()));
}
-void DolphinContextMenu::addVersionControlPluginActions()
+void DolphinContextMenu::addCustomActions()
+{
+ addActions(m_customActions);
+}
+
+void DolphinContextMenu::addAdditionalActions(KFileItemActions &fileItemActions, const KFileItemListProperties &props)
{
+ addSeparator();
+
+ QList<QAction *> additionalActions;
+ if (props.isDirectory() && props.isLocal()) {
+ additionalActions << m_mainWindow->actionCollection()->action(QStringLiteral("open_terminal"));
+ }
+ fileItemActions.addActionsTo(this, KFileItemActions::MenuActionSource::All, additionalActions);
+
const DolphinView* view = m_mainWindow->activeViewContainer()->view();
const QList<QAction*> versionControlActions = view->versionControlActions(m_selectedItems);
if (!versionControlActions.isEmpty()) {
}
}
-void DolphinContextMenu::addCustomActions()
-{
- addActions(m_customActions);
-}
-
Command open();
protected:
- void keyPressEvent(QKeyEvent *ev) override;
- void keyReleaseEvent(QKeyEvent *ev) override;
+ void childEvent(QChildEvent* event) override;
+ bool eventFilter(QObject* dest, QEvent* event) override;
private:
void openTrashContextMenu();
*/
void addOpenWithActions(KFileItemActions& fileItemActions);
- /**
- * Adds actions that are provided by a KVersionControlPlugin.
- */
- void addVersionControlPluginActions();
-
/**
* Adds custom actions e.g. like the "[x] Expandable Folders"-action
* provided in the details view.
void addCustomActions();
private:
+ /**
+ * Add services, custom actions, plugins and version control items to the menu
+ */
+ void addAdditionalActions(KFileItemActions &fileItemActions, const KFileItemListProperties &props);
+
struct Entry
{
int type;
connect(undoManager, &KIO::FileUndoManager::jobRecordingFinished,
this, &DolphinMainWindow::showCommand);
- GeneralSettings* generalSettings = GeneralSettings::self();
- const bool firstRun = (generalSettings->version() < 200);
+ const bool firstRun = (GeneralSettings::version() < 200);
if (firstRun) {
- generalSettings->setViewPropsTimestamp(QDateTime::currentDateTime());
+ GeneralSettings::setViewPropsTimestamp(QDateTime::currentDateTime());
}
setAcceptDrops(true);
connect(clipboard, &QClipboard::dataChanged,
this, &DolphinMainWindow::updatePasteAction);
- QAction* showFilterBarAction = actionCollection()->action(QStringLiteral("show_filter_bar"));
- showFilterBarAction->setChecked(generalSettings->filterBar());
+ QAction* toggleFilterBarAction = actionCollection()->action(QStringLiteral("toggle_filter"));
+ toggleFilterBarAction->setChecked(GeneralSettings::filterBar());
if (firstRun) {
menuBar()->setVisible(false);
void DolphinMainWindow::updateFilterBarAction(bool show)
{
- QAction* showFilterBarAction = actionCollection()->action(QStringLiteral("show_filter_bar"));
- showFilterBarAction->setChecked(show);
+ QAction* toggleFilterBarAction = actionCollection()->action(QStringLiteral("toggle_filter"));
+ toggleFilterBarAction->setChecked(show);
}
void DolphinMainWindow::openNewMainWindow()
m_activeViewContainer->setFilterBarVisible(true);
}
+void DolphinMainWindow::toggleFilterBar()
+{
+ const bool checked = !m_activeViewContainer->isFilterBarVisible();
+ m_activeViewContainer->setFilterBarVisible(checked);
+
+ QAction* toggleFilterBarAction = actionCollection()->action(QStringLiteral("toggle_filter"));
+ toggleFilterBarAction->setChecked(checked);
+}
+
void DolphinMainWindow::toggleEditLocation()
{
clearStatusBar();
"<emphasis>Tab</emphasis> with the current location and view.<nl/>"
"A tab is an additional view within this window. "
"You can drag and drop items between tabs."));
- actionCollection()->setDefaultShortcuts(newTab, {Qt::CTRL + Qt::Key_T, Qt::CTRL + Qt::SHIFT + Qt::Key_N});
+ actionCollection()->setDefaultShortcuts(newTab, {Qt::CTRL | Qt::Key_T, Qt::CTRL | Qt::SHIFT | Qt::Key_N});
connect(newTab, &QAction::triggered, this, &DolphinMainWindow::openNewActivatedTab);
QAction* addToPlaces = actionCollection()->addAction(QStringLiteral("add_to_places"));
"the <emphasis>active</emphasis> view to the inactive split view."));
copyToOtherViewAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
copyToOtherViewAction->setIconText(i18nc("@action:inmenu Edit", "Copy to Inactive Split View"));
- actionCollection()->setDefaultShortcut(copyToOtherViewAction, Qt::SHIFT + Qt::Key_F5 );
+ actionCollection()->setDefaultShortcut(copyToOtherViewAction, Qt::SHIFT | Qt::Key_F5 );
connect(copyToOtherViewAction, &QAction::triggered, m_tabWidget, &DolphinTabWidget::copyToInactiveSplitView);
QAction* moveToOtherViewAction = actionCollection()->addAction(QStringLiteral("move_to_inactive_split_view"));
"the <emphasis>active</emphasis> view to the inactive split view."));
moveToOtherViewAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-cut")));
moveToOtherViewAction->setIconText(i18nc("@action:inmenu Edit", "Move to Inactive Split View"));
- actionCollection()->setDefaultShortcut(moveToOtherViewAction, Qt::SHIFT + Qt::Key_F6 );
+ actionCollection()->setDefaultShortcut(moveToOtherViewAction, Qt::SHIFT | Qt::Key_F6 );
connect(moveToOtherViewAction, &QAction::triggered, m_tabWidget, &DolphinTabWidget::moveToInactiveSplitView);
+ QAction* showFilterBar = actionCollection()->addAction(QStringLiteral("show_filter_bar"));
+ showFilterBar->setText(i18nc("@action:inmenu Tools", "Filter..."));
+ showFilterBar->setToolTip(i18nc("@info:tooltip", "Toggle Filter Bar"));
+ showFilterBar->setWhatsThis(xi18nc("@info:whatsthis", "This opens the "
+ "<emphasis>Filter Bar</emphasis> at the bottom of the window.<nl/> "
+ "There you can enter a text to filter the files and folders currently displayed. "
+ "Only those that contain the text in their name will be kept in view."));
+ showFilterBar->setIcon(QIcon::fromTheme(QStringLiteral("view-filter")));
+ actionCollection()->setDefaultShortcuts(showFilterBar, {Qt::CTRL | Qt::Key_I, Qt::Key_Slash});
+ connect(showFilterBar, &QAction::triggered, this, &DolphinMainWindow::showFilterBar);
+
+ // toggle_filter acts as a copy of the main showFilterBar to be used mainly
+ // in the toolbar, with no default shortcut attached, to avoid messing with
+ // existing workflows (filter bar always open and Ctrl-I to focus)
+ QAction *toggleFilter = actionCollection()->addAction(QStringLiteral("toggle_filter"));
+ toggleFilter->setText(i18nc("@action:inmenu", "Toggle Filter Bar"));
+ toggleFilter->setIconText(i18nc("@action:intoolbar", "Filter"));
+ toggleFilter->setIcon(showFilterBar->icon());
+ toggleFilter->setToolTip(showFilterBar->toolTip());
+ toggleFilter->setWhatsThis(showFilterBar->whatsThis());
+ toggleFilter->setCheckable(true);
+ connect(toggleFilter, &QAction::triggered, this, &DolphinMainWindow::toggleFilterBar);
+
QAction *searchAction = KStandardAction::find(this, &DolphinMainWindow::find, actionCollection());
searchAction->setText(i18n("Search..."));
searchAction->setToolTip(i18nc("@info:tooltip", "Search for files and folders"));
invertSelection->setWhatsThis(xi18nc("@info:whatsthis invert", "This selects all "
"objects that you have currently <emphasis>not</emphasis> selected instead."));
invertSelection->setIcon(QIcon::fromTheme(QStringLiteral("edit-select-invert")));
- actionCollection()->setDefaultShortcut(invertSelection, Qt::CTRL + Qt::SHIFT + Qt::Key_A);
+ actionCollection()->setDefaultShortcut(invertSelection, Qt::CTRL | Qt::SHIFT | Qt::Key_A);
connect(invertSelection, &QAction::triggered, this, &DolphinMainWindow::invertSelection);
// setup 'View' menu
connect(split, &QAction::triggered, this, &DolphinMainWindow::toggleSplitView);
QAction* stashSplit = actionCollection()->addAction(QStringLiteral("split_stash"));
- actionCollection()->setDefaultShortcut(stashSplit, Qt::CTRL + Qt::Key_S);
+ actionCollection()->setDefaultShortcut(stashSplit, Qt::CTRL | Qt::Key_S);
stashSplit->setText(i18nc("@action:intoolbar Stash", "Stash"));
stashSplit->setToolTip(i18nc("@info", "Opens the stash virtual directory in a split window"));
stashSplit->setIcon(QIcon::fromTheme(QStringLiteral("folder-stash")));
replaceLocation->setWhatsThis(xi18nc("@info:whatsthis",
"This switches to editing the location and selects it "
"so you can quickly enter a different location."));
- actionCollection()->setDefaultShortcut(replaceLocation, Qt::CTRL + Qt::Key_L);
+ actionCollection()->setDefaultShortcut(replaceLocation, Qt::CTRL | Qt::Key_L);
connect(replaceLocation, &QAction::triggered, this, &DolphinMainWindow::replaceLocation);
// setup 'Go' menu
undoCloseTab->setText(i18nc("@action:inmenu File", "Undo close tab"));
undoCloseTab->setWhatsThis(i18nc("@info:whatsthis undo close tab",
"This returns you to the previously closed tab."));
- actionCollection()->setDefaultShortcut(undoCloseTab, Qt::CTRL + Qt::SHIFT + Qt::Key_T);
+ actionCollection()->setDefaultShortcut(undoCloseTab, Qt::CTRL | Qt::SHIFT | Qt::Key_T);
undoCloseTab->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo")));
undoCloseTab->setEnabled(false);
connect(undoCloseTab, &QAction::triggered, recentTabsMenu, &DolphinRecentTabsMenu::undoCloseTab);
"including folders that contain personal application data."));
// setup 'Tools' menu
- QAction* showFilterBar = actionCollection()->addAction(QStringLiteral("show_filter_bar"));
- showFilterBar->setText(i18nc("@action:inmenu Tools", "Show Filter Bar"));
- showFilterBar->setWhatsThis(xi18nc("@info:whatsthis", "This opens the "
- "<emphasis>Filter Bar</emphasis> at the bottom of the window.<nl/> "
- "There you can enter a text to filter the files and folders currently displayed. "
- "Only those that contain the text in their name will be kept in view."));
- showFilterBar->setIcon(QIcon::fromTheme(QStringLiteral("view-filter")));
- actionCollection()->setDefaultShortcuts(showFilterBar, {Qt::CTRL + Qt::Key_I, Qt::Key_Slash});
- connect(showFilterBar, &QAction::triggered, this, &DolphinMainWindow::showFilterBar);
-
QAction* compareFiles = actionCollection()->addAction(QStringLiteral("compare_files"));
compareFiles->setText(i18nc("@action:inmenu Tools", "Compare Files"));
compareFiles->setIcon(QIcon::fromTheme(QStringLiteral("kompare")));
"<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);
+ actionCollection()->setDefaultShortcut(openPreferredSearchTool, Qt::CTRL | Qt::SHIFT | Qt::Key_F);
connect(openPreferredSearchTool, &QAction::triggered, this, &DolphinMainWindow::openPreferredSearchTool);
if (KAuthorized::authorize(QStringLiteral("shell_access"))) {
openTerminal->setWhatsThis(xi18nc("@info:whatsthis",
"<para>This opens a <emphasis>terminal</emphasis> application for the viewed location.</para>"
"<para>To learn more about terminals use the help in the terminal application.</para>"));
- openTerminal->setIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts")));
- actionCollection()->setDefaultShortcut(openTerminal, Qt::SHIFT + Qt::Key_F4);
+ openTerminal->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal")));
+ actionCollection()->setDefaultShortcut(openTerminal, Qt::SHIFT | Qt::Key_F4);
connect(openTerminal, &QAction::triggered, this, &DolphinMainWindow::openTerminal);
#ifdef HAVE_TERMINAL
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);
+ actionCollection()->setDefaultShortcut(focusTerminalPanel, Qt::CTRL | Qt::SHIFT | Qt::Key_F4);
connect(focusTerminalPanel, &QAction::triggered, this, &DolphinMainWindow::focusTerminalPanel);
#endif
}
// not in menu actions
QList<QKeySequence> nextTabKeys = KStandardShortcut::tabNext();
- nextTabKeys.append(QKeySequence(Qt::CTRL + Qt::Key_Tab));
+ nextTabKeys.append(QKeySequence(Qt::CTRL | Qt::Key_Tab));
QList<QKeySequence> prevTabKeys = KStandardShortcut::tabPrev();
- prevTabKeys.append(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab));
+ prevTabKeys.append(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_Tab));
for (int i = 0; i < MaxActivateTabShortcuts; ++i) {
QAction* activateTab = actionCollection()->addAction(QStringLiteral("activate_tab_%1").arg(i));
activateLastTab->setText(i18nc("@action:inmenu", "Activate Last Tab"));
activateLastTab->setEnabled(false);
connect(activateLastTab, &QAction::triggered, m_tabWidget, &DolphinTabWidget::activateLastTab);
- actionCollection()->setDefaultShortcut(activateLastTab, Qt::ALT + Qt::Key_0);
+ actionCollection()->setDefaultShortcut(activateLastTab, Qt::ALT | Qt::Key_0);
QAction* activateNextTab = actionCollection()->addAction(QStringLiteral("activate_next_tab"));
activateNextTab->setIconText(i18nc("@action:inmenu", "Next Tab"));
{
m_actionHandler->updateViewActions();
- QAction* showFilterBarAction = actionCollection()->action(QStringLiteral("show_filter_bar"));
- showFilterBarAction->setChecked(m_activeViewContainer->isFilterBarVisible());
+ QAction* toggleFilterBarAction = actionCollection()->action(QStringLiteral("toggle_filter"));
+ toggleFilterBarAction->setChecked(m_activeViewContainer->isFilterBarVisible());
updateSplitAction();
}
void disableStopAction();
void showFilterBar();
+ void toggleFilterBar();
/**
* Toggles between edit and browse mode of the navigation bar.
{
const int urlNavigatorsAmount = m_splitter->count() > 1 && m_splitter->widget(1)->isVisible() ?
2 : 1;
- setText(i18ncp("@action:inmenu", "Url Navigator", "Url Navigators", urlNavigatorsAmount));
+ setText(i18ncp("@action:inmenu", "Location Bar", "Location Bars", urlNavigatorsAmount));
}
#include "views/dolphinview.h"
#include "views/dolphinviewactionhandler.h"
-#include <KAboutData>
+#include <KPluginMetaData>
#include <KActionCollection>
#include <KAuthorized>
#include <KConfigGroup>
#include <QStandardPaths>
#include <QTextDocument>
-K_PLUGIN_FACTORY(DolphinPartFactory, registerPlugin<DolphinPart>();)
+K_PLUGIN_CLASS_WITH_JSON(DolphinPart, "dolphinpart.json")
-DolphinPart::DolphinPart(QWidget* parentWidget, QObject* parent, const QVariantList& args)
+DolphinPart::DolphinPart(QWidget* parentWidget, QObject* parent,
+ const KPluginMetaData& metaData, const QVariantList& args)
: KParts::ReadOnlyPart(parent)
,m_openTerminalAction(nullptr)
,m_removeAction(nullptr)
{
Q_UNUSED(args)
- setComponentData(*createAboutData(), false);
+ setMetaData(metaData);
+
m_extension = new DolphinPartBrowserExtension(this);
// make sure that other apps using this part find Dolphin's view-file-columns icons
// TODO there was a "always open a new window" (when clicking on a directory) setting in konqueror
// (sort of spacial navigation)
- loadPlugins(this, this, componentData());
+ loadPlugins(this, this, componentName());
}
DolphinPart::~DolphinPart()
QAction* selectItemsMatching = actionCollection()->addAction(QStringLiteral("select_items_matching"));
selectItemsMatching->setText(i18nc("@action:inmenu Edit", "Select Items Matching..."));
- actionCollection()->setDefaultShortcut(selectItemsMatching, Qt::CTRL + Qt::Key_S);
+ actionCollection()->setDefaultShortcut(selectItemsMatching, Qt::CTRL | Qt::Key_S);
connect(selectItemsMatching, &QAction::triggered, this, &DolphinPart::slotSelectItemsMatchingPattern);
QAction* unselectItemsMatching = actionCollection()->addAction(QStringLiteral("unselect_items_matching"));
QAction* invertSelection = actionCollection()->addAction(QStringLiteral("invert_selection"));
invertSelection->setText(i18nc("@action:inmenu Edit", "Invert Selection"));
- actionCollection()->setDefaultShortcut(invertSelection, Qt::CTRL + Qt::SHIFT + Qt::Key_A);
+ actionCollection()->setDefaultShortcut(invertSelection, Qt::CTRL | Qt::SHIFT | Qt::Key_A);
connect(invertSelection, &QAction::triggered, m_view, &DolphinView::invertSelection);
// View menu: all done by DolphinViewActionHandler
Q_EMIT m_extension->setActionText( "paste", pasteInfo.second );
}
-KAboutData* DolphinPart::createAboutData()
-{
- return new KAboutData(QStringLiteral("dolphinpart"), i18nc("@title", "Dolphin Part"), QStringLiteral("0.1"));
-}
-
bool DolphinPart::openUrl(const QUrl &url)
{
bool reload = arguments().reload();
Name[zh_TW]=Dolphin 檢視
MimeType=inode/directory;
X-KDE-ServiceTypes=KParts/ReadOnlyPart,Browser/View
-X-KDE-Library=dolphinpart
+X-KDE-Library=kf5/parts/dolphinpart
#X-KDE-BrowserView-Args=Icon
X-KDE-BrowserView-HideFromMenus=true
X-KDE-BrowserView-Built-Into=konqueror
-Icon=view-icon
+Icon=view-list-icons
InitialPreference=7
+X-KDE-PluginInfo-Name=dolphinpart
+X-KDE-PluginInfo-Version=@DOLPHIN_VERSION@
+X-KDE-PluginInfo-License=LGPL v2+
+
+
# Provide info about the view modes using the Actions mechanism so that KService parses it.
# Konqueror then queries KService to get hold of the translated texts for the view modes
Actions=icons;details;compact;
class DolphinRemoteEncoding;
class KDirLister;
class DolphinView;
-class KAboutData;
class DolphinRemoveAction;
class DolphinPart : public KParts::ReadOnlyPart
Q_PROPERTY( QList<QUrl> filesToSelect READ filesToSelect WRITE setFilesToSelect )
public:
- explicit DolphinPart(QWidget* parentWidget, QObject* parent, const QVariantList& args);
+ explicit DolphinPart(QWidget* parentWidget, QObject* parent,
+ const KPluginMetaData& metaData, const QVariantList& args);
~DolphinPart() override;
- static KAboutData* createAboutData();
-
/**
* Standard KParts::ReadOnlyPart openUrl method.
* Called by Konqueror to view a directory in DolphinPart.
-<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="dolphinpart" version="15" translationDomain="dolphin">
+<?xml version="1.0"?>
+<!DOCTYPE gui SYSTEM "kpartgui.dtd">
+<gui name="dolphinpart" version="15" translationDomain="dolphin">
<MenuBar>
<Menu name="edit"><text>&Edit</text>
<Action name="new_menu"/>
<Action name="deletefile" />
</disable>
</State>
-</kpartgui>
+</gui>
-<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="dolphin" version="33">
+<?xml version="1.0"?>
+<!DOCTYPE gui SYSTEM "kpartgui.dtd">
+<gui name="dolphin" version="33">
<MenuBar>
<Menu name="file">
<Action name="new_menu" />
<Action name="copy_location" />
<Action name="edit_paste" />
<Separator />
+ <Action name="show_filter_bar" />
<Action name="edit_find" />
<Separator />
<Action name="copy_to_inactive_split_view" />
<Action name="closed_tabs" />
</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="split_view" />
<Action name="split_stash" />
<Action name="toggle_search" />
+ <Action name="toggle_filter" />
</ToolBar>
<ActionProperties scheme="Default">
<Action priority="0" name="go_back"/>
<Action priority="0" name="edit_copy"/>
<Action priority="0" name="edit_paste"/>
<Action priority="0" name="toggle_search"/>
+ <Action priority="0" name="toggle_filter"/>
</ActionProperties>
-</kpartgui>
+</gui>
#include <QPropertyAnimation>
#include <QStyleOptionRubberBand>
#include <QTimer>
+#include <QVariantAnimation>
namespace {
// Delay in ms for triggering the next autoscroll
const int RepeatingAutoScrollDelay = 1000 / 60;
+
+ // Copied from the Kirigami.Units.shortDuration
+ const int RubberFadeSpeed = 150;
+
+ const char* RubberPropertyName = "_kitemviews_rubberBandPosition";
}
#ifndef QT_NO_ACCESSIBILITY
{
QGraphicsWidget::paint(painter, option, widget);
+ for (auto animation : qAsConst(m_rubberBandAnimations)) {
+ QRectF rubberBandRect = animation->property(RubberPropertyName).toRectF();
+
+ const QPointF topLeft = rubberBandRect.topLeft();
+ if (scrollOrientation() == Qt::Vertical) {
+ rubberBandRect.moveTo(topLeft.x(), topLeft.y() - scrollOffset());
+ } else {
+ rubberBandRect.moveTo(topLeft.x() - scrollOffset(), topLeft.y());
+ }
+
+ QStyleOptionRubberBand opt;
+ initStyleOption(&opt);
+ opt.shape = QRubberBand::Rectangle;
+ opt.opaque = false;
+ opt.rect = rubberBandRect.toRect();
+
+ painter->save();
+
+ painter->setOpacity(animation->currentValue().toReal());
+ style()->drawControl(QStyle::CE_RubberBand, &opt, painter);
+
+ painter->restore();
+ }
+
if (m_rubberBand->isActive()) {
QRectF rubberBandRect = QRectF(m_rubberBand->startPosition(),
m_rubberBand->endPosition()).normalized();
connect(m_rubberBand, &KItemListRubberBand::endPositionChanged, this, &KItemListView::slotRubberBandPosChanged);
m_skipAutoScrollForRubberBand = true;
} else {
+ QRectF rubberBandRect = QRectF(m_rubberBand->startPosition(),
+ m_rubberBand->endPosition()).normalized();
+
+ auto animation = new QVariantAnimation(this);
+ animation->setStartValue(1.0);
+ animation->setEndValue(0.0);
+ animation->setDuration(RubberFadeSpeed);
+ animation->setProperty(RubberPropertyName, rubberBandRect);
+
+ QEasingCurve curve;
+ curve.setType(QEasingCurve::BezierSpline);
+ curve.addCubicBezierSegment(QPointF(0.4, 0.0), QPointF(1.0, 1.0), QPointF(1.0, 1.0));
+ animation->setEasingCurve(curve);
+
+ connect(animation, &QVariantAnimation::valueChanged, this, [=](const QVariant&) {
+ update();
+ });
+ connect(animation, &QVariantAnimation::finished, this, [=]() {
+ m_rubberBandAnimations.removeAll(animation);
+ delete animation;
+ });
+ animation->start();
+ m_rubberBandAnimations << animation;
+
disconnect(m_rubberBand, &KItemListRubberBand::startPositionChanged, this, &KItemListView::slotRubberBandPosChanged);
disconnect(m_rubberBand, &KItemListRubberBand::endPositionChanged, this, &KItemListView::slotRubberBandPosChanged);
m_skipAutoScrollForRubberBand = false;
class KItemListWidgetCreatorBase;
class QTimer;
class QPropertyAnimation;
+class QVariantAnimation;
/**
* @brief Represents the view of an item-list.
// by KItemListView::showDropIndicator() and KItemListView::hideDropIndicator().
QRectF m_dropIndicator;
+ QList<QVariantAnimation*> m_rubberBandAnimations;
+
friend class KItemListContainer; // Accesses scrollBarRequired()
friend class KItemListHeader; // Accesses m_headerWidget
friend class KItemListController;
<caption xml:lang="sk">Správa súborov v Dolphin</caption>
<caption xml:lang="sl">Upravljanje datotek v Dolphinu</caption>
<caption xml:lang="sv">Filhantering i Dolphin</caption>
+ <caption xml:lang="tr">Dolphin'de dosya yönetimi</caption>
<caption xml:lang="uk">Керування файлами у Dolphin</caption>
<caption xml:lang="vi">Quản lí tệp trong Dolphin</caption>
<caption xml:lang="x-test">xxFile management in Dolphinxx</caption>
m_facetsWidget->layout()->setSpacing(Dolphin::LAYOUT_SPACING_SMALL);
connect(m_facetsWidget, &DolphinFacetsWidget::facetChanged, this, &DolphinSearchBox::slotFacetChanged);
+ // Put the options into a QScrollArea. This prevents increasing the view width
+ // in case that not enough width for the options is available.
+ QWidget* optionsContainer = new QWidget(this);
+
// Apply layout for the options
- QHBoxLayout* optionsLayout = new QHBoxLayout();
+ QHBoxLayout* optionsLayout = new QHBoxLayout(optionsContainer);
optionsLayout->setContentsMargins(0, 0, 0, 0);
optionsLayout->setSpacing(Dolphin::LAYOUT_SPACING_SMALL);
optionsLayout->addWidget(m_fileNameButton);
optionsLayout->addWidget(moreSearchToolsButton);
optionsLayout->addStretch(1);
- // Put the options into a QScrollArea. This prevents increasing the view width
- // in case that not enough width for the options is available.
- QWidget* optionsContainer = new QWidget(this);
- optionsContainer->setLayout(optionsLayout);
-
m_optionsScrollArea = new QScrollArea(this);
m_optionsScrollArea->setFrameShape(QFrame::NoFrame);
m_optionsScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setMinimumWidth(400);
auto layout = new QVBoxLayout(this);
- setLayout(layout);
if (previewPlugin) {
auto configurationWidget = previewPlugin->createConfigurationWidget();
layout->addWidget(buttonBox);
auto okButton = buttonBox->button(QDialogButtonBox::Ok);
- okButton->setShortcut(Qt::CTRL + Qt::Key_Return);
+ okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
okButton->setDefault(true);
}
#include <KLocalizedString>
#include <KPluginFactory>
-#include <KPluginLoader>
#include <kconfigwidgets_version.h>
#include <QTabWidget>
#include <kconfigwidgets_version.h>
#include <KPluginFactory>
-#include <KPluginLoader>
#include <QVBoxLayout>
#include <kconfigwidgets_version.h>
#include <KPluginFactory>
-#include <KPluginLoader>
#include <QVBoxLayout>
#include <KLocalizedString>
#include <KPluginFactory>
-#include <KPluginLoader>
#include <QDBusConnection>
#include <QDBusMessage>
auto layout = new QFormLayout(this);
// Otherwise the dialog won't resize when we collapse the KCollapsibleGroupBox.
layout->setSizeConstraint(QLayout::SetFixedSize);
- setLayout(layout);
// create 'Properties' group containing view mode, sorting, sort order and show hidden files
m_viewMode = new QComboBox();
auto additionalInfoBox = new KCollapsibleGroupBox();
additionalInfoBox->setTitle(i18nc("@title:group", "Additional Information"));
- auto innerLayout = new QVBoxLayout();
+ auto innerLayout = new QVBoxLayout(additionalInfoBox);
{
QList<QByteArray> visibleRoles = m_viewProps->visibleRoles();
innerLayout->addWidget(m_listWidget);
}
- additionalInfoBox->setLayout(innerLayout);
-
QHBoxLayout* sortingLayout = new QHBoxLayout();
sortingLayout->setContentsMargins(0, 0, 0, 0);
sortingLayout->addWidget(m_sortOrder);
layout->addWidget(buttonBox);
auto okButton = buttonBox->button(QDialogButtonBox::Ok);
- okButton->setShortcut(Qt::CTRL + Qt::Key_Return);
+ okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
okButton->setDefault(true);
auto applyButton = buttonBox->button(QDialogButtonBox::Apply);
m_viewProps->setAutoSaveEnabled(false);
auto layout = new QVBoxLayout(this);
- setLayout(layout);
m_label = new QLabel(i18nc("@info:progress", "Counting folders: %1", 0), this);
layout->addWidget(m_label);
ecm_add_test(draganddrophelpertest.cpp LINK_LIBRARIES dolphinprivate Qt5::Test)
# PlacesItemModelTest
-if (KF5_VERSION VERSION_GREATER_EQUAL 5.63.0)
- ecm_add_test(placesitemmodeltest.cpp
- TEST_NAME placesitemmodeltest
- LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test)
-endif()
+ecm_add_test(placesitemmodeltest.cpp
+TEST_NAME placesitemmodeltest
+LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test)
find_gem(test-unit)
set_package_properties(Gem:test-unit PROPERTIES
#include <QApplication>
#include <QClipboard>
#include <QDropEvent>
+#include <QGraphicsOpacityEffect>
#include <QGraphicsSceneDragDropEvent>
+#include <QLabel>
#include <QMenu>
#include <QMimeDatabase>
#include <QPixmapCache>
m_clearSelectionBeforeSelectingNewItems(false),
m_markFirstNewlySelectedItemAsCurrent(false),
m_versionControlObserver(nullptr),
- m_twoClicksRenamingTimer(nullptr)
+ m_twoClicksRenamingTimer(nullptr),
+ m_placeholderLabel(nullptr)
{
m_topLayout = new QVBoxLayout(this);
m_topLayout->setSpacing(0);
connect(m_container->horizontalScrollBar(), &QScrollBar::valueChanged, this, [=] { hideToolTip(); });
connect(m_container->verticalScrollBar(), &QScrollBar::valueChanged, this, [=] { hideToolTip(); });
+ // Show some placeholder text for empty folders
+ // This is made using a heavily-modified QLabel rather than a KTitleWidget
+ // because KTitleWidget can't be told to turn off mouse-selectable text
+ m_placeholderLabel = new QLabel(this);
+ QFont placeholderLabelFont;
+ // To match the size of a level 2 Heading/KTitleWidget
+ placeholderLabelFont.setPointSize(qRound(placeholderLabelFont.pointSize() * 1.3));
+ m_placeholderLabel->setFont(placeholderLabelFont);
+ m_placeholderLabel->setTextInteractionFlags(Qt::NoTextInteraction);
+ m_placeholderLabel->setWordWrap(true);
+ m_placeholderLabel->setAlignment(Qt::AlignCenter);
+ // Match opacity of QML placeholder label component
+ auto *effect = new QGraphicsOpacityEffect(m_placeholderLabel);
+ effect->setOpacity(0.5);
+ m_placeholderLabel->setGraphicsEffect(effect);
+ // Set initial text and visibility
+ updatePlaceholderLabel();
+
+ auto *centeringLayout = new QVBoxLayout(m_container);
+ centeringLayout->addWidget(m_placeholderLabel);
+ centeringLayout->setAlignment(m_placeholderLabel, Qt::AlignCenter);
+
controller->setSelectionBehavior(KItemListController::MultiSelection);
connect(controller, &KItemListController::itemActivated, this, &DolphinView::slotItemActivated);
connect(controller, &KItemListController::itemsActivated, this, &DolphinView::slotItemsActivated);
connect(m_model, &KFileItemModel::directoryRedirection, this, &DolphinView::slotDirectoryRedirection);
connect(m_model, &KFileItemModel::urlIsFileError, this, &DolphinView::urlIsFileError);
+ connect(this, &DolphinView::itemCountChanged,
+ this, &DolphinView::updatePlaceholderLabel);
+ connect(this, &DolphinView::urlChanged,
+ this, &DolphinView::updatePlaceholderLabel);
+
m_view->installEventFilter(this);
connect(m_view, &DolphinItemListView::sortOrderChanged,
this, &DolphinView::slotSortOrderChangedByHeader);
void DolphinView::slotDirectoryLoadingStarted()
{
+ // We don't want the placeholder label to flicker while the folder is loading
+ m_placeholderLabel->setVisible(false);
+
// Disable the writestate temporary until it can be determined in a fast way
// in DolphinView::slotDirectoryLoadingCompleted()
if (m_isFolderWritable) {
// because the view might not be in its final state yet.
QTimer::singleShot(0, this, &DolphinView::updateViewState);
+ // Update the placeholder label in case we found that the folder was empty
+ // after loading it
+
Q_EMIT directoryLoadingCompleted();
+ updatePlaceholderLabel();
updateWritableState();
}
{
Q_EMIT goUpRequested();
}
+
+void DolphinView::updatePlaceholderLabel()
+{
+ if (itemsCount() > 0) {
+ m_placeholderLabel->setVisible(false);
+ return;
+ }
+
+ if (!nameFilter().isEmpty()) {
+ m_placeholderLabel->setText(i18n("No items matching the filter"));
+ } else if (m_url.scheme() == QLatin1String("baloosearch") || m_url.scheme() == QLatin1String("filenamesearch")) {
+ m_placeholderLabel->setText(i18n("No items matching the search"));
+ } else if (m_url.scheme() == QLatin1String("trash")) {
+ m_placeholderLabel->setText(i18n("Trash is empty"));
+ } else if (m_url.scheme() == QLatin1String("tags")) {
+ m_placeholderLabel->setText(i18n("No tags"));
+ } else if (m_url.scheme() == QLatin1String("recentlyused")) {
+ m_placeholderLabel->setText(i18n("No recently used items"));
+ } else if (m_url.scheme() == QLatin1String("smb")) {
+ m_placeholderLabel->setText(i18n("No shared folders found"));
+ } else if (m_url.scheme() == QLatin1String("network")) {
+ m_placeholderLabel->setText(i18n("No relevant network resources found"));
+ } else if (m_url.scheme() == QLatin1String("mtp")) {
+ m_placeholderLabel->setText(i18n("No MTP-compatible devices found"));
+ } else if (m_url.scheme() == QLatin1String("bluetooth")) {
+ m_placeholderLabel->setText(i18n("No Bluetooth devices found"));
+ } else {
+ m_placeholderLabel->setText(i18n("Folder is empty"));
+ }
+
+ m_placeholderLabel->setVisible(true);
+}
class ToolTipManager;
class VersionControlObserver;
class ViewProperties;
+class QLabel;
class QGraphicsSceneDragDropEvent;
class QRegularExpression;
void abortTwoClicksRenaming();
+ void updatePlaceholderLabel();
+
private:
void updatePalette();
QTimer* m_twoClicksRenamingTimer;
QUrl m_twoClicksRenamingItemUrl;
+ QLabel* m_placeholderLabel;
// For unit tests
friend class TestBase;
#include "kitemviews/kfileitemmodel.h"
#include "settings/viewpropertiesdialog.h"
#include "views/zoomlevelinfo.h"
+#include "kconfig_version.h"
#ifdef HAVE_BALOO
#include <Baloo/IndexerConfig>
// KNewFileMenu takes care of the GUI stuff.
QAction* newDirAction = m_actionCollection->addAction(QStringLiteral("create_dir"));
newDirAction->setText(i18nc("@action", "Create Folder..."));
- m_actionCollection->setDefaultShortcut(newDirAction, Qt::Key_F10);
+ m_actionCollection->setDefaultShortcuts(newDirAction, KStandardShortcut::createFolder());
newDirAction->setIcon(QIcon::fromTheme(QStringLiteral("folder-new")));
newDirAction->setEnabled(false); // Will be enabled in slotWriteStateChanged(bool) if the current URL is writable
connect(newDirAction, &QAction::triggered, this, &DolphinViewActionHandler::createDirectoryTriggered);
"You can configure advanced options there like managing "
"read- and write-permissions."));
propertiesAction->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")));
- m_actionCollection->setDefaultShortcuts(propertiesAction, {Qt::ALT + Qt::Key_Return, Qt::ALT + Qt::Key_Enter});
+ m_actionCollection->setDefaultShortcuts(propertiesAction, {Qt::ALT | Qt::Key_Return, Qt::ALT | Qt::Key_Enter});
connect(propertiesAction, &QAction::triggered, this, &DolphinViewActionHandler::slotProperties);
QAction *copyPathAction = m_actionCollection->addAction( QStringLiteral("copy_location") );
));
copyPathAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
- m_actionCollection->setDefaultShortcuts(copyPathAction, {Qt::CTRL + Qt::SHIFT + Qt::Key_C});
+ m_actionCollection->setDefaultShortcuts(copyPathAction, {Qt::CTRL | Qt::SHIFT | Qt::Key_C});
connect(copyPathAction, &QAction::triggered, this, &DolphinViewActionHandler::slotCopyPath);
zoomResetAction->setToolTip(i18n("Zoom To Default"));
zoomResetAction->setWhatsThis(i18nc("@info:whatsthis zoom reset", "This resets the icon size to default."));
zoomResetAction->setIcon(QIcon::fromTheme(QStringLiteral("zoom-original")));
- m_actionCollection->setDefaultShortcuts(zoomResetAction, {Qt::CTRL + Qt::Key_0});
+ m_actionCollection->setDefaultShortcuts(zoomResetAction, {Qt::CTRL | Qt::Key_0});
connect(zoomResetAction, &QAction::triggered, this, &DolphinViewActionHandler::zoomReset);
QAction* zoomOutAction = KStandardAction::zoomOut(this,
KToggleAction* iconsView = m_actionCollection->add<KToggleAction>(QStringLiteral("icons"));
iconsView->setText(i18nc("@action:inmenu View Mode", "Icons"));
iconsView->setToolTip(i18nc("@info", "Icons view mode"));
- m_actionCollection->setDefaultShortcut(iconsView, Qt::CTRL + Qt::Key_1);
+ m_actionCollection->setDefaultShortcut(iconsView, Qt::CTRL | Qt::Key_1);
iconsView->setIcon(QIcon::fromTheme(QStringLiteral("view-list-icons")));
iconsView->setData(QVariant::fromValue(DolphinView::IconsView));
return iconsView;
KToggleAction* iconsView = m_actionCollection->add<KToggleAction>(QStringLiteral("compact"));
iconsView->setText(i18nc("@action:inmenu View Mode", "Compact"));
iconsView->setToolTip(i18nc("@info", "Compact view mode"));
- m_actionCollection->setDefaultShortcut(iconsView, Qt::CTRL + Qt::Key_2);
+ m_actionCollection->setDefaultShortcut(iconsView, Qt::CTRL | Qt::Key_2);
iconsView->setIcon(QIcon::fromTheme(QStringLiteral("view-list-details"))); // TODO: discuss with Oxygen-team the wrong (?) name
iconsView->setData(QVariant::fromValue(DolphinView::CompactView));
return iconsView;
KToggleAction* detailsView = m_actionCollection->add<KToggleAction>(QStringLiteral("details"));
detailsView->setText(i18nc("@action:inmenu View Mode", "Details"));
detailsView->setToolTip(i18nc("@info", "Details view mode"));
- m_actionCollection->setDefaultShortcut(detailsView, Qt::CTRL + Qt::Key_3);
+ m_actionCollection->setDefaultShortcut(detailsView, Qt::CTRL | Qt::Key_3);
detailsView->setIcon(QIcon::fromTheme(QStringLiteral("view-list-tree")));
detailsView->setData(QVariant::fromValue(DolphinView::DetailsView));
return detailsView;