Allow having the UrlNavigators below the tab bar

This commit restores the possibility to have the UrlNavigators below
the tab bar. This will happen automatically whenever the UrlNavigator
is removed from the toolbar.

It is also now again possible to have the toolbar on the side. This
option is disabled while the toolbar contains the UrlNavigators.

This commit makes no changes to the new default which is having the
UrlNavigators in the toolbar but makes sure that upgrading users won't
be affected.
This commit is contained in:
Felix Ernst 2020-11-19 21:22:27 +00:00 committed by Elvis Angelaccio
parent f2d2f325b6
commit 50ca5af7e0
7 changed files with 110 additions and 51 deletions

View file

@ -169,11 +169,6 @@ DolphinMainWindow::DolphinMainWindow() :
setupGUI(Keys | Save | Create | ToolBar); setupGUI(Keys | Save | Create | ToolBar);
stateChanged(QStringLiteral("new_file")); 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(); QClipboard* clipboard = QApplication::clipboard();
connect(clipboard, &QClipboard::dataChanged, connect(clipboard, &QClipboard::dataChanged,
this, &DolphinMainWindow::updatePasteAction); this, &DolphinMainWindow::updatePasteAction);
@ -194,6 +189,8 @@ DolphinMainWindow::DolphinMainWindow() :
createControlButton(); createControlButton();
} }
updateAllowedToolbarAreas();
// enable middle-click on back/forward/up to open in a new tab // enable middle-click on back/forward/up to open in a new tab
auto *middleClickEventFilter = new MiddleClickActionEventFilter(this); auto *middleClickEventFilter = new MiddleClickActionEventFilter(this);
connect(middleClickEventFilter, &MiddleClickActionEventFilter::actionMiddleClicked, this, &DolphinMainWindow::slotToolBarActionMiddleClicked); connect(middleClickEventFilter, &MiddleClickActionEventFilter::actionMiddleClicked, this, &DolphinMainWindow::slotToolBarActionMiddleClicked);
@ -2217,6 +2214,21 @@ void DolphinMainWindow::updateSplitAction()
} }
} }
void DolphinMainWindow::updateAllowedToolbarAreas()
{
auto navigators = static_cast<DolphinNavigatorsWidgetAction *>
(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 bool DolphinMainWindow::isKompareInstalled() const
{ {
static bool initialized = false; static bool initialized = false;
@ -2424,6 +2436,19 @@ bool DolphinMainWindow::eventFilter(QObject* obj, QEvent* event)
return false; 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<DolphinNavigatorsWidgetAction *>
(actionCollection()->action(QStringLiteral("url_navigators")));
if (!toolBar()->actions().contains(navigators)) {
m_tabWidget->currentTabPage()->insertNavigatorsWidget(navigators);
}
updateAllowedToolbarAreas();
}
void DolphinMainWindow::focusTerminalPanel() void DolphinMainWindow::focusTerminalPanel()
{ {
if (m_terminalPanel->isVisible()) { if (m_terminalPanel->isVisible()) {

View file

@ -221,6 +221,14 @@ protected:
/** Handles QWhatsThisClickedEvent and passes all others on. */ /** Handles QWhatsThisClickedEvent and passes all others on. */
bool eventFilter(QObject*, QEvent*) override; 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: private slots:
/** /**
* Refreshes the views of the main window by recreating them according to * Refreshes the views of the main window by recreating them according to
@ -593,6 +601,11 @@ private:
*/ */
void updateSplitAction(); void updateSplitAction();
/**
* Sets the window sides the toolbar may be moved to based on toolbar contents.
*/
void updateAllowedToolbarAreas();
bool isKompareInstalled() const; bool isKompareInstalled() const;
/** /**

View file

@ -18,6 +18,7 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QPushButton> #include <QPushButton>
#include <QSplitter> #include <QSplitter>
#include <QToolBar>
#include <limits> #include <limits>
@ -35,7 +36,6 @@ DolphinNavigatorsWidgetAction::DolphinNavigatorsWidgetAction(QWidget *parent) :
setIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts"))); setIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts")));
m_splitter->setChildrenCollapsible(false); m_splitter->setChildrenCollapsible(false);
setDefaultWidget(m_splitter.get());
m_splitter->addWidget(createNavigatorWidget(Primary)); m_splitter->addWidget(createNavigatorWidget(Primary));
@ -45,34 +45,6 @@ DolphinNavigatorsWidgetAction::DolphinNavigatorsWidgetAction(QWidget *parent) :
this, &DolphinNavigatorsWidgetAction::adjustSpacing); 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() void DolphinNavigatorsWidgetAction::createSecondaryUrlNavigator()
{ {
Q_ASSERT(m_splitter->count() == 1); Q_ASSERT(m_splitter->count() == 1);
@ -109,6 +81,11 @@ void DolphinNavigatorsWidgetAction::followViewContainersGeometry(
adjustSpacing(); adjustSpacing();
} }
bool DolphinNavigatorsWidgetAction::isInToolbar() const
{
return qobject_cast<QToolBar *>(m_splitter->parentWidget());
}
DolphinUrlNavigator* DolphinNavigatorsWidgetAction::primaryUrlNavigator() const DolphinUrlNavigator* DolphinNavigatorsWidgetAction::primaryUrlNavigator() const
{ {
Q_ASSERT(m_splitter); Q_ASSERT(m_splitter);
@ -137,6 +114,29 @@ void DolphinNavigatorsWidgetAction::setSecondaryNavigatorVisible(bool visible)
updateText(); 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<QGridLayout *>(oldParent->layout());
if (qobject_cast<QToolBar *>(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() void DolphinNavigatorsWidgetAction::adjustSpacing()
{ {
Q_ASSERT(m_globalXOfSplitter != INT_MIN); Q_ASSERT(m_globalXOfSplitter != INT_MIN);

View file

@ -41,13 +41,6 @@ class DolphinNavigatorsWidgetAction : public QWidgetAction
public: public:
DolphinNavigatorsWidgetAction(QWidget *parent = nullptr); 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 * The secondary UrlNavigator is only created on-demand. Such an action is not necessary
* for the primary UrlNavigator which is created preemptively. * for the primary UrlNavigator which is created preemptively.
@ -71,6 +64,8 @@ public:
void followViewContainersGeometry(int globalXOfPrimary, int widthOfPrimary, void followViewContainersGeometry(int globalXOfPrimary, int widthOfPrimary,
int globalXOfSecondary, int widthOfSecondary); int globalXOfSecondary, int widthOfSecondary);
bool isInToolbar() const;
/** /**
* @return the primary UrlNavigator. * @return the primary UrlNavigator.
*/ */
@ -87,6 +82,20 @@ public:
*/ */
void setSecondaryNavigatorVisible(bool visible); 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: private:
/** /**
* Adjusts the width of the spacings used to align the UrlNavigators with ViewContainers. * Adjusts the width of the spacings used to align the UrlNavigators with ViewContainers.

View file

@ -10,7 +10,8 @@
#include "dolphinviewcontainer.h" #include "dolphinviewcontainer.h"
#include <QSplitter> #include <QSplitter>
#include <QVBoxLayout> #include <QGridLayout>
#include <QWidgetAction>
DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, QWidget* parent) : DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, QWidget* parent) :
QWidget(parent), QWidget(parent),
@ -18,7 +19,7 @@ DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl,
m_splitViewEnabled(false), m_splitViewEnabled(false),
m_active(true) m_active(true)
{ {
QVBoxLayout* layout = new QVBoxLayout(this); QGridLayout *layout = new QGridLayout(this);
layout->setSpacing(0); layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
@ -26,7 +27,8 @@ DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl,
m_splitter->setChildrenCollapsible(false); m_splitter->setChildrenCollapsible(false);
connect(m_splitter, &QSplitter::splitterMoved, connect(m_splitter, &QSplitter::splitterMoved,
this, &DolphinTabPage::splitterMoved); this, &DolphinTabPage::splitterMoved);
layout->addWidget(m_splitter); layout->addWidget(m_splitter, 1, 0);
layout->setRowStretch(1, 1);
// Create a new primary view // Create a new primary view
m_primaryViewContainer = createViewContainer(primaryUrl); m_primaryViewContainer = createViewContainer(primaryUrl);
@ -157,6 +159,7 @@ int DolphinTabPage::selectedItemsCount() const
void DolphinTabPage::connectNavigators(DolphinNavigatorsWidgetAction *navigatorsWidget) void DolphinTabPage::connectNavigators(DolphinNavigatorsWidgetAction *navigatorsWidget)
{ {
insertNavigatorsWidget(navigatorsWidget);
m_navigatorsWidget = navigatorsWidget; m_navigatorsWidget = navigatorsWidget;
auto primaryNavigator = navigatorsWidget->primaryUrlNavigator(); auto primaryNavigator = navigatorsWidget->primaryUrlNavigator();
m_primaryViewContainer->connectUrlNavigator(primaryNavigator); m_primaryViewContainer->connectUrlNavigator(primaryNavigator);
@ -185,6 +188,20 @@ bool DolphinTabPage::eventFilter(QObject *watched, QEvent *event)
return QWidget::eventFilter(watched, event); return QWidget::eventFilter(watched, event);
} }
void DolphinTabPage::insertNavigatorsWidget(DolphinNavigatorsWidgetAction* navigatorsWidget)
{
QGridLayout *gridLayout = static_cast<QGridLayout *>(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 void DolphinTabPage::resizeNavigators() const
{ {
if (!m_splitViewEnabled) { if (!m_splitViewEnabled) {

View file

@ -85,6 +85,8 @@ public:
*/ */
bool eventFilter(QObject *watched, QEvent *event) override; bool eventFilter(QObject *watched, QEvent *event) override;
void insertNavigatorsWidget(DolphinNavigatorsWidgetAction *navigatorsWidget);
/** /**
* Notify the connected DolphinNavigatorsWidgetAction of geometry changes which it * Notify the connected DolphinNavigatorsWidgetAction of geometry changes which it
* needs for visual alignment. * needs for visual alignment.

View file

@ -21,7 +21,6 @@
#include <KCrash> #include <KCrash>
#include <KDBusService> #include <KDBusService>
#include <KLocalizedString> #include <KLocalizedString>
#include <KToolBar>
#include <Kdelibs4ConfigMigrator> #include <Kdelibs4ConfigMigrator>
#include <KConfigGui> #include <KConfigGui>
@ -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 #ifdef HAVE_KUSERFEEDBACK
auto feedbackProvider = DolphinFeedbackProvider::instance(); auto feedbackProvider = DolphinFeedbackProvider::instance();