From 37327c9b0aae112c5890703cba1f0157043007e0 Mon Sep 17 00:00:00 2001 From: Felix Ernst Date: Sun, 20 Sep 2020 18:53:59 +0200 Subject: Make UrlNavigators in the toolbar the only option The UrlNavigators will be automatically added to the toolbar. The Sort By action is removed from the default toolbar to make space. Remove all options to have UrlNavigators outside the toolbar and remove those code paths. Make it so the new NavigatorsWidgetAction contains two UrlNavigators when in split view mode. Spacing was also added to align these UrlNavigators with the ViewContainers when enough space is available. Force the toolbar to be either at the top or bottom of the window. Set a sane sizeHint for DolphinUrlNavigator. It would be better to do this in KUrlNavigator in the future. This commit also contains a changes which should be moved to a separate merge requests before this gets merged: - Add an expansion animation when split view is enabled by the user --- src/dolphinnavigatorswidgetaction.h | 149 ++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 src/dolphinnavigatorswidgetaction.h (limited to 'src/dolphinnavigatorswidgetaction.h') diff --git a/src/dolphinnavigatorswidgetaction.h b/src/dolphinnavigatorswidgetaction.h new file mode 100644 index 000000000..c1808d68e --- /dev/null +++ b/src/dolphinnavigatorswidgetaction.h @@ -0,0 +1,149 @@ +/* + This file is part of the KDE project + SPDX-FileCopyrightText: 2020 Felix Ernst + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef DOLPHINNAVIGATORSWIDGETACTION_H +#define DOLPHINNAVIGATORSWIDGETACTION_H + +#include "dolphinurlnavigator.h" + +#include +#include +#include + +#include + +class KXmlGuiWindow; +class QPushButton; + +/** + * @brief QWidgetAction that allows to use DolphinUrlNavigators in a toolbar. + * + * This class is mainly a container that manages up to two DolphinUrlNavigator objects so they + * can be added to a toolbar. It also deals with alignment. + * + * The structure of the defaultWidget() of this QWidgetAction is as follows: + * - A QSplitter manages up to two sides which each correspond to one DolphinViewContainer. + * The secondary side only exists for split view and is created by + * createSecondaryUrlNavigator() when necessary. + * - Each side is a QWidget which I call NavigatorWidget with a QHBoxLayout. + * - Each NavigatorWidget consists an UrlNavigator, an emptyTrashButton and spacing. + * - Only the primary navigatorWidget has leading spacing. Both have trailing spacing. + * The spacing is there to align the UrlNavigator with its DolphinViewContainer. + */ +class DolphinNavigatorsWidgetAction : public QWidgetAction +{ + Q_OBJECT + + /** + * In Left-to-right languages the Primary side will be the left one. + */ + enum Side { + Primary, + Secondary + }; + +public: + DolphinNavigatorsWidgetAction(QWidget *parent = nullptr); + + /** + * Adds this action to the mainWindow's toolbar and saves the change + * in the users ui configuration file. + * @return true if successful. Otherwise false. + */ + bool addToToolbarAndSave(KXmlGuiWindow *mainWindow); + + /** + * Different to the primary UrlNavigator, the secondary UrlNavigator is only created on-demand. + */ + void createSecondaryUrlNavigator(); + + /** + * Notify the primary UrlNavigator of changes in geometry of the ViewContainer it tries to be + * aligned with. Only call this method if there is no secondary UrlNavigator. + */ + void followViewContainerGeometry(int globalXOfPrimary, int widthOfPrimary); + /** + * Notify this widget of changes in geometry of the ViewContainers it tries to be + * aligned with. + */ + void followViewContainersGeometry(int globalXOfPrimary, int widthOfPrimary, + int globalXOfSecondary, int widthOfSecondary); + + /** + * @return the primary UrlNavigator. + */ + DolphinUrlNavigator *primaryUrlNavigator() const; + /** + * @return the secondary UrlNavigator and nullptr if it doesn't exist. + */ + DolphinUrlNavigator *secondaryUrlNavigator() const; + + /** + * Change the visibility of the secondary UrlNavigator including spacing. + * @param visible Setting this to false will completely hide the secondary side of this + * WidgetAction's QSplitter making the QSplitter effectively disappear. + */ + void setSecondaryNavigatorVisible(bool visible); + +protected: + /** + * Adjusts the width of the spacings used to align the UrlNavigators with ViewContainers. + * This can only work nicely if up-to-date geometry of ViewContainers is cached so + * followViewContainersGeometry() has to have been called at least once before. + */ + void adjustSpacing(); + + /** + * Used to create the navigatorWidgets for both sides of the QSplitter. + */ + QWidget *createNavigatorWidget(Side side) const; + + /** + * Used to retrieve the emptyTrashButtons for the navigatorWidgets on both sides. + */ + QPushButton *emptyTrashButton(Side side); + + /** + * Creates a new empty trash button. + * @param urlNavigator Only when this UrlNavigator shows the trash directory + * will the the button be visible. + * @param parent Aside from the usual QObject deletion mechanisms, + * this parameter influences the positioning of dialog windows + * pertaining to this trash button. + */ + QPushButton *newEmptyTrashButton(const DolphinUrlNavigator *urlNavigator, QWidget *parent) const; + + enum Position { + Leading, + Trailing + }; + /** + * Used to retrieve both the leading and trailing spacing for the navigatorWidgets + * on both sides. A secondary leading spacing does not exist. + */ + QWidget *spacing(Side side, Position position) const; + + /** + * The defaultWidget() of this QWidgetAction. + */ + std::unique_ptr m_splitter; + + /** + * adjustSpacing() has to be called slightly later than when urlChanged is emitted. + * This timer bridges that time. + */ + std::unique_ptr m_adjustSpacingTimer; + + // cached values + int m_globalXOfSplitter; + int m_globalXOfPrimary; + int m_widthOfPrimary; + int m_globalXOfSecondary; + int m_widthOfSecondary; +}; + +#endif // DOLPHINNAVIGATORSWIDGETACTION_H -- cgit v1.3 From a418d6229e31dac254660da2a417b4306f066ae3 Mon Sep 17 00:00:00 2001 From: Felix Ernst Date: Wed, 28 Oct 2020 17:52:29 +0100 Subject: Fix a crash and extract unrelated changes The secondary UrlNavigator is now created when and only when: - split view mode is activated for the active tab OR - switching to a tab that has split view already enabled. This fixes a crash that occurs when the setting to always start in split view mode is enabled. An animation for activating split view is also removed from this and moved into a separate MR. Another unrelated name change left over from a previous commit (viewContainers() -> activeViewContainers()) is dropped. --- src/dolphinbookmarkhandler.cpp | 2 +- src/dolphinmainwindow.cpp | 3 ++- src/dolphinmainwindow.h | 6 +++--- src/dolphinnavigatorswidgetaction.h | 8 +++++++- src/dolphintabpage.cpp | 41 +------------------------------------ src/dolphintabpage.h | 2 -- src/dolphintabwidget.cpp | 8 ++++---- 7 files changed, 18 insertions(+), 52 deletions(-) (limited to 'src/dolphinnavigatorswidgetaction.h') diff --git a/src/dolphinbookmarkhandler.cpp b/src/dolphinbookmarkhandler.cpp index 576a9314b..be4f447d8 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->activeViewContainers(); + const auto viewContainers = m_mainWindow->viewContainers(); QList bookmarks; bookmarks.reserve(viewContainers.size()); for (const auto viewContainer : viewContainers) { diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 6a93de078..8b389ce9b 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -213,7 +213,7 @@ DolphinMainWindow::~DolphinMainWindow() { } -QVector DolphinMainWindow::activeViewContainers() const +QVector DolphinMainWindow::viewContainers() const { QVector viewContainers; @@ -2178,6 +2178,7 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container) auto navigators = static_cast (actionCollection()->action(QStringLiteral("url_navigators"))); + KUrlNavigator *navigator = m_tabWidget->currentTabPage()->primaryViewActive() ? navigators->primaryUrlNavigator() : navigators->secondaryUrlNavigator(); diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index 173e017c9..29ab6326d 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -65,12 +65,12 @@ public: * having a split view setup, the nonactive view * is usually shown in darker colors. */ - DolphinViewContainer *activeViewContainer() const; + DolphinViewContainer* activeViewContainer() const; /** - * Returns the active view containers of all tabs. + * Returns view container for all tabs */ - QVector activeViewContainers() const; + QVector viewContainers() const; /** * Opens each directory in \p dirs in a separate tab. If \a splitView is set, diff --git a/src/dolphinnavigatorswidgetaction.h b/src/dolphinnavigatorswidgetaction.h index c1808d68e..8046ce2dc 100644 --- a/src/dolphinnavigatorswidgetaction.h +++ b/src/dolphinnavigatorswidgetaction.h @@ -57,7 +57,13 @@ public: bool addToToolbarAndSave(KXmlGuiWindow *mainWindow); /** - * Different to the primary UrlNavigator, the secondary UrlNavigator is only created on-demand. + * The secondary UrlNavigator is only created on-demand. Such an action is not necessary + * for the primary UrlNavigator which is created preemptively. + * + * This method should preferably only be called when: + * - Split view is activated in the active tab + * OR + * - A switch to a tab that is already in split view mode is occuring */ void createSecondaryUrlNavigator(); diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index d2fd1d143..d196508a8 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -9,7 +9,6 @@ #include "dolphin_generalsettings.h" #include "dolphinviewcontainer.h" -#include #include #include @@ -70,7 +69,6 @@ void DolphinTabPage::setSplitViewEnabled(bool enabled, const QUrl &secondaryUrl) m_splitViewEnabled = enabled; if (enabled) { - int splitterTotalWidth = m_splitter->width(); const QUrl& url = (secondaryUrl.isEmpty()) ? m_primaryViewContainer->url() : secondaryUrl; m_secondaryViewContainer = createViewContainer(url); @@ -84,33 +82,8 @@ void DolphinTabPage::setSplitViewEnabled(bool enabled, const QUrl &secondaryUrl) m_splitter->addWidget(m_secondaryViewContainer); m_secondaryViewContainer->installEventFilter(this); - m_secondaryViewContainer->setActive(true); - - // opening animation - m_splitter->widget(1)->setMinimumWidth(1); - const QList splitterSizes = {m_splitter->width(), 0}; - m_splitter->setSizes(splitterSizes); - - // TODO: This is only here to test the robustness of DolphinNavigatorsWidgetAction! I still have to move it to another merge request! - m_splitViewAnimation = new QVariantAnimation(m_splitter); - m_splitViewAnimation->setDuration(200); // TODO: where do I get the animation times from again? - m_splitViewAnimation->setStartValue(splitterTotalWidth); - m_splitViewAnimation->setEndValue(splitterTotalWidth / 2); - m_splitViewAnimation->setEasingCurve(QEasingCurve::OutCubic); - - connect(m_splitViewAnimation, &QVariantAnimation::valueChanged, [=]() { - if (m_splitter->count() != 2) { - return; - } - int value = m_splitViewAnimation->currentValue().toInt(); - const QList splitterSizes = {value, m_splitter->width() - value}; - m_splitter->setSizes(splitterSizes); - if (value == m_splitViewAnimation->endValue().toInt()) { - m_splitter->widget(1)->setMinimumWidth(m_splitter->widget(1)->minimumSizeHint().width()); - } - }); - m_splitViewAnimation->start(QAbstractAnimation::DeleteWhenStopped); m_secondaryViewContainer->show(); + m_secondaryViewContainer->setActive(true); } else { m_navigatorsWidget->setSecondaryNavigatorVisible(false); m_secondaryViewContainer->disconnectUrlNavigator(); @@ -144,10 +117,6 @@ void DolphinTabPage::setSplitViewEnabled(bool enabled, const QUrl &secondaryUrl) m_primaryViewContainer->setActive(true); view->close(); view->deleteLater(); - if (m_splitViewAnimation) { - delete m_splitViewAnimation; - m_splitter->widget(0)->setMinimumWidth(m_splitter->widget(0)->minimumSizeHint().width()); - } } } } @@ -194,10 +163,6 @@ void DolphinTabPage::connectNavigators(DolphinNavigatorsWidgetAction *navigators m_primaryViewContainer->connectUrlNavigator(primaryNavigator); if (m_splitViewEnabled) { auto secondaryNavigator = navigatorsWidget->secondaryUrlNavigator(); - if (!secondaryNavigator) { - navigatorsWidget->createSecondaryUrlNavigator(); - secondaryNavigator = navigatorsWidget->secondaryUrlNavigator(); - } secondaryNavigator->setActive(!m_primaryViewActive); m_secondaryViewContainer->connectUrlNavigator(secondaryNavigator); } @@ -334,10 +299,6 @@ void DolphinTabPage::restoreState(const QByteArray& state) m_navigatorsWidget->primaryUrlNavigator()->setActive(false); } - if (m_splitViewAnimation) { - delete m_splitViewAnimation; - m_splitter->widget(0)->setMinimumWidth(m_splitter->widget(0)->minimumSizeHint().width()); - } QByteArray splitterState; stream >> splitterState; m_splitter->restoreState(splitterState); diff --git a/src/dolphintabpage.h b/src/dolphintabpage.h index 6a8801edd..650594214 100644 --- a/src/dolphintabpage.h +++ b/src/dolphintabpage.h @@ -14,7 +14,6 @@ class DolphinNavigatorsWidgetAction; class DolphinViewContainer; class QSplitter; -class QVariantAnimation; class KFileItemList; class DolphinTabPage : public QWidget @@ -175,7 +174,6 @@ private: QPointer m_navigatorsWidget; QPointer m_primaryViewContainer; QPointer m_secondaryViewContainer; - QPointer m_splitViewAnimation; bool m_primaryViewActive; bool m_splitViewEnabled; diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp index a09a769d3..eb3f741ee 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -128,12 +128,9 @@ bool DolphinTabWidget::isUrlOpen(const QUrl &url) const void DolphinTabWidget::openNewActivatedTab() { std::unique_ptr oldNavigatorState; - if (currentTabPage()->primaryViewActive()) { + if (currentTabPage()->primaryViewActive() || !m_navigatorsWidget->secondaryUrlNavigator()) { oldNavigatorState = m_navigatorsWidget->primaryUrlNavigator()->visualState(); } else { - if (!m_navigatorsWidget->secondaryUrlNavigator()) { - m_navigatorsWidget->createSecondaryUrlNavigator(); - } oldNavigatorState = m_navigatorsWidget->secondaryUrlNavigator()->visualState(); } @@ -401,6 +398,9 @@ void DolphinTabWidget::currentTabChanged(int index) m_lastViewedTab->disconnectNavigators(); m_lastViewedTab->setActive(false); } + if (tabPage->splitViewEnabled() && !m_navigatorsWidget->secondaryUrlNavigator()) { + m_navigatorsWidget->createSecondaryUrlNavigator(); + } DolphinViewContainer* viewContainer = tabPage->activeViewContainer(); Q_EMIT activeViewChanged(viewContainer); Q_EMIT currentUrlChanged(viewContainer->url()); -- cgit v1.3 From 2d4d2ce9a14902ee5a2b236f8510596fc2f86b99 Mon Sep 17 00:00:00 2001 From: Felix Ernst Date: Thu, 5 Nov 2020 23:30:07 +0100 Subject: Adress most of the second round of Angelaccio's review comments This commit applies most suggestions which were made on the MR. Most notably the DolphinUrlNavigator class is split up which leads to the creation of a DolphinUrlNavigatorsController class. Additionally some minor coding style and const correctness changes are included. The error value of cached integers is changed from -1 to INT_MIN because situations could come up in which -1 would be a valid value. --- src/CMakeLists.txt | 1 + src/dolphinmainwindow.cpp | 27 ++++++------ src/dolphinnavigatorswidgetaction.cpp | 37 +++++++++++------ src/dolphinnavigatorswidgetaction.h | 22 ++++++---- src/dolphintabwidget.cpp | 1 - src/dolphintabwidget.h | 2 +- src/dolphinurlnavigator.cpp | 61 ++++----------------------- src/dolphinurlnavigator.h | 44 ++------------------ src/dolphinurlnavigatorscontroller.cpp | 67 ++++++++++++++++++++++++++++++ src/dolphinurlnavigatorscontroller.h | 76 ++++++++++++++++++++++++++++++++++ src/dolphinviewcontainer.cpp | 3 +- 11 files changed, 208 insertions(+), 133 deletions(-) create mode 100644 src/dolphinurlnavigatorscontroller.cpp create mode 100644 src/dolphinurlnavigatorscontroller.h (limited to 'src/dolphinnavigatorswidgetaction.h') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8fad34347..1955ce558 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -210,6 +210,7 @@ set(dolphinstatic_SRCS dolphintabpage.cpp dolphintabwidget.cpp dolphinurlnavigator.cpp + dolphinurlnavigatorscontroller.cpp trash/dolphintrash.cpp filterbar/filterbar.cpp panels/places/placespanel.cpp diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index e3435685f..0c4c3c881 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -14,8 +14,10 @@ #include "dolphinbookmarkhandler.h" #include "dolphindockwidget.h" #include "dolphincontextmenu.h" +#include "dolphinnavigatorswidgetaction.h" #include "dolphinnewfilemenu.h" #include "dolphinrecenttabsmenu.h" +#include "dolphinurlnavigatorscontroller.h" #include "dolphinviewcontainer.h" #include "dolphintabpage.h" #include "middleclickactioneventfilter.h" @@ -31,7 +33,6 @@ #include "views/draganddrophelper.h" #include "views/viewproperties.h" #include "views/dolphinnewfilemenuobserver.h" -#include "dolphinnavigatorswidgetaction.h" #include "dolphin_generalsettings.h" #include @@ -106,8 +107,7 @@ DolphinMainWindow::DolphinMainWindow() : m_placesPanel(nullptr), m_tearDownFromPlacesRequested(false), m_backAction(nullptr), - m_forwardAction(nullptr), - m_updateHistoryConnection{} + m_forwardAction(nullptr) { Q_INIT_RESOURCE(dolphin); @@ -210,7 +210,7 @@ DolphinMainWindow::~DolphinMainWindow() { } -QVector DolphinMainWindow::viewContainers() const +QVector DolphinMainWindow::viewContainers() const { QVector viewContainers; @@ -927,14 +927,14 @@ void DolphinMainWindow::goHome() void DolphinMainWindow::goBackInNewTab() { - KUrlNavigator* urlNavigator = activeViewContainer()->urlNavigatorInternalWithHistory(); + const KUrlNavigator* urlNavigator = activeViewContainer()->urlNavigatorInternalWithHistory(); const int index = urlNavigator->historyIndex() + 1; openNewTabAfterCurrentTab(urlNavigator->locationUrl(index)); } void DolphinMainWindow::goForwardInNewTab() { - KUrlNavigator* urlNavigator = activeViewContainer()->urlNavigatorInternalWithHistory(); + const KUrlNavigator* urlNavigator = activeViewContainer()->urlNavigatorInternalWithHistory(); const int index = urlNavigator->historyIndex() - 1; openNewTabAfterCurrentTab(urlNavigator->locationUrl(index)); } @@ -1066,7 +1066,8 @@ 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); + connect(settingsDialog, &DolphinSettingsDialog::settingsChanged, + &DolphinUrlNavigatorsController::slotReadSettings); settingsDialog->setAttribute(Qt::WA_DeleteOnClose); settingsDialog->show(); m_settingsDialog = settingsDialog; @@ -1898,14 +1899,14 @@ void DolphinMainWindow::setupDockWidgets() connect(this, &DolphinMainWindow::urlChanged, m_placesPanel, &PlacesPanel::setUrl); connect(placesDock, &DolphinDockWidget::visibilityChanged, - &DolphinUrlNavigator::slotPlacesPanelVisibilityChanged); + &DolphinUrlNavigatorsController::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); - DolphinUrlNavigator::slotPlacesPanelVisibilityChanged(m_placesPanel->isVisible()); + DolphinUrlNavigatorsController::slotPlacesPanelVisibilityChanged(m_placesPanel->isVisible()); auto actionShowAllPlaces = new QAction(QIcon::fromTheme(QStringLiteral("view-hidden")), i18nc("@item:inmenu", "Show Hidden Places"), this); actionShowAllPlaces->setCheckable(true); @@ -2176,13 +2177,13 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container) auto navigators = static_cast (actionCollection()->action(QStringLiteral("url_navigators"))); - KUrlNavigator *navigator = m_tabWidget->currentTabPage()->primaryViewActive() ? - navigators->primaryUrlNavigator() : - navigators->secondaryUrlNavigator(); + const KUrlNavigator *navigator = m_tabWidget->currentTabPage()->primaryViewActive() ? + navigators->primaryUrlNavigator() : + navigators->secondaryUrlNavigator(); connect(navigator, &KUrlNavigator::urlChanged, this, &DolphinMainWindow::changeUrl); - QAction* editableLocactionAction = actionCollection()->action(QStringLiteral("editable_location")); + QAction *editableLocactionAction = actionCollection()->action(QStringLiteral("editable_location")); editableLocactionAction->setChecked(navigator->isUrlEditable()); connect(navigator, &KUrlNavigator::editableStateChanged, this, &DolphinMainWindow::slotEditableStateChanged); diff --git a/src/dolphinnavigatorswidgetaction.cpp b/src/dolphinnavigatorswidgetaction.cpp index 11140347a..84f52279a 100644 --- a/src/dolphinnavigatorswidgetaction.cpp +++ b/src/dolphinnavigatorswidgetaction.cpp @@ -18,18 +18,19 @@ #include #include +#include + DolphinNavigatorsWidgetAction::DolphinNavigatorsWidgetAction(QWidget *parent) : QWidgetAction{parent}, m_splitter{new QSplitter(Qt::Horizontal)}, m_adjustSpacingTimer{new QTimer(this)}, - m_globalXOfPrimary{-1}, - m_widthOfPrimary{-1}, - m_globalXOfSecondary{-1}, - m_widthOfSecondary{-1} + m_globalXOfSplitter{INT_MIN}, + m_globalXOfPrimary{INT_MIN}, + m_widthOfPrimary{INT_MIN}, + m_globalXOfSecondary{INT_MIN}, + m_widthOfSecondary{INT_MIN} { - setText(i18nc( - "@action:inmenu When split view is enabled there are two otherwise one.", - "Url Navigator(s)")); + updateText(); setIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts"))); m_splitter->setChildrenCollapsible(false); @@ -76,12 +77,13 @@ void DolphinNavigatorsWidgetAction::createSecondaryUrlNavigator() Q_ASSERT(m_splitter->count() == 1); m_splitter->addWidget(createNavigatorWidget(Secondary)); Q_ASSERT(m_splitter->count() == 2); + updateText(); } void DolphinNavigatorsWidgetAction::followViewContainerGeometry( int globalXOfPrimary, int widthOfPrimary) { - followViewContainersGeometry(globalXOfPrimary, widthOfPrimary, -1, -1); + followViewContainersGeometry(globalXOfPrimary, widthOfPrimary, INT_MIN, INT_MIN); } void DolphinNavigatorsWidgetAction::followViewContainersGeometry( @@ -99,7 +101,7 @@ void DolphinNavigatorsWidgetAction::followViewContainersGeometry( DolphinUrlNavigator* DolphinNavigatorsWidgetAction::primaryUrlNavigator() const { Q_ASSERT(m_splitter); - return static_cast(m_splitter->widget(0)->findChild()); + return m_splitter->widget(0)->findChild(); } DolphinUrlNavigator* DolphinNavigatorsWidgetAction::secondaryUrlNavigator() const @@ -108,7 +110,7 @@ DolphinUrlNavigator* DolphinNavigatorsWidgetAction::secondaryUrlNavigator() cons if (m_splitter->count() < 2) { return nullptr; } - return static_cast(m_splitter->widget(1)->findChild()); + return m_splitter->widget(1)->findChild(); } void DolphinNavigatorsWidgetAction::setSecondaryNavigatorVisible(bool visible) @@ -121,10 +123,14 @@ void DolphinNavigatorsWidgetAction::setSecondaryNavigatorVisible(bool visible) // Fix an unlikely event of wrong trash button visibility. emptyTrashButton(Secondary)->setVisible(false); } + updateText(); } void DolphinNavigatorsWidgetAction::adjustSpacing() { + Q_ASSERT(m_globalXOfSplitter != INT_MIN); + Q_ASSERT(m_globalXOfPrimary != INT_MIN); + Q_ASSERT(m_widthOfPrimary != INT_MIN); const int widthOfSplitterPrimary = m_globalXOfPrimary + m_widthOfPrimary - m_globalXOfSplitter; const QList splitterSizes = {widthOfSplitterPrimary, m_splitter->width() - widthOfSplitterPrimary}; @@ -156,8 +162,8 @@ void DolphinNavigatorsWidgetAction::adjustSpacing() spacing(Primary, Trailing)->setFixedWidth(trailingSpacing); // secondary side of m_splitter - if (m_globalXOfSecondary == -1) { - Q_ASSERT(m_widthOfSecondary == -1); + if (m_globalXOfSecondary == INT_MIN) { + Q_ASSERT(m_widthOfSecondary == INT_MIN); return; } spacing(Primary, Trailing)->setFixedWidth(0); @@ -244,3 +250,10 @@ QWidget *DolphinNavigatorsWidgetAction::spacing(Side side, Position position) co } return m_splitter->widget(sideIndex)->layout()->itemAt(2)->widget(); } + +void DolphinNavigatorsWidgetAction::updateText() +{ + const int urlNavigatorsAmount = m_splitter->count() > 1 && m_splitter->widget(1)->isVisible() ? + 2 : 1; + setText(i18ncp("@action:inmenu", "Url Navigator", "Url Navigators", urlNavigatorsAmount)); +} diff --git a/src/dolphinnavigatorswidgetaction.h b/src/dolphinnavigatorswidgetaction.h index 8046ce2dc..f343e6a1c 100644 --- a/src/dolphinnavigatorswidgetaction.h +++ b/src/dolphinnavigatorswidgetaction.h @@ -38,14 +38,6 @@ class DolphinNavigatorsWidgetAction : public QWidgetAction { Q_OBJECT - /** - * In Left-to-right languages the Primary side will be the left one. - */ - enum Side { - Primary, - Secondary - }; - public: DolphinNavigatorsWidgetAction(QWidget *parent = nullptr); @@ -95,7 +87,7 @@ public: */ void setSecondaryNavigatorVisible(bool visible); -protected: +private: /** * Adjusts the width of the spacings used to align the UrlNavigators with ViewContainers. * This can only work nicely if up-to-date geometry of ViewContainers is cached so @@ -103,6 +95,13 @@ protected: */ void adjustSpacing(); + /** + * In Left-to-right languages the Primary side will be the left one. + */ + enum Side { + Primary, + Secondary + }; /** * Used to create the navigatorWidgets for both sides of the QSplitter. */ @@ -133,6 +132,11 @@ protected: */ QWidget *spacing(Side side, Position position) const; + /** + * Sets this action's text depending on the amount of visible UrlNavigators. + */ + void updateText(); + /** * The defaultWidget() of this QWidgetAction. */ diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp index eb3f741ee..94cdc627b 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -8,7 +8,6 @@ #include "dolphin_generalsettings.h" #include "dolphintabbar.h" -#include "dolphintabpage.h" #include "dolphinviewcontainer.h" #include diff --git a/src/dolphintabwidget.h b/src/dolphintabwidget.h index 707eb086a..4a1b9d99c 100644 --- a/src/dolphintabwidget.h +++ b/src/dolphintabwidget.h @@ -8,11 +8,11 @@ #define DOLPHIN_TAB_WIDGET_H #include "dolphinnavigatorswidgetaction.h" +#include "dolphintabpage.h" #include #include -class DolphinTabPage; class DolphinViewContainer; class KConfigGroup; diff --git a/src/dolphinurlnavigator.cpp b/src/dolphinurlnavigator.cpp index 2b7f3d4eb..f24cf2e06 100644 --- a/src/dolphinurlnavigator.cpp +++ b/src/dolphinurlnavigator.cpp @@ -9,6 +9,7 @@ #include "dolphin_generalsettings.h" #include "dolphinplacesmodelsingleton.h" +#include "dolphinurlnavigatorscontroller.h" #include "global.h" #include @@ -19,24 +20,17 @@ #include DolphinUrlNavigator::DolphinUrlNavigator(QWidget *parent) : - KUrlNavigator(DolphinPlacesModelSingleton::instance().placesModel(), QUrl(), parent) -{ - init(); -} + DolphinUrlNavigator(QUrl(), parent) +{} 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); + setPlacesSelectorVisible(DolphinUrlNavigatorsController::placesSelectorVisible()); editor()->setCompletionMode(KCompletion::CompletionMode(settings->urlCompletionMode())); setWhatsThis(xi18nc("@info:whatsthis location bar", "This describes the location of the files and folders " @@ -51,22 +45,21 @@ void DolphinUrlNavigator::init() "click here. " "This will open the dedicated page in the Handbook.")); - s_instances.push_front(this); + DolphinUrlNavigatorsController::registerDolphinUrlNavigator(this); connect(this, &DolphinUrlNavigator::returnPressed, this, &DolphinUrlNavigator::slotReturnPressed); connect(editor(), &KUrlComboBox::completionModeChanged, - this, DolphinUrlNavigator::setCompletionMode); + DolphinUrlNavigatorsController::setCompletionMode); } DolphinUrlNavigator::~DolphinUrlNavigator() { - s_instances.remove(this); + DolphinUrlNavigatorsController::unregisterDolphinUrlNavigator(this); } QSize DolphinUrlNavigator::sizeHint() const { - // Change sizeHint() in KUrlNavigator instead. if (isUrlEditable()) { return editor()->lineEdit()->sizeHint(); } @@ -110,49 +103,9 @@ void DolphinUrlNavigator::setVisualState(const VisualState& visualState) } } -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::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; diff --git a/src/dolphinurlnavigator.h b/src/dolphinurlnavigator.h index 8f8d270ae..a15428799 100644 --- a/src/dolphinurlnavigator.h +++ b/src/dolphinurlnavigator.h @@ -8,17 +8,12 @@ #ifndef DOLPHINURLNAVIGATOR_H #define DOLPHINURLNAVIGATOR_H -#include #include -#include - -class KToggleAction; - /** - * @brief Extends KUrlNavigator in a Dolphin-specific way + * @brief Extends KUrlNavigator in a Dolphin-specific way. * - * Makes sure that Dolphin preferences, settings and settings changes are + * Makes sure that Dolphin preferences and settings are * applied to all constructed DolphinUrlNavigators. * * @see KUrlNavigator @@ -42,12 +37,7 @@ public: virtual ~DolphinUrlNavigator(); - /** - * This method is needed so the DolphinNavigatorWidgetAction knows when there is not enough - * space to neatly align the UrlNavigator with the ViewContainers. Unfortunately KUrlNavigator - * does not have a useful sizeHint() currently. It would make more sense to change - * KUrlNavigator instead. - */ + // TODO: Fix KUrlNavigator::sizeHint() instead. QSize sizeHint() const override; /** @@ -73,39 +63,11 @@ public: void setVisualState(const VisualState &visualState); 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(); - - static void slotPlacesPanelVisibilityChanged(bool visible); - -protected: - /** - * Constructor-helper function - */ - void init(); - -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; }; #endif // DOLPHINURLNAVIGATOR_H diff --git a/src/dolphinurlnavigatorscontroller.cpp b/src/dolphinurlnavigatorscontroller.cpp new file mode 100644 index 000000000..78fecd18a --- /dev/null +++ b/src/dolphinurlnavigatorscontroller.cpp @@ -0,0 +1,67 @@ +/* + This file is part of the KDE project + SPDX-FileCopyrightText: 2020 Felix Ernst + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "dolphinurlnavigatorscontroller.h" + +#include "dolphin_generalsettings.h" +#include "dolphinurlnavigator.h" +#include "global.h" + +#include + +void DolphinUrlNavigatorsController::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 DolphinUrlNavigatorsController::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); + } +} + +bool DolphinUrlNavigatorsController::placesSelectorVisible() +{ + return s_placesSelectorVisible; +} + +void DolphinUrlNavigatorsController::registerDolphinUrlNavigator(DolphinUrlNavigator *dolphinUrlNavigator) +{ + s_instances.push_front(dolphinUrlNavigator); +} + +void DolphinUrlNavigatorsController::unregisterDolphinUrlNavigator(DolphinUrlNavigator *dolphinUrlNavigator) +{ + s_instances.remove(dolphinUrlNavigator); +} + +void DolphinUrlNavigatorsController::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 DolphinUrlNavigatorsController::s_instances; +bool DolphinUrlNavigatorsController::s_placesSelectorVisible = true; diff --git a/src/dolphinurlnavigatorscontroller.h b/src/dolphinurlnavigatorscontroller.h new file mode 100644 index 000000000..797cbf4f9 --- /dev/null +++ b/src/dolphinurlnavigatorscontroller.h @@ -0,0 +1,76 @@ +/* + This file is part of the KDE project + SPDX-FileCopyrightText: 2020 Felix Ernst + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef DOLPHINURLNAVIGATORSCONTROLLER_H +#define DOLPHINURLNAVIGATORSCONTROLLER_H + +#include + +#include + +#include + +class DolphinUrlNavigator; + +/** + * @brief A controller managing all DolphinUrlNavigators. + * + * This class is used to apply settings changes to all constructed DolphinUrlNavigators. + * + * @see DolphinUrlNavigator + */ +class DolphinUrlNavigatorsController : public QObject +{ + Q_OBJECT + +public: + DolphinUrlNavigatorsController() = delete; + +public slots: + /** + * Refreshes all DolphinUrlNavigators to get synchronized with the + * Dolphin settings if they were changed. + */ + static void slotReadSettings(); + + static void slotPlacesPanelVisibilityChanged(bool visible); + +private: + /** + * @return wether the places selector of DolphinUrlNavigators should be visible. + */ + static bool placesSelectorVisible(); + + /** + * Adds \p dolphinUrlNavigator to the list of DolphinUrlNavigators + * controlled by this class. + */ + static void registerDolphinUrlNavigator(DolphinUrlNavigator *dolphinUrlNavigator); + + /** + * Removes \p dolphinUrlNavigator from the list of DolphinUrlNavigators + * controlled by this class. + */ + static void unregisterDolphinUrlNavigator(DolphinUrlNavigator *dolphinUrlNavigator); + +private slots: + /** + * Sets the completion mode for all DolphinUrlNavigators and saves it in settings. + */ + static void setCompletionMode(const KCompletion::CompletionMode completionMode); + +private: + /** Contains all currently constructed DolphinUrlNavigators */ + static std::forward_list s_instances; + + /** Caches the (negated) places panel visibility */ + static bool s_placesSelectorVisible; + + friend class DolphinUrlNavigator; +}; + +#endif // DOLPHINURLNAVIGATORSCONTROLLER_H diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index 46968e9ff..9761f108f 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -53,8 +53,7 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) : m_statusBar(nullptr), m_statusBarTimer(nullptr), m_statusBarTimestamp(), - m_autoGrabFocus(true), - m_urlNavigatorVisualState{} + m_autoGrabFocus(true) #ifdef HAVE_KACTIVITIES , m_activityResourceInstance(nullptr) #endif -- cgit v1.3