X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/7c2559dd0bf469454fbd83cde74dbd15c9aa09bc..b6fc58c3c32b03f504a5f697b62c4834dc3f650a:/src/dolphinmainwindow.cpp diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 0ba799fde..5e6b6e94a 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -31,6 +31,7 @@ #include "views/draganddrophelper.h" #include "views/viewproperties.h" #include "views/dolphinnewfilemenuobserver.h" +#include "views/dolphinurlnavigatorwidgetaction.h" #include "dolphin_generalsettings.h" #include @@ -48,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -70,7 +72,6 @@ #include #include #include -#include #include #include #include @@ -202,16 +203,35 @@ DolphinMainWindow::~DolphinMainWindow() { } -QVector DolphinMainWindow::viewContainers() const +QVector DolphinMainWindow::activeViewContainers() const { QVector viewContainers; - viewContainers.reserve(m_tabWidget->count()); + for (int i = 0; i < m_tabWidget->count(); ++i) { - viewContainers << m_tabWidget->tabPageAt(i)->activeViewContainer(); + DolphinTabPage *tabPage = m_tabWidget->tabPageAt(i); + + viewContainers << tabPage->primaryViewContainer(); + if (tabPage->splitViewEnabled()) { + viewContainers << tabPage->secondaryViewContainer(); + } } return viewContainers; } +void DolphinMainWindow::setViewsWithInvalidPathsToHome() +{ + const QVector 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& dirs, bool splitView) { m_tabWidget->openDirectories(dirs, splitView); @@ -227,6 +247,16 @@ void DolphinMainWindow::openFiles(const QList& files, bool splitView) m_tabWidget->openFiles(files, splitView); } +bool DolphinMainWindow::isFoldersPanelEnabled() const +{ + return actionCollection()->action(QStringLiteral("show_folders_panel"))->isChecked(); +} + +bool DolphinMainWindow::isInformationPanelEnabled() const +{ + return actionCollection()->action(QStringLiteral("show_information_panel"))->isChecked(); +} + void DolphinMainWindow::openFiles(const QStringList& files, bool splitView) { openFiles(QUrl::fromStringList(files), splitView); @@ -288,7 +318,7 @@ void DolphinMainWindow::changeUrl(const QUrl &url) updateViewActions(); updateGoActions(); - emit urlChanged(url); + Q_EMIT urlChanged(url); } void DolphinMainWindow::slotTerminalDirectoryChanged(const QUrl& url) @@ -323,12 +353,12 @@ void DolphinMainWindow::slotSelectionChanged(const KFileItemList& selection) compareFilesAction->setEnabled(false); } - emit selectionChanged(selection); + Q_EMIT selectionChanged(selection); } void DolphinMainWindow::updateHistory() { - const KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator(); + const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternal(); const int index = urlNavigator->historyIndex(); QAction* backAction = actionCollection()->action(KStandardAction::name(KStandardAction::Back)); @@ -409,7 +439,7 @@ void DolphinMainWindow::openInNewTab() const KFileItemList& list = m_activeViewContainer->view()->selectedItems(); bool tabCreated = false; - foreach (const KFileItem& item, list) { + for (const KFileItem& item : list) { const QUrl& url = DolphinView::openItemAsFolderUrl(item); if (!url.isEmpty()) { openNewTabAfterCurrentTab(url); @@ -475,7 +505,10 @@ void DolphinMainWindow::closeEvent(QCloseEvent* event) closedByUser = false; } - if (m_tabWidget->count() > 1 && GeneralSettings::confirmClosingMultipleTabs() && closedByUser) { + if (m_tabWidget->count() > 1 + && GeneralSettings::confirmClosingMultipleTabs() + && !GeneralSettings::rememberOpenedTabs() + && closedByUser) { // Ask the user if he really wants to quit and close all tabs. // Open a confirmation dialog with 3 buttons: // QDialogButtonBox::Yes -> Quit @@ -696,7 +729,7 @@ void DolphinMainWindow::slotToolBarActionMiddleClicked(QAction *action) void DolphinMainWindow::slotAboutToShowBackPopupMenu() { - KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator(); + const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternal(); int entries = 0; m_backAction->menu()->clear(); for (int i = urlNavigator->historyIndex() + 1; i < urlNavigator->historySize() && entries < MaxNumberOfNavigationentries; ++i, ++entries) { @@ -709,7 +742,7 @@ void DolphinMainWindow::slotAboutToShowBackPopupMenu() void DolphinMainWindow::slotGoBack(QAction* action) { int gotoIndex = action->data().value(); - KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator(); + const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternal(); for (int i = gotoIndex - urlNavigator->historyIndex(); i > 0; --i) { goBack(); } @@ -718,14 +751,14 @@ void DolphinMainWindow::slotGoBack(QAction* action) void DolphinMainWindow::slotBackForwardActionMiddleClicked(QAction* action) { if (action) { - KUrlNavigator* urlNavigator = activeViewContainer()->urlNavigator(); + const KUrlNavigator *urlNavigator = activeViewContainer()->urlNavigatorInternal(); openNewTabAfterCurrentTab(urlNavigator->locationUrl(action->data().value())); } } void DolphinMainWindow::slotAboutToShowForwardPopupMenu() { - KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator(); + const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternal(); int entries = 0; m_forwardAction->menu()->clear(); for (int i = urlNavigator->historyIndex() - 1; i >= 0 && entries < MaxNumberOfNavigationentries; --i, ++entries) { @@ -738,7 +771,7 @@ void DolphinMainWindow::slotAboutToShowForwardPopupMenu() void DolphinMainWindow::slotGoForward(QAction* action) { int gotoIndex = action->data().value(); - KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator(); + const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternal(); for (int i = urlNavigator->historyIndex() - gotoIndex; i > 0; --i) { goForward(); } @@ -810,6 +843,62 @@ void DolphinMainWindow::showFilterBar() m_activeViewContainer->setFilterBarVisible(true); } +void DolphinMainWindow::toggleLocationInToolbar() +{ + // collect needed variables + QAction *locationInToolbarAction = actionCollection()->action(QStringLiteral("location_in_toolbar")); + const bool locationInToolbar = locationInToolbarAction->isChecked(); + auto viewContainers = this->viewContainers(); + auto urlNavigatorWidgetAction = static_cast + (actionCollection()->action(QStringLiteral("url_navigator"))); + const bool isEditable = m_activeViewContainer->urlNavigator()->isUrlEditable(); + const QLineEdit *lineEdit = m_activeViewContainer->urlNavigator()->editor()->lineEdit(); + const bool hasFocus = lineEdit->hasFocus(); + const int cursorPosition = lineEdit->cursorPosition(); + const int selectionStart = lineEdit->selectionStart(); + const int selectionLength = lineEdit->selectionLength(); + + // prevent the switching if it would leave the user without a visible UrlNavigator + if (locationInToolbar && !toolBar()->actions().contains(urlNavigatorWidgetAction)) { + QAction *configureToolbars = actionCollection()->action(KStandardAction::name(KStandardAction::ConfigureToolbars)); + KMessageWidget *messageWidget = m_activeViewContainer->showMessage( + xi18nc("@info 2 is the visible text on a button just below the message", + "The location could not be moved onto the toolbar because there is currently " + "no \"%1\" item on the toolbar. Select %2 and add the " + "\"%1\" item. Then this will work.", urlNavigatorWidgetAction->iconText(), + configureToolbars->iconText()), DolphinViewContainer::Information); + messageWidget->addAction(configureToolbars); + messageWidget->addAction(locationInToolbarAction); + locationInToolbarAction->setChecked(false); + return; + } + + // do the switching + GeneralSettings::setLocationInToolbar(locationInToolbar); + if (locationInToolbar) { + for (const auto viewContainer : viewContainers) { + viewContainer->disconnectUrlNavigator(); + } + m_activeViewContainer->connectUrlNavigator(urlNavigatorWidgetAction->urlNavigator()); + } else { + m_activeViewContainer->disconnectUrlNavigator(); + for (const auto viewContainer : viewContainers) { + viewContainer->connectToInternalUrlNavigator(); + } + } + + urlNavigatorWidgetAction->setUrlNavigatorVisible(locationInToolbar); + m_activeViewContainer->urlNavigator()->setUrlEditable(isEditable); + if (hasFocus) { // the rest of this method is unneeded perfectionism + m_activeViewContainer->urlNavigator()->editor()->lineEdit()->setText(lineEdit->text()); + m_activeViewContainer->urlNavigator()->editor()->lineEdit()->setFocus(); + m_activeViewContainer->urlNavigator()->editor()->lineEdit()->setCursorPosition(cursorPosition); + if (selectionStart != -1) { + m_activeViewContainer->urlNavigator()->editor()->lineEdit()->setSelection(selectionStart, selectionLength); + } + } +} + void DolphinMainWindow::toggleEditLocation() { clearStatusBar(); @@ -840,7 +929,8 @@ void DolphinMainWindow::replaceLocation() void DolphinMainWindow::togglePanelLockState() { const bool newLockState = !GeneralSettings::lockPanels(); - foreach (QObject* child, children()) { + const auto childrenObjects = children(); + for (QObject* child : childrenObjects) { DolphinDockWidget* dock = qobject_cast(child); if (dock) { dock->setLocked(newLockState); @@ -859,7 +949,7 @@ void DolphinMainWindow::slotTerminalPanelVisibilityChanged() void DolphinMainWindow::goBack() { - KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator(); + DolphinUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternal(); urlNavigator->goBack(); if (urlNavigator->locationState().isEmpty()) { @@ -886,14 +976,14 @@ void DolphinMainWindow::goHome() void DolphinMainWindow::goBackInNewTab() { - KUrlNavigator* urlNavigator = activeViewContainer()->urlNavigator(); + KUrlNavigator* urlNavigator = activeViewContainer()->urlNavigatorInternal(); const int index = urlNavigator->historyIndex() + 1; openNewTabAfterCurrentTab(urlNavigator->locationUrl(index)); } void DolphinMainWindow::goForwardInNewTab() { - KUrlNavigator* urlNavigator = activeViewContainer()->urlNavigator(); + KUrlNavigator* urlNavigator = activeViewContainer()->urlNavigatorInternal(); const int index = urlNavigator->historyIndex() - 1; openNewTabAfterCurrentTab(urlNavigator->locationUrl(index)); } @@ -943,18 +1033,6 @@ void DolphinMainWindow::toggleShowMenuBar() } } -QString DolphinMainWindow::activeContainerLocalPath() -{ - KIO::StatJob* statJob = KIO::mostLocalUrl(m_activeViewContainer->url()); - KJobWidgets::setWindow(statJob, this); - statJob->exec(); - QUrl url = statJob->mostLocalUrl(); - if (url.isLocalFile()) { - return url.toLocalFile(); - } - return QDir::homePath(); -} - QPointer DolphinMainWindow::preferredSearchTool() { m_searchTools.clear(); @@ -1001,7 +1079,31 @@ void DolphinMainWindow::openPreferredSearchTool() void DolphinMainWindow::openTerminal() { - KToolInvocation::invokeTerminal(QString(), activeContainerLocalPath()); + const QUrl url = m_activeViewContainer->url(); + + if (url.isLocalFile()) { + KToolInvocation::invokeTerminal(QString(), url.toLocalFile()); + return; + } + + // Not a local file, with protocol Class ":local", try stat'ing + if (KProtocolInfo::protocolClass(url.scheme()) == QLatin1String(":local")) { + KIO::StatJob *job = KIO::mostLocalUrl(url); + KJobWidgets::setWindow(job, this); + connect(job, &KJob::result, this, [job]() { + QUrl statUrl; + if (!job->error()) { + statUrl = job->mostLocalUrl(); + } + + KToolInvocation::invokeTerminal(QString(), statUrl.isLocalFile() ? statUrl.toLocalFile() : QDir::homePath()); + }); + + return; + } + + // Nothing worked, just use $HOME + KToolInvocation::invokeTerminal(QString(), QDir::homePath()); } void DolphinMainWindow::editSettings() @@ -1013,6 +1115,7 @@ void DolphinMainWindow::editSettings() const QUrl url = container->url(); DolphinSettingsDialog* settingsDialog = new DolphinSettingsDialog(url, this); connect(settingsDialog, &DolphinSettingsDialog::settingsChanged, this, &DolphinMainWindow::refreshViews); + connect(settingsDialog, &DolphinSettingsDialog::settingsChanged, &DolphinUrlNavigator::slotReadSettings); settingsDialog->setAttribute(Qt::WA_DeleteOnClose); settingsDialog->show(); m_settingsDialog = settingsDialog; @@ -1210,12 +1313,19 @@ void DolphinMainWindow::activeViewChanged(DolphinViewContainer* viewContainer) oldViewContainer->disconnect(this); oldViewContainer->view()->disconnect(this); oldViewContainer->urlNavigator()->disconnect(this); + if (GeneralSettings::locationInToolbar()) { + oldViewContainer->disconnectUrlNavigator(); + } // except the requestItemInfo so that on hover the information panel can still be updated connect(oldViewContainer->view(), &DolphinView::requestItemInfo, this, &DolphinMainWindow::requestItemInfo); } + if (GeneralSettings::locationInToolbar()) { + viewContainer->connectUrlNavigator(static_cast + (actionCollection()->action(QStringLiteral("url_navigator")))->urlNavigator()); + } connectViewSignals(viewContainer); m_actionHandler->setCurrentView(viewContainer->view()); @@ -1228,7 +1338,7 @@ void DolphinMainWindow::activeViewChanged(DolphinViewContainer* viewContainer) updateSearchAction(); const QUrl url = viewContainer->url(); - emit urlChanged(url); + Q_EMIT urlChanged(url); } void DolphinMainWindow::tabCountChanged(int count) @@ -1252,6 +1362,10 @@ void DolphinMainWindow::updateWindowTitle() void DolphinMainWindow::slotStorageTearDownFromPlacesRequested(const QString& mountPath) { + connect(m_placesPanel, &PlacesPanel::storageTearDownSuccessful, this, [this, mountPath]() { + setViewsToHomeIfMountPathOpen(mountPath); + }); + if (m_terminalPanel && m_terminalPanel->currentWorkingDirectory().startsWith(mountPath)) { m_tearDownFromPlacesRequested = true; m_terminalPanel->goHome(); @@ -1263,12 +1377,27 @@ void DolphinMainWindow::slotStorageTearDownFromPlacesRequested(const QString& mo void DolphinMainWindow::slotStorageTearDownExternallyRequested(const QString& mountPath) { + connect(m_placesPanel, &PlacesPanel::storageTearDownSuccessful, this, [this, mountPath]() { + setViewsToHomeIfMountPathOpen(mountPath); + }); + if (m_terminalPanel && m_terminalPanel->currentWorkingDirectory().startsWith(mountPath)) { m_tearDownFromPlacesRequested = false; m_terminalPanel->goHome(); } } +void DolphinMainWindow::setViewsToHomeIfMountPathOpen(const QString& mountPath) +{ + const QVector theViewContainers = viewContainers(); + for (DolphinViewContainer *viewContainer : theViewContainers) { + if (viewContainer && viewContainer->url().toLocalFile().startsWith(mountPath)) { + viewContainer->setUrl(QUrl::fromLocalFile(QDir::homePath())); + } + } + disconnect(m_placesPanel, &PlacesPanel::storageTearDownSuccessful, nullptr, nullptr); +} + void DolphinMainWindow::setupActions() { // setup 'File' menu @@ -1428,6 +1557,16 @@ void DolphinMainWindow::setupActions() stop->setIcon(QIcon::fromTheme(QStringLiteral("process-stop"))); connect(stop, &QAction::triggered, this, &DolphinMainWindow::stopLoading); + KToggleAction* locationInToolbar = actionCollection()->add(QStringLiteral("location_in_toolbar")); + locationInToolbar->setText(i18nc("@action:inmenu Navigation Bar", "Location in Toolbar")); + locationInToolbar->setWhatsThis(xi18nc("@info:whatsthis", + "This toggles between showing the path in the " + "Location Bar and in the Toolbar.")); + actionCollection()->setDefaultShortcut(locationInToolbar, Qt::Key_F12); + locationInToolbar->setChecked(GeneralSettings::locationInToolbar()); + connect(locationInToolbar, &KToggleAction::triggered, this, &DolphinMainWindow::toggleLocationInToolbar); + DolphinUrlNavigator::addToContextMenu(locationInToolbar); + KToggleAction* editableLocation = actionCollection()->add(QStringLiteral("editable_location")); editableLocation->setText(i18nc("@action:inmenu Navigation Bar", "Editable Location")); editableLocation->setWhatsThis(xi18nc("@info:whatsthis", @@ -1546,7 +1685,6 @@ void DolphinMainWindow::setupActions() 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->setText(i18nc("@action:inmenu Tools", "Open Terminal")); @@ -1557,13 +1695,14 @@ void DolphinMainWindow::setupActions() 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); connect(focusTerminalPanel, &QAction::triggered, this, &DolphinMainWindow::focusTerminalPanel); - } #endif + } // setup 'Bookmarks' menu KActionMenu *bookmarkMenu = new KActionMenu(i18nc("@title:menu", "&Bookmarks"), this); @@ -1629,6 +1768,12 @@ void DolphinMainWindow::setupActions() connect(activatePrevTab, &QAction::triggered, m_tabWidget, &DolphinTabWidget::activatePrevTab); actionCollection()->setDefaultShortcuts(activatePrevTab, prevTabKeys); + auto *urlNavigatorWidgetAction = new DolphinUrlNavigatorWidgetAction(this); + urlNavigatorWidgetAction->setText(i18nc("@action:inmenu auto-hide: " + "Depending on the settings this Widget is blank/invisible.", + "Url Navigator (auto-hide)")); + actionCollection()->addAction(QStringLiteral("url_navigator"), urlNavigatorWidgetAction); + // for context menu QAction* showTarget = actionCollection()->addAction(QStringLiteral("show_target")); showTarget->setText(i18nc("@action:inmenu", "Show Target")); @@ -1820,14 +1965,14 @@ void DolphinMainWindow::setupDockWidgets() connect(this, &DolphinMainWindow::urlChanged, m_placesPanel, &PlacesPanel::setUrl); connect(placesDock, &DolphinDockWidget::visibilityChanged, - m_tabWidget, &DolphinTabWidget::slotPlacesPanelVisibilityChanged); + &DolphinUrlNavigator::slotPlacesPanelVisibilityChanged); connect(this, &DolphinMainWindow::settingsChanged, m_placesPanel, &PlacesPanel::readSettings); connect(m_placesPanel, &PlacesPanel::storageTearDownRequested, this, &DolphinMainWindow::slotStorageTearDownFromPlacesRequested); connect(m_placesPanel, &PlacesPanel::storageTearDownExternallyRequested, this, &DolphinMainWindow::slotStorageTearDownExternallyRequested); - m_tabWidget->slotPlacesPanelVisibilityChanged(m_placesPanel->isVisible()); + DolphinUrlNavigator::slotPlacesPanelVisibilityChanged(m_placesPanel->isVisible()); auto actionShowAllPlaces = new QAction(QIcon::fromTheme(QStringLiteral("view-hidden")), i18nc("@item:inmenu", "Show Hidden Places"), this); actionShowAllPlaces->setCheckable(true); @@ -2031,7 +2176,8 @@ bool DolphinMainWindow::addActionToMenu(QAction* action, QMenu* menu) Q_ASSERT(menu); const KToolBar* toolBarWidget = toolBar(); - foreach (const QWidget* widget, action->associatedWidgets()) { + const auto associatedWidgets = action->associatedWidgets(); + for (const QWidget* widget : associatedWidgets) { if (widget == toolBarWidget) { return false; } @@ -2054,7 +2200,7 @@ void DolphinMainWindow::refreshViews() updateWindowTitle(); } - emit settingsChanged(); + Q_EMIT settingsChanged(); } void DolphinMainWindow::clearStatusBar() @@ -2095,16 +2241,19 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container) this, &DolphinMainWindow::goForward); connect(view, &DolphinView::urlActivated, this, &DolphinMainWindow::handleUrl); + connect(view, &DolphinView::goUpRequested, + this, &DolphinMainWindow::goUp); const KUrlNavigator* navigator = container->urlNavigator(); connect(navigator, &KUrlNavigator::urlChanged, this, &DolphinMainWindow::changeUrl); - connect(navigator, &KUrlNavigator::historyChanged, - this, &DolphinMainWindow::updateHistory); connect(navigator, &KUrlNavigator::editableStateChanged, this, &DolphinMainWindow::slotEditableStateChanged); connect(navigator, &KUrlNavigator::tabRequested, this, &DolphinMainWindow::openNewTabAfterLastTab); + + connect(container->urlNavigatorInternal(), &KUrlNavigator::historyChanged, + this, &DolphinMainWindow::updateHistory); } void DolphinMainWindow::updateSplitAction()