File indexing completed on 2024-04-21 08:48:01

0001 /*  This file is part of the KDE project
0002     SPDX-FileCopyrightText: 1998, 1999 Michael Reiher <michael.reiher@gmx.de>
0003     SPDX-FileCopyrightText: 2007 David Faure <faure@kde.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "konqframecontainer.h"
0009 #include "konqdebug.h"
0010 #include <kconfig.h>
0011 #include <math.h> // pow()
0012 #include <kconfiggroup.h>
0013 
0014 #include "konqframevisitor.h"
0015 
0016 void KonqFrameContainerBase::replaceChildFrame(KonqFrameBase *oldFrame, KonqFrameBase *newFrame)
0017 {
0018     childFrameRemoved(oldFrame);
0019     insertChildFrame(newFrame);
0020 }
0021 
0022 KonqFrameContainer *KonqFrameContainerBase::splitChildFrame(KonqFrameBase *splitFrame, Qt::Orientation orientation)
0023 {
0024     KonqFrameContainer *newContainer = new KonqFrameContainer(orientation, asQWidget(), this);
0025     replaceChildFrame(splitFrame, newContainer);
0026     newContainer->insertChildFrame(splitFrame);
0027     return newContainer;
0028 }
0029 
0030 ////
0031 
0032 KonqFrameContainer::KonqFrameContainer(Qt::Orientation o,
0033                                        QWidget *parent,
0034                                        KonqFrameContainerBase *parentContainer)
0035     : QSplitter(o, parent), m_bAboutToBeDeleted(false)
0036 {
0037     m_pParentContainer = parentContainer;
0038     m_pFirstChild = nullptr;
0039     m_pSecondChild = nullptr;
0040     m_pActiveChild = nullptr;
0041     connect(this, &KonqFrameContainer::splitterMoved, this, &KonqFrameContainer::setRubberbandCalled);
0042 //### CHECKME
0043 }
0044 
0045 KonqFrameContainer::~KonqFrameContainer()
0046 {
0047     delete m_pFirstChild;
0048     delete m_pSecondChild;
0049 }
0050 
0051 void KonqFrameContainer::saveConfig(KConfigGroup &config, const QString &prefix, const KonqFrameBase::Options &options, KonqFrameBase *docContainer, int id, int depth)
0052 {
0053     int idSecond = id + int(pow(2.0, depth));
0054 
0055     //write children sizes
0056     config.writeEntry(QStringLiteral("SplitterSizes").prepend(prefix), sizes());
0057 
0058     //write children
0059     QStringList strlst;
0060     if (firstChild()) {
0061         strlst.append(KonqFrameBase::frameTypeToString(firstChild()->frameType()) + QString::number(idSecond - 1));
0062     }
0063     if (secondChild()) {
0064         strlst.append(KonqFrameBase::frameTypeToString(secondChild()->frameType()) + QString::number(idSecond));
0065     }
0066 
0067     config.writeEntry(QStringLiteral("Children").prepend(prefix), strlst);
0068 
0069     //write orientation
0070     QString o;
0071     if (orientation() == Qt::Horizontal) {
0072         o = QStringLiteral("Horizontal");
0073     } else if (orientation() == Qt::Vertical) {
0074         o = QStringLiteral("Vertical");
0075     }
0076     config.writeEntry(QStringLiteral("Orientation").prepend(prefix), o);
0077 
0078     //write docContainer
0079     if (this == docContainer) {
0080         config.writeEntry(QStringLiteral("docContainer").prepend(prefix), true);
0081     }
0082 
0083     if (m_pSecondChild == m_pActiveChild) {
0084         config.writeEntry(QStringLiteral("activeChildIndex").prepend(prefix), 1);
0085     } else {
0086         config.writeEntry(QStringLiteral("activeChildIndex").prepend(prefix), 0);
0087     }
0088 
0089     //write child configs
0090     if (firstChild()) {
0091         QString newPrefix = KonqFrameBase::frameTypeToString(firstChild()->frameType()) + QString::number(idSecond - 1);
0092         newPrefix.append(QLatin1Char('_'));
0093         firstChild()->saveConfig(config, newPrefix, options, docContainer, id, depth + 1);
0094     }
0095 
0096     if (secondChild()) {
0097         QString newPrefix = KonqFrameBase::frameTypeToString(secondChild()->frameType()) + QString::number(idSecond);
0098         newPrefix.append(QLatin1Char('_'));
0099         secondChild()->saveConfig(config, newPrefix, options, docContainer, idSecond, depth + 1);
0100     }
0101 }
0102 
0103 void KonqFrameContainer::copyHistory(KonqFrameBase *other)
0104 {
0105     Q_ASSERT(other->frameType() == KonqFrameBase::Container);
0106     if (firstChild()) {
0107         firstChild()->copyHistory(static_cast<KonqFrameContainer *>(other)->firstChild());
0108     }
0109     if (secondChild()) {
0110         secondChild()->copyHistory(static_cast<KonqFrameContainer *>(other)->secondChild());
0111     }
0112 }
0113 
0114 KonqFrameBase *KonqFrameContainer::otherChild(KonqFrameBase *child)
0115 {
0116     if (m_pFirstChild == child) {
0117         return m_pSecondChild;
0118     } else if (m_pSecondChild == child) {
0119         return m_pFirstChild;
0120     }
0121     return nullptr;
0122 }
0123 
0124 void KonqFrameContainer::swapChildren()
0125 {
0126     qSwap(m_pFirstChild, m_pSecondChild);
0127 }
0128 
0129 void KonqFrameContainer::setTitle(const QString &title, QWidget *sender)
0130 {
0131     //qCDebug(KONQUEROR_LOG) << title << sender;
0132     if (m_pParentContainer && activeChild() && (sender == activeChild()->asQWidget())) {
0133         m_pParentContainer->setTitle(title, this);
0134     }
0135 }
0136 
0137 void KonqFrameContainer::setTabIcon(const QUrl &url, QWidget *sender)
0138 {
0139     //qCDebug(KONQUEROR_LOG) << url << sender;
0140     if (m_pParentContainer && activeChild() && (sender == activeChild()->asQWidget())) {
0141         m_pParentContainer->setTabIcon(url, this);
0142     }
0143 }
0144 
0145 void KonqFrameContainer::insertChildFrame(KonqFrameBase *frame, int index)
0146 {
0147     //qCDebug(KONQUEROR_LOG) << this << frame;
0148     if (frame) {
0149         QSplitter::insertWidget(index, frame->asQWidget());
0150         // Insert before existing child? Move first to second.
0151         if (index == 0 && m_pFirstChild && !m_pSecondChild) {
0152             qSwap(m_pFirstChild, m_pSecondChild);
0153         }
0154         if (!m_pFirstChild) {
0155             m_pFirstChild = frame;
0156             frame->setParentContainer(this);
0157             //qCDebug(KONQUEROR_LOG) << "Setting as first child";
0158         } else if (!m_pSecondChild) {
0159             m_pSecondChild = frame;
0160             frame->setParentContainer(this);
0161             //qCDebug(KONQUEROR_LOG) << "Setting as second child";
0162         } else {
0163             qCWarning(KONQUEROR_LOG) << this << "already has two children..."
0164                        << m_pFirstChild << "and" << m_pSecondChild;
0165         }
0166     } else {
0167         qCWarning(KONQUEROR_LOG) << "KonqFrameContainer" << this << ": insertChildFrame(NULL)!";
0168     }
0169 }
0170 
0171 void KonqFrameContainer::childFrameRemoved(KonqFrameBase *frame)
0172 {
0173     //qCDebug(KONQUEROR_LOG) << this << "Child" << frame << "removed";
0174 
0175     if (m_pFirstChild == frame) {
0176         m_pFirstChild = m_pSecondChild;
0177         m_pSecondChild = nullptr;
0178     } else if (m_pSecondChild == frame) {
0179         m_pSecondChild = nullptr;
0180     } else {
0181         qCWarning(KONQUEROR_LOG) << this << "Can't find this child:" << frame;
0182     }
0183 }
0184 
0185 void KonqFrameContainer::childEvent(QChildEvent *c)
0186 {
0187     // Child events cause layout changes. These are unnecessary if we are going
0188     // to be deleted anyway.
0189     if (!m_bAboutToBeDeleted) {
0190         QSplitter::childEvent(c);
0191     }
0192 }
0193 
0194 bool KonqFrameContainer::accept(KonqFrameVisitor *visitor)
0195 {
0196     if (!visitor->visit(this)) {
0197         return false;
0198     }
0199     //Q_ASSERT( m_pFirstChild );
0200     if (m_pFirstChild && !m_pFirstChild->accept(visitor)) {
0201         return false;
0202     }
0203     //Q_ASSERT( m_pSecondChild );
0204     if (m_pSecondChild && !m_pSecondChild->accept(visitor)) {
0205         return false;
0206     }
0207     if (!visitor->endVisit(this)) {
0208         return false;
0209     }
0210     return true;
0211 }
0212 
0213 void KonqFrameContainer::replaceChildFrame(KonqFrameBase *oldFrame, KonqFrameBase *newFrame)
0214 {
0215     const int idx = QSplitter::indexOf(oldFrame->asQWidget());
0216     const QList<int> splitterSizes = sizes();
0217     childFrameRemoved(oldFrame);
0218     insertChildFrame(newFrame, idx);
0219     setSizes(splitterSizes);
0220 }
0221