]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphinmainwindow.cpp
Adress the first round of Angelaccio's review comments
[dolphin.git] / src / dolphinmainwindow.cpp
index 8bc890f04a592e50d894d3b040e30ae6860b9e7c..5e6b6e94a21c15d04d22ad2b4d67aa8a935622d7 100644 (file)
@@ -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 <KActionCollection>
@@ -48,6 +49,7 @@
 #include <KJobWidgets>
 #include <KLocalizedString>
 #include <KMessageBox>
+#include <KMessageWidget>
 #include <KNS3/KMoreToolsMenuFactory>
 #include <KProtocolInfo>
 #include <KProtocolManager>
@@ -201,16 +203,35 @@ DolphinMainWindow::~DolphinMainWindow()
 {
 }
 
-QVector<DolphinViewContainer*> DolphinMainWindow::viewContainers() const
+QVector<DolphinViewContainer *> DolphinMainWindow::activeViewContainers() const
 {
     QVector<DolphinViewContainer*> 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<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);
@@ -226,6 +247,16 @@ void DolphinMainWindow::openFiles(const QList<QUrl>& 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);
@@ -287,7 +318,7 @@ void DolphinMainWindow::changeUrl(const QUrl &url)
     updateViewActions();
     updateGoActions();
 
-    emit urlChanged(url);
+    Q_EMIT urlChanged(url);
 }
 
 void DolphinMainWindow::slotTerminalDirectoryChanged(const QUrl& url)
@@ -322,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));
@@ -408,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);
@@ -698,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) {
@@ -711,7 +742,7 @@ void DolphinMainWindow::slotAboutToShowBackPopupMenu()
 void DolphinMainWindow::slotGoBack(QAction* action)
 {
     int gotoIndex = action->data().value<int>();
-    KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
+    const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternal();
     for (int i = gotoIndex - urlNavigator->historyIndex(); i > 0; --i) {
         goBack();
     }
@@ -720,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<int>()));
     }
 }
 
 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) {
@@ -740,7 +771,7 @@ void DolphinMainWindow::slotAboutToShowForwardPopupMenu()
 void DolphinMainWindow::slotGoForward(QAction* action)
 {
     int gotoIndex = action->data().value<int>();
-    KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
+    const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternal();
     for (int i = urlNavigator->historyIndex() - gotoIndex; i > 0; --i) {
         goForward();
     }
@@ -812,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<DolphinUrlNavigatorWidgetAction *>
+        (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 <interface>%2</interface> 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();
@@ -842,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<DolphinDockWidget*>(child);
         if (dock) {
             dock->setLocked(newLockState);
@@ -861,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()) {
@@ -888,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));
 }
@@ -1027,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;
@@ -1224,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<DolphinUrlNavigatorWidgetAction *>
+            (actionCollection()->action(QStringLiteral("url_navigator")))->urlNavigator());
+    }
     connectViewSignals(viewContainer);
 
     m_actionHandler->setCurrentView(viewContainer->view());
@@ -1242,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)
@@ -1266,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();
@@ -1277,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<DolphinViewContainer*> 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
@@ -1442,6 +1557,16 @@ void DolphinMainWindow::setupActions()
     stop->setIcon(QIcon::fromTheme(QStringLiteral("process-stop")));
     connect(stop, &QAction::triggered, this, &DolphinMainWindow::stopLoading);
 
+    KToggleAction* locationInToolbar = actionCollection()->add<KToggleAction>(QStringLiteral("location_in_toolbar"));
+    locationInToolbar->setText(i18nc("@action:inmenu Navigation Bar", "Location in Toolbar"));
+    locationInToolbar->setWhatsThis(xi18nc("@info:whatsthis",
+        "This toggles between showing the <emphasis>path</emphasis> in the "
+        "<emphasis>Location Bar</emphasis> and in the <emphasis>Toolbar</emphasis>."));
+    actionCollection()->setDefaultShortcut(locationInToolbar, Qt::Key_F12);
+    locationInToolbar->setChecked(GeneralSettings::locationInToolbar());
+    connect(locationInToolbar, &KToggleAction::triggered, this, &DolphinMainWindow::toggleLocationInToolbar);
+    DolphinUrlNavigator::addToContextMenu(locationInToolbar);
+
     KToggleAction* editableLocation = actionCollection()->add<KToggleAction>(QStringLiteral("editable_location"));
     editableLocation->setText(i18nc("@action:inmenu Navigation Bar", "Editable Location"));
     editableLocation->setWhatsThis(xi18nc("@info:whatsthis",
@@ -1643,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"));
@@ -1834,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);
@@ -2045,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;
         }
@@ -2068,7 +2200,7 @@ void DolphinMainWindow::refreshViews()
         updateWindowTitle();
     }
 
-    emit settingsChanged();
+    Q_EMIT settingsChanged();
 }
 
 void DolphinMainWindow::clearStatusBar()
@@ -2115,12 +2247,13 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container)
     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()