-/***************************************************************************
- * Copyright (C) 2014 by Emmanuel Pescosta <emmanuelpescosta099@gmail.com> *
- * *
- * 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 <emmanuelpescosta099@gmail.com>
+ * SPDX-FileCopyrightText: 2020 Felix Ernst <felixernst@kde.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
#include "dolphintabpage.h"
-#include "dolphinviewcontainer.h"
#include "dolphin_generalsettings.h"
+#include "dolphinviewcontainer.h"
-#include <QSplitter>
-#include <QVBoxLayout>
+#include <QGridLayout>
+#include <QStyle>
+#include <QVariantAnimation>
-DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, QWidget* parent) :
- QWidget(parent),
- m_primaryViewActive(true),
- m_splitViewEnabled(false)
+DolphinTabPage::DolphinTabPage(const QUrl &primaryUrl, const QUrl &secondaryUrl, QWidget *parent)
+ : QWidget(parent)
+ , m_expandingContainer{nullptr}
+ , m_primaryViewActive(true)
+ , m_splitViewEnabled(false)
+ , m_active(true)
{
- QVBoxLayout* layout = new QVBoxLayout(this);
+ QGridLayout *layout = new QGridLayout(this);
layout->setSpacing(0);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
- m_splitter = new QSplitter(Qt::Horizontal, this);
+ m_splitter = new DolphinTabPageSplitter(Qt::Horizontal, this);
m_splitter->setChildrenCollapsible(false);
- layout->addWidget(m_splitter);
+ connect(m_splitter, &QSplitter::splitterMoved, this, &DolphinTabPage::splitterMoved);
+ layout->addWidget(m_splitter, 1, 0);
+ layout->setRowStretch(1, 1);
// Create a new primary view
m_primaryViewContainer = createViewContainer(primaryUrl);
- connect(m_primaryViewContainer->view(), SIGNAL(urlChanged(KUrl)),
- this, SIGNAL(activeViewUrlChanged(KUrl)));
- connect(m_primaryViewContainer->view(), SIGNAL(redirection(KUrl,KUrl)),
- this, SLOT(slotViewUrlRedirection(KUrl,KUrl)));
+ 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->show();
// Provide a secondary view, if the given secondary url is valid or if the
// startup settings are set this way (use the url of the primary view).
m_splitViewEnabled = true;
- const KUrl& url = secondaryUrl.isValid() ? secondaryUrl : primaryUrl;
+ const QUrl &url = secondaryUrl.isValid() ? secondaryUrl : primaryUrl;
m_secondaryViewContainer = createViewContainer(url);
+ connect(m_secondaryViewContainer->view(), &DolphinView::redirection, this, &DolphinTabPage::slotViewUrlRedirection);
m_splitter->addWidget(m_secondaryViewContainer);
m_secondaryViewContainer->show();
}
return m_splitViewEnabled;
}
-void DolphinTabPage::setSplitViewEnabled(bool enabled)
+void DolphinTabPage::setSplitViewEnabled(bool enabled, Animated animated, const QUrl &secondaryUrl)
{
if (m_splitViewEnabled != enabled) {
m_splitViewEnabled = enabled;
+ if (animated == WithAnimation
+ && (style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, this) < 1 || GlobalConfig::animationDurationFactor() <= 0.0)) {
+ animated = WithoutAnimation;
+ }
+ if (m_expandViewAnimation) {
+ m_expandViewAnimation->stop(); // deletes because of QAbstractAnimation::DeleteWhenStopped.
+ if (animated == WithoutAnimation) {
+ slotAnimationFinished();
+ }
+ }
if (enabled) {
- const KUrl& url = m_primaryViewContainer->url();
+ QList<int> splitterSizes = m_splitter->sizes();
+ 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);
+ connect(m_secondaryViewContainer->view(), &DolphinView::redirection, this, &DolphinTabPage::slotViewUrlRedirection);
+ m_navigatorsWidget->setSecondaryNavigatorVisible(true);
+ m_navigatorsWidget->followViewContainersGeometry(m_primaryViewContainer, m_secondaryViewContainer);
m_splitter->addWidget(m_secondaryViewContainer);
- m_secondaryViewContainer->show();
m_secondaryViewContainer->setActive(true);
+
+ if (animated == WithAnimation) {
+ m_secondaryViewContainer->setMinimumWidth(1);
+ splitterSizes.append(1);
+ m_splitter->setSizes(splitterSizes);
+ startExpandViewAnimation(m_secondaryViewContainer);
+ }
+ 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();
+ disconnect(m_secondaryViewContainer->view(), &DolphinView::redirection, this, &DolphinTabPage::slotViewUrlRedirection);
+
+ 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.
+ std::swap(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.
+ std::swap(m_primaryViewContainer, m_secondaryViewContainer);
+ m_primaryViewActive = true;
+ }
}
m_primaryViewContainer->setActive(true);
- view->close();
- view->deleteLater();
+ m_navigatorsWidget->followViewContainersGeometry(m_primaryViewContainer, nullptr);
+
+ if (animated == WithoutAnimation) {
+ view->close();
+ view->deleteLater();
+ } else {
+ // Kill it but keep it as a zombie for the closing animation.
+ m_secondaryViewContainer = nullptr;
+ view->blockSignals(true);
+ view->view()->blockSignals(true);
+ view->setDisabled(true);
+ startExpandViewAnimation(m_primaryViewContainer);
+ }
+
+ m_primaryViewContainer->slotSplitTabDisabled();
}
}
}
-DolphinViewContainer* DolphinTabPage::primaryViewContainer() const
+DolphinViewContainer *DolphinTabPage::primaryViewContainer() const
{
return m_primaryViewContainer;
}
-DolphinViewContainer* DolphinTabPage::secondaryViewContainer() const
+DolphinViewContainer *DolphinTabPage::secondaryViewContainer() const
{
return m_secondaryViewContainer;
}
-DolphinViewContainer* DolphinTabPage::activeViewContainer() const
+DolphinViewContainer *DolphinTabPage::activeViewContainer() const
{
- return m_primaryViewActive ? m_primaryViewContainer :
- m_secondaryViewContainer;
+ return m_primaryViewActive ? m_primaryViewContainer : m_secondaryViewContainer;
+}
+
+DolphinViewContainer *DolphinTabPage::inactiveViewContainer() const
+{
+ if (!splitViewEnabled()) {
+ return nullptr;
+ }
+
+ return primaryViewActive() ? secondaryViewContainer() : primaryViewContainer();
}
KFileItemList DolphinTabPage::selectedItems() const
return selectedItemsCount;
}
-void DolphinTabPage::markUrlsAsSelected(const QList<QUrl>& urls)
+void DolphinTabPage::connectNavigators(DolphinNavigatorsWidgetAction *navigatorsWidget)
{
- m_primaryViewContainer->view()->markUrlsAsSelected(urls);
+ insertNavigatorsWidget(navigatorsWidget);
+ m_navigatorsWidget = navigatorsWidget;
+ auto primaryNavigator = navigatorsWidget->primaryUrlNavigator();
+ m_primaryViewContainer->connectUrlNavigator(primaryNavigator);
if (m_splitViewEnabled) {
- m_secondaryViewContainer->view()->markUrlsAsSelected(urls);
+ auto secondaryNavigator = navigatorsWidget->secondaryUrlNavigator();
+ m_secondaryViewContainer->connectUrlNavigator(secondaryNavigator);
}
+ m_navigatorsWidget->followViewContainersGeometry(m_primaryViewContainer, m_secondaryViewContainer);
}
-void DolphinTabPage::markUrlAsCurrent(const QUrl& url)
+void DolphinTabPage::disconnectNavigators()
{
- m_primaryViewContainer->view()->markUrlAsCurrent(url);
+ m_navigatorsWidget = nullptr;
+ m_primaryViewContainer->disconnectUrlNavigator();
if (m_splitViewEnabled) {
- m_secondaryViewContainer->view()->markUrlAsCurrent(url);
+ m_secondaryViewContainer->disconnectUrlNavigator();
+ }
+}
+
+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::markUrlsAsSelected(const QList<QUrl> &urls)
+{
+ m_primaryViewContainer->view()->markUrlsAsSelected(urls);
+ if (m_splitViewEnabled) {
+ m_secondaryViewContainer->view()->markUrlsAsSelected(urls);
}
}
-void DolphinTabPage::setPlacesSelectorVisible(bool visible)
+void DolphinTabPage::markUrlAsCurrent(const QUrl &url)
{
- m_primaryViewContainer->urlNavigator()->setPlacesSelectorVisible(visible);
+ m_primaryViewContainer->view()->markUrlAsCurrent(url);
if (m_splitViewEnabled) {
- m_secondaryViewContainer->urlNavigator()->setPlacesSelectorVisible(visible);
+ m_secondaryViewContainer->view()->markUrlAsCurrent(url);
}
}
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);
}
stream << m_primaryViewActive;
stream << m_splitter->saveState();
+ if (!m_customLabel.isEmpty()) {
+ stream << m_customLabel;
+ }
+
return state;
}
-void DolphinTabPage::restoreState(const QByteArray& state)
+void DolphinTabPage::restoreState(const QByteArray &state)
{
if (state.isEmpty()) {
return;
bool isSplitViewEnabled = false;
stream >> isSplitViewEnabled;
- setSplitViewEnabled(isSplitViewEnabled);
+ setSplitViewEnabled(isSplitViewEnabled, WithoutAnimation);
- KUrl primaryUrl;
+ QUrl primaryUrl;
stream >> primaryUrl;
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) {
- KUrl secondaryUrl;
+ QUrl secondaryUrl;
stream >> secondaryUrl;
m_secondaryViewContainer->setUrl(secondaryUrl);
bool secondaryUrlEditable;
stream >> secondaryUrlEditable;
- m_secondaryViewContainer->urlNavigator()->setUrlEditable(secondaryUrlEditable);
+ m_secondaryViewContainer->urlNavigatorInternalWithHistory()->setUrlEditable(secondaryUrlEditable);
m_secondaryViewContainer->view()->restoreState(stream);
}
QByteArray splitterState;
stream >> splitterState;
m_splitter->restoreState(splitterState);
+
+ if (!stream.atEnd()) {
+ QString tabTitle;
+ stream >> tabTitle;
+ setCustomLabel(tabTitle);
+ }
}
-void DolphinTabPage::restoreStateV1(const QByteArray& state)
+void DolphinTabPage::setActive(bool active)
{
- if (state.isEmpty()) {
- return;
+ 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);
+}
- QByteArray sd = state;
- QDataStream stream(&sd, QIODevice::ReadOnly);
-
- bool isSplitViewEnabled = false;
- stream >> isSplitViewEnabled;
- setSplitViewEnabled(isSplitViewEnabled);
+void DolphinTabPage::setCustomLabel(const QString &label)
+{
+ m_customLabel = label;
+}
- KUrl primaryUrl;
- stream >> primaryUrl;
- m_primaryViewContainer->setUrl(primaryUrl);
- bool primaryUrlEditable;
- stream >> primaryUrlEditable;
- m_primaryViewContainer->urlNavigator()->setUrlEditable(primaryUrlEditable);
+QString DolphinTabPage::customLabel() const
+{
+ return m_customLabel;
+}
- if (isSplitViewEnabled) {
- KUrl secondaryUrl;
- stream >> secondaryUrl;
- m_secondaryViewContainer->setUrl(secondaryUrl);
- bool secondaryUrlEditable;
- stream >> secondaryUrlEditable;
- m_secondaryViewContainer->urlNavigator()->setUrlEditable(secondaryUrlEditable);
+void DolphinTabPage::slotAnimationFinished()
+{
+ for (int i = 0; i < m_splitter->count(); ++i) {
+ QWidget *viewContainer = m_splitter->widget(i);
+ if (viewContainer != m_primaryViewContainer && viewContainer != m_secondaryViewContainer) {
+ viewContainer->close();
+ viewContainer->deleteLater();
+ }
+ }
+ for (int i = 0; i < m_splitter->count(); ++i) {
+ QWidget *viewContainer = m_splitter->widget(i);
+ viewContainer->setMinimumWidth(viewContainer->minimumSizeHint().width());
}
+ m_expandingContainer = nullptr;
+}
- stream >> m_primaryViewActive;
- if (m_primaryViewActive) {
- m_primaryViewContainer->setActive(true);
+void DolphinTabPage::slotAnimationValueChanged(const QVariant &value)
+{
+ Q_CHECK_PTR(m_expandingContainer);
+ const int indexOfExpandingContainer = m_splitter->indexOf(m_expandingContainer);
+ int indexOfNonExpandingContainer = -1;
+ if (m_expandingContainer == m_primaryViewContainer) {
+ indexOfNonExpandingContainer = m_splitter->indexOf(m_secondaryViewContainer);
} else {
+ indexOfNonExpandingContainer = m_splitter->indexOf(m_primaryViewContainer);
+ }
+ std::vector<QWidget *> widgetsToRemove;
+ const QList<int> oldSplitterSizes = m_splitter->sizes();
+ QList<int> newSplitterSizes{oldSplitterSizes};
+ int expansionWidthNeeded = value.toInt() - oldSplitterSizes.at(indexOfExpandingContainer);
+
+ // Reduce the size of the other widgets to make space for the expandingContainer.
+ for (int i = m_splitter->count() - 1; i >= 0; --i) {
+ if (m_splitter->widget(i) == m_primaryViewContainer || m_splitter->widget(i) == m_secondaryViewContainer) {
+ continue;
+ }
+ newSplitterSizes[i] = oldSplitterSizes.at(i) - expansionWidthNeeded;
+ expansionWidthNeeded = 0;
+ if (indexOfNonExpandingContainer != -1) {
+ // Make sure every zombie container is at least slightly reduced in size
+ // so it doesn't seem like they are here to stay.
+ newSplitterSizes[i]--;
+ newSplitterSizes[indexOfNonExpandingContainer]++;
+ }
+ if (newSplitterSizes.at(i) <= 0) {
+ expansionWidthNeeded -= newSplitterSizes.at(i);
+ newSplitterSizes[i] = 0;
+ widgetsToRemove.emplace_back(m_splitter->widget(i));
+ }
+ }
+ if (expansionWidthNeeded > 1 && indexOfNonExpandingContainer != -1) {
Q_ASSERT(m_splitViewEnabled);
- m_secondaryViewContainer->setActive(true);
+ newSplitterSizes[indexOfNonExpandingContainer] -= expansionWidthNeeded;
+ }
+ newSplitterSizes[indexOfExpandingContainer] = value.toInt();
+ m_splitter->setSizes(newSplitterSizes);
+ while (!widgetsToRemove.empty()) {
+ widgetsToRemove.back()->close();
+ widgetsToRemove.back()->deleteLater();
+ widgetsToRemove.pop_back();
}
-
- QByteArray splitterState;
- stream >> splitterState;
- m_splitter->restoreState(splitterState);
}
void DolphinTabPage::slotViewActivated()
{
- const DolphinView* oldActiveView = activeViewContainer()->view();
+ 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();
+ const DolphinView *newActiveView = activeViewContainer()->view();
- if (newActiveView != oldActiveView) {
- disconnect(oldActiveView, SIGNAL(urlChanged(KUrl)),
- this, SIGNAL(activeViewUrlChanged(KUrl)));
- disconnect(oldActiveView, SIGNAL(redirection(KUrl,KUrl)),
- this, SLOT(slotViewUrlRedirection(KUrl,KUrl)));
- connect(newActiveView, SIGNAL(urlChanged(KUrl)),
- this, SIGNAL(activeViewUrlChanged(KUrl)));
- connect(newActiveView, SIGNAL(redirection(KUrl,KUrl)),
- this, SLOT(slotViewUrlRedirection(KUrl,KUrl)));
+ if (newActiveView == oldActiveView) {
+ return;
}
- emit activeViewUrlChanged(activeViewContainer()->url());
- emit activeViewChanged(activeViewContainer());
+ disconnect(oldActiveView, &DolphinView::urlChanged, this, &DolphinTabPage::activeViewUrlChanged);
+ connect(newActiveView, &DolphinView::urlChanged, this, &DolphinTabPage::activeViewUrlChanged);
+ Q_EMIT activeViewChanged(activeViewContainer());
+ Q_EMIT activeViewUrlChanged(activeViewContainer()->url());
}
-void DolphinTabPage::slotViewUrlRedirection(const KUrl& oldUrl, const KUrl& newUrl)
+void DolphinTabPage::slotViewUrlRedirection(const QUrl &oldUrl, const QUrl &newUrl)
{
- Q_UNUSED(oldUrl);
+ // Make sure the url of the view is updated. BUG:496414
+ if (splitViewEnabled()) {
+ if (primaryViewContainer()->view()->url() == oldUrl) {
+ primaryViewContainer()->view()->setUrl(newUrl);
+ }
+ if (secondaryViewContainer()->view()->url() == oldUrl) {
+ secondaryViewContainer()->view()->setUrl(newUrl);
+ }
+ } else {
+ activeViewContainer()->view()->setUrl(newUrl);
+ }
+ Q_EMIT activeViewUrlChanged(newUrl);
+}
- 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 KUrl& url) const
+DolphinViewContainer *DolphinTabPage::createViewContainer(const QUrl &url) const
{
- DolphinViewContainer* container = new DolphinViewContainer(url, m_splitter);
+ DolphinViewContainer *container = new DolphinViewContainer(url, m_splitter);
container->setActive(false);
- const DolphinView* view = container->view();
- connect(view, SIGNAL(activated()),
- this, SLOT(slotViewActivated()));
+ const DolphinView *view = container->view();
+ connect(view, &DolphinView::activated, this, &DolphinTabPage::slotViewActivated);
+
+ connect(view, &DolphinView::toggleActiveViewRequested, this, &DolphinTabPage::switchActiveView);
return container;
}
+
+void DolphinTabPage::startExpandViewAnimation(DolphinViewContainer *expandingContainer)
+{
+ Q_CHECK_PTR(expandingContainer);
+ Q_ASSERT(expandingContainer == m_primaryViewContainer || expandingContainer == m_secondaryViewContainer);
+ m_expandingContainer = expandingContainer;
+
+ m_expandViewAnimation = new QVariantAnimation(m_splitter);
+ m_expandViewAnimation->setDuration(2 * style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, this) * GlobalConfig::animationDurationFactor());
+ for (int i = 0; i < m_splitter->count(); ++i) {
+ m_splitter->widget(i)->setMinimumWidth(1);
+ }
+ connect(m_expandViewAnimation, &QAbstractAnimation::finished, this, &DolphinTabPage::slotAnimationFinished);
+ connect(m_expandViewAnimation, &QVariantAnimation::valueChanged, this, &DolphinTabPage::slotAnimationValueChanged);
+
+ m_expandViewAnimation->setStartValue(expandingContainer->width());
+ if (m_splitViewEnabled) { // A new viewContainer is being opened.
+ m_expandViewAnimation->setEndValue(m_splitter->width() / 2);
+ m_expandViewAnimation->setEasingCurve(QEasingCurve::OutCubic);
+ } else { // A viewContainer is being closed.
+ m_expandViewAnimation->setEndValue(m_splitter->width());
+ m_expandViewAnimation->setEasingCurve(QEasingCurve::InCubic);
+ }
+ m_expandViewAnimation->start(QAbstractAnimation::DeleteWhenStopped);
+}
+
+DolphinTabPageSplitterHandle::DolphinTabPageSplitterHandle(Qt::Orientation orientation, QSplitter *parent)
+ : QSplitterHandle(orientation, parent)
+ , m_mouseReleaseWasReceived(false)
+{
+}
+
+bool DolphinTabPageSplitterHandle::event(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ m_mouseReleaseWasReceived = false;
+ break;
+ case QEvent::MouseButtonRelease:
+ if (m_mouseReleaseWasReceived) {
+ resetSplitterSizes();
+ }
+ m_mouseReleaseWasReceived = !m_mouseReleaseWasReceived;
+ break;
+ case QEvent::MouseButtonDblClick:
+ m_mouseReleaseWasReceived = false;
+ resetSplitterSizes();
+ break;
+ default:
+ break;
+ }
+
+ return QSplitterHandle::event(event);
+}
+
+void DolphinTabPageSplitterHandle::resetSplitterSizes()
+{
+ QList<int> splitterSizes = splitter()->sizes();
+ std::fill(splitterSizes.begin(), splitterSizes.end(), 0);
+ splitter()->setSizes(splitterSizes);
+}
+
+DolphinTabPageSplitter::DolphinTabPageSplitter(Qt::Orientation orientation, QWidget *parent)
+ : QSplitter(orientation, parent)
+{
+}
+
+QSplitterHandle *DolphinTabPageSplitter::createHandle()
+{
+ return new DolphinTabPageSplitterHandle(orientation(), this);
+}
+
+#include "moc_dolphintabpage.cpp"