1 /*
2 SPDX-FileCopyrightText: 2006-2007 Alexander Dymo <adymo@kdevelop.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7 #include "test_areaoperation.h"
8
9 #include <QTest>
10 #include <QListView>
11 #include <QTextEdit>
12 #include <QSplitter>
13 #include <QUrl>
14 #include <QDebug>
15
16 #include <KSharedConfig>
17
18 #include <sublime/view.h>
19 #include <sublime/area.h>
20 #include <sublime/sublimedefs.h>
21 #include <sublime/tooldocument.h>
22 #include <sublime/urldocument.h>
23 #include <sublime/controller.h>
24 #include <sublime/mainwindow.h>
25 #include <sublime/container.h>
26
27 #include "areaprinter.h"
28
29 using namespace Sublime;
30
31 struct ViewCounter {
ViewCounterViewCounter32 ViewCounter() {}
operator ()ViewCounter33 Area::WalkerMode operator()(AreaIndex *index)
34 {
35 count += index->views().count();
36 return Area::ContinueWalker;
37 }
38 int count = 0;
39 };
40
initTestCase()41 void TestAreaOperation::initTestCase()
42 {
43 QStandardPaths::setTestModeEnabled(true);
44 }
45
init()46 void TestAreaOperation::init()
47 {
48 m_controller = new Controller(this);
49 Document *doc1 = new UrlDocument(m_controller, QUrl::fromLocalFile(QStringLiteral("~/foo.cpp")));
50 Document *doc2 = new UrlDocument(m_controller, QUrl::fromLocalFile(QStringLiteral("~/boo.cpp")));
51 Document *doc3 = new UrlDocument(m_controller, QUrl::fromLocalFile(QStringLiteral("~/moo.cpp")));
52 Document *doc4 = new UrlDocument(m_controller, QUrl::fromLocalFile(QStringLiteral("~/zoo.cpp")));
53
54 //documents for tool views
55 Document *tool1 = new ToolDocument(QStringLiteral("tool1"), m_controller, new SimpleToolWidgetFactory<QListView>(QStringLiteral("tool1")));
56 Document *tool2 = new ToolDocument(QStringLiteral("tool2"), m_controller, new SimpleToolWidgetFactory<QTextEdit>(QStringLiteral("tool2")));
57 Document *tool3 = new ToolDocument(QStringLiteral("tool3"), m_controller, new SimpleToolWidgetFactory<QTextEdit>(QStringLiteral("tool3")));
58
59 //areas (aka perspectives)
60 //view object names are in form AreaNumber.DocumentNumber.ViewNumber
61 //"tool" prefix is there for tooldocument views
62 m_area1 = new Area(m_controller, QStringLiteral("Area 1"));
63 m_pView111 = doc1->createView();
64 m_pView111->setObjectName(QStringLiteral("view1.1.1"));
65 m_area1->addView(m_pView111);
66 m_pView121 = doc2->createView();
67 m_pView121->setObjectName(QStringLiteral("view1.2.1"));
68 m_area1->addView(m_pView121);
69 m_pView122 = doc2->createView();
70 m_pView122->setObjectName(QStringLiteral("view1.2.2"));
71 m_area1->addView(m_pView122);
72 m_pView131 = doc3->createView();
73 m_pView131->setObjectName(QStringLiteral("view1.3.1"));
74 m_area1->addView(m_pView131);
75
76 View *view = tool1->createView();
77 view->setObjectName(QStringLiteral("toolview1.1.1"));
78 m_area1->addToolView(view, Sublime::Left);
79 view = tool2->createView();
80 view->setObjectName(QStringLiteral("toolview1.2.1"));
81 m_area1->addToolView(view, Sublime::Bottom);
82 view = tool2->createView();
83 view->setObjectName(QStringLiteral("toolview1.2.2"));
84 m_area1->addToolView(view, Sublime::Bottom);
85
86 m_area2 = new Area(m_controller, QStringLiteral("Area 2"));
87 View *view211 = doc1->createView();
88 view211->setObjectName(QStringLiteral("view2.1.1"));
89 m_area2->addView(view211);
90 View *view212 = doc1->createView();
91 view212->setObjectName(QStringLiteral("view2.1.2"));
92 m_area2->addView(view212);
93 View *view221 = doc2->createView();
94 view221->setObjectName(QStringLiteral("view2.2.1"));
95 m_area2->addView(view221, view211, Qt::Vertical);
96 View *view231 = doc3->createView();
97 view231->setObjectName(QStringLiteral("view2.3.1"));
98 m_area2->addView(view231, view221, Qt::Horizontal);
99 View *view241 = doc4->createView();
100 view241->setObjectName(QStringLiteral("view2.4.1"));
101 m_area2->addView(view241, view212, Qt::Vertical);
102 view = tool1->createView();
103 view->setObjectName(QStringLiteral("toolview2.1.1"));
104 m_area2->addToolView(view, Sublime::Bottom);
105 view = tool2->createView();
106 view->setObjectName(QStringLiteral("toolview2.2.1"));
107 m_area2->addToolView(view, Sublime::Right);
108 view = tool3->createView();
109 view->setObjectName(QStringLiteral("toolview2.3.1"));
110 m_area2->addToolView(view, Sublime::Top);
111 view = tool3->createView();
112 view->setObjectName(QStringLiteral("toolview2.3.2"));
113 m_area2->addToolView(view, Sublime::Top);
114
115 m_area3 = new Area(m_controller, QStringLiteral("Area 3"));
116 View *view0 = doc1->createView();
117 view0->setObjectName(QStringLiteral("view3.1.1"));
118 m_area3->addView(view0);
119 View *view1 = doc2->createView();
120 view1->setObjectName(QStringLiteral("view3.1.2"));
121 m_area3->addView(view1, view0);
122 View *view2 = doc3->createView();
123 view2->setObjectName(QStringLiteral("view3.1.3"));
124 m_area3->addView(view2, view1);
125 View *view3 = doc4->createView();
126 view3->setObjectName(QStringLiteral("view3.1.4"));
127 m_area3->addView(view3, view1);
128
129 m_controller->addDefaultArea(m_area1);
130 m_controller->addDefaultArea(m_area2);
131 m_controller->addDefaultArea(m_area3);
132
133 }
134
cleanup()135 void TestAreaOperation::cleanup()
136 {
137 delete m_area1;
138 delete m_area2;
139 delete m_controller;
140 m_area1 = nullptr;
141 m_area2 = nullptr;
142 m_controller = nullptr;
143 }
144
areaConstruction()145 void TestAreaOperation::areaConstruction()
146 {
147 //check if areas has proper object names
148 QCOMPARE(m_area1->objectName(), QStringLiteral("Area 1"));
149 QCOMPARE(m_area2->objectName(), QStringLiteral("Area 2"));
150
151 //check that area1 contents is properly initialised
152 AreaViewsPrinter viewsPrinter1;
153 m_area1->walkViews(viewsPrinter1, m_area1->rootIndex());
154 QCOMPARE(viewsPrinter1.result, QStringLiteral("\n\
155 [ view1.1.1 view1.2.1 view1.2.2 view1.3.1 ]\n\
156 "));
157 AreaToolViewsPrinter toolViewsPrinter1;
158 m_area1->walkToolViews(toolViewsPrinter1, Sublime::AllPositions);
159 QCOMPARE(toolViewsPrinter1.result, QStringLiteral("\n\
160 toolview1.1.1 [ left ]\n\
161 toolview1.2.1 [ bottom ]\n\
162 toolview1.2.2 [ bottom ]\n\
163 "));
164
165 //check that area2 contents is properly initialised
166 AreaViewsPrinter viewsPrinter2;
167 m_area2->walkViews(viewsPrinter2, m_area2->rootIndex());
168 QCOMPARE(viewsPrinter2.result, QStringLiteral("\n\
169 [ vertical splitter ]\n\
170 [ vertical splitter ]\n\
171 [ view2.1.1 view2.1.2 ]\n\
172 [ view2.4.1 ]\n\
173 [ horizontal splitter ]\n\
174 [ view2.2.1 ]\n\
175 [ view2.3.1 ]\n\
176 "));
177 AreaToolViewsPrinter toolViewsPrinter2;
178 m_area2->walkToolViews(toolViewsPrinter2, Sublime::AllPositions);
179 QCOMPARE(toolViewsPrinter2.result, QStringLiteral("\n\
180 toolview2.1.1 [ bottom ]\n\
181 toolview2.2.1 [ right ]\n\
182 toolview2.3.1 [ top ]\n\
183 toolview2.3.2 [ top ]\n\
184 "));
185 }
186
mainWindowConstruction()187 void TestAreaOperation::mainWindowConstruction()
188 {
189 //====== check for m_area1 ======
190 MainWindow mw1(m_controller);
191 m_controller->showArea(m_area1, &mw1);
192 checkArea1(&mw1);
193
194 /////////////
195 //====== check for m_area2 ======
196 MainWindow mw2(m_controller);
197 m_controller->showArea(m_area2, &mw2);
198 checkArea2(&mw2);
199 }
200
checkArea1(MainWindow * mw)201 void TestAreaOperation::checkArea1(MainWindow *mw)
202 {
203 Area *area = mw->area();
204 //check that all docks have their widgets
205 const auto toolDocks = mw->toolDocks();
206 for (View* dock : toolDocks) {
207 //QVERIFY(dock->widget() != 0);
208 QVERIFY(dock->hasWidget());
209 }
210 QCOMPARE(toolDocks.count(), area->toolViews().count());
211
212 //check that mainwindow have all splitters and widgets in splitters inside centralWidget
213 QWidget *central = mw->centralWidget();
214 QVERIFY(central != nullptr);
215 QVERIFY(central->inherits("QWidget"));
216
217 QWidget *splitter = central->findChild<QSplitter*>();
218 QVERIFY(splitter);
219 QVERIFY(splitter->inherits("QSplitter"));
220
221 //check that we have a container and 4 views inside
222 auto *container = splitter->findChild<Sublime::Container*>();
223 QVERIFY(container);
224 ViewCounter c;
225 area->walkViews(c, area->rootIndex());
226 QCOMPARE(container->count(), c.count);
227 for (int i = 0; i < container->count(); ++i)
228 QVERIFY(container->widget(i) != nullptr);
229 }
230
checkArea2(MainWindow * mw)231 void TestAreaOperation::checkArea2(MainWindow *mw)
232 {
233 Area *area = mw->area();
234 //check that all docks have their widgets
235 const auto toolDocks = mw->toolDocks();
236 for (View* dock : toolDocks) {
237 //QVERIFY(dock->widget() != 0);
238 QVERIFY(dock->hasWidget());
239 }
240 QCOMPARE(toolDocks.count(), area->toolViews().count());
241
242 //check that mainwindow have all splitters and widgets in splitters inside centralWidget
243 QWidget *central = mw->centralWidget();
244 QVERIFY(central != nullptr);
245 QVERIFY(central->inherits("QWidget"));
246
247 QWidget *splitter = central->findChild<QSplitter*>();
248 QVERIFY(splitter);
249 QVERIFY(splitter->inherits("QSplitter"));
250
251 //check that we have 4 properly initialized containers
252 const QList<Container*> containers = splitter->findChildren<Sublime::Container*>();
253 QCOMPARE(containers.count(), 4);
254
255 int widgetCount = 0;
256 for (Container* c : containers) {
257 for (int i = 0; i < c->count(); ++i)
258 QVERIFY(c->widget(i) != nullptr);
259 widgetCount += c->count();
260 }
261
262 ViewCounter c;
263 area->walkViews(c, area->rootIndex());
264 QCOMPARE(widgetCount, c.count);
265
266 //check that we have 7 splitters: 2 vertical and 1 horizontal, rest is not split
267 QList<QSplitter*> splitters = splitter->findChildren<QSplitter*>();
268 splitters.append(qobject_cast<QSplitter*>(splitter));
269 QCOMPARE(splitters.count(), 6+1); //6 child splitters + 1 central itself = 7 splitters
270 int verticalSplitterCount = 0;
271 int horizontalSplitterCount = 0;
272 for (QSplitter* s : qAsConst(splitters)) {
273 if (s->count() == 1)
274 continue; //this is a splitter with container inside, its orientation is not relevant
275 if (s->orientation() == Qt::Vertical)
276 verticalSplitterCount += 1;
277 else
278 horizontalSplitterCount += 1;
279 }
280 QCOMPARE(verticalSplitterCount, 2);
281 QCOMPARE(horizontalSplitterCount, 1);
282 }
283
areaCloning()284 void TestAreaOperation::areaCloning()
285 {
286 //show m_area1 in MainWindow1
287 MainWindow mw1(m_controller);
288 m_controller->showArea(m_area1, &mw1);
289 checkArea1(&mw1);
290
291 //now try to show the same area in MainWindow2 and check that we get a clone
292 MainWindow mw2(m_controller);
293 m_controller->showArea(m_area1, &mw2);
294
295 //two mainwindows have different areas
296 QVERIFY(mw1.area() != mw2.area());
297 //the area for the second mainwindow is a clone of the
298 //original area and should have the same name.
299 QVERIFY(mw2.area()->objectName() == mw1.area()->objectName());
300
301 //check mainwindow layouts - original and copy
302 checkArea1(&mw1);
303 checkArea1(&mw2);
304 }
305
306 /*! Functor used by areaSwitchingInSameMainWindow()
307 Walks all Views and checks if they got a widget.
308 hasWidget will be set to false if any View lacks a widget.*/
309 struct AreaWidgetChecker {
310 AreaWidgetChecker() = default;
operator ()AreaWidgetChecker311 Area::WalkerMode operator()(AreaIndex *index)
312 {
313 for (View* view : qAsConst(index->views())) {
314 if (!view->hasWidget()) {
315 failureMessage += view->objectName() + " has no widget\n";
316 foundViewWithoutWidget = true;
317 }
318 }
319 return Area::ContinueWalker;
320 }
operator ()AreaWidgetChecker321 Area::WalkerMode operator()(View *view, Sublime::Position)
322 {
323 if (!view->hasWidget()) {
324 foundViewWithoutWidget = true;
325 failureMessage += view->objectName() + " has no widget\n";
326 }
327 return Area::ContinueWalker;
328 }
329
330 bool foundViewWithoutWidget = false;
331 QString failureMessage;
332 };
333
areaSwitchingInSameMainwindow()334 void TestAreaOperation::areaSwitchingInSameMainwindow()
335 {
336 MainWindow mw(m_controller);
337 m_controller->showArea(m_area1, &mw);
338 checkArea1(&mw);
339
340 m_controller->showArea(m_area2, &mw);
341 checkArea2(&mw);
342
343 //check what happened to area1 widgets, they should be intact
344 AreaWidgetChecker checker;
345 m_area1->walkViews(checker, m_area1->rootIndex());
346 m_area1->walkToolViews(checker, Sublime::AllPositions);
347 QVERIFY2(!checker.foundViewWithoutWidget, checker.failureMessage.toLatin1().data());
348 }
349
simpleViewAdditionAndDeletion()350 void TestAreaOperation::simpleViewAdditionAndDeletion()
351 {
352 // set TabBarOpenAfterCurrent=0, otherwise we'd have a different order of tabs
353 int oldTabBarOpenAfterCurrent;
354 {
355 KConfigGroup uiGroup = KSharedConfig::openConfig()->group("UiSettings");
356 oldTabBarOpenAfterCurrent = uiGroup.readEntry("TabBarOpenAfterCurrent", 1);
357 uiGroup.writeEntry("TabBarOpenAfterCurrent", 0);
358 uiGroup.sync();
359 }
360 m_controller->loadSettings();
361
362 MainWindow mw(m_controller);
363 m_controller->addMainWindow(&mw);
364
365 m_controller->showArea(m_area1, &mw);
366 checkArea1(&mw);
367
368 Document *doc5 = new UrlDocument(m_controller, QUrl::fromLocalFile(QStringLiteral("~/new.cpp")));
369 View *view = doc5->createView();
370 view->setObjectName(QStringLiteral("view1.5.1"));
371 m_area1->addView(view);
372
373 checkAreaViewsDisplay(&mw, m_area1,
374 QStringLiteral("\n[ view1.1.1 view1.2.1 view1.2.2 view1.3.1 view1.5.1 ]\n"),
375 1, 1, QStringLiteral("Added an url view (view1.5.1)"));
376
377 //now remove view and check that area is valid
378 delete m_area1->removeView(view);
379
380 checkAreaViewsDisplay(&mw, m_area1,
381 QStringLiteral("\n[ view1.1.1 view1.2.1 view1.2.2 view1.3.1 ]\n"),
382 1, 1, QStringLiteral("Removed the url view (view1.5.1)"));
383
384 //now remove all other views one by one and leave an empty container
385 const QList<View*> list(m_area1->views());
386 for (View* view : list) {
387 delete m_area1->removeView(view);
388 }
389
390 checkAreaViewsDisplay(&mw, m_area1,
391 QStringLiteral("\n[ horizontal splitter ]\n"),
392 0, 1, QStringLiteral("Removed all views. Only horizontal splitter should remain."));
393
394 //add a view again and check that mainwindow is correctly reconstructed
395 view = doc5->createView();
396 view->setObjectName(QStringLiteral("view1.5.1"));
397 m_area1->addView(view);
398
399 checkAreaViewsDisplay(&mw, m_area1,
400 QStringLiteral("\n[ view1.5.1 ]\n"),
401 1, 1, QStringLiteral("Added a single view to previously emptied mainwindow."));
402
403 {
404 KConfigGroup uiGroup = KSharedConfig::openConfig()->group("UiSettings");
405 uiGroup.writeEntry("TabBarOpenAfterCurrent", oldTabBarOpenAfterCurrent);
406 uiGroup.sync();
407 }
408 m_controller->loadSettings();
409 }
410
complexViewAdditionAndDeletion()411 void TestAreaOperation::complexViewAdditionAndDeletion()
412 {
413 Area *area = m_area2;
414 MainWindow mw(m_controller);
415 m_controller->addMainWindow(&mw);
416
417 m_controller->showArea(m_area2, &mw);
418
419 Document *doc5 = new UrlDocument(m_controller, QUrl::fromLocalFile(QStringLiteral("~/new.cpp")));
420 View *view = doc5->createView();
421 view->setObjectName(QStringLiteral("view2.5.1"));
422
423 View *view221 = findNamedView(area, QStringLiteral("view2.2.1"));
424 QVERIFY(view221);
425 area->addView(view, view221, Qt::Vertical);
426
427 checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
428 [ vertical splitter ]\n\
429 [ vertical splitter ]\n\
430 [ view2.1.1 view2.1.2 ]\n\
431 [ view2.4.1 ]\n\
432 [ horizontal splitter ]\n\
433 [ vertical splitter ]\n\
434 [ view2.2.1 ]\n\
435 [ view2.5.1 ]\n\
436 [ view2.3.1 ]\n\
437 "), 5, 8+1);
438
439 //now delete view221
440 delete area->removeView(view221);
441
442 checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
443 [ vertical splitter ]\n\
444 [ vertical splitter ]\n\
445 [ view2.1.1 view2.1.2 ]\n\
446 [ view2.4.1 ]\n\
447 [ horizontal splitter ]\n\
448 [ view2.5.1 ]\n\
449 [ view2.3.1 ]\n\
450 "), 4, 6+1);
451
452 //remove one more view, this time the one inside non-empty container
453 View *view211 = findNamedView(area, QStringLiteral("view2.1.1"));
454 delete m_area2->removeView(view211);
455
456 checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
457 [ vertical splitter ]\n\
458 [ vertical splitter ]\n\
459 [ view2.1.2 ]\n\
460 [ view2.4.1 ]\n\
461 [ horizontal splitter ]\n\
462 [ view2.5.1 ]\n\
463 [ view2.3.1 ]\n\
464 "), 4, 6+1);
465
466 //and now remove all remaining views one by one
467 delete m_area2->removeView(findNamedView(area, QStringLiteral("view2.1.2")));
468 checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
469 [ vertical splitter ]\n\
470 [ view2.4.1 ]\n\
471 [ horizontal splitter ]\n\
472 [ view2.5.1 ]\n\
473 [ view2.3.1 ]\n\
474 "), 3, 4+1);
475
476 delete m_area2->removeView(findNamedView(area, QStringLiteral("view2.4.1")));
477 checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
478 [ horizontal splitter ]\n\
479 [ view2.5.1 ]\n\
480 [ view2.3.1 ]\n\
481 "), 2, 2+1);
482
483 delete m_area2->removeView(findNamedView(area, QStringLiteral("view2.5.1")));
484 checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
485 [ view2.3.1 ]\n\
486 "), 1, 1);
487
488 delete m_area2->removeView(findNamedView(area, QStringLiteral("view2.3.1")));
489 checkAreaViewsDisplay(&mw, area, QStringLiteral("\n\
490 [ horizontal splitter ]\n\
491 "), 0, 1);
492 }
493
toolViewAdditionAndDeletion()494 void TestAreaOperation::toolViewAdditionAndDeletion()
495 {
496 MainWindow mw(m_controller);
497 m_controller->showArea(m_area1, &mw);
498 checkArea1(&mw);
499
500 Document *tool4 = new ToolDocument(QStringLiteral("tool4"), m_controller, new SimpleToolWidgetFactory<QTextEdit>(QStringLiteral("tool4")));
501 View *view = tool4->createView();
502 view->setObjectName(QStringLiteral("toolview1.4.1"));
503 m_area1->addToolView(view, Sublime::Right);
504
505 //check that area is in valid state
506 AreaToolViewsPrinter toolViewsPrinter1;
507 m_area1->walkToolViews(toolViewsPrinter1, Sublime::AllPositions);
508 QCOMPARE(toolViewsPrinter1.result, QStringLiteral("\n\
509 toolview1.1.1 [ left ]\n\
510 toolview1.2.1 [ bottom ]\n\
511 toolview1.2.2 [ bottom ]\n\
512 toolview1.4.1 [ right ]\n\
513 "));
514
515 //check that mainwindow has newly added tool view
516 {
517 const auto toolDocks = mw.toolDocks();
518 for (View* dock : toolDocks) {
519 QVERIFY(dock->widget() != nullptr);
520 }
521 QCOMPARE(toolDocks.count(), m_area1->toolViews().count());
522 }
523
524 //now remove tool view
525 m_area1->removeToolView(view);
526
527 AreaToolViewsPrinter toolViewsPrinter2;
528 //check that area doesn't have it anymore
529 m_area1->walkToolViews(toolViewsPrinter2, Sublime::AllPositions);
530 QCOMPARE(toolViewsPrinter2.result, QStringLiteral("\n\
531 toolview1.1.1 [ left ]\n\
532 toolview1.2.1 [ bottom ]\n\
533 toolview1.2.2 [ bottom ]\n\
534 "));
535
536 //check that mainwindow has newly added tool view
537 {
538 const auto toolDocks = mw.toolDocks();
539 for (View* dock : toolDocks) {
540 QVERIFY(dock->widget() != nullptr);
541 }
542 QCOMPARE(toolDocks.count(), m_area1->toolViews().count());
543 }
544 }
545
546
547
testAddingViewAfter()548 void TestAreaOperation::testAddingViewAfter()
549 {
550
551 const QList<View*> list(m_area3->views());
552 for (View* view : list) {
553 qDebug() << "name of view : " << view->objectName() << " , it's index : " << m_area3->views().indexOf(view);
554 }
555
556 }
557
558 ////////////////////////////////////////////////////////////////////////////////
559 ////////////////////////////////////////////////////////////////////////////////
splitViewActiveTabsTest()560 void TestAreaOperation::splitViewActiveTabsTest()
561 {
562 MainWindow mw(m_controller);
563 m_controller->showArea(m_area1, &mw);
564 checkArea1(&mw);
565
566 // at first show of the area, the active view should be m_pView111
567 QCOMPARE(mw.activeView(), m_pView111);
568
569 // Try to get to the main container :
570 // get the central widget
571 QWidget *pCentral = mw.centralWidget();
572 QVERIFY(pCentral);
573 QVERIFY(pCentral->inherits("QWidget"));
574
575 // get its first splitter
576 QWidget *pSplitter = pCentral->findChild<QSplitter*>();
577 QVERIFY(pSplitter);
578 QVERIFY(pSplitter->inherits("QSplitter"));
579
580 // finally, get the splitter's container
581 auto *pContainer = pSplitter->findChild<Sublime::Container*>();
582 QVERIFY(pContainer);
583
584 // verify that the current active widget in the container is the one in activeview (m_pView111)
585 QCOMPARE(pContainer->currentWidget(), mw.activeView()->widget());
586
587 // activate the second tab of the area (view212)
588 mw.activateView(m_pView121);
589
590 // verify that the active view was correctly updated to m_pView121
591 QCOMPARE(mw.activeView(), m_pView121);
592
593 // check if the container's current widget was updated to the active view's
594 QCOMPARE(pContainer->currentWidget(), mw.activeView()->widget());
595
596 // now, create a split view of the active view (m_pView121)
597 Sublime::View *pNewView = mw.activeView()->document()->createView();
598 pNewView->setObjectName("splitOf" + mw.activeView()->objectName());
599 m_area1->addView(pNewView, mw.activeView(), Qt::Vertical);
600
601 // verify that creating a new view did not break the central widget
602 QCOMPARE(pCentral, mw.centralWidget());
603
604 // verify that creating a new view did not break the main splitter
605 QCOMPARE(pSplitter, pCentral->findChild<QSplitter*>());
606
607 // creating a new view created two new children splitters, get them
608 QVERIFY(pSplitter->findChildren<QSplitter*>().size() == 2);
609 QWidget *pFirstSplitter = pSplitter->findChildren<QSplitter*>().at(0);
610 QVERIFY(pFirstSplitter);
611 QWidget *pSecondSplitter = pSplitter->findChildren<QSplitter*>().at(1);
612 QVERIFY(pSecondSplitter);
613
614 // for each splitter, get the corresponding container
615 auto *pFirstContainer = pFirstSplitter->findChild<Sublime::Container*>();
616 QVERIFY(pFirstContainer);
617 auto *pSecondContainer = pSecondSplitter->findChild<Sublime::Container*>();
618 QVERIFY(pSecondContainer);
619
620 // the active view should have remained view121
621 QCOMPARE(mw.activeView(), m_pView121);
622
623 // pFirstContainer should contain the newView's widget
624 QVERIFY(pFirstContainer->hasWidget(pNewView->widget()));
625
626 // the new view's widget should be the current widget of the new container
627 QCOMPARE(pFirstContainer->currentWidget(), pNewView->widget());
628
629 // pSecondContainer should contain all the old views widgets
630 QVERIFY(pSecondContainer->hasWidget(m_pView111->widget()));
631 QVERIFY(pSecondContainer->hasWidget(m_pView121->widget()));
632 QVERIFY(pSecondContainer->hasWidget(m_pView122->widget()));
633 QVERIFY(pSecondContainer->hasWidget(m_pView131->widget()));
634
635 // the active widget should be the current widget of the second container
636 QCOMPARE(pSecondContainer->currentWidget(), mw.activeView()->widget());
637
638 ////////////////////////////////////////////////////////////////////////////
639 // now, activate the new view and check if all went well
640 mw.activateView(pNewView);
641
642 // active view should now be newView
643 QCOMPARE(mw.activeView(), pNewView);
644
645 // the active widget should be the current widget of the new container
646 QCOMPARE(pFirstContainer->currentWidget(), mw.activeView()->widget());
647
648 // the current widget of the old container should have remained view121's
649 QCOMPARE(pSecondContainer->currentWidget(), m_pView121->widget());
650
651 ////////////////////////////////////////////////////////////////////////////
652 // now delete newView and check area state
653 delete m_area1->removeView(pNewView);
654
655 // verify that deleting the view did not broke the central widget
656 QCOMPARE(pCentral, mw.centralWidget());
657
658 // removing the view should have destroyed the sub splitters and containers,
659 // so get the main one and verify that deleting the view did not break it
660 QCOMPARE(pSplitter, pCentral->findChild<QSplitter*>());
661
662 // get the new container inside the main splitter
663 pContainer = pSplitter->findChild<Sublime::Container*>();
664 QVERIFY(pContainer);
665
666 // active view should now be back to m_pView121 again
667 QCOMPARE(mw.activeView(), m_pView121);
668
669 // check also the container current widget
670 QCOMPARE(pContainer->currentWidget(), mw.activeView()->widget());
671 }
672
checkAreaViewsDisplay(MainWindow * mw,Area * area,const QString & printedAreas,int containerCount,int splitterCount,const QString & location)673 void TestAreaOperation::checkAreaViewsDisplay(MainWindow *mw, Area *area,
674 const QString &printedAreas, int containerCount, int splitterCount, const QString& location)
675 {
676 //check area
677 AreaViewsPrinter viewsPrinter;
678 area->walkViews(viewsPrinter, area->rootIndex());
679 QCOMPARE(viewsPrinter.result, printedAreas);
680
681 //check mainwindow
682 QWidget *central = mw->centralWidget();
683 QVERIFY(central != nullptr);
684 QVERIFY(central->inherits("QWidget"));
685
686 QWidget *splitter = central->findChild<QSplitter*>();
687 QVERIFY(splitter);
688 QVERIFY(splitter->inherits("QSplitter"));
689
690 //check containers
691 const QList<Container*> containers = splitter->findChildren<Sublime::Container*>();
692 QString failMsg = QStringLiteral("\nFailure while checking area contents @ %1\n"
693 "Expected %2 containers in central splitter but got %3 \n").
694 arg(location).arg(containerCount).arg(containers.count());
695 QVERIFY2(containers.count() == containerCount, failMsg.toLatin1().data());
696
697 int widgetCount = 0;
698 for (Container* c : containers) {
699 for (int i = 0; i < c->count(); ++i)
700 {
701 QVERIFY(c->widget(i) != nullptr);
702 QVERIFY(c->widget(i)->parentWidget() != nullptr);
703 }
704 widgetCount += c->count();
705 }
706
707 ViewCounter c;
708 area->walkViews(c, area->rootIndex());
709 QCOMPARE(widgetCount, c.count);
710
711 QList<QSplitter*> splitters = splitter->findChildren<QSplitter*>();
712 splitters.append(qobject_cast<QSplitter*>(splitter));
713 QCOMPARE(splitters.count(), splitterCount);
714 }
715
findNamedView(Area * area,const QString & name)716 View *TestAreaOperation::findNamedView(Area *area, const QString &name)
717 {
718 const auto views = area->views();
719 for (View* view : views) {
720 if (view->objectName() == name)
721 return view;
722 }
723 return nullptr;
724 }
725
726 ///////////
727 QTEST_MAIN(TestAreaOperation)
728