File indexing completed on 2024-05-19 04:39:50

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 "test_areaoperation.h"
0008 
0009 #include <QTest>
0010 #include <QListView>
0011 #include <QTextEdit>
0012 #include <QSplitter>
0013 #include <QUrl>
0014 #include <QDebug>
0015 
0016 #include <KSharedConfig>
0017 
0018 #include <sublime/view.h>
0019 #include <sublime/area.h>
0020 #include <sublime/sublimedefs.h>
0021 #include <sublime/tooldocument.h>
0022 #include <sublime/urldocument.h>
0023 #include <sublime/controller.h>
0024 #include <sublime/mainwindow.h>
0025 #include <sublime/container.h>
0026 
0027 #include "areaprinter.h"
0028 
0029 using namespace Sublime;
0030 
0031 struct ViewCounter {
0032     ViewCounter() {}
0033     Area::WalkerMode operator()(AreaIndex *index)
0034     {
0035         count += index->views().count();
0036         return Area::ContinueWalker;
0037     }
0038     int count = 0;
0039 };
0040 
0041 void TestAreaOperation::initTestCase()
0042 {
0043     QStandardPaths::setTestModeEnabled(true);
0044 }
0045 
0046 void TestAreaOperation::init()
0047 {
0048     m_controller = new Controller(this);
0049     Document *doc1 = new UrlDocument(m_controller, QUrl::fromLocalFile(QStringLiteral("~/foo.cpp")));
0050     Document *doc2 = new UrlDocument(m_controller, QUrl::fromLocalFile(QStringLiteral("~/boo.cpp")));
0051     Document *doc3 = new UrlDocument(m_controller, QUrl::fromLocalFile(QStringLiteral("~/moo.cpp")));
0052     Document *doc4 = new UrlDocument(m_controller, QUrl::fromLocalFile(QStringLiteral("~/zoo.cpp")));
0053 
0054     //documents for tool views
0055     Document *tool1 = new ToolDocument(QStringLiteral("tool1"), m_controller, new SimpleToolWidgetFactory<QListView>(QStringLiteral("tool1")));
0056     Document *tool2 = new ToolDocument(QStringLiteral("tool2"), m_controller, new SimpleToolWidgetFactory<QTextEdit>(QStringLiteral("tool2")));
0057     Document *tool3 = new ToolDocument(QStringLiteral("tool3"), m_controller, new SimpleToolWidgetFactory<QTextEdit>(QStringLiteral("tool3")));
0058 
0059     //areas (aka perspectives)
0060     //view object names are in form AreaNumber.DocumentNumber.ViewNumber
0061     //"tool" prefix is there for tooldocument views
0062     m_area1 = new Area(m_controller, QStringLiteral("Area 1"));
0063     m_pView111 = doc1->createView();
0064     m_pView111->setObjectName(QStringLiteral("view1.1.1"));
0065     m_area1->addView(m_pView111);
0066     m_pView121 = doc2->createView();
0067     m_pView121->setObjectName(QStringLiteral("view1.2.1"));
0068     m_area1->addView(m_pView121);
0069     m_pView122 = doc2->createView();
0070     m_pView122->setObjectName(QStringLiteral("view1.2.2"));
0071     m_area1->addView(m_pView122);
0072     m_pView131 = doc3->createView();
0073     m_pView131->setObjectName(QStringLiteral("view1.3.1"));
0074     m_area1->addView(m_pView131);
0075 
0076     View *view = tool1->createView();
0077     view->setObjectName(QStringLiteral("toolview1.1.1"));
0078     m_area1->addToolView(view, Sublime::Left);
0079     view = tool2->createView();
0080     view->setObjectName(QStringLiteral("toolview1.2.1"));
0081     m_area1->addToolView(view, Sublime::Bottom);
0082     view = tool2->createView();
0083     view->setObjectName(QStringLiteral("toolview1.2.2"));
0084     m_area1->addToolView(view, Sublime::Bottom);
0085 
0086     m_area2 = new Area(m_controller, QStringLiteral("Area 2"));
0087     View *view211 = doc1->createView();
0088     view211->setObjectName(QStringLiteral("view2.1.1"));
0089     m_area2->addView(view211);
0090     View *view212 = doc1->createView();
0091     view212->setObjectName(QStringLiteral("view2.1.2"));
0092     m_area2->addView(view212);
0093     View *view221 = doc2->createView();
0094     view221->setObjectName(QStringLiteral("view2.2.1"));
0095     m_area2->addView(view221, view211, Qt::Vertical);
0096     View *view231 = doc3->createView();
0097     view231->setObjectName(QStringLiteral("view2.3.1"));
0098     m_area2->addView(view231, view221, Qt::Horizontal);
0099     View *view241 = doc4->createView();
0100     view241->setObjectName(QStringLiteral("view2.4.1"));
0101     m_area2->addView(view241, view212, Qt::Vertical);
0102     view = tool1->createView();
0103     view->setObjectName(QStringLiteral("toolview2.1.1"));
0104     m_area2->addToolView(view, Sublime::Bottom);
0105     view = tool2->createView();
0106     view->setObjectName(QStringLiteral("toolview2.2.1"));
0107     m_area2->addToolView(view, Sublime::Right);
0108     view = tool3->createView();
0109     view->setObjectName(QStringLiteral("toolview2.3.1"));
0110     m_area2->addToolView(view, Sublime::Top);
0111     view = tool3->createView();
0112     view->setObjectName(QStringLiteral("toolview2.3.2"));
0113     m_area2->addToolView(view, Sublime::Top);
0114 
0115     m_area3 = new Area(m_controller, QStringLiteral("Area 3"));
0116     View *view0 = doc1->createView();
0117     view0->setObjectName(QStringLiteral("view3.1.1"));
0118     m_area3->addView(view0);
0119     View *view1 = doc2->createView();
0120     view1->setObjectName(QStringLiteral("view3.1.2"));
0121     m_area3->addView(view1, view0);
0122     View *view2 = doc3->createView();
0123     view2->setObjectName(QStringLiteral("view3.1.3"));
0124     m_area3->addView(view2, view1);
0125     View *view3 = doc4->createView();
0126     view3->setObjectName(QStringLiteral("view3.1.4"));
0127     m_area3->addView(view3, view1);
0128 
0129     m_controller->addDefaultArea(m_area1);
0130     m_controller->addDefaultArea(m_area2);
0131     m_controller->addDefaultArea(m_area3);
0132 
0133 }
0134 
0135 void TestAreaOperation::cleanup()
0136 {
0137     delete m_area1;
0138     delete m_area2;
0139     delete m_controller;
0140     m_area1 = nullptr;
0141     m_area2 = nullptr;
0142     m_controller = nullptr;
0143 }
0144 
0145 void TestAreaOperation::areaConstruction()
0146 {
0147     //check if areas has proper object names
0148     QCOMPARE(m_area1->objectName(), QStringLiteral("Area 1"));
0149     QCOMPARE(m_area2->objectName(), QStringLiteral("Area 2"));
0150 
0151     //check that area1 contents is properly initialised
0152     AreaViewsPrinter viewsPrinter1;
0153     m_area1->walkViews(viewsPrinter1, m_area1->rootIndex());
0154     QCOMPARE(viewsPrinter1.result, QStringLiteral("\n\
0155 [ view1.1.1 view1.2.1 view1.2.2 view1.3.1 ]\n\
0156 "));
0157     AreaToolViewsPrinter toolViewsPrinter1;
0158     m_area1->walkToolViews(toolViewsPrinter1, Sublime::AllPositions);
0159     QCOMPARE(toolViewsPrinter1.result, QStringLiteral("\n\
0160 toolview1.1.1 [ left ]\n\
0161 toolview1.2.1 [ bottom ]\n\
0162 toolview1.2.2 [ bottom ]\n\
0163 "));
0164 
0165     //check that area2 contents is properly initialised
0166     AreaViewsPrinter viewsPrinter2;
0167     m_area2->walkViews(viewsPrinter2, m_area2->rootIndex());
0168     QCOMPARE(viewsPrinter2.result, QStringLiteral("\n\
0169 [ vertical splitter ]\n\
0170     [ vertical splitter ]\n\
0171         [ view2.1.1 view2.1.2 ]\n\
0172         [ view2.4.1 ]\n\
0173     [ horizontal splitter ]\n\
0174         [ view2.2.1 ]\n\
0175         [ view2.3.1 ]\n\
0176 "));
0177     AreaToolViewsPrinter toolViewsPrinter2;
0178     m_area2->walkToolViews(toolViewsPrinter2, Sublime::AllPositions);
0179     QCOMPARE(toolViewsPrinter2.result, QStringLiteral("\n\
0180 toolview2.1.1 [ bottom ]\n\
0181 toolview2.2.1 [ right ]\n\
0182 toolview2.3.1 [ top ]\n\
0183 toolview2.3.2 [ top ]\n\
0184 "));
0185 }
0186 
0187 void TestAreaOperation::mainWindowConstruction()
0188 {
0189     //====== check for m_area1 ======
0190     MainWindow mw1(m_controller);
0191     m_controller->showArea(m_area1, &mw1);
0192     checkArea1(&mw1);
0193 
0194 /////////////
0195  //====== check for m_area2 ======
0196     MainWindow mw2(m_controller);
0197     m_controller->showArea(m_area2, &mw2);
0198     checkArea2(&mw2);
0199 }
0200 
0201 void TestAreaOperation::checkArea1(MainWindow *mw)
0202 {
0203     Area *area = mw->area();
0204     //check that all docks have their widgets
0205     const auto toolDocks = mw->toolDocks();
0206     for (View* dock : toolDocks) {
0207         //QVERIFY(dock->widget() != 0);
0208         QVERIFY(dock->hasWidget());
0209     }
0210     QCOMPARE(toolDocks.count(), area->toolViews().count());
0211 
0212     //check that mainwindow have all splitters and widgets in splitters inside centralWidget
0213     QWidget *central = mw->centralWidget();
0214     QVERIFY(central != nullptr);
0215     QVERIFY(central->inherits("QWidget"));
0216 
0217     QWidget *splitter = central->findChild<QSplitter*>();
0218     QVERIFY(splitter);
0219     QVERIFY(splitter->inherits("QSplitter"));
0220 
0221     //check that we have a container and 4 views inside
0222     auto *container = splitter->findChild<Sublime::Container*>();
0223     QVERIFY(container);
0224     ViewCounter c;
0225     area->walkViews(c, area->rootIndex());
0226     QCOMPARE(container->count(), c.count);
0227     for (int i = 0; i < container->count(); ++i)
0228         QVERIFY(container->widget(i) != nullptr);
0229 }
0230 
0231 void TestAreaOperation::checkArea2(MainWindow *mw)
0232 {
0233     Area *area = mw->area();
0234     //check that all docks have their widgets
0235     const auto toolDocks = mw->toolDocks();
0236     for (View* dock : toolDocks) {
0237         //QVERIFY(dock->widget() != 0);
0238         QVERIFY(dock->hasWidget());
0239     }
0240     QCOMPARE(toolDocks.count(), area->toolViews().count());
0241 
0242     //check that mainwindow have all splitters and widgets in splitters inside centralWidget
0243     QWidget *central = mw->centralWidget();
0244     QVERIFY(central != nullptr);
0245     QVERIFY(central->inherits("QWidget"));
0246 
0247     QWidget *splitter = central->findChild<QSplitter*>();
0248     QVERIFY(splitter);
0249     QVERIFY(splitter->inherits("QSplitter"));
0250 
0251     //check that we have 4 properly initialized containers
0252     const QList<Container*> containers = splitter->findChildren<Sublime::Container*>();
0253     QCOMPARE(containers.count(), 4);
0254 
0255     int widgetCount = 0;
0256     for (Container* c : containers) {
0257         for (int i = 0; i < c->count(); ++i)
0258             QVERIFY(c->widget(i) != nullptr);
0259         widgetCount += c->count();
0260     }
0261 
0262     ViewCounter c;
0263     area->walkViews(c, area->rootIndex());
0264     QCOMPARE(widgetCount, c.count);
0265 
0266     //check that we have 7 splitters: 2 vertical and 1 horizontal, rest is not split
0267     QList<QSplitter*> splitters = splitter->findChildren<QSplitter*>();
0268     splitters.append(qobject_cast<QSplitter*>(splitter));
0269     QCOMPARE(splitters.count(), 6+1); //6 child splitters + 1 central itself = 7 splitters
0270     int verticalSplitterCount = 0;
0271     int horizontalSplitterCount = 0;
0272     for (QSplitter* s : qAsConst(splitters)) {
0273         if (s->count() == 1)
0274             continue;   //this is a splitter with container inside, its orientation is not relevant
0275         if (s->orientation() == Qt::Vertical)
0276             verticalSplitterCount += 1;
0277         else
0278             horizontalSplitterCount += 1;
0279     }
0280     QCOMPARE(verticalSplitterCount, 2);
0281     QCOMPARE(horizontalSplitterCount, 1);
0282 }
0283 
0284 void TestAreaOperation::areaCloning()
0285 {
0286     //show m_area1 in MainWindow1
0287     MainWindow mw1(m_controller);
0288     m_controller->showArea(m_area1, &mw1);
0289     checkArea1(&mw1);
0290 
0291     //now try to show the same area in MainWindow2 and check that we get a clone
0292     MainWindow mw2(m_controller);
0293     m_controller->showArea(m_area1, &mw2);
0294 
0295     //two mainwindows have different areas
0296     QVERIFY(mw1.area() != mw2.area());
0297     //the area for the second mainwindow is a clone of the
0298     //original area and should have the same name.
0299     QVERIFY(mw2.area()->objectName() == mw1.area()->objectName());
0300 
0301     //check mainwindow layouts - original and copy
0302     checkArea1(&mw1);
0303     checkArea1(&mw2);
0304 }
0305 
0306 /*! Functor used by areaSwitchingInSameMainWindow()
0307     Walks all Views and checks if they got a widget.
0308     hasWidget will be set to false if any View lacks a widget.*/
0309 struct AreaWidgetChecker {
0310     AreaWidgetChecker() = default;
0311     Area::WalkerMode operator()(AreaIndex *index)
0312     {
0313         for (View* view : qAsConst(index->views())) {
0314             if (!view->hasWidget()) {
0315                 failureMessage += view->objectName() + " has no widget\n";
0316                 foundViewWithoutWidget = true;
0317             }
0318         }
0319         return Area::ContinueWalker;
0320     }
0321     Area::WalkerMode operator()(View *view, Sublime::Position)
0322     {
0323         if (!view->hasWidget()) {
0324             foundViewWithoutWidget = true;
0325             failureMessage += view->objectName() + " has no widget\n";
0326         }
0327         return Area::ContinueWalker;
0328     }
0329 
0330     bool foundViewWithoutWidget = false;
0331     QString failureMessage;
0332 };
0333 
0334 void TestAreaOperation::areaSwitchingInSameMainwindow()
0335 {
0336     MainWindow mw(m_controller);
0337     m_controller->showArea(m_area1, &mw);
0338     checkArea1(&mw);
0339 
0340     m_controller->showArea(m_area2, &mw);
0341     checkArea2(&mw);
0342 
0343     //check what happened to area1 widgets, they should be intact
0344     AreaWidgetChecker checker;
0345     m_area1->walkViews(checker, m_area1->rootIndex());
0346     m_area1->walkToolViews(checker, Sublime::AllPositions);
0347     QVERIFY2(!checker.foundViewWithoutWidget, checker.failureMessage.toLatin1().data());
0348 }
0349 
0350 void TestAreaOperation::simpleViewAdditionAndDeletion()
0351 {
0352     // set TabBarOpenAfterCurrent=0, otherwise we'd have a different order of tabs
0353     int oldTabBarOpenAfterCurrent;
0354     {
0355         KConfigGroup uiGroup = KSharedConfig::openConfig()->group("UiSettings");
0356         oldTabBarOpenAfterCurrent = uiGroup.readEntry("TabBarOpenAfterCurrent", 1);
0357         uiGroup.writeEntry("TabBarOpenAfterCurrent", 0);
0358         uiGroup.sync();
0359     }
0360     m_controller->loadSettings();
0361 
0362     MainWindow mw(m_controller);
0363     m_controller->addMainWindow(&mw);
0364 
0365     m_controller->showArea(m_area1, &mw);
0366     checkArea1(&mw);
0367 
0368     Document *doc5 = new UrlDocument(m_controller, QUrl::fromLocalFile(QStringLiteral("~/new.cpp")));
0369     View *view = doc5->createView();
0370     view->setObjectName(QStringLiteral("view1.5.1"));
0371     m_area1->addView(view);
0372 
0373     checkAreaViewsDisplay(&mw, m_area1,
0374         QStringLiteral("\n[ view1.1.1 view1.2.1 view1.2.2 view1.3.1 view1.5.1 ]\n"),
0375         1, 1, QStringLiteral("Added an url view (view1.5.1)"));
0376 
0377     //now remove view and check that area is valid
0378     delete m_area1->removeView(view);
0379 
0380     checkAreaViewsDisplay(&mw, m_area1,
0381         QStringLiteral("\n[ view1.1.1 view1.2.1 view1.2.2 view1.3.1 ]\n"),
0382         1, 1, QStringLiteral("Removed the url view (view1.5.1)"));
0383 
0384     //now remove all other views one by one and leave an empty container
0385     const QList<View*> list(m_area1->views());
0386     for (View* view : list) {
0387         delete m_area1->removeView(view);
0388     }
0389 
0390     checkAreaViewsDisplay(&mw, m_area1,
0391         QStringLiteral("\n[ horizontal splitter ]\n"),
0392         0, 1, QStringLiteral("Removed all views. Only horizontal splitter should remain."));
0393 
0394     //add a view again and check that mainwindow is correctly reconstructed
0395     view = doc5->createView();
0396     view->setObjectName(QStringLiteral("view1.5.1"));
0397     m_area1->addView(view);
0398 
0399     checkAreaViewsDisplay(&mw, m_area1,
0400         QStringLiteral("\n[ view1.5.1 ]\n"),
0401         1, 1, QStringLiteral("Added a single view to previously emptied mainwindow."));
0402 
0403     {
0404         KConfigGroup uiGroup = KSharedConfig::openConfig()->group("UiSettings");
0405         uiGroup.writeEntry("TabBarOpenAfterCurrent", oldTabBarOpenAfterCurrent);
0406         uiGroup.sync();
0407     }
0408     m_controller->loadSettings();
0409 }
0410 
0411 void TestAreaOperation::complexViewAdditionAndDeletion()
0412 {
0413     Area *area = m_area2;
0414     MainWindow mw(m_controller);
0415     m_controller->addMainWindow(&mw);
0416 
0417     m_controller->showArea(m_area2, &mw);
0418 
0419     Document *doc5 = new UrlDocument(m_controller, QUrl::fromLocalFile(QStringLiteral("~/new.cpp")));
0420     View *view = doc5->createView();
0421     view->setObjectName(QStringLiteral("view2.5.1"));
0422 
0423     View *view221 = findNamedView(area, QStringLiteral("view2.2.1"));
0424     QVERIFY(view221);
0425     area->addView(view, view221, Qt::Vertical);
0426 
0427     checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
0428 [ vertical splitter ]\n\
0429     [ vertical splitter ]\n\
0430         [ view2.1.1 view2.1.2 ]\n\
0431         [ view2.4.1 ]\n\
0432     [ horizontal splitter ]\n\
0433         [ vertical splitter ]\n\
0434             [ view2.2.1 ]\n\
0435             [ view2.5.1 ]\n\
0436         [ view2.3.1 ]\n\
0437 "), 5, 8+1);
0438 
0439     //now delete view221
0440     delete area->removeView(view221);
0441 
0442     checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
0443 [ vertical splitter ]\n\
0444     [ vertical splitter ]\n\
0445         [ view2.1.1 view2.1.2 ]\n\
0446         [ view2.4.1 ]\n\
0447     [ horizontal splitter ]\n\
0448         [ view2.5.1 ]\n\
0449         [ view2.3.1 ]\n\
0450 "), 4, 6+1);
0451 
0452     //remove one more view, this time the one inside non-empty container
0453     View *view211 = findNamedView(area, QStringLiteral("view2.1.1"));
0454     delete m_area2->removeView(view211);
0455 
0456     checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
0457 [ vertical splitter ]\n\
0458     [ vertical splitter ]\n\
0459         [ view2.1.2 ]\n\
0460         [ view2.4.1 ]\n\
0461     [ horizontal splitter ]\n\
0462         [ view2.5.1 ]\n\
0463         [ view2.3.1 ]\n\
0464 "), 4, 6+1);
0465 
0466     //and now remove all remaining views one by one
0467     delete m_area2->removeView(findNamedView(area, QStringLiteral("view2.1.2")));
0468     checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
0469 [ vertical splitter ]\n\
0470     [ view2.4.1 ]\n\
0471     [ horizontal splitter ]\n\
0472         [ view2.5.1 ]\n\
0473         [ view2.3.1 ]\n\
0474 "), 3, 4+1);
0475 
0476     delete m_area2->removeView(findNamedView(area, QStringLiteral("view2.4.1")));
0477     checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
0478 [ horizontal splitter ]\n\
0479     [ view2.5.1 ]\n\
0480     [ view2.3.1 ]\n\
0481 "), 2, 2+1);
0482 
0483     delete m_area2->removeView(findNamedView(area, QStringLiteral("view2.5.1")));
0484     checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
0485 [ view2.3.1 ]\n\
0486 "), 1, 1);
0487 
0488     delete m_area2->removeView(findNamedView(area, QStringLiteral("view2.3.1")));
0489     checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
0490 [ horizontal splitter ]\n\
0491 "), 0, 1);
0492 }
0493 
0494 void TestAreaOperation::toolViewAdditionAndDeletion()
0495 {
0496     MainWindow mw(m_controller);
0497     m_controller->showArea(m_area1, &mw);
0498     checkArea1(&mw);
0499 
0500     Document *tool4 = new ToolDocument(QStringLiteral("tool4"), m_controller, new SimpleToolWidgetFactory<QTextEdit>(QStringLiteral("tool4")));
0501     View *view = tool4->createView();
0502     view->setObjectName(QStringLiteral("toolview1.4.1"));
0503     m_area1->addToolView(view, Sublime::Right);
0504 
0505     //check that area is in valid state
0506     AreaToolViewsPrinter toolViewsPrinter1;
0507     m_area1->walkToolViews(toolViewsPrinter1, Sublime::AllPositions);
0508     QCOMPARE(toolViewsPrinter1.result, QStringLiteral("\n\
0509 toolview1.1.1 [ left ]\n\
0510 toolview1.2.1 [ bottom ]\n\
0511 toolview1.2.2 [ bottom ]\n\
0512 toolview1.4.1 [ right ]\n\
0513 "));
0514 
0515     //check that mainwindow has newly added tool view
0516     {
0517     const auto toolDocks = mw.toolDocks();
0518     for (View* dock : toolDocks) {
0519         QVERIFY(dock->widget() != nullptr);
0520     }
0521     QCOMPARE(toolDocks.count(), m_area1->toolViews().count());
0522     }
0523 
0524     //now remove tool view
0525     m_area1->removeToolView(view);
0526 
0527     AreaToolViewsPrinter toolViewsPrinter2;
0528     //check that area doesn't have it anymore
0529     m_area1->walkToolViews(toolViewsPrinter2, Sublime::AllPositions);
0530     QCOMPARE(toolViewsPrinter2.result, QStringLiteral("\n\
0531 toolview1.1.1 [ left ]\n\
0532 toolview1.2.1 [ bottom ]\n\
0533 toolview1.2.2 [ bottom ]\n\
0534 "));
0535 
0536     //check that mainwindow has newly added tool view
0537     {
0538     const auto toolDocks = mw.toolDocks();
0539     for (View* dock : toolDocks) {
0540         QVERIFY(dock->widget() != nullptr);
0541     }
0542     QCOMPARE(toolDocks.count(), m_area1->toolViews().count());
0543     }
0544 }
0545 
0546 
0547 
0548 void TestAreaOperation::testAddingViewAfter()
0549 {
0550 
0551     const QList<View*> list(m_area3->views());
0552     for (View* view : list) {
0553         qDebug() << "name of view : " << view->objectName() << " , it's index : " << m_area3->views().indexOf(view);
0554     }
0555 
0556 }
0557 
0558 ////////////////////////////////////////////////////////////////////////////////
0559 ////////////////////////////////////////////////////////////////////////////////
0560 void TestAreaOperation::splitViewActiveTabsTest()
0561 {
0562     MainWindow mw(m_controller);
0563     m_controller->showArea(m_area1, &mw);
0564     checkArea1(&mw);
0565 
0566     // at first show of the area, the active view should be m_pView111
0567     QCOMPARE(mw.activeView(), m_pView111);
0568 
0569     // Try to get to the main container :
0570     // get the central widget
0571     QWidget *pCentral = mw.centralWidget();
0572     QVERIFY(pCentral);
0573     QVERIFY(pCentral->inherits("QWidget"));
0574 
0575     // get its first splitter
0576     QWidget *pSplitter = pCentral->findChild<QSplitter*>();
0577     QVERIFY(pSplitter);
0578     QVERIFY(pSplitter->inherits("QSplitter"));
0579 
0580     // finally, get the splitter's container
0581     auto *pContainer = pSplitter->findChild<Sublime::Container*>();
0582     QVERIFY(pContainer);
0583 
0584     // verify that the current active widget in the container is the one in activeview (m_pView111)
0585     QCOMPARE(pContainer->currentWidget(), mw.activeView()->widget());
0586 
0587     // activate the second tab of the area (view212)
0588     mw.activateView(m_pView121);
0589 
0590     // verify that the active view was correctly updated to m_pView121
0591     QCOMPARE(mw.activeView(), m_pView121);
0592 
0593     // check if the container's current widget was updated to the active view's
0594     QCOMPARE(pContainer->currentWidget(), mw.activeView()->widget());
0595 
0596     // now, create a split view of the active view (m_pView121)
0597     Sublime::View *pNewView = mw.activeView()->document()->createView();
0598     pNewView->setObjectName("splitOf" + mw.activeView()->objectName());
0599     m_area1->addView(pNewView, mw.activeView(), Qt::Vertical);
0600 
0601     // verify that creating a new view did not break the central widget
0602     QCOMPARE(pCentral, mw.centralWidget());
0603 
0604     // verify that creating a new view did not break the main splitter
0605     QCOMPARE(pSplitter, pCentral->findChild<QSplitter*>());
0606 
0607     // creating a new view created two new children splitters, get them
0608     QVERIFY(pSplitter->findChildren<QSplitter*>().size() == 2);
0609     QWidget *pFirstSplitter = pSplitter->findChildren<QSplitter*>().at(0);
0610     QVERIFY(pFirstSplitter);
0611     QWidget *pSecondSplitter = pSplitter->findChildren<QSplitter*>().at(1);
0612     QVERIFY(pSecondSplitter);
0613 
0614     // for each splitter, get the corresponding container
0615     auto *pFirstContainer = pFirstSplitter->findChild<Sublime::Container*>();
0616     QVERIFY(pFirstContainer);
0617     auto *pSecondContainer = pSecondSplitter->findChild<Sublime::Container*>();
0618     QVERIFY(pSecondContainer);
0619 
0620     // the active view should have remained view121
0621     QCOMPARE(mw.activeView(), m_pView121);
0622 
0623     // pFirstContainer should contain the newView's widget
0624     QVERIFY(pFirstContainer->hasWidget(pNewView->widget()));
0625 
0626     // the new view's widget should be the current widget of the new container
0627     QCOMPARE(pFirstContainer->currentWidget(), pNewView->widget());
0628 
0629     // pSecondContainer should contain all the old views widgets
0630     QVERIFY(pSecondContainer->hasWidget(m_pView111->widget()));
0631     QVERIFY(pSecondContainer->hasWidget(m_pView121->widget()));
0632     QVERIFY(pSecondContainer->hasWidget(m_pView122->widget()));
0633     QVERIFY(pSecondContainer->hasWidget(m_pView131->widget()));
0634 
0635     // the active widget should be the current widget of the second container
0636     QCOMPARE(pSecondContainer->currentWidget(), mw.activeView()->widget());
0637 
0638     ////////////////////////////////////////////////////////////////////////////
0639     // now, activate the new view and check if all went well
0640     mw.activateView(pNewView);
0641 
0642     // active view should now be newView
0643     QCOMPARE(mw.activeView(), pNewView);
0644 
0645     // the active widget should be the current widget of the new container
0646     QCOMPARE(pFirstContainer->currentWidget(), mw.activeView()->widget());
0647 
0648     // the current widget of the old container should have remained view121's
0649     QCOMPARE(pSecondContainer->currentWidget(), m_pView121->widget());
0650 
0651     ////////////////////////////////////////////////////////////////////////////
0652     // now delete newView and check area state
0653     delete m_area1->removeView(pNewView);
0654 
0655     // verify that deleting the view did not broke the central widget
0656     QCOMPARE(pCentral, mw.centralWidget());
0657 
0658     // removing the view should have destroyed the sub splitters and containers,
0659     // so get the main one and verify that deleting the view did not break it
0660     QCOMPARE(pSplitter, pCentral->findChild<QSplitter*>());
0661 
0662     // get the new container inside the main splitter
0663     pContainer = pSplitter->findChild<Sublime::Container*>();
0664     QVERIFY(pContainer);
0665 
0666     // active view should now be back to m_pView121 again
0667     QCOMPARE(mw.activeView(), m_pView121);
0668 
0669     // check also the container current widget
0670     QCOMPARE(pContainer->currentWidget(), mw.activeView()->widget());
0671 }
0672 
0673 void TestAreaOperation::checkAreaViewsDisplay(MainWindow *mw, Area *area,
0674     const QString &printedAreas, int containerCount, int splitterCount, const QString& location)
0675 {
0676     //check area
0677     AreaViewsPrinter viewsPrinter;
0678     area->walkViews(viewsPrinter, area->rootIndex());
0679     QCOMPARE(viewsPrinter.result, printedAreas);
0680 
0681     //check mainwindow
0682     QWidget *central = mw->centralWidget();
0683     QVERIFY(central != nullptr);
0684     QVERIFY(central->inherits("QWidget"));
0685 
0686     QWidget *splitter = central->findChild<QSplitter*>();
0687     QVERIFY(splitter);
0688     QVERIFY(splitter->inherits("QSplitter"));
0689 
0690     //check containers
0691     const QList<Container*> containers = splitter->findChildren<Sublime::Container*>();
0692     QString failMsg = QStringLiteral("\nFailure while checking area contents @ %1\n"
0693                               "Expected %2 containers in central splitter but got %3 \n").
0694                       arg(location).arg(containerCount).arg(containers.count());
0695     QVERIFY2(containers.count() == containerCount, failMsg.toLatin1().data());
0696 
0697     int widgetCount = 0;
0698     for (Container* c : containers) {
0699         for (int i = 0; i < c->count(); ++i)
0700         {
0701             QVERIFY(c->widget(i) != nullptr);
0702             QVERIFY(c->widget(i)->parentWidget() != nullptr);
0703         }
0704         widgetCount += c->count();
0705     }
0706 
0707     ViewCounter c;
0708     area->walkViews(c, area->rootIndex());
0709     QCOMPARE(widgetCount, c.count);
0710 
0711     QList<QSplitter*> splitters = splitter->findChildren<QSplitter*>();
0712     splitters.append(qobject_cast<QSplitter*>(splitter));
0713     QCOMPARE(splitters.count(), splitterCount);
0714 }
0715 
0716 View *TestAreaOperation::findNamedView(Area *area, const QString &name)
0717 {
0718     const auto views = area->views();
0719     for (View* view : views) {
0720         if (view->objectName() == name)
0721             return view;
0722     }
0723     return nullptr;
0724 }
0725 
0726 ///////////
0727 QTEST_MAIN(TestAreaOperation)
0728 
0729 #include "moc_test_areaoperation.cpp"