X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/1b4572dac9fb529d31b786f93e4f02c6f8aeeb21..37327c9b0aae112c5890703cba1f0157043007e0:/src/dolphintabpage.cpp diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index 6d55ebeb2..d2fd1d143 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -1,51 +1,43 @@ -/*************************************************************************** - * Copyright (C) 2014 by Emmanuel Pescosta * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ +/* + * SPDX-FileCopyrightText: 2014 Emmanuel Pescosta + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ #include "dolphintabpage.h" -#include "dolphinviewcontainer.h" #include "dolphin_generalsettings.h" +#include "dolphinviewcontainer.h" +#include #include #include DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, QWidget* parent) : QWidget(parent), m_primaryViewActive(true), - m_splitViewEnabled(false) + m_splitViewEnabled(false), + m_active(true) { QVBoxLayout* layout = new QVBoxLayout(this); layout->setSpacing(0); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); 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 m_primaryViewContainer = createViewContainer(primaryUrl); - connect(m_primaryViewContainer->view(), SIGNAL(urlChanged(QUrl)), - this, SIGNAL(activeViewUrlChanged(QUrl))); - connect(m_primaryViewContainer->view(), SIGNAL(redirection(QUrl,QUrl)), - this, SLOT(slotViewUrlRedirection(QUrl,QUrl))); + connect(m_primaryViewContainer->view(), &DolphinView::urlChanged, + this, &DolphinTabPage::activeViewUrlChanged); + connect(m_primaryViewContainer->view(), &DolphinView::redirection, + this, &DolphinTabPage::slotViewUrlRedirection); m_splitter->addWidget(m_primaryViewContainer); + m_primaryViewContainer->installEventFilter(this); m_primaryViewContainer->show(); if (secondaryUrl.isValid() || GeneralSettings::splitView()) { @@ -55,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(); } @@ -71,32 +64,90 @@ bool DolphinTabPage::splitViewEnabled() const return m_splitViewEnabled; } -void DolphinTabPage::setSplitViewEnabled(bool enabled) +void DolphinTabPage::setSplitViewEnabled(bool enabled, const QUrl &secondaryUrl) { if (m_splitViewEnabled != enabled) { m_splitViewEnabled = enabled; if (enabled) { - const QUrl& url = m_primaryViewContainer->url(); + int splitterTotalWidth = m_splitter->width(); + const QUrl& url = (secondaryUrl.isEmpty()) ? m_primaryViewContainer->url() : secondaryUrl; m_secondaryViewContainer = createViewContainer(url); - const bool placesSelectorVisible = m_primaryViewContainer->urlNavigator()->isPlacesSelectorVisible(); - m_secondaryViewContainer->urlNavigator()->setPlacesSelectorVisible(placesSelectorVisible); + 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 { - // Close the view which is active. - DolphinViewContainer* view = activeViewContainer(); - if (m_primaryViewActive) { - // 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); + 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); + m_primaryViewActive = false; + } + } 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); + m_primaryViewActive = true; + } } 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()); + } } } } @@ -135,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); @@ -151,14 +252,6 @@ void DolphinTabPage::markUrlAsCurrent(const QUrl& url) } } -void DolphinTabPage::setPlacesSelectorVisible(bool visible) -{ - m_primaryViewContainer->urlNavigator()->setPlacesSelectorVisible(visible); - if (m_splitViewEnabled) { - m_secondaryViewContainer->urlNavigator()->setPlacesSelectorVisible(visible); - } -} - void DolphinTabPage::refreshViews() { m_primaryViewContainer->readSettings(); @@ -177,12 +270,12 @@ QByteArray DolphinTabPage::saveState() const stream << m_splitViewEnabled; stream << m_primaryViewContainer->url(); - stream << m_primaryViewContainer->urlNavigator()->isUrlEditable(); + stream << m_primaryViewContainer->urlNavigatorInternalWithHistory()->isUrlEditable(); m_primaryViewContainer->view()->saveState(stream); if (m_splitViewEnabled) { stream << m_secondaryViewContainer->url(); - stream << m_secondaryViewContainer->urlNavigator()->isUrlEditable(); + stream << m_secondaryViewContainer->urlNavigatorInternalWithHistory()->isUrlEditable(); m_secondaryViewContainer->view()->saveState(stream); } @@ -218,7 +311,7 @@ void DolphinTabPage::restoreState(const QByteArray& state) m_primaryViewContainer->setUrl(primaryUrl); bool primaryUrlEditable; stream >> primaryUrlEditable; - m_primaryViewContainer->urlNavigator()->setUrlEditable(primaryUrlEditable); + m_primaryViewContainer->urlNavigatorInternalWithHistory()->setUrlEditable(primaryUrlEditable); m_primaryViewContainer->view()->restoreState(stream); if (isSplitViewEnabled) { @@ -227,18 +320,24 @@ void DolphinTabPage::restoreState(const QByteArray& state) m_secondaryViewContainer->setUrl(secondaryUrl); bool secondaryUrlEditable; stream >> secondaryUrlEditable; - m_secondaryViewContainer->urlNavigator()->setUrlEditable(secondaryUrlEditable); + m_secondaryViewContainer->urlNavigatorInternalWithHistory()->setUrlEditable(secondaryUrlEditable); m_secondaryViewContainer->view()->restoreState(stream); } 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); @@ -262,7 +361,7 @@ void DolphinTabPage::restoreStateV1(const QByteArray& state) m_primaryViewContainer->setUrl(primaryUrl); bool primaryUrlEditable; stream >> primaryUrlEditable; - m_primaryViewContainer->urlNavigator()->setUrlEditable(primaryUrlEditable); + m_primaryViewContainer->urlNavigatorInternalWithHistory()->setUrlEditable(primaryUrlEditable); if (isSplitViewEnabled) { QUrl secondaryUrl; @@ -270,7 +369,7 @@ void DolphinTabPage::restoreStateV1(const QByteArray& state) m_secondaryViewContainer->setUrl(secondaryUrl); bool secondaryUrlEditable; stream >> secondaryUrlEditable; - m_secondaryViewContainer->urlNavigator()->setUrlEditable(secondaryUrlEditable); + m_secondaryViewContainer->urlNavigatorInternalWithHistory()->setUrlEditable(secondaryUrlEditable); } stream >> m_primaryViewActive; @@ -286,41 +385,71 @@ void DolphinTabPage::restoreStateV1(const QByteArray& state) m_splitter->restoreState(splitterState); } +void DolphinTabPage::setActive(bool active) +{ + if (active) { + m_active = active; + } else { + // we should bypass changing active view in split mode + m_active = !m_splitViewEnabled; + } + // we want view to fire activated when goes from false to true + activeViewContainer()->setActive(active); +} + void DolphinTabPage::slotViewActivated() { const DolphinView* oldActiveView = activeViewContainer()->view(); // Set the view, which was active before, to inactive - // and update the active view type. - if (m_splitViewEnabled) { - activeViewContainer()->setActive(false); - m_primaryViewActive = !m_primaryViewActive; - } else { - m_primaryViewActive = true; + // and update the active view type, if tab is active + if (m_active) { + if (m_splitViewEnabled) { + activeViewContainer()->setActive(false); + m_primaryViewActive = !m_primaryViewActive; + } else { + m_primaryViewActive = true; + if (m_secondaryViewContainer) { + m_secondaryViewContainer->setActive(false); + } + } } const DolphinView* newActiveView = activeViewContainer()->view(); - if (newActiveView != oldActiveView) { - disconnect(oldActiveView, SIGNAL(urlChanged(QUrl)), - this, SIGNAL(activeViewUrlChanged(QUrl))); - disconnect(oldActiveView, SIGNAL(redirection(QUrl,QUrl)), - this, SLOT(slotViewUrlRedirection(QUrl,QUrl))); - connect(newActiveView, SIGNAL(urlChanged(QUrl)), - this, SIGNAL(activeViewUrlChanged(QUrl))); - connect(newActiveView, SIGNAL(redirection(QUrl,QUrl)), - this, SLOT(slotViewUrlRedirection(QUrl,QUrl))); + if (newActiveView == oldActiveView) { + return; } - emit activeViewUrlChanged(activeViewContainer()->url()); - emit activeViewChanged(activeViewContainer()); + disconnect(oldActiveView, &DolphinView::urlChanged, + this, &DolphinTabPage::activeViewUrlChanged); + disconnect(oldActiveView, &DolphinView::redirection, + this, &DolphinTabPage::slotViewUrlRedirection); + connect(newActiveView, &DolphinView::urlChanged, + this, &DolphinTabPage::activeViewUrlChanged); + connect(newActiveView, &DolphinView::redirection, + this, &DolphinTabPage::slotViewUrlRedirection); + Q_EMIT activeViewChanged(activeViewContainer()); + Q_EMIT activeViewUrlChanged(activeViewContainer()->url()); } void DolphinTabPage::slotViewUrlRedirection(const QUrl& oldUrl, const QUrl& newUrl) { - Q_UNUSED(oldUrl); + Q_UNUSED(oldUrl) - emit activeViewUrlChanged(newUrl); + Q_EMIT activeViewUrlChanged(newUrl); +} + +void DolphinTabPage::switchActiveView() +{ + if (!m_splitViewEnabled) { + return; + } + if (m_primaryViewActive) { + m_secondaryViewContainer->setActive(true); + } else { + m_primaryViewContainer->setActive(true); + } } DolphinViewContainer* DolphinTabPage::createViewContainer(const QUrl& url) const @@ -329,8 +458,11 @@ DolphinViewContainer* DolphinTabPage::createViewContainer(const QUrl& url) const container->setActive(false); const DolphinView* view = container->view(); - connect(view, SIGNAL(activated()), - this, SLOT(slotViewActivated())); + connect(view, &DolphinView::activated, + this, &DolphinTabPage::slotViewActivated); + + connect(view, &DolphinView::toggleActiveViewRequested, + this, &DolphinTabPage::switchActiveView); return container; }