diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 0c4c3c88177b1f43b2fcb46763738e1b01284347..b72f2eb90ced1460776083c148219163b9c1abd3 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -169,11 +169,6 @@ 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); @@ -194,6 +189,8 @@ DolphinMainWindow::DolphinMainWindow() : createControlButton(); } + updateAllowedToolbarAreas(); + // enable middle-click on back/forward/up to open in a new tab auto *middleClickEventFilter = new MiddleClickActionEventFilter(this); connect(middleClickEventFilter, &MiddleClickActionEventFilter::actionMiddleClicked, this, &DolphinMainWindow::slotToolBarActionMiddleClicked); @@ -2217,6 +2214,21 @@ void DolphinMainWindow::updateSplitAction() } } +void DolphinMainWindow::updateAllowedToolbarAreas() +{ + auto navigators = static_cast + (actionCollection()->action(QStringLiteral("url_navigators"))); + if (toolBar()->actions().contains(navigators)) { + toolBar()->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); + if (toolBarArea(toolBar()) == Qt::LeftToolBarArea || + toolBarArea(toolBar()) == Qt::RightToolBarArea) { + addToolBar(Qt::TopToolBarArea, toolBar()); + } + } else { + toolBar()->setAllowedAreas(Qt::AllToolBarAreas); + } +} + bool DolphinMainWindow::isKompareInstalled() const { static bool initialized = false; @@ -2424,6 +2436,19 @@ bool DolphinMainWindow::eventFilter(QObject* obj, QEvent* event) return false; } +void DolphinMainWindow::saveNewToolbarConfig() +{ + KXmlGuiWindow::saveNewToolbarConfig(); // Applies the new config. This has to be called first + // because the rest of this method decides things + // based on the new config. + auto navigators = static_cast + (actionCollection()->action(QStringLiteral("url_navigators"))); + if (!toolBar()->actions().contains(navigators)) { + m_tabWidget->currentTabPage()->insertNavigatorsWidget(navigators); + } + updateAllowedToolbarAreas(); +} + void DolphinMainWindow::focusTerminalPanel() { if (m_terminalPanel->isVisible()) { diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index 29ab6326dac20128fc7aa9bdff59b7f74ff52f16..8d5eae344c63da5c21f9ac96f8aa5e3a3699cf48 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -221,6 +221,14 @@ protected: /** Handles QWhatsThisClickedEvent and passes all others on. */ bool eventFilter(QObject*, QEvent*) override; +protected slots: + /** + * Calls the base method KXmlGuiWindow::saveNewToolbarConfig(). + * Is also used to set toolbar constraints and UrlNavigator position + * based on the newly changed toolbar configuration. + */ + void saveNewToolbarConfig() override; + private slots: /** * Refreshes the views of the main window by recreating them according to @@ -593,6 +601,11 @@ private: */ void updateSplitAction(); + /** + * Sets the window sides the toolbar may be moved to based on toolbar contents. + */ + void updateAllowedToolbarAreas(); + bool isKompareInstalled() const; /** diff --git a/src/dolphinnavigatorswidgetaction.cpp b/src/dolphinnavigatorswidgetaction.cpp index e0ae3132acb6a073dcc45bc13685d290b99547b4..b8c77c69b1ab7c94a803aeba933b867fe9b954b9 100644 --- a/src/dolphinnavigatorswidgetaction.cpp +++ b/src/dolphinnavigatorswidgetaction.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -35,7 +36,6 @@ DolphinNavigatorsWidgetAction::DolphinNavigatorsWidgetAction(QWidget *parent) : setIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts"))); m_splitter->setChildrenCollapsible(false); - setDefaultWidget(m_splitter.get()); m_splitter->addWidget(createNavigatorWidget(Primary)); @@ -45,34 +45,6 @@ DolphinNavigatorsWidgetAction::DolphinNavigatorsWidgetAction(QWidget *parent) : 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.firstChildElement(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); @@ -109,6 +81,11 @@ void DolphinNavigatorsWidgetAction::followViewContainersGeometry( adjustSpacing(); } +bool DolphinNavigatorsWidgetAction::isInToolbar() const +{ + return qobject_cast(m_splitter->parentWidget()); +} + DolphinUrlNavigator* DolphinNavigatorsWidgetAction::primaryUrlNavigator() const { Q_ASSERT(m_splitter); @@ -137,6 +114,29 @@ void DolphinNavigatorsWidgetAction::setSecondaryNavigatorVisible(bool visible) updateText(); } +QWidget *DolphinNavigatorsWidgetAction::createWidget(QWidget *parent) +{ + QWidget *oldParent = m_splitter->parentWidget(); + if (oldParent && oldParent->layout()) { + oldParent->layout()->removeWidget(m_splitter.get()); + QGridLayout *layout = qobject_cast(oldParent->layout()); + if (qobject_cast(parent) && layout) { + // in DolphinTabPage::insertNavigatorsWidget the minimumHeight of this row was + // set to fit the m_splitter. Since we are now removing it again, the + // minimumHeight can be reset to 0. + layout->setRowMinimumHeight(0, 0); + } + } + m_splitter->setParent(parent); + return m_splitter.get(); +} + +void DolphinNavigatorsWidgetAction::deleteWidget(QWidget *widget) +{ + Q_UNUSED(widget) + m_splitter->setParent(nullptr); +} + void DolphinNavigatorsWidgetAction::adjustSpacing() { Q_ASSERT(m_globalXOfSplitter != INT_MIN); diff --git a/src/dolphinnavigatorswidgetaction.h b/src/dolphinnavigatorswidgetaction.h index f343e6a1c23a1dc8dd32debf45b6d24d54be9417..bbd8cf127fc9e51deb4515da2894718eb22455b0 100644 --- a/src/dolphinnavigatorswidgetaction.h +++ b/src/dolphinnavigatorswidgetaction.h @@ -41,13 +41,6 @@ class DolphinNavigatorsWidgetAction : public QWidgetAction 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); - /** * The secondary UrlNavigator is only created on-demand. Such an action is not necessary * for the primary UrlNavigator which is created preemptively. @@ -71,6 +64,8 @@ public: void followViewContainersGeometry(int globalXOfPrimary, int widthOfPrimary, int globalXOfSecondary, int widthOfSecondary); + bool isInToolbar() const; + /** * @return the primary UrlNavigator. */ @@ -87,6 +82,20 @@ public: */ void setSecondaryNavigatorVisible(bool visible); +protected: + /** + * There should always ever be one navigatorsWidget for this action so + * this method always returns the same widget and reparents it. + * You normally don't have to use this method directly because + * QWidgetAction::requestWidget() is used to obtain the navigatorsWidget + * and to steal it from whereever it was prior. + * @param parent the new parent of the navigatorsWidget. + */ + QWidget *createWidget(QWidget *parent) override; + + /** @see QWidgetAction::deleteWidget() */ + void deleteWidget(QWidget *widget) override; + private: /** * Adjusts the width of the spacings used to align the UrlNavigators with ViewContainers. diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index 7f945dce27772a0476ebaa49a8ea052e0cc222ac..138822cfd36a009c254f465d055956d93b49dbe0 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -10,7 +10,8 @@ #include "dolphinviewcontainer.h" #include -#include +#include +#include DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, QWidget* parent) : QWidget(parent), @@ -18,7 +19,7 @@ DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, m_splitViewEnabled(false), m_active(true) { - QVBoxLayout* layout = new QVBoxLayout(this); + QGridLayout *layout = new QGridLayout(this); layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); @@ -26,7 +27,8 @@ DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, m_splitter->setChildrenCollapsible(false); connect(m_splitter, &QSplitter::splitterMoved, this, &DolphinTabPage::splitterMoved); - layout->addWidget(m_splitter); + layout->addWidget(m_splitter, 1, 0); + layout->setRowStretch(1, 1); // Create a new primary view m_primaryViewContainer = createViewContainer(primaryUrl); @@ -157,6 +159,7 @@ int DolphinTabPage::selectedItemsCount() const void DolphinTabPage::connectNavigators(DolphinNavigatorsWidgetAction *navigatorsWidget) { + insertNavigatorsWidget(navigatorsWidget); m_navigatorsWidget = navigatorsWidget; auto primaryNavigator = navigatorsWidget->primaryUrlNavigator(); m_primaryViewContainer->connectUrlNavigator(primaryNavigator); @@ -185,6 +188,20 @@ bool DolphinTabPage::eventFilter(QObject *watched, QEvent *event) return QWidget::eventFilter(watched, event); } +void DolphinTabPage::insertNavigatorsWidget(DolphinNavigatorsWidgetAction* navigatorsWidget) +{ + QGridLayout *gridLayout = static_cast(layout()); + if (navigatorsWidget->isInToolbar()) { + gridLayout->setRowMinimumHeight(0, 0); + } else { + // We set a row minimum height, so the height does not visibly change whenever + // navigatorsWidget is inserted which happens every time the current tab is changed. + gridLayout->setRowMinimumHeight(0, navigatorsWidget->primaryUrlNavigator()->height()); + gridLayout->addWidget(navigatorsWidget->requestWidget(this), 0, 0); + } +} + + void DolphinTabPage::resizeNavigators() const { if (!m_splitViewEnabled) { diff --git a/src/dolphintabpage.h b/src/dolphintabpage.h index b874d128f6bb5dd5b53ba0b9bc8250c93340ca87..63a246328f074bdfa4eb78355ecd8ddd51ba1703 100644 --- a/src/dolphintabpage.h +++ b/src/dolphintabpage.h @@ -85,6 +85,8 @@ public: */ bool eventFilter(QObject *watched, QEvent *event) override; + void insertNavigatorsWidget(DolphinNavigatorsWidgetAction *navigatorsWidget); + /** * Notify the connected DolphinNavigatorsWidgetAction of geometry changes which it * needs for visual alignment. diff --git a/src/main.cpp b/src/main.cpp index a4b1b1963fc61683ccaf31bf214b25b926648443..ef2905d776ade988e669f67dd134e78cce10f146 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -214,12 +213,6 @@ 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();