diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -200,6 +200,7 @@ dolphinrecenttabsmenu.cpp dolphintabpage.cpp dolphintabwidget.cpp + dolphinurlnavigatorwidgetaction.cpp trash/dolphintrash.cpp filterbar/filterbar.cpp panels/places/placespanel.cpp diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -78,8 +78,10 @@ /** * Returns view container for all tabs + * @includeInactive Set true if inactive viewContainers in split + * views should also be returned. */ - QVector viewContainers() const; + QVector viewContainers(bool includeInactive = false) const; /** * Opens each directory in \p dirs in a separate tab. If \a splitView is set, @@ -296,6 +298,12 @@ void disableStopAction(); void showFilterBar(); + + /** + * Toggle between either having the location bars of the views + * being visible or the the location in the toolbar being visible + */ + void toggleLocationBar(); /** * Toggles between edit and browse mode of the navigation bar. diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -30,6 +30,7 @@ #include "dolphinrecenttabsmenu.h" #include "dolphinviewcontainer.h" #include "dolphintabpage.h" +#include "dolphinurlnavigatorwidgetaction.h" #include "middleclickactioneventfilter.h" #include "panels/folders/folderspanel.h" #include "panels/places/placesitemmodel.h" @@ -206,12 +207,20 @@ { } -QVector DolphinMainWindow::viewContainers() const +QVector DolphinMainWindow::viewContainers(bool includeInactive) const { QVector viewContainers; viewContainers.reserve(m_tabWidget->count()); for (int i = 0; i < m_tabWidget->count(); ++i) { viewContainers << m_tabWidget->tabPageAt(i)->activeViewContainer(); + + if (includeInactive && m_tabWidget->tabPageAt(i)->splitViewEnabled()) { + if (m_tabWidget->tabPageAt(i)->primaryViewActive()) { + viewContainers << m_tabWidget->tabPageAt(i)->secondaryViewContainer(); + } else { + viewContainers << m_tabWidget->tabPageAt(i)->primaryViewContainer(); + } + } } return viewContainers; } @@ -312,6 +321,10 @@ KToggleAction* editableLocationAction = static_cast(actionCollection()->action(QStringLiteral("editable_location"))); editableLocationAction->setChecked(editable); + + qobject_cast + (actionCollection()->action(QStringLiteral("url_navigator"))) + ->setUrlEditable(editable); } void DolphinMainWindow::slotSelectionChanged(const KFileItemList& selection) @@ -806,18 +819,43 @@ m_activeViewContainer->setFilterBarVisible(true); } +void DolphinMainWindow::toggleLocationBar() +{ + QAction* action = actionCollection()->action(QStringLiteral("show_location_bar")); + GeneralSettings::setLocationBar(action->isChecked()); + + const auto viewContainers = this->viewContainers(true); + for (const auto viewContainer : viewContainers) { + viewContainer->setLocationBarVisible(action->isChecked()); + } + + qobject_cast + (actionCollection()->action(QStringLiteral("url_navigator"))) + ->setWidgetVisible(!action->isChecked()); +} + void DolphinMainWindow::toggleEditLocation() { clearStatusBar(); QAction* action = actionCollection()->action(QStringLiteral("editable_location")); KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator(); urlNavigator->setUrlEditable(action->isChecked()); + + qobject_cast + (actionCollection()->action(QStringLiteral("url_navigator"))) + ->setUrlEditable(action->isChecked()); } void DolphinMainWindow::replaceLocation() { - KUrlNavigator* navigator = m_activeViewContainer->urlNavigator(); + KUrlNavigator* navigator; + if (GeneralSettings::locationBar()) { + navigator = m_activeViewContainer->urlNavigator(); + } else { + navigator = qobject_cast + (actionCollection()->action(QStringLiteral("url_navigator")))->urlNavigator(); + } QLineEdit* lineEdit = navigator->editor()->lineEdit(); // If the text field currently has focus and everything is selected, @@ -1244,6 +1282,9 @@ updateGoActions(); updateSearchAction(); + qobject_cast + (actionCollection()->action(QStringLiteral("url_navigator"))) + ->setUrlEditable(viewContainer->urlNavigator()->isUrlEditable()); const QUrl url = viewContainer->url(); emit urlChanged(url); } @@ -1426,6 +1467,12 @@ stop->setIcon(QIcon::fromTheme(QStringLiteral("process-stop"))); connect(stop, &QAction::triggered, this, &DolphinMainWindow::stopLoading); + KToggleAction* showLocationBar = actionCollection()->add(QStringLiteral("show_location_bar")); + showLocationBar->setText(i18nc("@action:inmenu Navigation Bar", "Separate Location Bar")); + actionCollection()->setDefaultShortcut(showLocationBar, Qt::Key_F12); + showLocationBar->setChecked(GeneralSettings::locationBar()); + connect(showLocationBar, &KToggleAction::triggered, this, &DolphinMainWindow::toggleLocationBar); + KToggleAction* editableLocation = actionCollection()->add(QStringLiteral("editable_location")); editableLocation->setText(i18nc("@action:inmenu Navigation Bar", "Editable Location")); editableLocation->setWhatsThis(xi18nc("@info:whatsthis", @@ -1627,6 +1674,19 @@ connect(activatePrevTab, &QAction::triggered, m_tabWidget, &DolphinTabWidget::activatePrevTab); actionCollection()->setDefaultShortcuts(activatePrevTab, prevTabKeys); + auto *urlNavigatorWidgetAction = new DolphinUrlNavigatorWidgetAction(this); + // i18n: "auto-hide": Depending on the settings this Widget is blank/invisible. + urlNavigatorWidgetAction->setText(i18nc("@action:inmenu", "Url Navigator (auto-hide)")); + actionCollection()->addAction(QStringLiteral("url_navigator"), urlNavigatorWidgetAction); + connect(this, &DolphinMainWindow::urlChanged, + urlNavigatorWidgetAction, &DolphinUrlNavigatorWidgetAction::setUrl); + connect(urlNavigatorWidgetAction, &DolphinUrlNavigatorWidgetAction::urlChanged, + this, &DolphinMainWindow::changeUrl); + connect(urlNavigatorWidgetAction, &DolphinUrlNavigatorWidgetAction::tabRequested, + this, &DolphinMainWindow::openNewTabAfterLastTab); + connect(urlNavigatorWidgetAction, &DolphinUrlNavigatorWidgetAction::editableStateChanged, + editableLocation, &QAction::trigger); + // for context menu QAction* showTarget = actionCollection()->addAction(QStringLiteral("show_target")); showTarget->setText(i18nc("@action:inmenu", "Show Target")); diff --git a/src/dolphinui.rc b/src/dolphinui.rc --- a/src/dolphinui.rc +++ b/src/dolphinui.rc @@ -1,5 +1,5 @@ - + @@ -42,6 +42,7 @@ Location Bar + @@ -107,7 +108,7 @@ - + diff --git a/src/dolphinurlnavigatorwidgetaction.h b/src/dolphinurlnavigatorwidgetaction.h new file mode 100644 --- /dev/null +++ b/src/dolphinurlnavigatorwidgetaction.h @@ -0,0 +1,117 @@ +/* + * 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 +#include + +#include +#include + +/** + * QWidgetAction that allows to use a KUrlNavigator in a toolbar. + * + * When a separate location bar is already present and this QWidgetAction + * is on a toolbar it will act like an empty expanding spacer but will + * internally mimic the state of the KUrlNavigator of the active view. + * + * When no separate location bar is present setWidgetVisible() is used + * to show the internal KUrlNavigator. This switch is done by a + * QStackedWidget which is the defaultWidget() of this QWidgetAction. + */ +class DolphinUrlNavigatorWidgetAction : public QWidgetAction +{ + Q_OBJECT + +public: + DolphinUrlNavigatorWidgetAction(QWidget *parent); + + KUrlNavigator * urlNavigator(); + + /** + * Set the QStackedWidget which is the defaultWidget() to either + * show a KUrlNavigator or an expanding spacer. + */ + void setWidgetVisible(bool visible); + +public slots: + /** + * This is invoked every time the folder being displayed in the + * active Dolphin view changes. + * Different from KUrlNavigator urlChanged() is not + * emitted following this to prevent a loop. + */ + void setUrl(const QUrl &url); + /** + * Set the interal KUrlNavigator to edit or breadcrumb mode. + * Different from KUrlNavigator editableStateChanged() is not + * emitted following this to prevent a loop. + */ + void setUrlEditable(bool editable); + +signals: + /** + * Is sent if the url of the internal KUrlNavigator has been + * changed by interacting with it directly. + * @see KUrlNavigator::urlChanged + */ + void urlChanged(const QUrl& url); + + /** @see KUrlNavigator::tabRequested */ + void tabRequested( const QUrl& url ); + + /** + * Is sent if the editable state of the internal KUrlNavigator + * has been changed by interacting with it directly. + * @see KUrlNavigator::editableStateChanged + */ + void editableStateChanged(bool editable); + +private slots: + /** + * Re-emits the urlChanged() signal of the internal KUrlNavigator + * if it has been changed by interacting with it directly. + */ + void transmitUrlChanged(const QUrl& url); + + /** + * Re-emits the editableStateChanged() signal of the internal + * KUrlNavigator if it has been changed by interacting with it directly. + */ + void transmitEditableStateChanged(const bool& editable); + + /** + * Saves the currently used URL completion mode of + * the URL navigator. + * @see DolphinViewContainer::saveUrlCompletionMode() + */ + void saveUrlCompletionMode(KCompletion::CompletionMode completion); + +private: + QStackedWidget *m_stackedWidget; + KUrlNavigator *m_urlNavigator; + QWidget *m_expandingSpacer; + QUrl m_url; + bool m_editable; +}; + +#endif // DOLPHINURLNAVIGATORWIDGETACTION_H diff --git a/src/dolphinurlnavigatorwidgetaction.cpp b/src/dolphinurlnavigatorwidgetaction.cpp new file mode 100644 --- /dev/null +++ b/src/dolphinurlnavigatorwidgetaction.cpp @@ -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 . + */ + +#include "dolphinurlnavigatorwidgetaction.h" + +#include "dolphinplacesmodelsingleton.h" +#include "dolphin_generalsettings.h" +#include "global.h" + +#include +#include + +#include +#include "dolphinviewcontainer.h" + +DolphinUrlNavigatorWidgetAction::DolphinUrlNavigatorWidgetAction(QWidget *parent) : + QWidgetAction(parent), + m_urlNavigator(nullptr) +{ + setText(i18nc("@action:inmenu", "Url navigator")); + + // Next seven lines copied from DolphinViewContainer::DolphinViewContainer + m_urlNavigator = new KUrlNavigator(DolphinPlacesModelSingleton::instance().placesModel(), *new QUrl, parent); + const GeneralSettings* settings = GeneralSettings::self(); + m_urlNavigator->setShowFullPath(settings->showFullPath()); + KUrlComboBox *editor = m_urlNavigator->editor(); + editor->setCompletionMode(KCompletion::CompletionMode(settings->urlCompletionMode())); + connect(editor, &KUrlComboBox::completionModeChanged, + this, &DolphinUrlNavigatorWidgetAction::saveUrlCompletionMode); + + connect(m_urlNavigator, &KUrlNavigator::urlChanged, + this, &DolphinUrlNavigatorWidgetAction::transmitUrlChanged); + connect(m_urlNavigator, &KUrlNavigator::tabRequested, + this, &DolphinUrlNavigatorWidgetAction::tabRequested); + connect(m_urlNavigator, &KUrlNavigator::editableStateChanged, + this, &DolphinUrlNavigatorWidgetAction::transmitEditableStateChanged); + + m_expandingSpacer = new QWidget(); + m_expandingSpacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + + m_stackedWidget = new QStackedWidget(); + m_stackedWidget->addWidget(m_urlNavigator); + m_stackedWidget->addWidget(m_expandingSpacer); + setWidgetVisible(!settings->locationBar()); + setDefaultWidget(m_stackedWidget); +} + +KUrlNavigator * DolphinUrlNavigatorWidgetAction::urlNavigator() +{ + return m_urlNavigator; +} + + +void DolphinUrlNavigatorWidgetAction::setWidgetVisible(bool visible) +{ + if (visible) { + m_stackedWidget->setCurrentIndex(0); + } else { + m_stackedWidget->setCurrentIndex(1); + } +} + +void DolphinUrlNavigatorWidgetAction::setUrl(const QUrl& url) +{ + if (!url.matches(m_url, QUrl::None)) { + m_url = url; + m_urlNavigator->setLocationUrl(url); + } +} + +void DolphinUrlNavigatorWidgetAction::transmitUrlChanged(const QUrl& url) +{ + if (!url.matches(m_url, QUrl::None)) { + m_url = url; + emit urlChanged(url); + } +} + +void DolphinUrlNavigatorWidgetAction::setUrlEditable(bool editable) +{ + if (m_editable != editable) { + m_editable = editable; + m_urlNavigator->setUrlEditable(editable); + } +} + +void DolphinUrlNavigatorWidgetAction::transmitEditableStateChanged(const bool& editable) +{ + if (m_editable != editable) { + m_editable = editable; + emit editableStateChanged(editable); + } +} + +void DolphinUrlNavigatorWidgetAction::saveUrlCompletionMode(KCompletion::CompletionMode completion) +{ + GeneralSettings::setUrlCompletionMode(completion); +} diff --git a/src/dolphinviewcontainer.h b/src/dolphinviewcontainer.h --- a/src/dolphinviewcontainer.h +++ b/src/dolphinviewcontainer.h @@ -104,6 +104,8 @@ const DolphinView* view() const; DolphinView* view(); + void setLocationBarVisible(bool visible); + /** * Shows the message \msg with the given type non-modal above * the view-content. diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -92,14 +92,15 @@ "about the basic and advanced features of the location bar " "click here. " "This will open the dedicated page in the Handbook.")); + const GeneralSettings* settings = GeneralSettings::self(); + m_navigatorWidget->setVisible(settings->locationBar()); 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()); @@ -331,6 +332,11 @@ return m_view; } +void DolphinViewContainer::setLocationBarVisible(bool visible) +{ + m_navigatorWidget->setVisible(visible); +} + void DolphinViewContainer::showMessage(const QString& msg, MessageType type) { if (msg.isEmpty()) { @@ -386,7 +392,11 @@ void DolphinViewContainer::setSearchModeEnabled(bool enabled) { m_searchBox->setVisible(enabled); - m_navigatorWidget->setVisible(!enabled); + if (enabled) { + m_navigatorWidget->setVisible(false); + } else if (GeneralSettings::locationBar()) { + m_navigatorWidget->setVisible(true); + } if (enabled) { const QUrl& locationUrl = m_urlNavigator->locationUrl(); diff --git a/src/settings/dolphin_generalsettings.kcfg b/src/settings/dolphin_generalsettings.kcfg --- a/src/settings/dolphin_generalsettings.kcfg +++ b/src/settings/dolphin_generalsettings.kcfg @@ -46,6 +46,10 @@ false + + + true + false