#include <KStandardAction>
#include <KStartupInfo>
#include <KSycoca>
+#include <KTerminalLauncherJob>
#include <KToggleAction>
#include <KToolBar>
#include <KToolBarPopupAction>
-#include <KToolInvocation>
#include <KUrlComboBox>
#include <KUrlNavigator>
#include <KWindowSystem>
#include <KXMLGUIFactory>
+#include <kio_version.h>
+
#include <QApplication>
#include <QClipboard>
#include <QCloseEvent>
auto hamburgerMenu = static_cast<KHamburgerMenu *>(actionCollection()->action(
KStandardAction::name(KStandardAction::HamburgerMenu)));
hamburgerMenu->setMenuBar(menuBar());
- hamburgerMenu->setMenuBarAdvertised(false); // This line will soon be removed when the
- // hamburger menu contents are re-arranged.
+ hamburgerMenu->setShowMenuBarAction(showMenuBarAction);
connect(hamburgerMenu, &KHamburgerMenu::aboutToShowMenu,
this, &DolphinMainWindow::updateHamburgerMenu);
hamburgerMenu->hideActionsOf(toolBar());
connect(KSycoca::self(), QOverload<>::of(&KSycoca::databaseChanged), this, &DolphinMainWindow::updateOpenPreferredSearchToolAction);
QTimer::singleShot(0, this, &DolphinMainWindow::updateOpenPreferredSearchToolAction);
+
+ m_fileItemActions.setParentWidget(this);
+ connect(&m_fileItemActions, &KFileItemActions::error, this, [this](const QString &errorMessage) {
+ showErrorMessage(errorMessage);
+ });
}
DolphinMainWindow::~DolphinMainWindow()
{
+ // This fixes a crash on Wayland when closing the mainwindow while another dialog is open.
+ disconnect(QGuiApplication::clipboard(), &QClipboard::dataChanged, this, &DolphinMainWindow::updatePasteAction);
}
QVector<DolphinViewContainer*> DolphinMainWindow::viewContainers() const
return viewContainers;
}
-void DolphinMainWindow::setViewsWithInvalidPathsToHome()
-{
- const QVector<DolphinViewContainer*> theViewContainers = viewContainers();
- for (DolphinViewContainer *viewContainer : theViewContainers) {
-
- // Only consider local dirs, not remote locations and abstract protocols
- if (viewContainer->url().isLocalFile()) {
- if (!QFileInfo::exists(viewContainer->url().toLocalFile())) {
- viewContainer->setUrl(QUrl::fromLocalFile(QDir::homePath()));
- }
- }
- }
-}
-
void DolphinMainWindow::openDirectories(const QList<QUrl>& dirs, bool splitView)
{
m_tabWidget->openDirectories(dirs, splitView);
const QUrl url = m_activeViewContainer->url();
if (url.isLocalFile()) {
- KToolInvocation::invokeTerminal(QString(), {}, url.toLocalFile());
+ auto job = new KTerminalLauncherJob(QString());
+ job->setWorkingDirectory(url.toLocalFile());
+ job->start();
return;
}
statUrl = job->mostLocalUrl();
}
- KToolInvocation::invokeTerminal(QString(), {}, statUrl.isLocalFile() ? statUrl.toLocalFile() : QDir::homePath());
+ auto job = new KTerminalLauncherJob(QString());
+ job->setWorkingDirectory(statUrl.isLocalFile() ? statUrl.toLocalFile() : QDir::homePath());
+ job->start();
});
return;
}
// Nothing worked, just use $HOME
- KToolInvocation::invokeTerminal(QString(), {}, QDir::homePath());
+ auto job = new KTerminalLauncherJob(QString());
+ job->setWorkingDirectory(QDir::homePath());
+ job->start();
}
void DolphinMainWindow::editSettings()
const QUrl& url,
const QList<QAction*>& customActions)
{
- QPointer<DolphinContextMenu> contextMenu = new DolphinContextMenu(this, pos, item, url);
+ QPointer<DolphinContextMenu> contextMenu = new DolphinContextMenu(this, pos, item, url, &m_fileItemActions);
contextMenu.data()->setCustomActions(customActions);
const DolphinContextMenu::Command command = contextMenu.data()->open();
if (!menu) {
menu = new QMenu(this);
hamburgerMenu->setMenu(menu);
+ hamburgerMenu->hideActionsOf(ac->action(QStringLiteral("basic_actions"))->menu());
+ hamburgerMenu->hideActionsOf(ac->action(QStringLiteral("zoom"))->menu());
} else {
menu->clear();
}
+ const QList<QAction *> toolbarActions = toolBar()->actions();
- menu->addMenu(m_newFileMenu->menu());
- menu->addAction(ac->action(QStringLiteral("file_new")));
- menu->addAction(ac->action(QStringLiteral("new_tab")));
- menu->addAction(ac->action(QStringLiteral("closed_tabs")));
-
- menu->addSeparator();
-
- // Add "Edit" actions
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::Undo)));
- menu->addAction(ac->action(QString("copy_location")));
- menu->addAction(ac->action(QStringLiteral("copy_to_inactive_split_view")));
- menu->addAction(ac->action(QStringLiteral("move_to_inactive_split_view")));
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::SelectAll)));
- menu->addAction(ac->action(QStringLiteral("invert_selection")));
-
- menu->addSeparator();
-
- // Add "View" actions
- if (!GeneralSettings::showZoomSlider()) {
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::ZoomIn)));
- menu->addAction(ac->action(QStringLiteral("view_zoom_reset")));
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::ZoomOut)));
+ if (!toolBar()->isVisible()) {
+ // If neither the menu bar nor the toolbar are visible, these actions should be available.
+ menu->addAction(ac->action(KStandardAction::name(KStandardAction::ShowMenubar)));
+ menu->addAction(toolBarMenuAction());
menu->addSeparator();
}
- menu->addAction(ac->action(QStringLiteral("show_preview")));
- menu->addAction(ac->action(QStringLiteral("show_in_groups")));
- menu->addAction(ac->action(QStringLiteral("show_hidden_files")));
- menu->addAction(ac->action(QStringLiteral("additional_info")));
- menu->addAction(ac->action(QStringLiteral("view_properties")));
+ // This group of actions (until the next separator) contains all the most basic actions
+ // necessary to use Dolphin effectively.
+ menu->addAction(ac->action(QStringLiteral("go_back")));
+ menu->addAction(ac->action(QStringLiteral("go_forward")));
+ menu->addMenu(m_newFileMenu->menu());
+ menu->addAction(ac->action(QStringLiteral("basic_actions")));
+ menu->addAction(ac->action(KStandardAction::name(KStandardAction::Undo)));
+ if (!toolBar()->isVisible()
+ || (!toolbarActions.contains(ac->action(QStringLiteral("toggle_search")))
+ && !toolbarActions.contains(ac->action(QStringLiteral("open_preferred_search_tool"))))
+ ) {
+ menu->addAction(ac->action(KStandardAction::name(KStandardAction::Find)));
+ // This way a search action will only be added if none of the three available
+ // search actions is present on the toolbar.
+ }
+ if (!toolBar()->isVisible()
+ || !toolbarActions.contains(ac->action(QStringLiteral("toggle_filter")))
+ ) {
+ menu->addAction(ac->action(QStringLiteral("show_filter_bar")));
+ // This way a filter action will only be added if none of the two available
+ // filter actions is present on the toolbar.
+ }
menu->addSeparator();
- // Add a curated assortment of items from the "Tools" menu
- menu->addAction(ac->action(QStringLiteral("show_filter_bar")));
- menu->addAction(ac->action(QStringLiteral("open_preferred_search_tool")));
+ // The second group of actions (up until the next separator) contains actions for opening
+ // additional views to interact with the file system.
+ menu->addAction(ac->action(QStringLiteral("file_new")));
+ menu->addAction(ac->action(QStringLiteral("new_tab")));
+ if (ac->action(QStringLiteral("undo_close_tab"))->isEnabled()) {
+ menu->addAction(ac->action(QStringLiteral("closed_tabs")));
+ }
menu->addAction(ac->action(QStringLiteral("open_terminal")));
-
menu->addSeparator();
- // Add "Show Panels" menu
+ // The third group contains actions to change what one sees in the view
+ // and to change the more general UI.
+ if (!toolBar()->isVisible()
+ || (!toolbarActions.contains(ac->action(QStringLiteral("icons")))
+ && !toolbarActions.contains(ac->action(QStringLiteral("compact")))
+ && !toolbarActions.contains(ac->action(QStringLiteral("details")))
+ && !toolbarActions.contains(ac->action(QStringLiteral("view_mode"))))
+ ) {
+ menu->addAction(ac->action(QStringLiteral("view_mode")));
+ }
+ menu->addAction(ac->action(QStringLiteral("show_hidden_files")));
+ menu->addAction(ac->action(QStringLiteral("sort")));
+ menu->addAction(ac->action(QStringLiteral("additional_info")));
+ if (!GeneralSettings::showStatusBar() || !GeneralSettings::showZoomSlider()) {
+ menu->addAction(ac->action(QStringLiteral("zoom")));
+ }
menu->addAction(ac->action(QStringLiteral("panels")));
- // Add "Settings" menu entries
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::KeyBindings)));
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::ConfigureToolbars)));
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::Preferences)));
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::ShowMenubar)));
+ // The "Configure" menu is not added to the actionCollection() because there is hardly
+ // a good reason for users to put it on their toolbar.
+ auto configureMenu = menu->addMenu(QIcon::fromTheme(QStringLiteral("configure")),
+ i18nc("@action:inmenu menu for configure actions", "Configure"));
+ configureMenu->addAction(ac->action(KStandardAction::name(KStandardAction::SwitchApplicationLanguage)));
+ configureMenu->addAction(ac->action(KStandardAction::name(KStandardAction::KeyBindings)));
+ configureMenu->addAction(ac->action(KStandardAction::name(KStandardAction::ConfigureToolbars)));
+ configureMenu->addAction(ac->action(KStandardAction::name(KStandardAction::Preferences)));
+ hamburgerMenu->hideActionsOf(configureMenu);
}
void DolphinMainWindow::slotPlaceActivated(const QUrl& url)
// view and url navigator) and main window.
oldViewContainer->disconnect(this);
oldViewContainer->view()->disconnect(this);
+ oldViewContainer->urlNavigatorInternalWithHistory()->disconnect(this);
auto navigators = static_cast<DolphinNavigatorsWidgetAction *>
(actionCollection()->action(QStringLiteral("url_navigators")));
navigators->primaryUrlNavigator()->disconnect(this);
m_newFileMenu = new DolphinNewFileMenu(actionCollection(), this);
QMenu* menu = m_newFileMenu->menu();
menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
- menu->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
- m_newFileMenu->setDelayed(false);
+ menu->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
+ m_newFileMenu->setPopupMode(QToolButton::InstantPopup);
connect(menu, &QMenu::aboutToShow,
this, &DolphinMainWindow::updateNewMenu);
stashSplit->setToolTip(i18nc("@info", "Opens the stash virtual directory in a split window"));
stashSplit->setIcon(QIcon::fromTheme(QStringLiteral("folder-stash")));
stashSplit->setCheckable(false);
- stashSplit->setVisible(QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("org.kde.kio.StashNotifier")));
+ QDBusConnectionInterface *sessionInterface = QDBusConnection::sessionBus().interface();
+ stashSplit->setVisible(sessionInterface && sessionInterface->isServiceRegistered(QStringLiteral("org.kde.kio.StashNotifier")));
connect(stashSplit, &QAction::triggered, this, &DolphinMainWindow::toggleSplitStash);
KStandardAction::redisplay(this, &DolphinMainWindow::reloadView, actionCollection());
m_backAction->setObjectName(backAction->objectName());
m_backAction->setShortcuts(backAction->shortcuts());
}
- m_backAction->setDelayed(true);
- m_backAction->setStickyMenu(false);
+ m_backAction->setPopupMode(QToolButton::DelayedPopup);
connect(m_backAction, &QAction::triggered, this, &DolphinMainWindow::goBack);
connect(m_backAction->menu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowBackPopupMenu);
connect(m_backAction->menu(), &QMenu::triggered, this, &DolphinMainWindow::slotGoBack);
m_forwardAction->setObjectName(forwardAction->objectName());
m_forwardAction->setShortcuts(forwardAction->shortcuts());
}
- m_forwardAction->setDelayed(true);
- m_forwardAction->setStickyMenu(false);
+ m_forwardAction->setPopupMode(QToolButton::DelayedPopup);
connect(m_forwardAction, &QAction::triggered, this, &DolphinMainWindow::goForward);
connect(m_forwardAction->menu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowForwardPopupMenu);
connect(m_forwardAction->menu(), &QMenu::triggered, this, &DolphinMainWindow::slotGoForward);
KActionMenu *bookmarkMenu = new KActionMenu(i18nc("@title:menu", "&Bookmarks"), this);
bookmarkMenu->setIcon(QIcon::fromTheme(QStringLiteral("bookmarks")));
// Make the toolbar button version work properly on click
- bookmarkMenu->setDelayed(false);
+ bookmarkMenu->setPopupMode(QToolButton::InstantPopup);
m_bookmarkHandler = new DolphinBookmarkHandler(this, actionCollection(), bookmarkMenu->menu(), this);
actionCollection()->addAction(QStringLiteral("bookmarks"), bookmarkMenu);
m_helpMenu = new KHelpMenu(nullptr);
m_helpMenu->menu()->installEventFilter(this);
// remove duplicate shortcuts
- m_helpMenu->action(KHelpMenu::menuHelpContents)->setShortcut(QKeySequence());
- m_helpMenu->action(KHelpMenu::menuWhatsThis)->setShortcut(QKeySequence());
+ auto removeHelpActionShortcut = [this](KHelpMenu::MenuId menuId) {
+ if (auto *action = m_helpMenu->action(menuId)) {
+ action->setShortcut(QKeySequence());
+ }
+ };
+ removeHelpActionShortcut(KHelpMenu::menuHelpContents);
+ removeHelpActionShortcut(KHelpMenu::menuWhatsThis);
// not in menu actions
QList<QKeySequence> nextTabKeys = KStandardShortcut::tabNext();
KActionMenu* panelsMenu = new KActionMenu(i18nc("@action:inmenu View", "Show Panels"), this);
actionCollection()->addAction(QStringLiteral("panels"), panelsMenu);
panelsMenu->setIcon(QIcon::fromTheme(QStringLiteral("view-sidetree")));
- panelsMenu->setDelayed(false);
+ panelsMenu->setPopupMode(QToolButton::InstantPopup);
const KActionCollection* ac = actionCollection();
panelsMenu->addAction(ac->action(QStringLiteral("show_places_panel")));
#ifdef HAVE_BALOO
connect(view, &DolphinView::goUpRequested,
this, &DolphinMainWindow::goUp);
+ connect(container->urlNavigatorInternalWithHistory(), &KUrlNavigator::urlChanged,
+ this, &DolphinMainWindow::changeUrl);
+ connect(container->urlNavigatorInternalWithHistory(), &KUrlNavigator::historyChanged,
+ this, &DolphinMainWindow::updateHistory);
+
auto navigators = static_cast<DolphinNavigatorsWidgetAction *>
(actionCollection()->action(QStringLiteral("url_navigators")));
-
const KUrlNavigator *navigator = m_tabWidget->currentTabPage()->primaryViewActive() ?
navigators->primaryUrlNavigator() :
navigators->secondaryUrlNavigator();
- connect(navigator, &KUrlNavigator::urlChanged,
- this, &DolphinMainWindow::changeUrl);
QAction *editableLocactionAction = actionCollection()->action(QStringLiteral("editable_location"));
editableLocactionAction->setChecked(navigator->isUrlEditable());
connect(navigator, &KUrlNavigator::editableStateChanged,
connect(navigator, &KUrlNavigator::tabRequested,
this, &DolphinMainWindow::openNewTab);
- disconnect(m_updateHistoryConnection);
- m_updateHistoryConnection = connect(
- container->urlNavigatorInternalWithHistory(), &KUrlNavigator::historyChanged,
- this, &DolphinMainWindow::updateHistory);
}
void DolphinMainWindow::updateSplitAction()
// StandardAction separately because both are used in different locations.
// m_helpMenu is only used for createControlButton() button.
+ auto setStandardActionWhatsThis = [this](KStandardAction::StandardAction actionId,
+ const QString &whatsThis) {
+ if (auto *action = actionCollection()->action(KStandardAction::name(actionId))) {
+ action->setWhatsThis(whatsThis);
+ }
+ };
+ auto setHelpActionWhatsThis = [this](KHelpMenu::MenuId menuId, const QString &whatsThis) {
+ if (auto *action = m_helpMenu->action(menuId)) {
+ action->setWhatsThis(whatsThis);
+ }
+ };
+
// Links do not work within the Menubar so texts without links are provided there.
// i18n: If the external link isn't available in your language you should
const QString whatsThisHelpContents = xi18nc("@info:whatsthis handbook",
"<para>This opens the Handbook for this application. It provides "
"explanations for every part of <emphasis>Dolphin</emphasis>.</para>");
- actionCollection()->action(KStandardAction::name(KStandardAction::HelpContents))
- ->setWhatsThis(whatsThisHelpContents
+ setStandardActionWhatsThis(KStandardAction::HelpContents, whatsThisHelpContents
+ xi18nc("@info:whatsthis second half of handbook hb text without link",
"<para>If you want more elaborate introductions to the "
"different features of <emphasis>Dolphin</emphasis> "
"go to the KDE UserBase Wiki.</para>"));
- m_helpMenu->action(KHelpMenu::menuHelpContents)->setWhatsThis(whatsThisHelpContents
+ setHelpActionWhatsThis(KHelpMenu::menuHelpContents, whatsThisHelpContents
+ xi18nc("@info:whatsthis second half of handbook text with link",
"<para>If you want more elaborate introductions to the "
"different features of <emphasis>Dolphin</emphasis> "
"using right now! Click it, then click any component of this "
"application to ask \"What's this?\" about it. The mouse cursor "
"will change appearance if no help is available for a spot.</para>");
- actionCollection()->action(KStandardAction::name(KStandardAction::WhatsThis))
- ->setWhatsThis(whatsThisWhatsThis
+ setStandardActionWhatsThis(KStandardAction::WhatsThis, whatsThisWhatsThis
+ xi18nc("@info:whatsthis second half of whatsthis button text without link",
"<para>There are two other ways to get help for this application: The "
"<interface>Dolphin Handbook</interface> in the <interface>Help"
"article about <emphasis>File Management</emphasis> online."
"</para><para>The \"What's this?\" help is "
"missing in most other windows so don't get too used to this.</para>"));
- m_helpMenu->action(KHelpMenu::menuWhatsThis)->setWhatsThis(whatsThisWhatsThis
+ setHelpActionWhatsThis(KHelpMenu::menuWhatsThis, whatsThisWhatsThis
+ xi18nc("@info:whatsthis second half of whatsthis button text with link",
"<para>There are two other ways to get help: "
"The <link url='help:/dolphin/index.html'>Dolphin Handbook</link> and "
const QString whatsThisReportBug = xi18nc("@info:whatsthis","<para>This opens a "
"window that will guide you through reporting errors or flaws "
"in this application or in other KDE software.</para>");
- actionCollection()->action(KStandardAction::name(KStandardAction::ReportBug))
- ->setWhatsThis(whatsThisReportBug);
- m_helpMenu->action(KHelpMenu::menuReportBug)->setWhatsThis(whatsThisReportBug
+ setStandardActionWhatsThis(KStandardAction::ReportBug, whatsThisReportBug);
+ setHelpActionWhatsThis(KHelpMenu::menuReportBug, whatsThisReportBug
+ xi18nc("@info:whatsthis second half of reportbug text with link",
"<para>High-quality bug reports are much appreciated. To learn "
"how to make your bug report as effective as possible "
"require money like servers, contributor meetings, etc.</para>"
"<para><emphasis>KDE e.V.</emphasis> is the non-profit "
"organization behind the KDE community.</para>");
- actionCollection()->action(KStandardAction::name(KStandardAction::Donate))
- ->setWhatsThis(whatsThisDonate);
- m_helpMenu->action(KHelpMenu::menuDonate)->setWhatsThis(whatsThisDonate);
+ setStandardActionWhatsThis(KStandardAction::Donate, whatsThisDonate);
+ setHelpActionWhatsThis(KHelpMenu::menuDonate, whatsThisDonate);
const QString whatsThisSwitchLanguage = xi18nc("@info:whatsthis",
"With this you can change the language this application uses."
"<nl/>You can even set secondary languages which will be used "
"if texts are not available in your preferred language.");
- actionCollection()->action(KStandardAction::name(KStandardAction::SwitchApplicationLanguage))
- ->setWhatsThis(whatsThisSwitchLanguage);
- m_helpMenu->action(KHelpMenu::menuSwitchLanguage)->setWhatsThis(whatsThisSwitchLanguage);
+ setStandardActionWhatsThis(KStandardAction::SwitchApplicationLanguage,
+ whatsThisSwitchLanguage);
+ setHelpActionWhatsThis(KHelpMenu::menuSwitchLanguage, whatsThisSwitchLanguage);
const QString whatsThisAboutApp = xi18nc("@info:whatsthis","This opens a "
"window that informs you about the version, license, "
"used libraries and maintainers of this application.");
- actionCollection()->action(KStandardAction::name(KStandardAction::AboutApp))
- ->setWhatsThis(whatsThisAboutApp);
- m_helpMenu->action(KHelpMenu::menuAboutApp)->setWhatsThis(whatsThisAboutApp);
+ setStandardActionWhatsThis(KStandardAction::AboutApp, whatsThisAboutApp);
+ setHelpActionWhatsThis(KHelpMenu::menuAboutApp, whatsThisAboutApp);
const QString whatsThisAboutKDE = xi18nc("@info:whatsthis","This opens a "
"window with information about <emphasis>KDE</emphasis>. "
"The KDE community are the people behind this free software."
"<nl/>If you like using this application but don't know "
"about KDE or want to see a cute dragon have a look!");
- actionCollection()->action(KStandardAction::name(KStandardAction::AboutKDE))
- ->setWhatsThis(whatsThisAboutKDE);
- m_helpMenu->action(KHelpMenu::menuAboutKDE)->setWhatsThis(whatsThisAboutKDE);
+ setStandardActionWhatsThis(KStandardAction::AboutKDE, whatsThisAboutKDE);
+ setHelpActionWhatsThis(KHelpMenu::menuAboutKDE, whatsThisAboutKDE);
}
bool DolphinMainWindow::addHamburgerMenuToToolbar()