From ad5d3367c7fef4c3c11188a768f21a2ee2b3c025 Mon Sep 17 00:00:00 2001 From: Felix Ernst Date: Sun, 14 Jun 2020 16:20:02 +0200 Subject: 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. --- src/dolphintabwidget.cpp | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'src/dolphintabwidget.cpp') 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(); -- cgit v1.3 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/CMakeLists.txt | 2 +- src/dolphinmainwindow.cpp | 121 ++++--------- src/dolphinmainwindow.h | 16 +- src/dolphinnavigatorswidgetaction.cpp | 243 ++++++++++++++++++++++++++ src/dolphinnavigatorswidgetaction.h | 149 ++++++++++++++++ src/dolphintabpage.cpp | 113 +++++++++++- src/dolphintabpage.h | 39 ++++- src/dolphintabwidget.cpp | 34 ++-- src/dolphintabwidget.h | 14 +- src/dolphinui.rc | 5 +- src/dolphinurlnavigator.cpp | 100 ++++++----- src/dolphinurlnavigator.h | 78 ++++----- src/dolphinviewcontainer.cpp | 112 ++++-------- src/dolphinviewcontainer.h | 34 ++-- src/main.cpp | 7 + src/settings/dolphin_generalsettings.kcfg | 4 - src/views/dolphinurlnavigatorwidgetaction.cpp | 91 ---------- src/views/dolphinurlnavigatorwidgetaction.h | 68 ------- 18 files changed, 746 insertions(+), 484 deletions(-) create mode 100644 src/dolphinnavigatorswidgetaction.cpp create mode 100644 src/dolphinnavigatorswidgetaction.h delete mode 100644 src/views/dolphinurlnavigatorwidgetaction.cpp delete mode 100644 src/views/dolphinurlnavigatorwidgetaction.h (limited to 'src/dolphintabwidget.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4610be463..8fad34347 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -203,6 +203,7 @@ set(dolphinstatic_SRCS dolphinmainwindow.cpp dolphinviewcontainer.cpp dolphincontextmenu.cpp + dolphinnavigatorswidgetaction.cpp dolphintabbar.cpp dolphinplacesmodelsingleton.cpp dolphinrecenttabsmenu.cpp @@ -249,7 +250,6 @@ 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/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 381d95013..6a93de078 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -31,7 +31,7 @@ #include "views/draganddrophelper.h" #include "views/viewproperties.h" #include "views/dolphinnewfilemenuobserver.h" -#include "views/dolphinurlnavigatorwidgetaction.h" +#include "dolphinnavigatorswidgetaction.h" #include "dolphin_generalsettings.h" #include @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include @@ -107,7 +106,8 @@ DolphinMainWindow::DolphinMainWindow() : m_placesPanel(nullptr), m_tearDownFromPlacesRequested(false), m_backAction(nullptr), - m_forwardAction(nullptr) + m_forwardAction(nullptr), + m_updateHistoryConnection{} { Q_INIT_RESOURCE(dolphin); @@ -142,7 +142,12 @@ DolphinMainWindow::DolphinMainWindow() : setAcceptDrops(true); - m_tabWidget = new DolphinTabWidget(this); + auto *navigatorsWidgetAction = new DolphinNavigatorsWidgetAction(this); + navigatorsWidgetAction->setText(i18nc( + "@action:inmenu When split view is enabled there are two otherwise one.", + "Url Navigator(s)")); + actionCollection()->addAction(QStringLiteral("url_navigators"), navigatorsWidgetAction); + m_tabWidget = new DolphinTabWidget(navigatorsWidgetAction, this); m_tabWidget->setObjectName("tabWidget"); connect(m_tabWidget, &DolphinTabWidget::activeViewChanged, this, &DolphinMainWindow::activeViewChanged); @@ -167,6 +172,11 @@ DolphinMainWindow::DolphinMainWindow() : setupGUI(Keys | Save | Create | ToolBar); stateChanged(QStringLiteral("new_file")); + toolBar()->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); + toolBar()->setFloatable(false); + if (!toolBar()->actions().contains(navigatorsWidgetAction)) { + navigatorsWidgetAction->addToToolbarAndSave(this); + } QClipboard* clipboard = QApplication::clipboard(); connect(clipboard, &QClipboard::dataChanged, this, &DolphinMainWindow::updatePasteAction); @@ -843,64 +853,6 @@ void DolphinMainWindow::showFilterBar() m_activeViewContainer->setFilterBarVisible(true); } -void DolphinMainWindow::toggleLocationInToolbar() -{ - // collect needed variables - QAction *locationInToolbarAction = actionCollection()->action(QStringLiteral("location_in_toolbar")); - const bool locationInToolbar = locationInToolbarAction->isChecked(); - auto viewContainers = this->viewContainers(); - auto urlNavigatorWidgetAction = static_cast - (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(); - - if (locationInToolbar && !toolBar()->actions().contains(urlNavigatorWidgetAction)) { - // There is no UrlNavigator on the toolbar. Try to fix it. Otherwise show an error. - if (!urlNavigatorWidgetAction->addToToolbarAndSave(this)) { - QAction *configureToolbars = actionCollection()->action(KStandardAction::name(KStandardAction::ConfigureToolbars)); - KMessageWidget *messageWidget = m_activeViewContainer->showMessage( - xi18nc("@info 2 is the visible text on a button just below the message", - "The location could not be moved onto the toolbar because there is currently " - "no \"%1\" item on the toolbar. Select %2 and add the " - "\"%1\" item. Then this will work.", urlNavigatorWidgetAction->iconText(), - configureToolbars->iconText()), DolphinViewContainer::Information); - messageWidget->addAction(configureToolbars); - messageWidget->addAction(locationInToolbarAction); - locationInToolbarAction->setChecked(false); - return; - } - } - - // do the switching - GeneralSettings::setLocationInToolbar(locationInToolbar); - if (locationInToolbar) { - for (const auto viewContainer : viewContainers) { - viewContainer->disconnectUrlNavigator(); - } - m_activeViewContainer->connectUrlNavigator(urlNavigatorWidgetAction->urlNavigator()); - } else { - m_activeViewContainer->disconnectUrlNavigator(); - for (const auto viewContainer : viewContainers) { - viewContainer->connectToInternalUrlNavigator(); - } - } - - urlNavigatorWidgetAction->setUrlNavigatorVisible(locationInToolbar); - m_activeViewContainer->urlNavigator()->setUrlEditable(isEditable); - if (hasFocus) { // the rest of this method is unneeded perfectionism - m_activeViewContainer->urlNavigator()->editor()->lineEdit()->setText(lineEdit->text()); - m_activeViewContainer->urlNavigator()->editor()->lineEdit()->setFocus(); - m_activeViewContainer->urlNavigator()->editor()->lineEdit()->setCursorPosition(cursorPosition); - if (selectionStart != -1) { - m_activeViewContainer->urlNavigator()->editor()->lineEdit()->setSelection(selectionStart, selectionLength); - } - } -} - void DolphinMainWindow::toggleEditLocation() { clearStatusBar(); @@ -1314,9 +1266,11 @@ void DolphinMainWindow::activeViewChanged(DolphinViewContainer* viewContainer) // view and url navigator) and main window. oldViewContainer->disconnect(this); oldViewContainer->view()->disconnect(this); - oldViewContainer->urlNavigator()->disconnect(this); - if (GeneralSettings::locationInToolbar()) { - oldViewContainer->disconnectUrlNavigator(); + auto navigators = static_cast + (actionCollection()->action(QStringLiteral("url_navigators"))); + navigators->primaryUrlNavigator()->disconnect(this); + if (auto secondaryUrlNavigator = navigators->secondaryUrlNavigator()) { + secondaryUrlNavigator->disconnect(this); } // except the requestItemInfo so that on hover the information panel can still be updated @@ -1324,10 +1278,6 @@ void DolphinMainWindow::activeViewChanged(DolphinViewContainer* viewContainer) this, &DolphinMainWindow::requestItemInfo); } - if (GeneralSettings::locationInToolbar()) { - viewContainer->connectUrlNavigator(static_cast - (actionCollection()->action(QStringLiteral("url_navigator")))->urlNavigator()); - } connectViewSignals(viewContainer); m_actionHandler->setCurrentView(viewContainer->view()); @@ -1559,16 +1509,6 @@ 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", @@ -1770,12 +1710,6 @@ void DolphinMainWindow::setupActions() connect(activatePrevTab, &QAction::triggered, m_tabWidget, &DolphinTabWidget::activatePrevTab); actionCollection()->setDefaultShortcuts(activatePrevTab, prevTabKeys); - auto *urlNavigatorWidgetAction = new DolphinUrlNavigatorWidgetAction(this); - urlNavigatorWidgetAction->setText(i18nc("@action:inmenu auto-hide: " - "Depending on the settings this Widget is blank/invisible.", - "Url Navigator (auto-hide)")); - actionCollection()->addAction(QStringLiteral("url_navigator"), urlNavigatorWidgetAction); - // for context menu QAction* showTarget = actionCollection()->addAction(QStringLiteral("show_target")); showTarget->setText(i18nc("@action:inmenu", "Show Target")); @@ -2107,10 +2041,6 @@ void DolphinMainWindow::updateViewActions() showFilterBarAction->setChecked(m_activeViewContainer->isFilterBarVisible()); updateSplitAction(); - - QAction* editableLocactionAction = actionCollection()->action(QStringLiteral("editable_location")); - const KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator(); - editableLocactionAction->setChecked(urlNavigator->isUrlEditable()); } void DolphinMainWindow::updateGoActions() @@ -2246,15 +2176,24 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container) connect(view, &DolphinView::goUpRequested, this, &DolphinMainWindow::goUp); - const KUrlNavigator* navigator = container->urlNavigator(); + auto navigators = static_cast + (actionCollection()->action(QStringLiteral("url_navigators"))); + KUrlNavigator *navigator = m_tabWidget->currentTabPage()->primaryViewActive() ? + navigators->primaryUrlNavigator() : + navigators->secondaryUrlNavigator(); + connect(navigator, &KUrlNavigator::urlChanged, this, &DolphinMainWindow::changeUrl); + QAction* editableLocactionAction = actionCollection()->action(QStringLiteral("editable_location")); + editableLocactionAction->setChecked(navigator->isUrlEditable()); connect(navigator, &KUrlNavigator::editableStateChanged, this, &DolphinMainWindow::slotEditableStateChanged); connect(navigator, &KUrlNavigator::tabRequested, this, &DolphinMainWindow::openNewTabAfterLastTab); - connect(container->urlNavigatorInternalWithHistory(), &KUrlNavigator::historyChanged, + disconnect(m_updateHistoryConnection); + m_updateHistoryConnection = connect( + container->urlNavigatorInternalWithHistory(), &KUrlNavigator::historyChanged, this, &DolphinMainWindow::updateHistory); } diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index 251f50d8d..173e017c9 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -69,16 +69,9 @@ public: /** * Returns the active view containers of all tabs. - * @see activeViewContainer() - * Use viewContainers() to also include the inactive ones. */ QVector activeViewContainers() const; - /** - * Returns all view containers. - */ - QVector viewContainers() const; - /** * Opens each directory in \p dirs in a separate tab. If \a splitView is set, * 2 directories are collected within one tab. @@ -312,12 +305,6 @@ 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. */ @@ -662,6 +649,9 @@ private: KToolBarPopupAction* m_backAction; KToolBarPopupAction* m_forwardAction; + /** Makes sure that only one object is ever connected to the history. */ + QMetaObject::Connection m_updateHistoryConnection; + QMenu m_searchTools; }; diff --git a/src/dolphinnavigatorswidgetaction.cpp b/src/dolphinnavigatorswidgetaction.cpp new file mode 100644 index 000000000..bd2985d47 --- /dev/null +++ b/src/dolphinnavigatorswidgetaction.cpp @@ -0,0 +1,243 @@ +/* + 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 "dolphinnavigatorswidgetaction.h" + +#include "trash/dolphintrash.h" + +#include +#include +#include + +#include +#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} +{ + setText(i18nc("@action:inmenu", "Url navigator")); + + m_splitter->setChildrenCollapsible(false); + setDefaultWidget(m_splitter.get()); + + m_splitter->addWidget(createNavigatorWidget(Primary)); + + m_adjustSpacingTimer->setInterval(100); + m_adjustSpacingTimer->setSingleShot(true); + connect(m_adjustSpacingTimer.get(), &QTimer::timeout, + this, &DolphinNavigatorsWidgetAction::adjustSpacing); +} + +bool DolphinNavigatorsWidgetAction::addToToolbarAndSave(KXmlGuiWindow *mainWindow) +{ + const QString rawXml = KXMLGUIFactory::readConfigFile(mainWindow->xmlFile()); + QDomDocument domDocument; + if (rawXml.isEmpty() || !domDocument.setContent(rawXml) || domDocument.isNull()) { + return false; + } + QDomNode toolbar = domDocument.elementsByTagName(QStringLiteral("ToolBar")).at(0); + if (toolbar.isNull()) { + return false; + } + + QDomElement urlNavigatorElement = domDocument.createElement(QStringLiteral("Action")); + urlNavigatorElement.setAttribute(QStringLiteral("name"), QStringLiteral("url_navigators")); + + QDomNode position = toolbar.lastChildElement(QStringLiteral("Spacer")); + if (position.isNull()) { + toolbar.appendChild(urlNavigatorElement); + } else { + toolbar.replaceChild(urlNavigatorElement, position); + } + + KXMLGUIFactory::saveConfigFile(domDocument, mainWindow->xmlFile()); + mainWindow->reloadXML(); + mainWindow->createGUI(); + return true; +} + +void DolphinNavigatorsWidgetAction::createSecondaryUrlNavigator() +{ + Q_ASSERT(m_splitter->count() == 1); + m_splitter->addWidget(createNavigatorWidget(Secondary)); + Q_ASSERT(m_splitter->count() == 2); +} + +void DolphinNavigatorsWidgetAction::followViewContainerGeometry( + int globalXOfPrimary, int widthOfPrimary) +{ + followViewContainersGeometry(globalXOfPrimary, widthOfPrimary, -1, -1); +} + +void DolphinNavigatorsWidgetAction::followViewContainersGeometry( + int globalXOfPrimary, int widthOfPrimary, + int globalXOfSecondary, int widthOfSecondary) +{ + m_globalXOfSplitter = m_splitter->mapToGlobal(QPoint(0,0)).x(); + m_globalXOfPrimary = globalXOfPrimary; + m_widthOfPrimary = widthOfPrimary; + m_globalXOfSecondary = globalXOfSecondary; + m_widthOfSecondary = widthOfSecondary; + adjustSpacing(); +} + +DolphinUrlNavigator* DolphinNavigatorsWidgetAction::primaryUrlNavigator() const +{ + Q_ASSERT(m_splitter); + return static_cast(m_splitter->widget(0)->findChild()); +} + +DolphinUrlNavigator* DolphinNavigatorsWidgetAction::secondaryUrlNavigator() const +{ + Q_ASSERT(m_splitter); + if (m_splitter->count() < 2) { + return nullptr; + } + return static_cast(m_splitter->widget(1)->findChild()); +} + +void DolphinNavigatorsWidgetAction::setSecondaryNavigatorVisible(bool visible) +{ + if (visible) { + Q_ASSERT(m_splitter->count() == 2); + m_splitter->widget(1)->setVisible(true); + } else if (m_splitter->count() > 1) { + m_splitter->widget(1)->setVisible(false); + // Fix an unlikely event of wrong trash button visibility. + emptyTrashButton(Secondary)->setVisible(false); + } +} + +void DolphinNavigatorsWidgetAction::adjustSpacing() +{ + const int widthOfSplitterPrimary = m_globalXOfPrimary + m_widthOfPrimary - m_globalXOfSplitter; + const QList splitterSizes = {widthOfSplitterPrimary, + m_splitter->width() - widthOfSplitterPrimary}; + m_splitter->setSizes(splitterSizes); + + // primary side of m_splitter + int leadingSpacing = m_globalXOfPrimary - m_globalXOfSplitter; + if (leadingSpacing < 0) { + leadingSpacing = 0; + } + int trailingSpacing = (m_globalXOfSplitter + m_splitter->width()) + - (m_globalXOfPrimary + m_widthOfPrimary); + if (trailingSpacing < 0 || emptyTrashButton(Primary)->isVisible()) { + trailingSpacing = 0; + } + const int widthLeftForUrlNavigator = m_splitter->widget(0)->width() - leadingSpacing - trailingSpacing; + const int widthNeededForUrlNavigator = primaryUrlNavigator()->sizeHint().width() - widthLeftForUrlNavigator; + if (widthNeededForUrlNavigator > 0) { + trailingSpacing -= widthNeededForUrlNavigator; + if (trailingSpacing < 0) { + leadingSpacing += trailingSpacing; + trailingSpacing = 0; + } + if (leadingSpacing < 0) { + leadingSpacing = 0; + } + } + spacing(Primary, Leading)->setMinimumWidth(leadingSpacing); + spacing(Primary, Trailing)->setFixedWidth(trailingSpacing); + + // secondary side of m_splitter + if (m_globalXOfSecondary == -1) { + Q_ASSERT(m_widthOfSecondary == -1); + return; + } + spacing(Primary, Trailing)->setFixedWidth(0); + + trailingSpacing = (m_globalXOfSplitter + m_splitter->width()) + - (m_globalXOfSecondary + m_widthOfSecondary); + if (trailingSpacing < 0 || emptyTrashButton(Secondary)->isVisible()) { + trailingSpacing = 0; + } else { + const int widthLeftForUrlNavigator2 = m_splitter->widget(1)->width() - trailingSpacing; + const int widthNeededForUrlNavigator2 = secondaryUrlNavigator()->sizeHint().width() - widthLeftForUrlNavigator2; + if (widthNeededForUrlNavigator2 > 0) { + trailingSpacing -= widthNeededForUrlNavigator2; + if (trailingSpacing < 0) { + trailingSpacing = 0; + } + } + } + spacing(Secondary, Trailing)->setMinimumWidth(trailingSpacing); +} + +QWidget *DolphinNavigatorsWidgetAction::createNavigatorWidget(Side side) const +{ + auto navigatorWidget = new QWidget(m_splitter.get()); + auto layout = new QHBoxLayout{navigatorWidget}; + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + if (side == Primary) { + auto leadingSpacing = new QWidget{navigatorWidget}; + layout->addWidget(leadingSpacing); + } + auto urlNavigator = new DolphinUrlNavigator(navigatorWidget); + layout->addWidget(urlNavigator); + + auto emptyTrashButton = newEmptyTrashButton(urlNavigator, navigatorWidget); + layout->addWidget(emptyTrashButton); + + connect(urlNavigator, &KUrlNavigator::urlChanged, [this]() { + // We have to wait for DolphinUrlNavigator::sizeHint() to update which + // happens a little bit later than when urlChanged is emitted. + this->m_adjustSpacingTimer->start(); + }); + + auto trailingSpacing = new QWidget{navigatorWidget}; + layout->addWidget(trailingSpacing); + return navigatorWidget; +} + +QPushButton * DolphinNavigatorsWidgetAction::emptyTrashButton(DolphinNavigatorsWidgetAction::Side side) +{ + int sideIndex = (side == Primary ? 0 : 1); + if (side == Primary) { + return static_cast(m_splitter->widget(sideIndex)->layout()->itemAt(2)->widget()); + } + return static_cast(m_splitter->widget(sideIndex)->layout()->itemAt(1)->widget()); +} + +QPushButton *DolphinNavigatorsWidgetAction::newEmptyTrashButton(const DolphinUrlNavigator *urlNavigator, QWidget *parent) const +{ + auto emptyTrashButton = new QPushButton(QIcon::fromTheme(QStringLiteral("user-trash")), + i18nc("@action:button", "Empty Trash"), parent); + emptyTrashButton->setFlat(true); + connect(emptyTrashButton, &QPushButton::clicked, + this, [parent]() { Trash::empty(parent); }); + connect(&Trash::instance(), &Trash::emptinessChanged, + emptyTrashButton, &QPushButton::setDisabled); + emptyTrashButton->hide(); + connect(urlNavigator, &KUrlNavigator::urlChanged, [emptyTrashButton, urlNavigator]() { + emptyTrashButton->setVisible(urlNavigator->locationUrl().scheme() == QLatin1String("trash")); + }); + emptyTrashButton->setDisabled(Trash::isEmpty()); + return emptyTrashButton; +} + +QWidget *DolphinNavigatorsWidgetAction::spacing(Side side, Position position) const +{ + int sideIndex = (side == Primary ? 0 : 1); + if (position == Leading) { + Q_ASSERT(side == Primary); // The secondary side of the splitter has no leading spacing. + return m_splitter->widget(sideIndex)->layout()->itemAt(0)->widget(); + } + if (side == Primary) { + return m_splitter->widget(sideIndex)->layout()->itemAt(3)->widget(); + } + return m_splitter->widget(sideIndex)->layout()->itemAt(2)->widget(); +} 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 diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index c2c573e1d..d2fd1d143 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -9,6 +9,7 @@ #include "dolphin_generalsettings.h" #include "dolphinviewcontainer.h" +#include #include #include @@ -24,6 +25,8 @@ DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, m_splitter = new QSplitter(Qt::Horizontal, this); m_splitter->setChildrenCollapsible(false); + connect(m_splitter, &QSplitter::splitterMoved, + this, &DolphinTabPage::splitterMoved); layout->addWidget(m_splitter); // Create a new primary view @@ -34,6 +37,7 @@ DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, this, &DolphinTabPage::slotViewUrlRedirection); m_splitter->addWidget(m_primaryViewContainer); + m_primaryViewContainer->installEventFilter(this); m_primaryViewContainer->show(); if (secondaryUrl.isValid() || GeneralSettings::splitView()) { @@ -43,6 +47,7 @@ DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, const QUrl& url = secondaryUrl.isValid() ? secondaryUrl : primaryUrl; m_secondaryViewContainer = createViewContainer(url); m_splitter->addWidget(m_secondaryViewContainer); + m_secondaryViewContainer->installEventFilter(this); m_secondaryViewContainer->show(); } @@ -65,17 +70,59 @@ 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); + auto secondaryNavigator = m_navigatorsWidget->secondaryUrlNavigator(); + if (!secondaryNavigator) { + m_navigatorsWidget->createSecondaryUrlNavigator(); + secondaryNavigator = m_navigatorsWidget->secondaryUrlNavigator(); + } + m_secondaryViewContainer->connectUrlNavigator(secondaryNavigator); + m_navigatorsWidget->setSecondaryNavigatorVisible(true); + m_splitter->addWidget(m_secondaryViewContainer); - m_secondaryViewContainer->show(); + 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(); } else { + m_navigatorsWidget->setSecondaryNavigatorVisible(false); + m_secondaryViewContainer->disconnectUrlNavigator(); + DolphinViewContainer* view; if (GeneralSettings::closeActiveSplitView()) { view = activeViewContainer(); if (m_primaryViewActive) { + m_primaryViewContainer->disconnectUrlNavigator(); + m_secondaryViewContainer->connectUrlNavigator( + m_navigatorsWidget->primaryUrlNavigator()); + // If the primary view is active, we have to swap the pointers // because the secondary view will be the new primary view. qSwap(m_primaryViewContainer, m_secondaryViewContainer); @@ -84,6 +131,10 @@ void DolphinTabPage::setSplitViewEnabled(bool enabled, const QUrl &secondaryUrl) } else { view = m_primaryViewActive ? m_secondaryViewContainer : m_primaryViewContainer; if (!m_primaryViewActive) { + m_primaryViewContainer->disconnectUrlNavigator(); + m_secondaryViewContainer->connectUrlNavigator( + m_navigatorsWidget->primaryUrlNavigator()); + // If the secondary view is active, we have to swap the pointers // because the secondary view will be the new primary view. qSwap(m_primaryViewContainer, m_secondaryViewContainer); @@ -93,6 +144,10 @@ 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()); + } } } } @@ -131,6 +186,56 @@ int DolphinTabPage::selectedItemsCount() const return selectedItemsCount; } +void DolphinTabPage::connectNavigators(DolphinNavigatorsWidgetAction *navigatorsWidget) +{ + m_navigatorsWidget = navigatorsWidget; + auto primaryNavigator = navigatorsWidget->primaryUrlNavigator(); + primaryNavigator->setActive(m_primaryViewActive); + 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); + } + resizeNavigators(); +} + +void DolphinTabPage::disconnectNavigators() +{ + m_navigatorsWidget = nullptr; + m_primaryViewContainer->disconnectUrlNavigator(); + if (m_splitViewEnabled) { + m_secondaryViewContainer->disconnectUrlNavigator(); + } +} + +bool DolphinTabPage::eventFilter(QObject */* watched */, QEvent *event) +{ + if (event->type() == QEvent::Resize && m_navigatorsWidget) { + resizeNavigators(); + } + return false; +} + +void DolphinTabPage::resizeNavigators() const +{ + if (!m_splitViewEnabled) { + m_navigatorsWidget->followViewContainerGeometry( + m_primaryViewContainer->mapToGlobal(QPoint(0,0)).x(), + m_primaryViewContainer->width()); + } else { + m_navigatorsWidget->followViewContainersGeometry( + m_primaryViewContainer->mapToGlobal(QPoint(0,0)).x(), + m_primaryViewContainer->width(), + m_secondaryViewContainer->mapToGlobal(QPoint(0,0)).x(), + m_secondaryViewContainer->width()); + } +} + void DolphinTabPage::markUrlsAsSelected(const QList& urls) { m_primaryViewContainer->view()->markUrlsAsSelected(urls); @@ -222,11 +327,17 @@ void DolphinTabPage::restoreState(const QByteArray& state) stream >> m_primaryViewActive; if (m_primaryViewActive) { m_primaryViewContainer->setActive(true); + m_navigatorsWidget->primaryUrlNavigator()->setActive(true); } else { Q_ASSERT(m_splitViewEnabled); m_secondaryViewContainer->setActive(true); + 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 74344acd1..6a8801edd 100644 --- a/src/dolphintabpage.h +++ b/src/dolphintabpage.h @@ -11,8 +11,10 @@ #include #include -class QSplitter; +class DolphinNavigatorsWidgetAction; class DolphinViewContainer; +class QSplitter; +class QVariantAnimation; class KFileItemList; class DolphinTabPage : public QWidget @@ -66,6 +68,30 @@ public: */ int selectedItemsCount() const; + /** + * Connects a navigatorsWidget to this. It will be connected to the DolphinViewContainers + * managed by this tab. For alignment purposes this will from now on notify the + * navigatorsWidget when this tab or its viewContainers are resized. + */ + void connectNavigators(DolphinNavigatorsWidgetAction *navigatorsWidget); + + /** + * Makes it so this tab and its DolphinViewContainers aren't controlled by any + * UrlNavigators anymore. + */ + void disconnectNavigators(); + + /** + * Calls resizeNavigators() when a watched object is resized. + */ + bool eventFilter(QObject */* watched */, QEvent *event) override; + + /** + * Notify the connected DolphinNavigatorsWidgetAction of geometry changes which it + * needs for visual alignment. + */ + void resizeNavigators() const; + /** * Marks the items indicated by \p urls to get selected after the * directory DolphinView::url() has been loaded. Note that nothing @@ -80,14 +106,6 @@ public: */ void markUrlAsCurrent(const QUrl& url); - /** - * Sets the places selector visible, if \a visible is true. - * The places selector allows to select the places provided - * by the places model passed in the constructor. Per default - * the places selector is visible. - */ - void setPlacesSelectorVisible(bool visible); - /** * Refreshes the views of the main window by recreating them according to * the given Dolphin settings. @@ -125,6 +143,7 @@ public: signals: void activeViewChanged(DolphinViewContainer* viewContainer); void activeViewUrlChanged(const QUrl& url); + void splitterMoved(int pos, int index); private slots: /** @@ -153,8 +172,10 @@ private: private: QSplitter* m_splitter; + 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 3ce8229f9..a09a769d3 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -20,9 +20,10 @@ #include #include -DolphinTabWidget::DolphinTabWidget(QWidget* parent) : +DolphinTabWidget::DolphinTabWidget(DolphinNavigatorsWidgetAction *navigatorsWidget, QWidget* parent) : QTabWidget(parent), - m_lastViewedTab(0) + m_lastViewedTab(nullptr), + m_navigatorsWidget{navigatorsWidget} { KAcceleratorManager::setNoAccel(this); @@ -126,11 +127,19 @@ bool DolphinTabWidget::isUrlOpen(const QUrl &url) const void DolphinTabWidget::openNewActivatedTab() { + std::unique_ptr oldNavigatorState; + if (currentTabPage()->primaryViewActive()) { + oldNavigatorState = m_navigatorsWidget->primaryUrlNavigator()->visualState(); + } else { + if (!m_navigatorsWidget->secondaryUrlNavigator()) { + m_navigatorsWidget->createSecondaryUrlNavigator(); + } + oldNavigatorState = m_navigatorsWidget->secondaryUrlNavigator()->visualState(); + } + const DolphinViewContainer* oldActiveViewContainer = currentTabPage()->activeViewContainer(); Q_ASSERT(oldActiveViewContainer); - const bool isUrlEditable = oldActiveViewContainer->urlNavigator()->isUrlEditable(); - openNewActivatedTab(oldActiveViewContainer->url()); DolphinViewContainer* newActiveViewContainer = currentTabPage()->activeViewContainer(); @@ -138,7 +147,7 @@ void DolphinTabWidget::openNewActivatedTab() // The URL navigator of the new tab should have the same editable state // as the current tab - newActiveViewContainer->urlNavigator()->setUrlEditable(isUrlEditable); + newActiveViewContainer->urlNavigator()->setVisualState(*oldNavigatorState.get()); // Always focus the new tab's view newActiveViewContainer->view()->setFocus(); @@ -384,16 +393,21 @@ void DolphinTabWidget::tabUrlChanged(const QUrl& url) void DolphinTabWidget::currentTabChanged(int index) { - // last-viewed tab deactivation - if (DolphinTabPage* tabPage = tabPageAt(m_lastViewedTab)) { - tabPage->setActive(false); + DolphinTabPage *tabPage = tabPageAt(index); + if (tabPage == m_lastViewedTab) { + return; + } + if (m_lastViewedTab) { + m_lastViewedTab->disconnectNavigators(); + m_lastViewedTab->setActive(false); } - DolphinTabPage* tabPage = tabPageAt(index); DolphinViewContainer* viewContainer = tabPage->activeViewContainer(); Q_EMIT activeViewChanged(viewContainer); Q_EMIT currentUrlChanged(viewContainer->url()); tabPage->setActive(true); - m_lastViewedTab = index; + tabPage->connectNavigators(m_navigatorsWidget); + m_navigatorsWidget->setSecondaryNavigatorVisible(tabPage->splitViewEnabled()); + m_lastViewedTab = tabPageAt(index); } void DolphinTabWidget::tabInserted(int index) diff --git a/src/dolphintabwidget.h b/src/dolphintabwidget.h index 9cc03f127..707eb086a 100644 --- a/src/dolphintabwidget.h +++ b/src/dolphintabwidget.h @@ -7,11 +7,13 @@ #ifndef DOLPHIN_TAB_WIDGET_H #define DOLPHIN_TAB_WIDGET_H +#include "dolphinnavigatorswidgetaction.h" + #include #include -class DolphinViewContainer; class DolphinTabPage; +class DolphinViewContainer; class KConfigGroup; class DolphinTabWidget : public QTabWidget @@ -32,7 +34,12 @@ public: */ AfterLastTab }; - explicit DolphinTabWidget(QWidget* parent); + + /** + * @param navigatorsWidget The navigatorsWidget which is always going to be connected + * to the active tabPage. + */ + explicit DolphinTabWidget(DolphinNavigatorsWidgetAction *navigatorsWidget, QWidget *parent); /** * @return Tab page at the current index (can be 0 if tabs count is smaller than 1) @@ -224,7 +231,8 @@ private: QPair indexByUrl(const QUrl& url) const; private: - int m_lastViewedTab; + QPointer m_lastViewedTab; + QPointer m_navigatorsWidget; }; #endif diff --git a/src/dolphinui.rc b/src/dolphinui.rc index 10c7c2fa4..01a3778f9 100644 --- a/src/dolphinui.rc +++ b/src/dolphinui.rc @@ -56,7 +56,6 @@ Location Bar - @@ -120,9 +119,7 @@ - - - + diff --git a/src/dolphinurlnavigator.cpp b/src/dolphinurlnavigator.cpp index 70f780e55..2b7f3d4eb 100644 --- a/src/dolphinurlnavigator.cpp +++ b/src/dolphinurlnavigator.cpp @@ -1,22 +1,9 @@ /* - * 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 . - */ + 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 "dolphinurlnavigator.h" @@ -24,12 +11,12 @@ #include "dolphinplacesmodelsingleton.h" #include "global.h" -#include #include #include +#include +#include #include -#include DolphinUrlNavigator::DolphinUrlNavigator(QWidget *parent) : KUrlNavigator(DolphinPlacesModelSingleton::instance().placesModel(), QUrl(), parent) @@ -51,10 +38,8 @@ void DolphinUrlNavigator::init() 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 " + "This 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 " @@ -79,30 +64,50 @@ DolphinUrlNavigator::~DolphinUrlNavigator() s_instances.remove(this); } -bool DolphinUrlNavigator::eventFilter(QObject* watched, QEvent* event) +QSize DolphinUrlNavigator::sizeHint() const { - 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); - } + // Change sizeHint() in KUrlNavigator instead. + if (isUrlEditable()) { + return editor()->lineEdit()->sizeHint(); + } + int widthHint = 0; + for (int i = 0; i < layout()->count(); ++i) { + QWidget *widget = layout()->itemAt(i)->widget(); + const QAbstractButton *button = qobject_cast(widget); + if (button && button->icon().isNull()) { + widthHint += widget->minimumSizeHint().width(); + } + } + return QSize(widthHint, KUrlNavigator::sizeHint().height()); +} + +std::unique_ptr DolphinUrlNavigator::visualState() const +{ + std::unique_ptr visualState{new VisualState}; + visualState->isUrlEditable = (isUrlEditable()); + const QLineEdit *lineEdit = editor()->lineEdit(); + visualState->hasFocus = lineEdit->hasFocus(); + visualState->text = lineEdit->text(); + visualState->cursorPosition = lineEdit->cursorPosition(); + visualState->selectionStart = lineEdit->selectionStart(); + visualState->selectionLength = lineEdit->selectionLength(); + return visualState; +} + +void DolphinUrlNavigator::setVisualState(const VisualState& visualState) +{ + setUrlEditable(visualState.isUrlEditable); + if (!visualState.isUrlEditable) { + return; + } + editor()->lineEdit()->setText(visualState.text); + if (visualState.hasFocus) { + editor()->lineEdit()->setFocus(); + editor()->lineEdit()->setCursorPosition(visualState.cursorPosition); + if (visualState.selectionStart != -1) { + editor()->lineEdit()->setSelection(visualState.selectionStart, visualState.selectionLength); } } - return false; } void DolphinUrlNavigator::slotReadSettings() @@ -126,12 +131,6 @@ void DolphinUrlNavigator::slotReturnPressed() } } -void DolphinUrlNavigator::addToContextMenu(QAction* action) -{ - s_ActionForContextMenu = action; -} - - void DolphinUrlNavigator::slotPlacesPanelVisibilityChanged(bool visible) { // The places-selector from the URL navigator should only be shown @@ -157,4 +156,3 @@ void DolphinUrlNavigator::setCompletionMode(const KCompletion::CompletionMode co 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 index 032b81e89..8f8d270ae 100644 --- a/src/dolphinurlnavigator.h +++ b/src/dolphinurlnavigator.h @@ -1,22 +1,9 @@ /* - * 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 . - */ + 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 DOLPHINURLNAVIGATOR_H #define DOLPHINURLNAVIGATOR_H @@ -30,10 +17,10 @@ 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 @@ -55,6 +42,36 @@ 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. + */ + QSize sizeHint() const override; + + /** + * Wraps the visual state of a DolphinUrlNavigator so it can be passed around. + * This notably doesn't involve the locationUrl or history. + */ + struct VisualState { + bool isUrlEditable; + bool hasFocus; + QString text; + int cursorPosition; + int selectionStart; + int selectionLength; + }; + /** + * Retrieve the visual state of this DolphinUrlNavigator. + * If two DolphinUrlNavigators have the same visual state they should look identical. + */ + std::unique_ptr visualState() const; + /** + * @param visualState A struct describing the new visual state of this object. + */ + void setVisualState(const VisualState &visualState); + public slots: /** * Refreshes all DolphinUrlNavigators to get synchronized with the @@ -68,16 +85,6 @@ public slots: */ 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: @@ -86,14 +93,6 @@ protected: */ 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 @@ -107,9 +106,6 @@ protected: /** 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 59a187e1f..46968e9ff 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -13,7 +13,6 @@ #include "global.h" #include "search/dolphinsearchbox.h" #include "statusbar/dolphinstatusbar.h" -#include "trash/dolphintrash.h" #include "views/viewmodecontroller.h" #include "views/viewproperties.h" #include "dolphin_detailsmodesettings.h" @@ -44,10 +43,8 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) : QWidget(parent), m_topLayout(nullptr), - m_navigatorWidget(nullptr), - m_urlNavigator(nullptr), - m_urlNavigatorConnected(nullptr), - m_emptyTrashButton(nullptr), + m_urlNavigator{new DolphinUrlNavigator(url)}, + m_urlNavigatorConnected{nullptr}, m_searchBox(nullptr), m_searchModeEnabled(false), m_messageWidget(nullptr), @@ -56,7 +53,8 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) : m_statusBar(nullptr), m_statusBarTimer(nullptr), m_statusBarTimestamp(), - m_autoGrabFocus(true) + m_autoGrabFocus(true), + m_urlNavigatorVisualState{} #ifdef HAVE_KACTIVITIES , m_activityResourceInstance(nullptr) #endif @@ -67,20 +65,6 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) : m_topLayout->setSpacing(0); 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_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); - connect(m_emptyTrashButton, &QPushButton::clicked, this, [this]() { Trash::empty(this); }); - connect(&Trash::instance(), &Trash::emptinessChanged, m_emptyTrashButton, &QPushButton::setDisabled); - m_emptyTrashButton->setDisabled(Trash::isEmpty()); - m_emptyTrashButton->hide(); - m_searchBox = new DolphinSearchBox(this); m_searchBox->hide(); connect(m_searchBox, &DolphinSearchBox::activated, this, &DolphinViewContainer::activate); @@ -132,8 +116,8 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) : // 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, + m_urlNavigator.get(), &DolphinUrlNavigator::setLocationUrl); + connect(m_urlNavigator.get(), &DolphinUrlNavigator::urlChanged, this, &DolphinViewContainer::slotUrlNavigatorLocationChanged); connect(m_view, &DolphinView::writeStateChanged, this, &DolphinViewContainer::writeStateChanged); @@ -166,10 +150,6 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) : connect(m_view, &DolphinView::activated, this, &DolphinViewContainer::activate); - connect(m_view, &DolphinView::directoryLoadingCompleted, this, [this]() { - m_emptyTrashButton->setVisible(m_view->url().scheme() == QLatin1String("trash")); - }); - // Initialize status bar m_statusBar = new DolphinStatusBar(this); m_statusBar->setUrl(m_view->url()); @@ -196,19 +176,12 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) : connect(undoManager, &KIO::FileUndoManager::jobRecordingFinished, this, &DolphinViewContainer::delayedStatusBarUpdate); - navigatorLayout->addWidget(m_urlNavigator); - navigatorLayout->addWidget(m_emptyTrashButton); - - m_topLayout->addWidget(m_navigatorWidget); m_topLayout->addWidget(m_searchBox); m_topLayout->addWidget(m_messageWidget); m_topLayout->addWidget(m_view); m_topLayout->addWidget(m_filterBar); m_topLayout->addWidget(m_statusBar); - if (!GeneralSettings::locationInToolbar()) { - connectToInternalUrlNavigator(); - } setSearchModeEnabled(isSearchUrl(url)); connect(DetailsModeSettings::self(), &KCoreConfigSkeleton::configChanged, this, [=]() { @@ -237,7 +210,9 @@ QUrl DolphinViewContainer::url() const void DolphinViewContainer::setActive(bool active) { m_searchBox->setActive(active); - m_urlNavigator->setActive(active); + if (m_urlNavigatorConnected) { + m_urlNavigatorConnected->setActive(active); + } m_view->setActive(active); #ifdef HAVE_KACTIVITIES @@ -251,7 +226,6 @@ void DolphinViewContainer::setActive(bool active) bool DolphinViewContainer::isActive() const { - Q_ASSERT(!m_urlNavigatorConnected || m_urlNavigatorConnected->isActive() == m_view->isActive()); return m_view->isActive(); } @@ -292,12 +266,12 @@ DolphinUrlNavigator* DolphinViewContainer::urlNavigator() const DolphinUrlNavigator *DolphinViewContainer::urlNavigatorInternalWithHistory() const { - return m_urlNavigator; + return m_urlNavigator.get(); } DolphinUrlNavigator *DolphinViewContainer::urlNavigatorInternalWithHistory() { - return m_urlNavigator; + return m_urlNavigator.get(); } const DolphinView* DolphinViewContainer::view() const @@ -314,19 +288,20 @@ void DolphinViewContainer::connectUrlNavigator(DolphinUrlNavigator *urlNavigator { Q_CHECK_PTR(urlNavigator); Q_ASSERT(!m_urlNavigatorConnected); + Q_ASSERT(m_urlNavigator.get() != urlNavigator); Q_CHECK_PTR(m_view); - m_urlNavigatorConnected = urlNavigator; + urlNavigator->setLocationUrl(m_view->url()); + urlNavigator->setActive(isActive()); + if (m_urlNavigatorVisualState) { + urlNavigator->setVisualState(*m_urlNavigatorVisualState.get()); + m_urlNavigatorVisualState.reset(); + } - // m_urlNavigator is already connected through urlChanged signals. - if (urlNavigator != m_urlNavigator) { - urlNavigator->setLocationUrl(m_view->url()); - connect(m_view, &DolphinView::urlChanged, + connect(m_view, &DolphinView::urlChanged, urlNavigator, &DolphinUrlNavigator::setLocationUrl); - connect(urlNavigator, &DolphinUrlNavigator::urlChanged, + connect(urlNavigator, &DolphinUrlNavigator::urlChanged, this, &DolphinViewContainer::slotUrlNavigatorLocationChanged); - } - connect(urlNavigator, &DolphinUrlNavigator::activated, this, &DolphinViewContainer::activate); connect(urlNavigator, &DolphinUrlNavigator::urlAboutToBeChanged, @@ -337,7 +312,7 @@ void DolphinViewContainer::connectUrlNavigator(DolphinUrlNavigator *urlNavigator m_view->dropUrls(destination, event, urlNavigator->dropWidget()); }); - updateNavigatorWidgetVisibility(); + m_urlNavigatorConnected = urlNavigator; } void DolphinViewContainer::disconnectUrlNavigator() @@ -346,34 +321,27 @@ void DolphinViewContainer::disconnectUrlNavigator() 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_view, &DolphinView::urlChanged, + m_urlNavigatorConnected, &DolphinUrlNavigator::setLocationUrl); + disconnect(m_urlNavigatorConnected, &DolphinUrlNavigator::urlChanged, + this, &DolphinViewContainer::slotUrlNavigatorLocationChanged); disconnect(m_urlNavigatorConnected, &DolphinUrlNavigator::activated, - this, &DolphinViewContainer::activate); + this, &DolphinViewContainer::activate); disconnect(m_urlNavigatorConnected, &DolphinUrlNavigator::urlAboutToBeChanged, - this, &DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged); + this, &DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged); disconnect(m_urlNavigatorConnected, &DolphinUrlNavigator::urlSelectionRequested, - this, &DolphinViewContainer::slotUrlSelectionRequested); + this, &DolphinViewContainer::slotUrlSelectionRequested); disconnect(m_urlNavigatorConnected, &DolphinUrlNavigator::urlsDropped, - this, nullptr); + this, nullptr); + m_urlNavigatorVisualState = m_urlNavigatorConnected->visualState(); m_urlNavigatorConnected = nullptr; - updateNavigatorWidgetVisibility(); } -KMessageWidget *DolphinViewContainer::showMessage(const QString& msg, MessageType type) +void DolphinViewContainer::showMessage(const QString& msg, MessageType type) { if (msg.isEmpty()) { - return m_messageWidget; - } - for (auto action : m_messageWidget->actions()) { - m_messageWidget->removeAction(action); + return; } m_messageWidget->setText(msg); @@ -399,7 +367,6 @@ KMessageWidget *DolphinViewContainer::showMessage(const QString& msg, MessageTyp m_messageWidget->hide(); } m_messageWidget->animatedShow(); - return m_messageWidget; } void DolphinViewContainer::readSettings() @@ -423,7 +390,6 @@ bool DolphinViewContainer::isFilterBarVisible() const void DolphinViewContainer::setSearchModeEnabled(bool enabled) { m_searchBox->setVisible(enabled); - updateNavigatorWidgetVisibility(); if (enabled) { const QUrl& locationUrl = m_urlNavigatorConnected->locationUrl(); @@ -540,9 +506,8 @@ QString DolphinViewContainer::caption() const void DolphinViewContainer::setUrl(const QUrl& newUrl) { - Q_CHECK_PTR(m_urlNavigatorConnected); - if (newUrl != m_urlNavigatorConnected->locationUrl()) { - m_urlNavigatorConnected->setLocationUrl(newUrl); + if (newUrl != m_urlNavigator->locationUrl()) { + m_urlNavigator->setLocationUrl(newUrl); } #ifdef HAVE_KACTIVITIES @@ -603,15 +568,6 @@ 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())) { diff --git a/src/dolphinviewcontainer.h b/src/dolphinviewcontainer.h index 2fe6b5f89..77b74d189 100644 --- a/src/dolphinviewcontainer.h +++ b/src/dolphinviewcontainer.h @@ -90,7 +90,7 @@ public: * or nullptr if there is none. * @see connectUrlNavigator() * @see disconnectUrlNavigator() - * + * * Use urlNavigatorInternalWithHistory() if you want to access the history. * @see urlNavigatorInternalWithHistory() */ @@ -100,7 +100,7 @@ public: * or nullptr if there is none. * @see connectUrlNavigator() * @see disconnectUrlNavigator() - * + * * Use urlNavigatorInternalWithHistory() if you want to access the history. * @see urlNavigatorInternalWithHistory() */ @@ -126,11 +126,6 @@ public: */ void connectUrlNavigator(DolphinUrlNavigator *urlNavigator); - inline void connectToInternalUrlNavigator() - { - connectUrlNavigator(m_urlNavigator); - } - /** * Disconnects the navigator that is currently controling the view. * This method completely reverses connectUrlNavigator(). @@ -140,9 +135,8 @@ public: /** * Shows the message \msg with the given type non-modal above * the view-content. - * @return the KMessageWidget used to show the message */ - KMessageWidget *showMessage(const QString& msg, MessageType type); + void showMessage(const QString& msg, MessageType type); /** * Refreshes the view container to get synchronized with the (updated) Dolphin settings. @@ -244,8 +238,6 @@ 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. @@ -369,21 +361,20 @@ private: private: QVBoxLayout* m_topLayout; - QWidget* m_navigatorWidget; /** - * 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. + * The internal UrlNavigator which is never visible to the user. + * m_urlNavigator is used even when another UrlNavigator is controlling + * the view to keep track of this object's history. */ - DolphinUrlNavigator *m_urlNavigator; + std::unique_ptr m_urlNavigator; /** - * The UrlNavigator that is currently connected to the view. This could - * either be m_urlNavigator, the urlNavigator in the toolbar or nullptr. + * The UrlNavigator that is currently connected to the view. + * This is a nullptr if no UrlNavigator is connected. + * Otherwise it's one of the UrlNavigators visible in the toolbar. */ QPointer m_urlNavigatorConnected; - QPushButton* m_emptyTrashButton; DolphinSearchBox* m_searchBox; bool m_searchModeEnabled; KMessageWidget* m_messageWidget; @@ -396,6 +387,11 @@ private: QTimer* m_statusBarTimer; // Triggers a delayed update QElapsedTimer m_statusBarTimestamp; // Time in ms since last update bool m_autoGrabFocus; + /** + * The visual state to be applied to the next UrlNavigator that gets + * connected to this ViewContainer. + */ + std::unique_ptr m_urlNavigatorVisualState; #ifdef HAVE_KACTIVITIES private: diff --git a/src/main.cpp b/src/main.cpp index ef2905d77..a4b1b1963 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -213,6 +214,12 @@ extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv) } } } + Qt::ToolBarArea area = mainWindow->toolBarArea(mainWindow->toolBar()); + if (area != Qt::TopToolBarArea && area != Qt::BottomToolBarArea) { + // Migrate users with disabled tool bar positions. + // Remove this a few years from now (2020). + mainWindow->addToolBar(Qt::TopToolBarArea, mainWindow->toolBar()); + } #ifdef HAVE_KUSERFEEDBACK auto feedbackProvider = DolphinFeedbackProvider::instance(); diff --git a/src/settings/dolphin_generalsettings.kcfg b/src/settings/dolphin_generalsettings.kcfg index 9a13493a1..c397b2945 100644 --- a/src/settings/dolphin_generalsettings.kcfg +++ b/src/settings/dolphin_generalsettings.kcfg @@ -50,10 +50,6 @@ false - - - false - false diff --git a/src/views/dolphinurlnavigatorwidgetaction.cpp b/src/views/dolphinurlnavigatorwidgetaction.cpp deleted file mode 100644 index 108a5de13..000000000 --- a/src/views/dolphinurlnavigatorwidgetaction.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 -#include -#include - -#include -#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 - } -} - -bool DolphinUrlNavigatorWidgetAction::addToToolbarAndSave(KXmlGuiWindow *mainWindow) -{ - const QString rawXml = KXMLGUIFactory::readConfigFile(mainWindow->xmlFile()); - QDomDocument domDocument; - if (rawXml.isEmpty() || !domDocument.setContent(rawXml) || domDocument.isNull()) { - return false; - } - QDomNode toolbar = domDocument.elementsByTagName(QStringLiteral("ToolBar")).at(0); - if (toolbar.isNull()) { - return false; - } - - QDomElement urlNavigatorElement = domDocument.createElement(QStringLiteral("Action")); - urlNavigatorElement.setAttribute(QStringLiteral("name"), QStringLiteral("url_navigator")); - - QDomNode position = toolbar.lastChildElement(QStringLiteral("Spacer")); - if (position.isNull()) { - toolbar.appendChild(urlNavigatorElement); - } else { - toolbar.replaceChild(urlNavigatorElement, position); - } - - KXMLGUIFactory::saveConfigFile(domDocument, mainWindow->xmlFile()); - mainWindow->reloadXML(); - mainWindow->createGUI(); - return true; -} diff --git a/src/views/dolphinurlnavigatorwidgetaction.h b/src/views/dolphinurlnavigatorwidgetaction.h deleted file mode 100644 index ed07115a6..000000000 --- a/src/views/dolphinurlnavigatorwidgetaction.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 - -class KXmlGuiWindow; -class QStackedWidget; - -/** - * @brief QWidgetAction that allows to use a KUrlNavigator in a toolbar. - * - * When the UrlNavigator of this object is not in use, - * setUrlNavigatorVisible(false) is used to hide it. It will then be - * replaced in the toolbar by an empty expanding spacer. This makes sure - * that the other widgets in the toolbar will not change location when - * switching the UrlNavigators visibility. - */ -class DolphinUrlNavigatorWidgetAction : public QWidgetAction -{ - Q_OBJECT - -public: - DolphinUrlNavigatorWidgetAction(QWidget *parent = nullptr); - - DolphinUrlNavigator *urlNavigator() const; - - /** - * Sets the QStackedWidget which is the defaultWidget() to either - * show a KUrlNavigator or an expanding spacer. - */ - void setUrlNavigatorVisible(bool visible); - - /** - * Adds this action to the mainWindow's toolbar and saves the change - * in the users ui configuration file. - * @return true if successful. Otherwise false. - * @note This method does multiple things which are discouraged in - * the API documentation. - */ - bool addToToolbarAndSave(KXmlGuiWindow *mainWindow); - -private: - QStackedWidget *m_stackedWidget; -}; - -#endif // DOLPHINURLNAVIGATORWIDGETACTION_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/dolphintabwidget.cpp') 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/dolphintabwidget.cpp') 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 From 63f4981fe01d88b2ef1b27e0577d7f5d4c8cc485 Mon Sep 17 00:00:00 2001 From: Felix Ernst Date: Mon, 9 Nov 2020 14:25:15 +0100 Subject: Adress the third round of Angelaccio's review comments Additionally remove some redundant code concerning UrlNavigator visuals. --- src/dolphinnavigatorswidgetaction.cpp | 4 ++-- src/dolphintabpage.cpp | 9 +++------ src/dolphintabpage.h | 2 +- src/dolphintabwidget.cpp | 2 +- src/dolphinurlnavigator.cpp | 4 +--- src/dolphinurlnavigator.h | 6 +++++- src/dolphinurlnavigatorscontroller.cpp | 2 ++ src/dolphinviewcontainer.cpp | 5 +++-- 8 files changed, 18 insertions(+), 16 deletions(-) (limited to 'src/dolphintabwidget.cpp') diff --git a/src/dolphinnavigatorswidgetaction.cpp b/src/dolphinnavigatorswidgetaction.cpp index 84f52279a..984e1f35c 100644 --- a/src/dolphinnavigatorswidgetaction.cpp +++ b/src/dolphinnavigatorswidgetaction.cpp @@ -201,7 +201,7 @@ QWidget *DolphinNavigatorsWidgetAction::createNavigatorWidget(Side side) const auto emptyTrashButton = newEmptyTrashButton(urlNavigator, navigatorWidget); layout->addWidget(emptyTrashButton); - connect(urlNavigator, &KUrlNavigator::urlChanged, [this]() { + connect(urlNavigator, &KUrlNavigator::urlChanged, this, [this]() { // We have to wait for DolphinUrlNavigator::sizeHint() to update which // happens a little bit later than when urlChanged is emitted. this->m_adjustSpacingTimer->start(); @@ -231,7 +231,7 @@ QPushButton *DolphinNavigatorsWidgetAction::newEmptyTrashButton(const DolphinUrl connect(&Trash::instance(), &Trash::emptinessChanged, emptyTrashButton, &QPushButton::setDisabled); emptyTrashButton->hide(); - connect(urlNavigator, &KUrlNavigator::urlChanged, [emptyTrashButton, urlNavigator]() { + connect(urlNavigator, &KUrlNavigator::urlChanged, this, [emptyTrashButton, urlNavigator]() { emptyTrashButton->setVisible(urlNavigator->locationUrl().scheme() == QLatin1String("trash")); }); emptyTrashButton->setDisabled(Trash::isEmpty()); diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index d196508a8..7f945dce2 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -159,11 +159,9 @@ void DolphinTabPage::connectNavigators(DolphinNavigatorsWidgetAction *navigators { m_navigatorsWidget = navigatorsWidget; auto primaryNavigator = navigatorsWidget->primaryUrlNavigator(); - primaryNavigator->setActive(m_primaryViewActive); m_primaryViewContainer->connectUrlNavigator(primaryNavigator); if (m_splitViewEnabled) { auto secondaryNavigator = navigatorsWidget->secondaryUrlNavigator(); - secondaryNavigator->setActive(!m_primaryViewActive); m_secondaryViewContainer->connectUrlNavigator(secondaryNavigator); } resizeNavigators(); @@ -178,12 +176,13 @@ void DolphinTabPage::disconnectNavigators() } } -bool DolphinTabPage::eventFilter(QObject */* watched */, QEvent *event) +bool DolphinTabPage::eventFilter(QObject *watched, QEvent *event) { if (event->type() == QEvent::Resize && m_navigatorsWidget) { resizeNavigators(); + return false; } - return false; + return QWidget::eventFilter(watched, event); } void DolphinTabPage::resizeNavigators() const @@ -292,11 +291,9 @@ void DolphinTabPage::restoreState(const QByteArray& state) stream >> m_primaryViewActive; if (m_primaryViewActive) { m_primaryViewContainer->setActive(true); - m_navigatorsWidget->primaryUrlNavigator()->setActive(true); } else { Q_ASSERT(m_splitViewEnabled); m_secondaryViewContainer->setActive(true); - m_navigatorsWidget->primaryUrlNavigator()->setActive(false); } QByteArray splitterState; diff --git a/src/dolphintabpage.h b/src/dolphintabpage.h index 650594214..b874d128f 100644 --- a/src/dolphintabpage.h +++ b/src/dolphintabpage.h @@ -83,7 +83,7 @@ public: /** * Calls resizeNavigators() when a watched object is resized. */ - bool eventFilter(QObject */* watched */, QEvent *event) override; + bool eventFilter(QObject *watched, QEvent *event) override; /** * Notify the connected DolphinNavigatorsWidgetAction of geometry changes which it diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp index 94cdc627b..da8f76d7c 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -406,7 +406,7 @@ void DolphinTabWidget::currentTabChanged(int index) tabPage->setActive(true); tabPage->connectNavigators(m_navigatorsWidget); m_navigatorsWidget->setSecondaryNavigatorVisible(tabPage->splitViewEnabled()); - m_lastViewedTab = tabPageAt(index); + m_lastViewedTab = tabPage; } void DolphinTabWidget::tabInserted(int index) diff --git a/src/dolphinurlnavigator.cpp b/src/dolphinurlnavigator.cpp index f24cf2e06..1dfe5420f 100644 --- a/src/dolphinurlnavigator.cpp +++ b/src/dolphinurlnavigator.cpp @@ -47,10 +47,8 @@ DolphinUrlNavigator::DolphinUrlNavigator(const QUrl &url, QWidget *parent) : DolphinUrlNavigatorsController::registerDolphinUrlNavigator(this); - connect(this, &DolphinUrlNavigator::returnPressed, + connect(this, &KUrlNavigator::returnPressed, this, &DolphinUrlNavigator::slotReturnPressed); - connect(editor(), &KUrlComboBox::completionModeChanged, - DolphinUrlNavigatorsController::setCompletionMode); } DolphinUrlNavigator::~DolphinUrlNavigator() diff --git a/src/dolphinurlnavigator.h b/src/dolphinurlnavigator.h index a15428799..9bcc32b4d 100644 --- a/src/dolphinurlnavigator.h +++ b/src/dolphinurlnavigator.h @@ -15,8 +15,9 @@ * * Makes sure that Dolphin preferences and settings are * applied to all constructed DolphinUrlNavigators. - * * @see KUrlNavigator + * + * To apply changes to all instances of this class @see DolphinUrlNavigatorsController. */ class DolphinUrlNavigator : public KUrlNavigator { @@ -55,6 +56,9 @@ public: /** * Retrieve the visual state of this DolphinUrlNavigator. * If two DolphinUrlNavigators have the same visual state they should look identical. + * + * @return a copy of the visualState of this object. Ownership of this copy is transferred + * to the caller via std::unique_ptr. */ std::unique_ptr visualState() const; /** diff --git a/src/dolphinurlnavigatorscontroller.cpp b/src/dolphinurlnavigatorscontroller.cpp index 78fecd18a..59e1d6356 100644 --- a/src/dolphinurlnavigatorscontroller.cpp +++ b/src/dolphinurlnavigatorscontroller.cpp @@ -46,6 +46,8 @@ bool DolphinUrlNavigatorsController::placesSelectorVisible() void DolphinUrlNavigatorsController::registerDolphinUrlNavigator(DolphinUrlNavigator *dolphinUrlNavigator) { s_instances.push_front(dolphinUrlNavigator); + connect(dolphinUrlNavigator->editor(), &KUrlComboBox::completionModeChanged, + DolphinUrlNavigatorsController::setCompletionMode); } void DolphinUrlNavigatorsController::unregisterDolphinUrlNavigator(DolphinUrlNavigator *dolphinUrlNavigator) diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index 9761f108f..0fe8ee9d3 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -291,11 +291,11 @@ void DolphinViewContainer::connectUrlNavigator(DolphinUrlNavigator *urlNavigator Q_CHECK_PTR(m_view); urlNavigator->setLocationUrl(m_view->url()); - urlNavigator->setActive(isActive()); if (m_urlNavigatorVisualState) { urlNavigator->setVisualState(*m_urlNavigatorVisualState.get()); m_urlNavigatorVisualState.reset(); } + urlNavigator->setActive(isActive()); connect(m_view, &DolphinView::urlChanged, urlNavigator, &DolphinUrlNavigator::setLocationUrl); @@ -307,7 +307,8 @@ void DolphinViewContainer::connectUrlNavigator(DolphinUrlNavigator *urlNavigator this, &DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged); connect(urlNavigator, &DolphinUrlNavigator::urlSelectionRequested, this, &DolphinViewContainer::slotUrlSelectionRequested); - connect(urlNavigator, &DolphinUrlNavigator::urlsDropped, this, [=](const QUrl &destination, QDropEvent *event) { + connect(urlNavigator, &DolphinUrlNavigator::urlsDropped, + this, [=](const QUrl &destination, QDropEvent *event) { m_view->dropUrls(destination, event, urlNavigator->dropWidget()); }); -- cgit v1.3