]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Add an option to use an UrlNavigator in the toolbar instead
authorFelix Ernst <fe.a.ernst@gmail.com>
Sun, 14 Jun 2020 14:20:02 +0000 (16:20 +0200)
committerElvis Angelaccio <elvis.angelaccio@kde.org>
Mon, 9 Nov 2020 22:49:07 +0000 (23:49 +0100)
This commit adds a locationInToolbar KToggleAction to switch between
using a location bar to navigate or using a new custom QWidgetAction
in the toolbar.

A big portion of this MR is refactoring because until now the
UrlNavigator was tightly intertwined with the DolphinViewContainer.
With this MR an UrlNavigator for controlling a View can be freely
connected or disconnected with a single method call.

A DolphinUrlNavigator class is created in the process which contains all
Dolphin-specific UrlNavigator code which did previously reside in the
DolphinViewContainer class. Other application parts that belong to
UrlNavigator-management are also moved here.

15 files changed:
src/CMakeLists.txt
src/dolphinbookmarkhandler.cpp
src/dolphinmainwindow.cpp
src/dolphinmainwindow.h
src/dolphintabpage.cpp
src/dolphintabwidget.cpp
src/dolphintabwidget.h
src/dolphinui.rc
src/dolphinurlnavigator.cpp [new file with mode: 0644]
src/dolphinurlnavigator.h [new file with mode: 0644]
src/dolphinviewcontainer.cpp
src/dolphinviewcontainer.h
src/settings/dolphin_generalsettings.kcfg
src/views/dolphinurlnavigatorwidgetaction.cpp [new file with mode: 0644]
src/views/dolphinurlnavigatorwidgetaction.h [new file with mode: 0644]

index bff52cf0f1e5c7714fd2fff9ba6402cb7985d25b..4610be463d2130c5c3f53003af65c2c3aba12d01 100644 (file)
@@ -208,6 +208,7 @@ set(dolphinstatic_SRCS
     dolphinrecenttabsmenu.cpp
     dolphintabpage.cpp
     dolphintabwidget.cpp
+    dolphinurlnavigator.cpp
     trash/dolphintrash.cpp
     filterbar/filterbar.cpp
     panels/places/placespanel.cpp
@@ -248,6 +249,7 @@ set(dolphinstatic_SRCS
     statusbar/mountpointobservercache.cpp
     statusbar/spaceinfoobserver.cpp
     statusbar/statusbarspaceinfo.cpp
+    views/dolphinurlnavigatorwidgetaction.cpp
     views/zoomlevelinfo.cpp
     dolphindebug.cpp
     global.cpp
index be4f447d86a77935a47328fa68d39413115671c5..efcb41692f631773827e8c4b89aa73ed13e3a53e 100644 (file)
@@ -68,7 +68,7 @@ bool DolphinBookmarkHandler::supportsTabs() const
 
 QList<KBookmarkOwner::FutureBookmark> DolphinBookmarkHandler::currentBookmarkList() const
 {
-    const auto viewContainers = m_mainWindow->viewContainers();
+    const auto viewContainers = m_mainWindow->viewContainers(false);
     QList<FutureBookmark> bookmarks;
     bookmarks.reserve(viewContainers.size());
     for (const auto viewContainer : viewContainers) {
index 97ced73b49df7fa033de3404a26e1083c19574c9..7c75ef0122736ad5f700cc35b010171cd24a82da 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>
@@ -201,7 +202,7 @@ DolphinMainWindow::~DolphinMainWindow()
 {
 }
 
-QVector<DolphinViewContainer*> DolphinMainWindow::viewContainers() const
+QVector<DolphinViewContainer*> DolphinMainWindow::viewContainers(bool includeInactive) const
 {
     QVector<DolphinViewContainer*> viewContainers;
 
@@ -356,7 +357,7 @@ void DolphinMainWindow::slotSelectionChanged(const KFileItemList& 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));
@@ -727,7 +728,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) {
@@ -740,7 +741,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();
     }
@@ -749,14 +750,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) {
@@ -769,7 +770,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();
     }
@@ -841,6 +842,47 @@ void DolphinMainWindow::showFilterBar()
     m_activeViewContainer->setFilterBarVisible(true);
 }
 
+void DolphinMainWindow::toggleLocationInToolbar()
+{
+    // collect needed variables
+    const bool locationInToolbar = actionCollection()->action(QStringLiteral("location_in_toolbar"))->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();
+
+    // 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();
@@ -891,7 +933,7 @@ void DolphinMainWindow::slotTerminalPanelVisibilityChanged()
 
 void DolphinMainWindow::goBack()
 {
-    KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
+    DolphinUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternal();
     urlNavigator->goBack();
 
     if (urlNavigator->locationState().isEmpty()) {
@@ -918,14 +960,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));
 }
@@ -1057,6 +1099,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;
@@ -1254,12 +1297,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());
@@ -1491,6 +1541,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",
@@ -1692,6 +1752,14 @@ 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);
+    connect(locationInToolbar, &KToggleAction::triggered,
+            urlNavigatorWidgetAction, &DolphinUrlNavigatorWidgetAction::setUrlNavigatorVisible);
+
     // for context menu
     QAction* showTarget = actionCollection()->addAction(QStringLiteral("show_target"));
     showTarget->setText(i18nc("@action:inmenu", "Show Target"));
@@ -1883,14 +1951,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);
@@ -2165,12 +2233,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()
index a56215fa7d28df019f924ded6b6c5d938ef1b1c5..529319e2adf1109193dcd81a171f61174b70749a 100644 (file)
@@ -68,9 +68,14 @@ public:
     DolphinViewContainer* activeViewContainer() const;
 
     /**
-     * Returns view container for all tabs
+     * Returns view containers for all tabs
+     * @param includeInactive   When true all view containers available in
+     *                          this window are returned. When false the
+     *                          view containers of split views that are not
+     *                          currently active are ignored.
+     *                          Default is true.
      */
-    QVector<DolphinViewContainer*> viewContainers() const;
+    QVector<DolphinViewContainer*> viewContainers(bool includeInactive = true) const;
 
     /**
      * Opens each directory in \p dirs in a separate tab. If \a splitView is set,
@@ -305,6 +310,12 @@ private slots:
 
     void showFilterBar();
 
+    /**
+     * Toggle between either using an UrlNavigator in the toolbar or the
+     * ones in the location bar for navigating.
+     */
+    void toggleLocationInToolbar();
+
     /**
      * Toggles between edit and browse mode of the navigation bar.
      */
index 837793b109695e14f9766dba3b673f84e9845815..30014eae87181ed2fb4ba77d8d019bb6f68ea653 100644 (file)
@@ -68,9 +68,6 @@ void DolphinTabPage::setSplitViewEnabled(bool enabled, const QUrl &secondaryUrl)
             const QUrl& url = (secondaryUrl.isEmpty()) ? m_primaryViewContainer->url() : secondaryUrl;
             m_secondaryViewContainer = createViewContainer(url);
 
-            const bool placesSelectorVisible = m_primaryViewContainer->urlNavigator()->isPlacesSelectorVisible();
-            m_secondaryViewContainer->urlNavigator()->setPlacesSelectorVisible(placesSelectorVisible);
-
             m_splitter->addWidget(m_secondaryViewContainer);
             m_secondaryViewContainer->show();
             m_secondaryViewContainer->setActive(true);
@@ -150,14 +147,6 @@ void DolphinTabPage::markUrlAsCurrent(const QUrl& url)
     }
 }
 
-void DolphinTabPage::setPlacesSelectorVisible(bool visible)
-{
-    m_primaryViewContainer->urlNavigator()->setPlacesSelectorVisible(visible);
-    if (m_splitViewEnabled) {
-        m_secondaryViewContainer->urlNavigator()->setPlacesSelectorVisible(visible);
-    }
-}
-
 void DolphinTabPage::refreshViews()
 {
     m_primaryViewContainer->readSettings();
@@ -176,12 +165,12 @@ QByteArray DolphinTabPage::saveState() const
     stream << m_splitViewEnabled;
 
     stream << m_primaryViewContainer->url();
-    stream << m_primaryViewContainer->urlNavigator()->isUrlEditable();
+    stream << m_primaryViewContainer->urlNavigatorInternal()->isUrlEditable();
     m_primaryViewContainer->view()->saveState(stream);
 
     if (m_splitViewEnabled) {
         stream << m_secondaryViewContainer->url();
-        stream << m_secondaryViewContainer->urlNavigator()->isUrlEditable();
+        stream << m_secondaryViewContainer->urlNavigatorInternal()->isUrlEditable();
         m_secondaryViewContainer->view()->saveState(stream);
     }
 
@@ -217,7 +206,7 @@ void DolphinTabPage::restoreState(const QByteArray& state)
     m_primaryViewContainer->setUrl(primaryUrl);
     bool primaryUrlEditable;
     stream >> primaryUrlEditable;
-    m_primaryViewContainer->urlNavigator()->setUrlEditable(primaryUrlEditable);
+    m_primaryViewContainer->urlNavigatorInternal()->setUrlEditable(primaryUrlEditable);
     m_primaryViewContainer->view()->restoreState(stream);
 
     if (isSplitViewEnabled) {
@@ -226,7 +215,7 @@ void DolphinTabPage::restoreState(const QByteArray& state)
         m_secondaryViewContainer->setUrl(secondaryUrl);
         bool secondaryUrlEditable;
         stream >> secondaryUrlEditable;
-        m_secondaryViewContainer->urlNavigator()->setUrlEditable(secondaryUrlEditable);
+        m_secondaryViewContainer->urlNavigatorInternal()->setUrlEditable(secondaryUrlEditable);
         m_secondaryViewContainer->view()->restoreState(stream);
     }
 
@@ -261,7 +250,7 @@ void DolphinTabPage::restoreStateV1(const QByteArray& state)
     m_primaryViewContainer->setUrl(primaryUrl);
     bool primaryUrlEditable;
     stream >> primaryUrlEditable;
-    m_primaryViewContainer->urlNavigator()->setUrlEditable(primaryUrlEditable);
+    m_primaryViewContainer->urlNavigatorInternal()->setUrlEditable(primaryUrlEditable);
 
     if (isSplitViewEnabled) {
         QUrl secondaryUrl;
@@ -269,7 +258,7 @@ void DolphinTabPage::restoreStateV1(const QByteArray& state)
         m_secondaryViewContainer->setUrl(secondaryUrl);
         bool secondaryUrlEditable;
         stream >> secondaryUrlEditable;
-        m_secondaryViewContainer->urlNavigator()->setUrlEditable(secondaryUrlEditable);
+        m_secondaryViewContainer->urlNavigatorInternal()->setUrlEditable(secondaryUrlEditable);
     }
 
     stream >> m_primaryViewActive;
index 5ef39dac658ce3793ac9083d2f10a64a300dca38..3ce8229f9325aaae10bedd1c3ae74a1d833da177 100644 (file)
@@ -22,7 +22,6 @@
 
 DolphinTabWidget::DolphinTabWidget(QWidget* parent) :
     QTabWidget(parent),
-    m_placesSelectorVisible(true),
     m_lastViewedTab(0)
 {
     KAcceleratorManager::setNoAccel(this);
@@ -157,7 +156,6 @@ void DolphinTabWidget::openNewTab(const QUrl& primaryUrl, const QUrl& secondaryU
 
     DolphinTabPage* tabPage = new DolphinTabPage(primaryUrl, secondaryUrl, this);
     tabPage->setActive(false);
-    tabPage->setPlacesSelectorVisible(m_placesSelectorVisible);
     connect(tabPage, &DolphinTabPage::activeViewChanged,
             this, &DolphinTabWidget::activeViewChanged);
     connect(tabPage, &DolphinTabPage::activeViewUrlChanged,
@@ -288,19 +286,6 @@ void DolphinTabWidget::activatePrevTab()
     setCurrentIndex(index >= 0 ? index : (count() - 1));
 }
 
-void DolphinTabWidget::slotPlacesPanelVisibilityChanged(bool visible)
-{
-    // The places-selector from the URL navigator should only be shown
-    // if the places dock is invisible
-    m_placesSelectorVisible = !visible;
-
-    const int tabCount = count();
-    for (int i = 0; i < tabCount; ++i) {
-        DolphinTabPage* tabPage = tabPageAt(i);
-        tabPage->setPlacesSelectorVisible(m_placesSelectorVisible);
-    }
-}
-
 void DolphinTabWidget::restoreClosedTab(const QByteArray& state)
 {
     openNewActivatedTab();
index 1eca71c5dccfc9ae8c294a225fa3d43b33c47512..9cc03f127659e2a453157c29142f75a721fd84ba 100644 (file)
@@ -163,13 +163,6 @@ public slots:
      */
     void activatePrevTab();
 
-    /**
-     * Is invoked if the Places panel got visible/invisible and takes care
-     * that the places-selector of all views is only shown if the Places panel
-     * is invisible.
-     */
-    void slotPlacesPanelVisibilityChanged(bool visible);
-
     /**
      * Is called when the user wants to reopen a previously closed tab from
      * the recent tabs menu.
@@ -231,9 +224,6 @@ private:
     QPair<int, bool> indexByUrl(const QUrl& url) const;
 
 private:
-    /** Caches the (negated) places panel visibility */
-    bool m_placesSelectorVisible;
-
     int m_lastViewedTab;
 };
 
index 46a4bac518c922064bdd63b80ff6399010b5db19..10c7c2fa4cc04fd54364e099d7f08023ec39c393 100644 (file)
@@ -56,6 +56,7 @@
                 <text context="@title:menu">Location Bar</text>
                 <Action name="editable_location" />
                 <Action name="replace_location" />
+                <Action name="location_in_toolbar" />
             </Menu>
             <Separator/>
             <Action name="view_properties" />
         <Action name="details" />
         <Separator name="separator_0" />
         <Action name="sort" />
-        <Spacer name="spacer_0" />
+        <Action name="url_navigator" />
         <Action name="split_view" />
         <Action name="split_stash" />
         <Action name="toggle_search" />
diff --git a/src/dolphinurlnavigator.cpp b/src/dolphinurlnavigator.cpp
new file mode 100644 (file)
index 0000000..70f780e
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2020  Felix Ernst <fe.a.ernst@gmail.com>
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "dolphinurlnavigator.h"
+
+#include "dolphin_generalsettings.h"
+#include "dolphinplacesmodelsingleton.h"
+#include "global.h"
+
+#include <KToggleAction>
+#include <KUrlComboBox>
+#include <KLocalizedString>
+
+#include <QLineEdit>
+#include <QMenu>
+
+DolphinUrlNavigator::DolphinUrlNavigator(QWidget *parent) :
+    KUrlNavigator(DolphinPlacesModelSingleton::instance().placesModel(), QUrl(), parent)
+{
+    init();
+}
+
+DolphinUrlNavigator::DolphinUrlNavigator(const QUrl &url, QWidget *parent) :
+    KUrlNavigator(DolphinPlacesModelSingleton::instance().placesModel(), url, parent)
+{
+    init();
+}
+
+void DolphinUrlNavigator::init()
+{
+    const GeneralSettings* settings = GeneralSettings::self();
+    setUrlEditable(settings->editableUrl());
+    setShowFullPath(settings->showFullPath());
+    setHomeUrl(Dolphin::homeUrl());
+    setPlacesSelectorVisible(s_placesSelectorVisible);
+    editor()->setCompletionMode(KCompletion::CompletionMode(settings->urlCompletionMode()));
+    editor()->lineEdit()->installEventFilter(this);
+    installEventFilter(this);
+    setWhatsThis(xi18nc("@info:whatsthis location bar",
+        "<para>This line describes the location of the files and folders "
+        "displayed below.</para><para>The name of the currently viewed "
+        "folder can be read at the very right. To the left of it is the "
+        "name of the folder that contains it. The whole line is called "
+        "the <emphasis>path</emphasis> to the current location because "
+        "following these folders from left to right leads here.</para>"
+        "<para>This interactive path "
+        "is more powerful than one would expect. To learn more "
+        "about the basic and advanced features of the location bar "
+        "<link url='help:/dolphin/location-bar.html'>click here</link>. "
+        "This will open the dedicated page in the Handbook.</para>"));
+
+    s_instances.push_front(this);
+
+    connect(this, &DolphinUrlNavigator::returnPressed,
+            this, &DolphinUrlNavigator::slotReturnPressed);
+    connect(editor(), &KUrlComboBox::completionModeChanged,
+            this, DolphinUrlNavigator::setCompletionMode);
+}
+
+DolphinUrlNavigator::~DolphinUrlNavigator()
+{
+    s_instances.remove(this);
+}
+
+bool DolphinUrlNavigator::eventFilter(QObject* watched, QEvent* event)
+{
+    Q_UNUSED(watched)
+    if (event->type() == QEvent::ChildPolished) {
+        QChildEvent *childEvent = static_cast<QChildEvent *>(event);
+        QMenu *popup = qobject_cast<QMenu *>(childEvent->child());
+        if (popup) {
+            // The popups of the "breadcrumb mode" navigation buttons
+            // should not get the action added. They can currently be
+            // identified by their number of separators: 0 or 1
+            // The popups we are interested in have 2 or more separators.
+            int separatorCount = 0;
+            for (QAction *action : popup->actions()) {
+                if (action->isSeparator()) {
+                    separatorCount++;
+                }
+            }
+            if (separatorCount > 1) {
+                q_check_ptr(s_ActionForContextMenu);
+                popup->addAction(s_ActionForContextMenu);
+            }
+        }
+    }
+    return false;
+}
+
+void DolphinUrlNavigator::slotReadSettings()
+{
+    // The startup settings should (only) get applied if they have been
+    // modified by the user. Otherwise keep the (possibly) different current
+    // settings of the URL navigators and split view.
+    if (GeneralSettings::modifiedStartupSettings()) {
+        for (DolphinUrlNavigator *urlNavigator : s_instances) {
+            urlNavigator->setUrlEditable(GeneralSettings::editableUrl());
+            urlNavigator->setShowFullPath(GeneralSettings::showFullPath());
+            urlNavigator->setHomeUrl(Dolphin::homeUrl());
+        }
+    }
+}
+
+void DolphinUrlNavigator::slotReturnPressed()
+{
+    if (!GeneralSettings::editableUrl()) {
+        setUrlEditable(false);
+    }
+}
+
+void DolphinUrlNavigator::addToContextMenu(QAction* action)
+{
+    s_ActionForContextMenu = action;
+}
+
+
+void DolphinUrlNavigator::slotPlacesPanelVisibilityChanged(bool visible)
+{
+    // The places-selector from the URL navigator should only be shown
+    // if the places dock is invisible
+    s_placesSelectorVisible = !visible;
+
+    for (DolphinUrlNavigator *urlNavigator : s_instances) {
+        urlNavigator->setPlacesSelectorVisible(s_placesSelectorVisible);
+    }
+}
+
+void DolphinUrlNavigator::setCompletionMode(const KCompletion::CompletionMode completionMode)
+{
+    if (completionMode != GeneralSettings::urlCompletionMode())
+    {
+        GeneralSettings::setUrlCompletionMode(completionMode);
+        for (const DolphinUrlNavigator *urlNavigator : s_instances)
+        {
+            urlNavigator->editor()->setCompletionMode(completionMode);
+        }
+    }
+}
+
+std::forward_list<DolphinUrlNavigator *> DolphinUrlNavigator::s_instances;
+bool DolphinUrlNavigator::s_placesSelectorVisible = true;
+QAction *DolphinUrlNavigator::s_ActionForContextMenu = nullptr;
diff --git a/src/dolphinurlnavigator.h b/src/dolphinurlnavigator.h
new file mode 100644 (file)
index 0000000..032b81e
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2020  Felix Ernst <fe.a.ernst@gmail.com>
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef DOLPHINURLNAVIGATOR_H
+#define DOLPHINURLNAVIGATOR_H
+
+#include <KCompletion>
+#include <KUrlNavigator>
+
+#include <forward_list>
+
+class KToggleAction;
+
+/**
+ * @brief Extends KUrlNavigator in a Dolphin-specific way
+ * 
+ * Makes sure that Dolphin preferences, settings and settings changes are
+ * applied to all constructed DolphinUrlNavigators.
+ * 
+ * @see KUrlNavigator
+ */
+class DolphinUrlNavigator : public KUrlNavigator
+{
+    Q_OBJECT
+
+public:
+    /**
+     * Applies all Dolphin-specific settings to a KUrlNavigator
+     * @see KUrlNavigator::KurlNavigator()
+     */
+    DolphinUrlNavigator(QWidget *parent = nullptr);
+
+    /**
+     * Applies all Dolphin-specific settings to a KUrlNavigator
+     * @see KUrlNavigator::KurlNavigator()
+     */
+    DolphinUrlNavigator(const QUrl &url, QWidget *parent = nullptr);
+
+    virtual ~DolphinUrlNavigator();
+
+public slots:
+    /**
+     * Refreshes all DolphinUrlNavigators to get synchronized with the
+     * Dolphin settings if they were changed.
+     */
+    static void slotReadSettings();
+
+    /**
+     * Switches to "breadcrumb" mode if the editable mode is not set to be
+     * preferred in the Dolphin settings.
+     */
+    void slotReturnPressed();
+
+    /**
+     * This method is specifically here so the locationInToolbar
+     * KToggleAction that is created in DolphinMainWindow can be passed to
+     * this class and then appear in all context menus. This last part is
+     * done by eventFilter().
+     * For any other use parts of this class need to be rewritten.
+     * @param action The locationInToolbar-action from DolphinMainWindow
+     */
+    static void addToContextMenu(QAction *action);
+
+    static void slotPlacesPanelVisibilityChanged(bool visible);
+
+protected:
+    /**
+     * Constructor-helper function
+     */
+    void init();
+
+    /**
+     * This filter adds the s_ActionForContextMenu action to QMenus which
+     * are spawned by the watched QObject if that QMenu contains at least
+     * two separators.
+     * @see addToContextMenu()
+     */
+    bool eventFilter(QObject * watched, QEvent * event) override;
+
+protected slots:
+    /**
+     * Sets the completion mode for all DolphinUrlNavigators
+     * and saves it in settings.
+     */
+    static void setCompletionMode(const KCompletion::CompletionMode completionMode);
+
+protected:
+    /** Contains all currently constructed DolphinUrlNavigators */
+    static std::forward_list<DolphinUrlNavigator *> s_instances;
+
+    /** Caches the (negated) places panel visibility */
+    static bool s_placesSelectorVisible;
+
+    /** An action that is added to the context menu */
+    static QAction *s_ActionForContextMenu;
+};
+
+#endif // DOLPHINURLNAVIGATOR_H
index b1b67447f8f90d1dbe2f2b793ceb4df247fbbd1d..da35041878d4749971f928c9d47922a48001c66a 100644 (file)
@@ -7,8 +7,8 @@
 #include "dolphinviewcontainer.h"
 
 #include "dolphin_generalsettings.h"
-#include "dolphinplacesmodelsingleton.h"
 #include "dolphindebug.h"
+#include "dolphinplacesmodelsingleton.h"
 #include "filterbar/filterbar.h"
 #include "global.h"
 #include "search/dolphinsearchbox.h"
@@ -31,6 +31,7 @@
 #include <KProtocolManager>
 #include <KShell>
 #include <KUrlComboBox>
+#include <KUrlNavigator>
 
 #include <QDropEvent>
 #include <QLoggingCategory>
@@ -45,6 +46,7 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) :
     m_topLayout(nullptr),
     m_navigatorWidget(nullptr),
     m_urlNavigator(nullptr),
+    m_urlNavigatorConnected(nullptr),
     m_emptyTrashButton(nullptr),
     m_searchBox(nullptr),
     m_searchModeEnabled(false),
@@ -66,34 +68,11 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) :
     m_topLayout->setContentsMargins(0, 0, 0, 0);
 
     m_navigatorWidget = new QWidget(this);
+    m_navigatorWidget->setVisible(false);
     QHBoxLayout* navigatorLayout = new QHBoxLayout(m_navigatorWidget);
     navigatorLayout->setSpacing(0);
     navigatorLayout->setContentsMargins(0, 0, 0, 0);
-    m_navigatorWidget->setWhatsThis(xi18nc("@info:whatsthis location bar",
-        "<para>This line describes the location of the files and folders "
-        "displayed below.</para><para>The name of the currently viewed "
-        "folder can be read at the very right. To the left of it is the "
-        "name of the folder that contains it. The whole line is called "
-        "the <emphasis>path</emphasis> to the current location because "
-        "following these folders from left to right leads here.</para>"
-        "<para>The path is displayed on the <emphasis>location bar</emphasis> "
-        "which is more powerful than one would expect. To learn more "
-        "about the basic and advanced features of the location bar "
-        "<link url='help:/dolphin/location-bar.html'>click here</link>. "
-        "This will open the dedicated page in the Handbook.</para>"));
-
-    m_urlNavigator = new KUrlNavigator(DolphinPlacesModelSingleton::instance().placesModel(), url, this);
-    connect(m_urlNavigator, &KUrlNavigator::activated,
-            this, &DolphinViewContainer::activate);
-    connect(m_urlNavigator->editor(), &KUrlComboBox::completionModeChanged,
-            this, &DolphinViewContainer::saveUrlCompletionMode);
-
-    const GeneralSettings* settings = GeneralSettings::self();
-    m_urlNavigator->setUrlEditable(settings->editableUrl());
-    m_urlNavigator->setShowFullPath(settings->showFullPath());
-    m_urlNavigator->setHomeUrl(Dolphin::homeUrl());
-    KUrlComboBox* editor = m_urlNavigator->editor();
-    editor->setCompletionMode(KCompletion::CompletionMode(settings->urlCompletionMode()));
+    m_urlNavigator = new DolphinUrlNavigator(url, m_navigatorWidget);
 
     m_emptyTrashButton = new QPushButton(QIcon::fromTheme(QStringLiteral("user-trash")), i18nc("@action:button", "Empty Trash"), this);
     m_emptyTrashButton->setFlat(true);
@@ -135,7 +114,7 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) :
 
     // Initialize filter bar
     m_filterBar = new FilterBar(this);
-    m_filterBar->setVisible(settings->filterBar());
+    m_filterBar->setVisible(GeneralSettings::filterBar());
 
     connect(m_filterBar, &FilterBar::filterChanged,
             this, &DolphinViewContainer::setNameFilter);
@@ -148,10 +127,14 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) :
     m_view = new DolphinView(url, this);
     connect(m_view, &DolphinView::urlChanged,
             m_filterBar, &FilterBar::slotUrlChanged);
-    connect(m_view, &DolphinView::urlChanged,
-            m_urlNavigator, &KUrlNavigator::setLocationUrl);
     connect(m_view, &DolphinView::urlChanged,
             m_messageWidget, &KMessageWidget::hide);
+    // m_urlNavigator stays in sync with m_view's location changes and
+    // keeps track of them so going back and forth in the history works.
+    connect(m_view, &DolphinView::urlChanged,
+            m_urlNavigator, &DolphinUrlNavigator::setLocationUrl);
+    connect(m_urlNavigator, &DolphinUrlNavigator::urlChanged,
+            this, &DolphinViewContainer::slotUrlNavigatorLocationChanged);
     connect(m_view, &DolphinView::writeStateChanged,
             this, &DolphinViewContainer::writeStateChanged);
     connect(m_view, &DolphinView::requestItemInfo,
@@ -183,18 +166,6 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) :
     connect(m_view, &DolphinView::activated,
             this, &DolphinViewContainer::activate);
 
-    connect(m_urlNavigator, &KUrlNavigator::urlAboutToBeChanged,
-            this, &DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged);
-    connect(m_urlNavigator, &KUrlNavigator::urlChanged,
-            this, &DolphinViewContainer::slotUrlNavigatorLocationChanged);
-    connect(m_urlNavigator, &KUrlNavigator::urlSelectionRequested,
-            this, &DolphinViewContainer::slotUrlSelectionRequested);
-    connect(m_urlNavigator, &KUrlNavigator::returnPressed,
-            this, &DolphinViewContainer::slotReturnPressed);
-    connect(m_urlNavigator, &KUrlNavigator::urlsDropped, this, [=](const QUrl &destination, QDropEvent *event) {
-        m_view->dropUrls(destination, event, m_urlNavigator->dropWidget());
-    });
-
     connect(m_view, &DolphinView::directoryLoadingCompleted, this, [this]() {
         m_emptyTrashButton->setVisible(m_view->url().scheme() == QLatin1String("trash"));
     });
@@ -235,6 +206,9 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) :
     m_topLayout->addWidget(m_filterBar);
     m_topLayout->addWidget(m_statusBar);
 
+    if (!GeneralSettings::locationInToolbar()) {
+        connectToInternalUrlNavigator();
+    }
     setSearchModeEnabled(isSearchUrl(url));
 
     connect(DetailsModeSettings::self(), &KCoreConfigSkeleton::configChanged, this, [=]() {
@@ -277,7 +251,7 @@ void DolphinViewContainer::setActive(bool active)
 
 bool DolphinViewContainer::isActive() const
 {
-    Q_ASSERT(m_view->isActive() == m_urlNavigator->isActive());
+    Q_ASSERT(!m_urlNavigatorConnected || m_urlNavigatorConnected->isActive() == m_view->isActive());
     return m_view->isActive();
 }
 
@@ -306,12 +280,22 @@ DolphinStatusBar* DolphinViewContainer::statusBar()
     return m_statusBar;
 }
 
-const KUrlNavigator* DolphinViewContainer::urlNavigator() const
+const DolphinUrlNavigator* DolphinViewContainer::urlNavigator() const
+{
+    return m_urlNavigatorConnected;
+}
+
+DolphinUrlNavigator* DolphinViewContainer::urlNavigator()
+{
+    return m_urlNavigatorConnected;
+}
+
+const DolphinUrlNavigator *DolphinViewContainer::urlNavigatorInternal() const
 {
     return m_urlNavigator;
 }
 
-KUrlNavigator* DolphinViewContainer::urlNavigator()
+DolphinUrlNavigator *DolphinViewContainer::urlNavigatorInternal()
 {
     return m_urlNavigator;
 }
@@ -326,6 +310,63 @@ DolphinView* DolphinViewContainer::view()
     return m_view;
 }
 
+void DolphinViewContainer::connectUrlNavigator(DolphinUrlNavigator *urlNavigator)
+{
+    Q_CHECK_PTR(urlNavigator);
+    Q_ASSERT(!m_urlNavigatorConnected);
+    Q_CHECK_PTR(m_view);
+
+    m_urlNavigatorConnected = urlNavigator;
+
+    // m_urlNavigator is already connected through urlChanged signals.
+    if (urlNavigator != m_urlNavigator) {
+        urlNavigator->setLocationUrl(m_view->url());
+        connect(m_view, &DolphinView::urlChanged,
+            urlNavigator, &DolphinUrlNavigator::setLocationUrl);
+        connect(urlNavigator, &DolphinUrlNavigator::urlChanged,
+            this, &DolphinViewContainer::slotUrlNavigatorLocationChanged);
+    }
+
+    connect(urlNavigator, &DolphinUrlNavigator::activated,
+            this, &DolphinViewContainer::activate);
+    connect(urlNavigator, &DolphinUrlNavigator::urlAboutToBeChanged,
+            this, &DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged);
+    connect(urlNavigator, &DolphinUrlNavigator::urlSelectionRequested,
+            this, &DolphinViewContainer::slotUrlSelectionRequested);
+    connect(urlNavigator, &DolphinUrlNavigator::urlsDropped, this, [=](const QUrl &destination, QDropEvent *event) {
+        m_view->dropUrls(destination, event, urlNavigator->dropWidget());
+    });
+
+    updateNavigatorWidgetVisibility();
+}
+
+void DolphinViewContainer::disconnectUrlNavigator()
+{
+    if (!m_urlNavigatorConnected) {
+        return;
+    }
+
+    // m_urlNavigator stays connected through the urlChanged signals.
+    if (m_urlNavigatorConnected != m_urlNavigator) {
+        disconnect(m_view, &DolphinView::urlChanged,
+            m_urlNavigatorConnected, &DolphinUrlNavigator::setLocationUrl);
+        disconnect(m_urlNavigatorConnected, &DolphinUrlNavigator::urlChanged,
+            this, &DolphinViewContainer::slotUrlNavigatorLocationChanged);
+    }
+
+    disconnect(m_urlNavigatorConnected, &DolphinUrlNavigator::activated,
+            this, &DolphinViewContainer::activate);
+    disconnect(m_urlNavigatorConnected, &DolphinUrlNavigator::urlAboutToBeChanged,
+            this, &DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged);
+    disconnect(m_urlNavigatorConnected, &DolphinUrlNavigator::urlSelectionRequested,
+            this, &DolphinViewContainer::slotUrlSelectionRequested);
+    disconnect(m_urlNavigatorConnected, &DolphinUrlNavigator::urlsDropped,
+            this, nullptr);
+
+    m_urlNavigatorConnected = nullptr;
+    updateNavigatorWidgetVisibility();
+}
+
 void DolphinViewContainer::showMessage(const QString& msg, MessageType type)
 {
     if (msg.isEmpty()) {
@@ -359,13 +400,10 @@ void DolphinViewContainer::showMessage(const QString& msg, MessageType type)
 
 void DolphinViewContainer::readSettings()
 {
+    // The startup settings should (only) get applied if they have been
+    // modified by the user. Otherwise keep the (possibly) different current
+    // setting of the filterbar.
     if (GeneralSettings::modifiedStartupSettings()) {
-        // The startup settings should only get applied if they have been
-        // modified by the user. Otherwise keep the (possibly) different current
-        // settings of the URL navigator and the filterbar.
-        m_urlNavigator->setUrlEditable(GeneralSettings::editableUrl());
-        m_urlNavigator->setShowFullPath(GeneralSettings::showFullPath());
-        m_urlNavigator->setHomeUrl(Dolphin::homeUrl());
         setFilterBarVisible(GeneralSettings::filterBar());
     }
 
@@ -381,10 +419,10 @@ bool DolphinViewContainer::isFilterBarVisible() const
 void DolphinViewContainer::setSearchModeEnabled(bool enabled)
 {
     m_searchBox->setVisible(enabled);
-    m_navigatorWidget->setVisible(!enabled);
+    updateNavigatorWidgetVisibility();
 
     if (enabled) {
-        const QUrl& locationUrl = m_urlNavigator->locationUrl();
+        const QUrl& locationUrl = m_urlNavigatorConnected->locationUrl();
         m_searchBox->fromSearchUrl(locationUrl);
     }
 
@@ -405,7 +443,7 @@ void DolphinViewContainer::setSearchModeEnabled(bool enabled)
         if (url.isEmpty() || !url.isValid() || isSearchUrl(url)) {
             url = Dolphin::homeUrl();
         }
-        m_urlNavigator->setLocationUrl(url);
+        m_urlNavigatorConnected->setLocationUrl(url);
     }
 
     m_searchModeEnabled = enabled;
@@ -498,8 +536,9 @@ QString DolphinViewContainer::caption() const
 
 void DolphinViewContainer::setUrl(const QUrl& newUrl)
 {
-    if (newUrl != m_urlNavigator->locationUrl()) {
-        m_urlNavigator->setLocationUrl(newUrl);
+    Q_CHECK_PTR(m_urlNavigatorConnected);
+    if (newUrl != m_urlNavigatorConnected->locationUrl()) {
+        m_urlNavigatorConnected->setLocationUrl(newUrl);
     }
 
 #ifdef HAVE_KACTIVITIES
@@ -560,6 +599,15 @@ void DolphinViewContainer::updateDirectorySortingProgress(int percent)
     m_statusBar->setProgress(percent);
 }
 
+void DolphinViewContainer::updateNavigatorWidgetVisibility()
+{
+    if (m_urlNavigatorConnected == m_urlNavigator && !m_searchBox->isVisible()) {
+        m_navigatorWidget->setVisible(true);
+    } else {
+        m_navigatorWidget->setVisible(false);
+    }
+}
+
 void DolphinViewContainer::slotDirectoryLoadingStarted()
 {
     if (isSearchUrl(url())) {
@@ -680,7 +728,9 @@ void DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged(const QUrl&)
 
 void DolphinViewContainer::slotUrlNavigatorLocationChanged(const QUrl& url)
 {
-    slotReturnPressed();
+    if (m_urlNavigatorConnected) {
+        m_urlNavigatorConnected->slotReturnPressed();
+    }
 
     if (KProtocolManager::supportsListing(url)) {
         setSearchModeEnabled(isSearchUrl(url));
@@ -739,24 +789,13 @@ void DolphinViewContainer::requestFocus()
     m_view->setFocus();
 }
 
-void DolphinViewContainer::saveUrlCompletionMode(KCompletion::CompletionMode completion)
-{
-    GeneralSettings::setUrlCompletionMode(completion);
-}
-
-void DolphinViewContainer::slotReturnPressed()
-{
-    if (!GeneralSettings::editableUrl()) {
-        m_urlNavigator->setUrlEditable(false);
-    }
-}
-
 void DolphinViewContainer::startSearching()
 {
+    Q_CHECK_PTR(m_urlNavigatorConnected);
     const QUrl url = m_searchBox->urlForSearching();
     if (url.isValid() && !url.isEmpty()) {
         m_view->setViewPropertiesContext(QStringLiteral("search"));
-        m_urlNavigator->setLocationUrl(url);
+        m_urlNavigatorConnected->setLocationUrl(url);
     }
 }
 
index ee1193f19c8d58bda831dac85c1fcca9bd2e1625..822d8072d1ea957db12489e733e8658a05e6db5c 100644 (file)
@@ -8,9 +8,9 @@
 #define DOLPHINVIEWCONTAINER_H
 
 #include "config-kactivities.h"
+#include "dolphinurlnavigator.h"
 #include "views/dolphinview.h"
 
-#include <KCompletion>
 #include <KFileItem>
 #include <KIO/Job>
 #include <KUrlNavigator>
@@ -85,12 +85,58 @@ public:
     const DolphinStatusBar* statusBar() const;
     DolphinStatusBar* statusBar();
 
-    const KUrlNavigator* urlNavigator() const;
-    KUrlNavigator* urlNavigator();
+    /**
+     * @return  An UrlNavigator that is controlling this view
+     *          or nullptr if there is none.
+     * @see connectUrlNavigator()
+     * @see disconnectUrlNavigator()
+     * 
+     * Use urlNavigatorInternal() if you want to access the history.
+     * @see urlNavigatorInternal()
+     */
+    const DolphinUrlNavigator *urlNavigator() const;
+    /**
+     * @return  An UrlNavigator that is controlling this view
+     *          or nullptr if there is none.
+     * @see connectUrlNavigator()
+     * @see disconnectUrlNavigator()
+     * 
+     * Use urlNavigatorInternal() if you want to access the history.
+     * @see urlNavigatorInternal()
+     */
+    DolphinUrlNavigator *urlNavigator();
+
+    /**
+     * @return An UrlNavigator that contains this view's history.
+     * Use urlNavigator() instead when not accessing the history.
+     */
+    const DolphinUrlNavigator *urlNavigatorInternal() const;
+    /**
+     * @return An UrlNavigator that contains this view's history.
+     * Use urlNavigator() instead when not accessing the history.
+     */
+    DolphinUrlNavigator *urlNavigatorInternal();
 
     const DolphinView* view() const;
     DolphinView* view();
 
+    /**
+     * @param urlNavigator  The UrlNavigator that is supposed to control
+     *                      this view.
+     */
+    void connectUrlNavigator(DolphinUrlNavigator *urlNavigator);
+
+    inline void connectToInternalUrlNavigator()
+    {
+        connectUrlNavigator(m_urlNavigator);
+    }
+
+    /**
+     * Disconnects the navigator that is currently controling the view.
+     * This method completely reverses connectUrlNavigator().
+     */
+    void disconnectUrlNavigator();
+
     /**
      * Shows the message \msg with the given type non-modal above
      * the view-content.
@@ -197,6 +243,8 @@ private slots:
 
     void updateDirectorySortingProgress(int percent);
 
+    void updateNavigatorWidgetVisibility();
+
     /**
      * Updates the statusbar to show an undetermined progress with the correct
      * context information whether a searching or a directory loading is done.
@@ -281,14 +329,6 @@ private slots:
     /** Requests the focus for the view \a m_view. */
     void requestFocus();
 
-    /**
-     * Saves the currently used URL completion mode of
-     * the URL navigator.
-     */
-    void saveUrlCompletionMode(KCompletion::CompletionMode completion);
-
-    void slotReturnPressed();
-
     /**
      * Gets the search URL from the searchbox and starts searching.
      */
@@ -329,7 +369,19 @@ private:
 private:
     QVBoxLayout* m_topLayout;
     QWidget* m_navigatorWidget;
-    KUrlNavigator* m_urlNavigator;
+
+    /**
+     * The UrlNavigator within the m_navigatorWidget. m_urlNavigator is
+     * used even when another UrlNavigator is controlling the view to keep
+     * track of this view containers history.
+     */
+    DolphinUrlNavigator *m_urlNavigator;
+
+    /**
+     * The UrlNavigator that is currently connected to the view. This could
+     * either be m_urlNavigator, the urlNavigator in the toolbar or nullptr.
+     */
+    QPointer<DolphinUrlNavigator> m_urlNavigatorConnected;
     QPushButton* m_emptyTrashButton;
     DolphinSearchBox* m_searchBox;
     bool m_searchModeEnabled;
index c397b2945124a49ab4867ff608337842c8d75e3d..9a13493a126275297d0103f75fa376313f20bc6b 100644 (file)
             <label>Split the view into two panes</label>
             <default>false</default>
         </entry>
+        <entry name="LocationInToolbar" type="Bool">
+            <label>Should the location be shown in the toolbar instead</label>
+            <default>false</default>
+        </entry>
         <entry name="FilterBar" type="Bool">
             <label>Should the filter bar be shown</label>
             <default>false</default>
diff --git a/src/views/dolphinurlnavigatorwidgetaction.cpp b/src/views/dolphinurlnavigatorwidgetaction.cpp
new file mode 100644 (file)
index 0000000..d9c9a4b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2020  Felix Ernst <fe.a.ernst@gmail.com>
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "dolphinurlnavigatorwidgetaction.h"
+
+#include "dolphin_generalsettings.h"
+#include "dolphinviewcontainer.h"
+
+#include <KLocalizedString>
+
+DolphinUrlNavigatorWidgetAction::DolphinUrlNavigatorWidgetAction(QWidget *parent) :
+    QWidgetAction(parent)
+{
+    setText(i18nc("@action:inmenu", "Url navigator"));
+
+    m_stackedWidget = new QStackedWidget(parent);
+
+    auto expandingSpacer = new QWidget(m_stackedWidget);
+    expandingSpacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
+    m_stackedWidget->addWidget(expandingSpacer); // index 0 of QStackedWidget
+
+    auto urlNavigator = new DolphinUrlNavigator(m_stackedWidget);
+    m_stackedWidget->addWidget(urlNavigator); // index 1 of QStackedWidget
+
+    setDefaultWidget(m_stackedWidget);
+    setUrlNavigatorVisible(GeneralSettings::locationInToolbar());
+}
+
+DolphinUrlNavigator* DolphinUrlNavigatorWidgetAction::urlNavigator() const
+{
+    return static_cast<DolphinUrlNavigator *>(m_stackedWidget->widget(1));
+}
+
+void DolphinUrlNavigatorWidgetAction::setUrlNavigatorVisible(bool visible)
+{
+    if (!visible) {
+        m_stackedWidget->setCurrentIndex(0); // expandingSpacer
+    } else {
+        m_stackedWidget->setCurrentIndex(1); // urlNavigator
+    }
+}
diff --git a/src/views/dolphinurlnavigatorwidgetaction.h b/src/views/dolphinurlnavigatorwidgetaction.h
new file mode 100644 (file)
index 0000000..5efd07f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020  Felix Ernst <fe.a.ernst@gmail.com>
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef DOLPHINURLNAVIGATORWIDGETACTION_H
+#define DOLPHINURLNAVIGATORWIDGETACTION_H
+
+#include "dolphinurlnavigator.h"
+
+#include <QWidgetAction>
+#include <QStackedWidget>
+
+/**
+ * @brief QWidgetAction that allows to use a KUrlNavigator in a toolbar.
+ * 
+ * When the UrlNavigator of this object is not in use,
+ * setUrlNavigatorVisible(false) is used to hide it. It will then be
+ * replaced in the toolbar by an empty expanding spacer. This makes sure
+ * that the other widgets in the toolbar will not change location when
+ * switching the UrlNavigators visibility.
+ */
+class DolphinUrlNavigatorWidgetAction : public QWidgetAction
+{
+    Q_OBJECT
+
+public:
+    DolphinUrlNavigatorWidgetAction(QWidget *parent = nullptr);
+
+    DolphinUrlNavigator *urlNavigator() const;
+    
+    /**
+     * Set the QStackedWidget which is the defaultWidget() to either
+     * show a KUrlNavigator or an expanding spacer.
+     */
+    void setUrlNavigatorVisible(bool visible);
+
+private:
+    QStackedWidget *m_stackedWidget;
+};
+
+#endif // DOLPHINURLNAVIGATORWIDGETACTION_H