#include "dolphinmainwindow.h"
+#include "dolphinmainwindowadaptor.h"
#include "config-terminal.h"
#include "global.h"
#include "dolphinbookmarkhandler.h"
#include <KJobWidgets>
#include <KLocalizedString>
#include <KMessageBox>
+#include <KNS3/KMoreToolsMenuFactory>
#include <KProtocolInfo>
#include <KProtocolManager>
#include <KRun>
const int CurrentDolphinVersion = 200;
// The maximum number of entries in the back/forward popup menu
const int MaxNumberOfNavigationentries = 12;
+ // The maximum number of "Activate Tab" shortcuts
+ const int MaxActivateTabShortcuts = 9;
}
DolphinMainWindow::DolphinMainWindow() :
- KXmlGuiWindow(nullptr, Qt::WindowContextHelpButtonHint),
+ KXmlGuiWindow(nullptr),
m_newFileMenu(nullptr),
m_helpMenu(nullptr),
m_tabWidget(nullptr),
m_forwardAction(nullptr)
{
Q_INIT_RESOURCE(dolphin);
+
+ new MainWindowAdaptor(this);
+
+#ifndef Q_OS_WIN
+ setWindowFlags(Qt::WindowContextHelpButtonHint);
+#endif
setComponentName(QStringLiteral("dolphin"), QGuiApplication::applicationDisplayName());
setObjectName(QStringLiteral("Dolphin#"));
toolBar()->installEventFilter(middleClickEventFilter);
setupWhatsThis();
+
+ QTimer::singleShot(0, this, &DolphinMainWindow::setupUpdateOpenPreferredSearchToolAction);
}
DolphinMainWindow::~DolphinMainWindow()
void DolphinMainWindow::activateWindow()
{
- KStartupInfo::setNewStartupId(window(), KStartupInfo::startupId());
+ window()->setAttribute(Qt::WA_NativeWindow, true);
+ KStartupInfo::setNewStartupId(window()->windowHandle(), KStartupInfo::startupId());
KWindowSystem::activateWindow(window()->effectiveWinId());
}
{
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" }, m_activeViewContainer->url()
+ );
+ QList<QAction*> actions = m_searchTools.actions();
+ if (actions.isEmpty()) {
+ return nullptr;
+ }
+ QAction* action = actions.first();
+ if (action->isSeparator()) {
+ return nullptr;
+ }
+ return action;
+}
- KToolInvocation::invokeTerminal(QString(), dir);
+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);
+ }
+ }
+
+ // 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();
void DolphinMainWindow::tabCountChanged(int count)
{
const bool enableTabActions = (count > 1);
+ for (int i = 0; i < MaxActivateTabShortcuts; ++i) {
+ actionCollection()->action(QStringLiteral("activate_tab_%1").arg(i))->setEnabled(enableTabActions);
+ }
+ actionCollection()->action(QStringLiteral("activate_last_tab"))->setEnabled(enableTabActions);
actionCollection()->action(QStringLiteral("activate_next_tab"))->setEnabled(enableTabActions);
actionCollection()->action(QStringLiteral("activate_prev_tab"))->setEnabled(enableTabActions);
}
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);
connect(m_forwardAction->menu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowForwardPopupMenu);
connect(m_forwardAction->menu(), &QMenu::triggered, this, &DolphinMainWindow::slotGoForward);
actionCollection()->addAction(m_forwardAction->objectName(), m_forwardAction);
+ actionCollection()->setDefaultShortcuts(m_forwardAction, m_forwardAction->shortcuts());
+
// enable middle-click to open in a new tab
auto *middleClickEventFilter = new MiddleClickActionEventFilter(this);
connect(middleClickEventFilter, &MiddleClickActionEventFilter::actionMiddleClicked, this, &DolphinMainWindow::slotBackForwardActionMiddleClicked);
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
QList<QKeySequence> prevTabKeys = KStandardShortcut::tabPrev();
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));
+ activateTab->setText(i18nc("@action:inmenu", "Activate Tab %1", i + 1));
+ activateTab->setEnabled(false);
+ connect(activateTab, &QAction::triggered, this, [this, i]() { m_tabWidget->activateTab(i); });
+
+ // only add default shortcuts for the first 9 tabs regardless of MaxActivateTabShortcuts
+ if (i < 9) {
+ actionCollection()->setDefaultShortcut(activateTab, QStringLiteral("Alt+%1").arg(i + 1));
+ }
+ }
+
+ QAction* activateLastTab = actionCollection()->addAction(QStringLiteral("activate_last_tab"));
+ 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);
+
QAction* activateNextTab = actionCollection()->addAction(QStringLiteral("activate_next_tab"));
activateNextTab->setIconText(i18nc("@action:inmenu", "Next Tab"));
activateNextTab->setText(i18nc("@action:inmenu", "Activate Next Tab"));
if (list.isEmpty()) {
stateChanged(QStringLiteral("has_no_selection"));
- addToPlacesAction->setText(i18nc("@action:inmenu Add current folder to places", "Add '%1' to Places", m_activeViewContainer->placesText()));
+ addToPlacesAction->setEnabled(true);
} else {
stateChanged(QStringLiteral("has_selection"));
QAction* cutAction = col->action(KStandardAction::name(KStandardAction::Cut));
QAction* deleteWithTrashShortcut = col->action(QStringLiteral("delete_shortcut")); // see DolphinViewActionHandler
QAction* showTarget = col->action(QStringLiteral("show_target"));
+ QAction* duplicateAction = col->action(QStringLiteral("duplicate")); // see DolphinViewActionHandler
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);
deleteWithTrashShortcut->setEnabled(capabilities.supportsDeleting() && !enableMoveToTrash);
cutAction->setEnabled(capabilities.supportsMoving());
showTarget->setEnabled(list.length() == 1 && list.at(0).isLink());
+ duplicateAction->setEnabled(capabilities.supportsWriting());
}
}
Q_ASSERT(!m_controlButton);
m_controlButton = new QToolButton(this);
+ m_controlButton->setAccessibleName(i18nc("@action:intoolbar", "Control"));
m_controlButton->setIcon(QIcon::fromTheme(QStringLiteral("application-menu")));
m_controlButton->setToolTip(i18nc("@action", "Show menu"));
m_controlButton->setAttribute(Qt::WidgetAttribute::WA_CustomWhatsThis);
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()
{