From: Felix Ernst Date: Sun, 14 Jun 2020 14:20:02 +0000 (+0200) Subject: Add an option to use an UrlNavigator in the toolbar instead X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/ad5d3367c7fef4c3c11188a768f21a2ee2b3c025 Add an option to use an UrlNavigator in the toolbar instead 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. --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bff52cf0f..4610be463 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/dolphinbookmarkhandler.cpp b/src/dolphinbookmarkhandler.cpp index be4f447d8..efcb41692 100644 --- a/src/dolphinbookmarkhandler.cpp +++ b/src/dolphinbookmarkhandler.cpp @@ -68,7 +68,7 @@ bool DolphinBookmarkHandler::supportsTabs() const QList DolphinBookmarkHandler::currentBookmarkList() const { - const auto viewContainers = m_mainWindow->viewContainers(); + const auto viewContainers = m_mainWindow->viewContainers(false); QList bookmarks; bookmarks.reserve(viewContainers.size()); for (const auto viewContainer : viewContainers) { diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 97ced73b4..7c75ef012 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 @@ -201,7 +202,7 @@ DolphinMainWindow::~DolphinMainWindow() { } -QVector DolphinMainWindow::viewContainers() const +QVector DolphinMainWindow::viewContainers(bool includeInactive) const { QVector 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(); - 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())); } } 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(); - 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 + (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 + (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(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", @@ -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() diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index a56215fa7..529319e2a 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -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 viewContainers() const; + QVector 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. */ diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index 837793b10..30014eae8 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -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; diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp index 5ef39dac6..3ce8229f9 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -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(); diff --git a/src/dolphintabwidget.h b/src/dolphintabwidget.h index 1eca71c5d..9cc03f127 100644 --- a/src/dolphintabwidget.h +++ b/src/dolphintabwidget.h @@ -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 indexByUrl(const QUrl& url) const; private: - /** Caches the (negated) places panel visibility */ - bool m_placesSelectorVisible; - int m_lastViewedTab; }; diff --git a/src/dolphinui.rc b/src/dolphinui.rc index 46a4bac51..10c7c2fa4 100644 --- a/src/dolphinui.rc +++ b/src/dolphinui.rc @@ -56,6 +56,7 @@ Location Bar + @@ -121,7 +122,7 @@ - + diff --git a/src/dolphinurlnavigator.cpp b/src/dolphinurlnavigator.cpp new file mode 100644 index 000000000..70f780e55 --- /dev/null +++ b/src/dolphinurlnavigator.cpp @@ -0,0 +1,160 @@ +/* + * Copyright 2020 Felix Ernst + * + * 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 . + */ + +#include "dolphinurlnavigator.h" + +#include "dolphin_generalsettings.h" +#include "dolphinplacesmodelsingleton.h" +#include "global.h" + +#include +#include +#include + +#include +#include + +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", + "This line describes the location of the files and folders " + "displayed below.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 path to the current location because " + "following these folders from left to right leads here." + "This interactive path " + "is more powerful than one would expect. To learn more " + "about the basic and advanced features of the location bar " + "click here. " + "This will open the dedicated page in the Handbook.")); + + 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(event); + QMenu *popup = qobject_cast(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::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 index 000000000..032b81e89 --- /dev/null +++ b/src/dolphinurlnavigator.h @@ -0,0 +1,115 @@ +/* + * Copyright 2020 Felix Ernst + * + * 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 . + */ + +#ifndef DOLPHINURLNAVIGATOR_H +#define DOLPHINURLNAVIGATOR_H + +#include +#include + +#include + +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 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 diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index b1b67447f..da3504187 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -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 #include #include +#include #include #include @@ -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", - "This line describes the location of the files and folders " - "displayed below.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 path to the current location because " - "following these folders from left to right leads here." - "The path is displayed on the location bar " - "which is more powerful than one would expect. To learn more " - "about the basic and advanced features of the location bar " - "click here. " - "This will open the dedicated page in the Handbook.")); - - 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); } } diff --git a/src/dolphinviewcontainer.h b/src/dolphinviewcontainer.h index ee1193f19..822d8072d 100644 --- a/src/dolphinviewcontainer.h +++ b/src/dolphinviewcontainer.h @@ -8,9 +8,9 @@ #define DOLPHINVIEWCONTAINER_H #include "config-kactivities.h" +#include "dolphinurlnavigator.h" #include "views/dolphinview.h" -#include #include #include #include @@ -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 m_urlNavigatorConnected; QPushButton* m_emptyTrashButton; DolphinSearchBox* m_searchBox; bool m_searchModeEnabled; diff --git a/src/settings/dolphin_generalsettings.kcfg b/src/settings/dolphin_generalsettings.kcfg index c397b2945..9a13493a1 100644 --- a/src/settings/dolphin_generalsettings.kcfg +++ b/src/settings/dolphin_generalsettings.kcfg @@ -50,6 +50,10 @@ false + + + false + false diff --git a/src/views/dolphinurlnavigatorwidgetaction.cpp b/src/views/dolphinurlnavigatorwidgetaction.cpp new file mode 100644 index 000000000..d9c9a4bfa --- /dev/null +++ b/src/views/dolphinurlnavigatorwidgetaction.cpp @@ -0,0 +1,58 @@ +/* + * Copyright 2020 Felix Ernst + * + * 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 . + */ + +#include "dolphinurlnavigatorwidgetaction.h" + +#include "dolphin_generalsettings.h" +#include "dolphinviewcontainer.h" + +#include + +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(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 index 000000000..5efd07f46 --- /dev/null +++ b/src/views/dolphinurlnavigatorwidgetaction.h @@ -0,0 +1,57 @@ +/* + * Copyright 2020 Felix Ernst + * + * 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 . + */ + +#ifndef DOLPHINURLNAVIGATORWIDGETACTION_H +#define DOLPHINURLNAVIGATORWIDGETACTION_H + +#include "dolphinurlnavigator.h" + +#include +#include + +/** + * @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