File indexing completed on 2024-04-28 04:37:30

0001 /*
0002     SPDX-FileCopyrightText: 2006-2007 Alexander Dymo <adymo@kdevelop.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "areaindex.h"
0008 
0009 #include <QList>
0010 
0011 #include "view.h"
0012 #include "document.h"
0013 #include <debug.h>
0014 
0015 namespace Sublime {
0016 
0017 // class AreaIndexPrivate
0018 
0019 class AreaIndexPrivate
0020 {
0021 public:
0022     AreaIndexPrivate()
0023     {
0024     }
0025     ~AreaIndexPrivate()
0026     {
0027         delete first;
0028         delete second;
0029         // TODO: does this still make sense?
0030         const auto oldViews = views;
0031         for (View* v : oldViews) {
0032             // Do the same as AreaIndex::remove(), seems like deletion of the view is happening elsewhere
0033             views.removeAll( v );
0034         }
0035     }
0036     AreaIndexPrivate(const AreaIndexPrivate &p)
0037     {
0038         parent = nullptr;
0039         orientation = p.orientation;
0040         first = p.first ? new AreaIndex(*(p.first)) : nullptr;
0041         second = p.second ? new AreaIndex(*(p.second)) : nullptr;
0042     }
0043 
0044     bool isSplit() const
0045     {
0046         return first || second;
0047     }
0048 
0049     QList<View*> views;
0050 
0051     AreaIndex *parent = nullptr;
0052     AreaIndex *first = nullptr;
0053     AreaIndex *second = nullptr;
0054     Qt::Orientation orientation = Qt::Horizontal;
0055 };
0056 
0057 
0058 
0059 // class AreaIndex
0060 
0061 AreaIndex::AreaIndex()
0062     : d_ptr(new AreaIndexPrivate)
0063 {
0064 }
0065 
0066 AreaIndex::AreaIndex(AreaIndex *parent)
0067     : d_ptr(new AreaIndexPrivate)
0068 {
0069     Q_D(AreaIndex);
0070 
0071     d->parent = parent;
0072 }
0073 
0074 AreaIndex::AreaIndex(const AreaIndex &index)
0075     : d_ptr(new AreaIndexPrivate(*(index.d_ptr)))
0076 {
0077     Q_D(AreaIndex);
0078 
0079     qCDebug(SUBLIME) << "copying area index";
0080     if (d->first)
0081         d->first->setParent(this);
0082     if (d->second)
0083         d->second->setParent(this);
0084     //clone views in this index
0085     d->views.clear();
0086     for (View* view : qAsConst(index.views())) {
0087         add(view->document()->createView());
0088     }
0089 }
0090 
0091 AreaIndex::~AreaIndex() = default;
0092 
0093 void AreaIndex::add(View *view, View *after)
0094 {
0095     Q_D(AreaIndex);
0096 
0097     //we can not add views to the areas that have already been split
0098     if (d->isSplit())
0099         return;
0100 
0101     if (after)
0102         d->views.insert(d->views.indexOf(after)+1, view);
0103     else
0104         d->views.append(view);
0105 }
0106 
0107 void AreaIndex::remove(View *view)
0108 {
0109     Q_D(AreaIndex);
0110 
0111     if (d->isSplit())
0112         return;
0113 
0114     d->views.removeAll(view);
0115     if (d->parent && (d->views.count() == 0))
0116         d->parent->unsplit(this);
0117 }
0118 
0119 void AreaIndex::split(Qt::Orientation orientation, bool moveViewsToSecond)
0120 {
0121     Q_D(AreaIndex);
0122 
0123     //we can not split areas that have already been split
0124     if (d->isSplit())
0125         return;
0126 
0127     d->first = new AreaIndex(this);
0128     d->second = new AreaIndex(this);
0129     d->orientation = orientation;
0130 
0131     if(moveViewsToSecond)
0132         moveViewsTo(d->second);
0133     else
0134         moveViewsTo(d->first);
0135 }
0136 
0137 void AreaIndex::split(View *newView, Qt::Orientation orientation)
0138 {
0139     Q_D(AreaIndex);
0140 
0141     split(orientation);
0142 
0143     //make new view as second widget in splitter
0144     d->second->add(newView);
0145 }
0146 
0147 void AreaIndex::unsplit(AreaIndex *childToRemove)
0148 {
0149     Q_D(AreaIndex);
0150 
0151     if (!d->isSplit())
0152         return;
0153 
0154     AreaIndex *other = d->first == childToRemove ? d->second : d->first;
0155     other->moveViewsTo(this);
0156     d->orientation = other->orientation();
0157     d->first = nullptr;
0158     d->second = nullptr;
0159     other->copyChildrenTo(this);
0160 
0161     delete other;
0162     delete childToRemove;
0163 }
0164 
0165 void AreaIndex::copyChildrenTo(AreaIndex *target)
0166 {
0167     Q_D(AreaIndex);
0168 
0169     if (!d->first || !d->second)
0170         return;
0171     target->d_ptr->first = d->first;
0172     target->d_ptr->second = d->second;
0173     target->d_ptr->first->setParent(target);
0174     target->d_ptr->second->setParent(target);
0175 
0176     d->first = nullptr;
0177     d->second = nullptr;
0178 }
0179 
0180 void AreaIndex::moveViewsTo(AreaIndex *target)
0181 {
0182     Q_D(AreaIndex);
0183 
0184     target->d_ptr->views = d->views;
0185     d->views.clear();
0186 }
0187 
0188 void AreaIndex::moveViewPosition(View* view, int newPos)
0189 {
0190     Q_D(AreaIndex);
0191 
0192     const auto oldPos = d->views.indexOf(view);
0193 
0194     d->views.move(oldPos, newPos);
0195 }
0196 
0197 const QList<View*>& AreaIndex::views() const
0198 {
0199     Q_D(const AreaIndex);
0200 
0201     return d->views;
0202 }
0203 
0204 View *AreaIndex::viewAt(int position) const
0205 {
0206     Q_D(const AreaIndex);
0207 
0208     return d->views.value(position, nullptr);
0209 }
0210 
0211 int AreaIndex::viewCount() const
0212 {
0213     Q_D(const AreaIndex);
0214 
0215     return d->views.count();
0216 }
0217 
0218 bool AreaIndex::hasView(View *view) const
0219 {
0220     Q_D(const AreaIndex);
0221 
0222     return d->views.contains(view);
0223 }
0224 
0225 AreaIndex *AreaIndex::parent() const
0226 {
0227     Q_D(const AreaIndex);
0228 
0229     return d->parent;
0230 }
0231 
0232 void AreaIndex::setParent(AreaIndex *parent)
0233 {
0234     Q_D(AreaIndex);
0235 
0236     d->parent = parent;
0237 }
0238 
0239 AreaIndex *AreaIndex::first() const
0240 {
0241     Q_D(const AreaIndex);
0242 
0243     return d->first;
0244 }
0245 
0246 AreaIndex *AreaIndex::second() const
0247 {
0248     Q_D(const AreaIndex);
0249 
0250     return d->second;
0251 }
0252 
0253 Qt::Orientation AreaIndex::orientation() const
0254 {
0255     Q_D(const AreaIndex);
0256 
0257     return d->orientation;
0258 }
0259 
0260 bool Sublime::AreaIndex::isSplit() const
0261 {
0262     Q_D(const AreaIndex);
0263 
0264     return d->isSplit();
0265 }
0266 
0267 void Sublime::AreaIndex::setOrientation(Qt::Orientation orientation)
0268 {
0269     Q_D(AreaIndex);
0270 
0271     d->orientation = orientation;
0272 }
0273 
0274 // class RootAreaIndex
0275 
0276 RootAreaIndex::RootAreaIndex()
0277     :AreaIndex()
0278 {
0279 }
0280 
0281 QString AreaIndex::print() const
0282 {
0283     if(isSplit())
0284         return QLatin1String(" [ ") + first()->print() + QLatin1String(orientation() == Qt::Horizontal ? " / " : " - ") + second()->print() + QLatin1String(" ] ");
0285     QStringList ret;
0286     const auto views = this->views();
0287     ret.reserve(views.size());
0288     for (const auto* view : views) {
0289         ret << view->document()->title();
0290     }
0291     return ret.join(QLatin1Char(' '));
0292 }
0293 
0294 }