QWidgetAction{parent},
m_splitter{new QSplitter(Qt::Horizontal)},
m_adjustSpacingTimer{new QTimer(this)},
- m_globalXOfSplitter{INT_MIN},
- m_globalXOfPrimary{INT_MIN},
- m_widthOfPrimary{INT_MIN},
- m_globalXOfSecondary{INT_MIN},
- m_widthOfSecondary{INT_MIN}
+ m_viewGeometriesHelper{m_splitter.get(), this}
{
updateText();
setIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts")));
this, &DolphinNavigatorsWidgetAction::adjustSpacing);
}
+void DolphinNavigatorsWidgetAction::adjustSpacing()
+{
+ auto viewGeometries = m_viewGeometriesHelper.viewGeometries();
+ const int widthOfSplitterPrimary = viewGeometries.globalXOfPrimary + viewGeometries.widthOfPrimary - viewGeometries.globalXOfNavigatorsWidget;
+ const QList<int> splitterSizes = {widthOfSplitterPrimary,
+ m_splitter->width() - widthOfSplitterPrimary};
+ m_splitter->setSizes(splitterSizes);
+
+ // primary side of m_splitter
+ int leadingSpacing = viewGeometries.globalXOfPrimary - viewGeometries.globalXOfNavigatorsWidget;
+ if (leadingSpacing < 0) {
+ leadingSpacing = 0;
+ }
+ int trailingSpacing = (viewGeometries.globalXOfNavigatorsWidget + m_splitter->width())
+ - (viewGeometries.globalXOfPrimary + viewGeometries.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 (viewGeometries.globalXOfSecondary == INT_MIN) {
+ Q_ASSERT(viewGeometries.widthOfSecondary == INT_MIN);
+ return;
+ }
+ spacing(Primary, Trailing)->setFixedWidth(0);
+
+ trailingSpacing = (viewGeometries.globalXOfNavigatorsWidget + m_splitter->width())
+ - (viewGeometries.globalXOfSecondary + viewGeometries.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);
+}
+
void DolphinNavigatorsWidgetAction::createSecondaryUrlNavigator()
{
Q_ASSERT(m_splitter->count() == 1);
updateText();
}
-void DolphinNavigatorsWidgetAction::followViewContainerGeometry(
- int globalXOfPrimary, int widthOfPrimary)
-{
- followViewContainersGeometry(globalXOfPrimary, widthOfPrimary, INT_MIN, INT_MIN);
-}
-
-void DolphinNavigatorsWidgetAction::followViewContainersGeometry(
- int globalXOfPrimary, int widthOfPrimary,
- int globalXOfSecondary, int widthOfSecondary)
+void DolphinNavigatorsWidgetAction::followViewContainersGeometry(QWidget *primaryViewContainer,
+ QWidget *secondaryViewContainer)
{
- if (QApplication::layoutDirection() == Qt::LeftToRight) {
- m_globalXOfSplitter = m_splitter->mapToGlobal(QPoint(0,0)).x();
- m_globalXOfPrimary = globalXOfPrimary;
- m_globalXOfSecondary = globalXOfSecondary;
- } else {
- // When the direction is reversed, globalX does not change.
- // For the adjustSpacing() code to work we need globalX to measure from right to left
- // and to measure up to the rightmost point of a widget instead of the leftmost.
- m_globalXOfSplitter = (-1) * (m_splitter->mapToGlobal(QPoint(0,0)).x() + m_splitter->width());
- m_globalXOfPrimary = (-1) * (globalXOfPrimary + widthOfPrimary);
- m_globalXOfSecondary = (globalXOfSecondary == INT_MIN) ? INT_MIN :
- (-1) * (globalXOfSecondary + widthOfSecondary);
- }
- m_widthOfPrimary = widthOfPrimary;
- m_widthOfSecondary = widthOfSecondary;
+ m_viewGeometriesHelper.setViewContainers(primaryViewContainer, secondaryViewContainer);
adjustSpacing();
}
m_splitter->setParent(nullptr);
}
-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<int> 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 == INT_MIN) {
- Q_ASSERT(m_widthOfSecondary == INT_MIN);
- 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());
2 : 1;
setText(i18ncp("@action:inmenu", "Location Bar", "Location Bars", urlNavigatorsAmount));
}
+
+DolphinNavigatorsWidgetAction::ViewGeometriesHelper::ViewGeometriesHelper
+ (QWidget *navigatorsWidget, DolphinNavigatorsWidgetAction *navigatorsWidgetAction) :
+ m_navigatorsWidget{navigatorsWidget},
+ m_navigatorsWidgetAction{navigatorsWidgetAction}
+{
+ Q_CHECK_PTR(navigatorsWidget);
+ Q_CHECK_PTR(navigatorsWidgetAction);
+}
+
+bool DolphinNavigatorsWidgetAction::ViewGeometriesHelper::eventFilter(QObject *watched, QEvent *event)
+{
+ if (event->type() == QEvent::Resize) {
+ m_navigatorsWidgetAction->adjustSpacing();
+ return false;
+ }
+ return QObject::eventFilter(watched, event);
+}
+
+void DolphinNavigatorsWidgetAction::ViewGeometriesHelper::setViewContainers(QWidget *primaryViewContainer,
+ QWidget *secondaryViewContainer)
+{
+ Q_CHECK_PTR(primaryViewContainer);
+ if (m_primaryViewContainer) {
+ m_primaryViewContainer->removeEventFilter(this);
+ }
+ primaryViewContainer->installEventFilter(this);
+ m_primaryViewContainer = primaryViewContainer;
+
+ // It is not possible to resize the secondaryViewContainer without simultaneously
+ // resizing the primaryViewContainer so we don't have to installEventFilter() here.
+ m_secondaryViewContainer = secondaryViewContainer;
+}
+
+DolphinNavigatorsWidgetAction::ViewGeometriesHelper::Geometries
+ DolphinNavigatorsWidgetAction::ViewGeometriesHelper::viewGeometries()
+{
+ Q_ASSERT(m_primaryViewContainer);
+ Geometries geometries;
+
+ // width
+ geometries.widthOfPrimary = m_primaryViewContainer->width();
+ if (m_secondaryViewContainer) {
+ geometries.widthOfSecondary = m_secondaryViewContainer->width();
+ } else {
+ geometries.widthOfSecondary = INT_MIN;
+ }
+
+ // globalX
+ if (QApplication::layoutDirection() == Qt::LeftToRight) {
+ geometries.globalXOfNavigatorsWidget = m_navigatorsWidget->mapToGlobal(QPoint(0,0)).x();
+ geometries.globalXOfPrimary = m_primaryViewContainer->mapToGlobal(QPoint(0,0)).x();
+ geometries.globalXOfSecondary = !m_secondaryViewContainer ? INT_MIN :
+ m_secondaryViewContainer->mapToGlobal(QPoint(0,0)).x();
+ } else {
+ // When the direction is reversed, globalX does not change.
+ // For the adjustSpacing() code to work we need globalX to measure from right to left
+ // and to measure up to the rightmost point of a widget instead of the leftmost.
+ geometries.globalXOfNavigatorsWidget =
+ (-1) * (m_navigatorsWidget->mapToGlobal(QPoint(0,0)).x() + m_navigatorsWidget->width());
+ geometries.globalXOfPrimary =
+ (-1) * (m_primaryViewContainer->mapToGlobal(QPoint(0,0)).x() + geometries.widthOfPrimary);
+ geometries.globalXOfSecondary = !m_secondaryViewContainer ? INT_MIN :
+ (-1) * (m_secondaryViewContainer->mapToGlobal(QPoint(0,0)).x() + geometries.widthOfSecondary);
+ }
+ return geometries;
+}
#include "dolphinurlnavigator.h"
+#include <QPointer>
#include <QSplitter>
#include <QTimer>
#include <QWidgetAction>
public:
DolphinNavigatorsWidgetAction(QWidget *parent = nullptr);
+ /**
+ * 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();
+
/**
* The secondary UrlNavigator is only created on-demand. Such an action is not necessary
* for the primary UrlNavigator which is created preemptively.
*/
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);
+ void followViewContainersGeometry(QWidget *primaryViewContainer,
+ QWidget *secondaryViewContainer = nullptr);
bool isInToolbar() const;
void deleteWidget(QWidget *widget) override;
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
- * followViewContainersGeometry() has to have been called at least once before.
- */
- void adjustSpacing();
-
/**
* In Left-to-right languages the Primary side will be the left one.
*/
*/
std::unique_ptr<QTimer> m_adjustSpacingTimer;
- // cached values
- int m_globalXOfSplitter;
- int m_globalXOfPrimary;
- int m_widthOfPrimary;
- int m_globalXOfSecondary;
- int m_widthOfSecondary;
+ /**
+ * Extracts the geometry information needed by adjustSpacing() from
+ * ViewContainers. They are also monitored for size changes which
+ * will lead to adjustSpacing() calls.
+ */
+ class ViewGeometriesHelper : public QObject
+ {
+ public:
+ /**
+ * @param navigatorsWidget The QWidget of the navigatorsWidgetAction.
+ * @param navigatorsWidgetAction is only used to call adjustSpacing() whenever that is
+ * deemed necessary.
+ */
+ ViewGeometriesHelper(QWidget *navigatorsWidget, DolphinNavigatorsWidgetAction *navigatorsWidgetAction);
+
+ /**
+ * Calls m_navigatorsWidgetAction::adjustSpacing() when a watched object is resized.
+ */
+ bool eventFilter(QObject *watched, QEvent *event) override;
+
+ /**
+ * Sets the ViewContainers whose geometry is obtained when viewGeometries() is called.
+ */
+ void setViewContainers(QWidget *primaryViewContainer,
+ QWidget *secondaryViewContainer = nullptr);
+
+ struct Geometries {
+ int globalXOfNavigatorsWidget;
+ int globalXOfPrimary;
+ int widthOfPrimary;
+ int globalXOfSecondary;
+ int widthOfSecondary;
+ };
+ /**
+ * @return a Geometries struct that contains values adjustSpacing() requires.
+ */
+ Geometries viewGeometries();
+
+ private:
+ QWidget *m_navigatorsWidget;
+ /** Is only used to call adjustSpacing() whenever that is deemed necessary. */
+ DolphinNavigatorsWidgetAction *m_navigatorsWidgetAction;
+
+ QPointer<QWidget> m_primaryViewContainer;
+ QPointer<QWidget> m_secondaryViewContainer;
+ };
+
+ ViewGeometriesHelper m_viewGeometriesHelper;
};
#endif // DOLPHINNAVIGATORSWIDGETACTION_H
this, &DolphinTabPage::slotViewUrlRedirection);
m_splitter->addWidget(m_primaryViewContainer);
- m_primaryViewContainer->installEventFilter(this);
m_primaryViewContainer->show();
if (secondaryUrl.isValid() || GeneralSettings::splitView()) {
const QUrl& url = secondaryUrl.isValid() ? secondaryUrl : primaryUrl;
m_secondaryViewContainer = createViewContainer(url);
m_splitter->addWidget(m_secondaryViewContainer);
- m_secondaryViewContainer->installEventFilter(this);
m_secondaryViewContainer->show();
}
}
m_secondaryViewContainer->connectUrlNavigator(secondaryNavigator);
m_navigatorsWidget->setSecondaryNavigatorVisible(true);
+ m_navigatorsWidget->followViewContainersGeometry(m_primaryViewContainer,
+ m_secondaryViewContainer);
m_splitter->addWidget(m_secondaryViewContainer);
- m_secondaryViewContainer->installEventFilter(this);
m_secondaryViewContainer->setActive(true);
if (animated == WithAnimation) {
}
}
m_primaryViewContainer->setActive(true);
+ m_navigatorsWidget->followViewContainersGeometry(m_primaryViewContainer, nullptr);
if (animated == WithoutAnimation) {
view->close();
auto secondaryNavigator = navigatorsWidget->secondaryUrlNavigator();
m_secondaryViewContainer->connectUrlNavigator(secondaryNavigator);
}
- resizeNavigators();
+ m_navigatorsWidget->followViewContainersGeometry(m_primaryViewContainer,
+ m_secondaryViewContainer);
}
void DolphinTabPage::disconnectNavigators()
}
}
-bool DolphinTabPage::eventFilter(QObject *watched, QEvent *event)
-{
- if (event->type() == QEvent::Resize && m_navigatorsWidget) {
- resizeNavigators();
- return false;
- }
- return QWidget::eventFilter(watched, event);
-}
-
void DolphinTabPage::insertNavigatorsWidget(DolphinNavigatorsWidgetAction* navigatorsWidget)
{
QGridLayout *gridLayout = static_cast<QGridLayout *>(layout());
}
}
-
-void DolphinTabPage::resizeNavigators() const
-{
- if (!m_secondaryViewContainer) {
- 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<QUrl>& urls)
{
m_primaryViewContainer->view()->markUrlsAsSelected(urls);