DockManager.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 ** Qt Advanced Docking System
3 ** Copyright (C) 2017 Uwe Kindler
4 **
5 ** This library is free software; you can redistribute it and/or
6 ** modify it under the terms of the GNU Lesser General Public
7 ** License as published by the Free Software Foundation; either
8 ** version 2.1 of the License, or (at your option) any later version.
9 **
10 ** This library is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ** Lesser General Public License for more details.
14 **
15 ** You should have received a copy of the GNU Lesser General Public
16 ** License along with this library; If not, see <http://www.gnu.org/licenses/>.
17 ******************************************************************************/
18 
19 
20 //============================================================================
25 //============================================================================
26 
27 
28 //============================================================================
29 // INCLUDES
30 //============================================================================
31 #include "DockWidgetTab.h"
32 #include "DockManager.h"
33 
34 #include <algorithm>
35 #include <iostream>
36 
37 #include <QMainWindow>
38 #include <QList>
39 #include <QMap>
40 #include <QVariant>
41 #include <QDebug>
42 #include <QFile>
43 #include <QAction>
44 #include <QXmlStreamWriter>
45 #include <QSettings>
46 #include <QMenu>
47 #include <QApplication>
48 
49 #include "FloatingDockContainer.h"
50 #include "DockOverlay.h"
51 #include "DockWidget.h"
52 #include "ads_globals.h"
53 #include "DockAreaWidget.h"
54 #include "IconProvider.h"
55 #include "DockingStateReader.h"
56 #include "DockAreaTitleBar.h"
57 #include "DockFocusController.h"
58 #include "DockSplitter.h"
59 
60 #ifdef Q_OS_LINUX
62 #endif
63 
64 
74 static void initResource()
75 {
76  Q_INIT_RESOURCE(ads);
77 }
78 
79 
80 namespace ads
81 {
86 {
88  Version1 = 1,
90 };
91 
92 static CDockManager::ConfigFlags StaticConfigFlags = CDockManager::DefaultNonOpaqueConfig;
93 
98 {
102  CDockOverlay* ContainerOverlay;
103  CDockOverlay* DockAreaOverlay;
107  QMenu* ViewMenu;
109  bool RestoringState = false;
113 
118 
123  bool checkFormat(const QByteArray &state, int version);
124 
128  bool restoreStateFromXml(const QByteArray &state, int version, bool Testing = internal::Restore);
129 
133  bool restoreState(const QByteArray &state, int version);
134 
137  void emitTopLevelEvents();
138 
140  {
141  // Hide updates of floating widgets from user
142  for (auto FloatingWidget : FloatingWidgets)
143  {
144  FloatingWidget->hide();
145  }
146  }
147 
149  {
150  for (auto DockWidget : DockWidgetsMap)
151  {
152  DockWidget->setProperty("dirty", true);
153  }
154  }
155 
159  bool restoreContainer(int Index, CDockingStateReader& stream, bool Testing);
160 
164  void loadStylesheet();
165 
169  void addActionToMenu(QAction* Action, QMenu* Menu, bool InsertSorted);
170 };
171 // struct DockManagerPrivate
172 
173 //============================================================================
175  _this(_public)
176 {
177 
178 }
179 
180 
181 //============================================================================
183 {
184  initResource();
185  QString Result;
186  QString FileName = ":ads/stylesheets/";
188  ? "focus_highlighting" : "default";
189 #ifdef Q_OS_LINUX
190  FileName += "_linux";
191 #endif
192  FileName += ".css";
193  QFile StyleSheetFile(FileName);
194  StyleSheetFile.open(QIODevice::ReadOnly);
195  QTextStream StyleSheetStream(&StyleSheetFile);
196  Result = StyleSheetStream.readAll();
197  StyleSheetFile.close();
198  //_this->setStyleSheet(Result);
199 }
200 
201 
202 //============================================================================
203 bool DockManagerPrivate::restoreContainer(int Index, CDockingStateReader& stream, bool Testing)
204 {
205  if (Testing)
206  {
207  Index = 0;
208  }
209 
210  bool Result = false;
211  if (Index >= Containers.count())
212  {
213  CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(_this);
214  Result = FloatingWidget->restoreState(stream, Testing);
215  }
216  else
217  {
218  ADS_PRINT("d->Containers[i]->restoreState ");
219  auto Container = Containers[Index];
220  if (Container->isFloating())
221  {
222  Result = Container->floatingWidget()->restoreState(stream, Testing);
223  }
224  else
225  {
226  Result = Container->restoreState(stream, Testing);
227  }
228  }
229 
230  return Result;
231 }
232 
233 
234 //============================================================================
235 bool DockManagerPrivate::checkFormat(const QByteArray &state, int version)
236 {
237  return restoreStateFromXml(state, version, internal::RestoreTesting);
238 }
239 
240 
241 //============================================================================
243  bool Testing)
244 {
245  Q_UNUSED(version);
246 
247  if (state.isEmpty())
248  {
249  return false;
250  }
251  CDockingStateReader s(state);
252  s.readNextStartElement();
253  if (s.name() != "QtAdvancedDockingSystem")
254  {
255  return false;
256  }
257  ADS_PRINT(s.attributes().value("Version"));
258  bool ok;
259  int v = s.attributes().value("Version").toInt(&ok);
260  if (!ok || v > CurrentVersion)
261  {
262  return false;
263  }
264  s.setFileVersion(v);
265 
266  ADS_PRINT(s.attributes().value("UserVersion"));
267  // Older files do not support UserVersion but we still want to load them so
268  // we first test if the attribute exists
269  if (!s.attributes().value("UserVersion").isEmpty())
270  {
271  v = s.attributes().value("UserVersion").toInt(&ok);
272  if (!ok || v != version)
273  {
274  return false;
275  }
276  }
277 
278  bool Result = true;
279 #ifdef ADS_DEBUG_PRINT
280  int DockContainers = s.attributes().value("Containers").toInt();
281 #endif
282  ADS_PRINT(DockContainers);
283 
284  if (CentralWidget)
285  {
286  const auto CentralWidgetAttribute = s.attributes().value("CentralWidget");
287  // If we have a central widget but a state without central widget, then
288  // something is wrong.
289  if (CentralWidgetAttribute.isEmpty())
290  {
291  qWarning() << "Dock manager has central widget but saved state does not have central widget.";
292  return false;
293  }
294 
295  // If the object name of the central widget does not match the name of the
296  // saved central widget, the something is wrong
297  if (CentralWidget->objectName() != CentralWidgetAttribute.toString())
298  {
299  qWarning() << "Object name of central widget does not match name of central widget in saved state.";
300  return false;
301  }
302  }
303 
304  int DockContainerCount = 0;
305  while (s.readNextStartElement())
306  {
307  if (s.name() == "Container")
308  {
309  Result = restoreContainer(DockContainerCount, s, Testing);
310  if (!Result)
311  {
312  break;
313  }
314  DockContainerCount++;
315  }
316  }
317 
318  if (!Testing)
319  {
320  // Delete remaining empty floating widgets
321  int FloatingWidgetIndex = DockContainerCount - 1;
322  for (int i = FloatingWidgetIndex; i < FloatingWidgets.count(); ++i)
323  {
324  auto* floatingWidget = FloatingWidgets[i];
325  _this->removeDockContainer(floatingWidget->dockContainer());
326  floatingWidget->deleteLater();
327  }
328  }
329 
330  return Result;
331 }
332 
333 
334 //============================================================================
336 {
337  // All dock widgets, that have not been processed in the restore state
338  // function are invisible to the user now and have no assigned dock area
339  // They do not belong to any dock container, until the user toggles the
340  // toggle view action the next time
341  for (auto DockWidget : DockWidgetsMap)
342  {
343  if (DockWidget->property(internal::DirtyProperty).toBool())
344  {
346  emit DockWidget->viewToggled(false);
347  }
348  else
349  {
351  }
352  }
353 }
354 
355 
356 //============================================================================
358 {
359  // Now all dock areas are properly restored and we setup the index of
360  // The dock areas because the previous toggleView() action has changed
361  // the dock area index
362  int Count = 0;
363  for (auto DockContainer : Containers)
364  {
365  Count++;
366  for (int i = 0; i < DockContainer->dockAreaCount(); ++i)
367  {
368  CDockAreaWidget* DockArea = DockContainer->dockArea(i);
369  QString DockWidgetName = DockArea->property("currentDockWidget").toString();
370  CDockWidget* DockWidget = nullptr;
371  if (!DockWidgetName.isEmpty())
372  {
373  DockWidget = _this->findDockWidget(DockWidgetName);
374  }
375 
376  if (!DockWidget || DockWidget->isClosed())
377  {
378  int Index = DockArea->indexOfFirstOpenDockWidget();
379  if (Index < 0)
380  {
381  continue;
382  }
383  DockArea->setCurrentIndex(Index);
384  }
385  else
386  {
387  DockArea->internalSetCurrentDockWidget(DockWidget);
388  }
389  }
390  }
391 }
392 
393 //============================================================================
395 {
396  // Finally we need to send the topLevelChanged() signals for all dock
397  // widgets if top level changed
398  for (auto DockContainer : Containers)
399  {
400  CDockWidget* TopLevelDockWidget = DockContainer->topLevelDockWidget();
401  if (TopLevelDockWidget)
402  {
403  TopLevelDockWidget->emitTopLevelChanged(true);
404  }
405  else
406  {
407  for (int i = 0; i < DockContainer->dockAreaCount(); ++i)
408  {
409  auto DockArea = DockContainer->dockArea(i);
410  for (auto DockWidget : DockArea->dockWidgets())
411  {
413  }
414  }
415  }
416  }
417 }
418 
419 
420 //============================================================================
421 bool DockManagerPrivate::restoreState(const QByteArray& State, int version)
422 {
423  QByteArray state = State.startsWith("<?xml") ? State : qUncompress(State);
424  if (!checkFormat(state, version))
425  {
426  ADS_PRINT("checkFormat: Error checking format!!!!!!!");
427  return false;
428  }
429 
430  // Hide updates of floating widgets from use
433 
434  if (!restoreStateFromXml(state, version))
435  {
436  ADS_PRINT("restoreState: Error restoring state!!!!!!!");
437  return false;
438  }
439 
443  _this->dumpLayout();
444 
445  return true;
446 }
447 
448 
449 //============================================================================
450 void DockManagerPrivate::addActionToMenu(QAction* Action, QMenu* Menu, bool InsertSorted)
451 {
452  if (InsertSorted)
453  {
454  auto Actions = Menu->actions();
455  auto it = std::find_if(Actions.begin(), Actions.end(),
456  [&Action](const QAction* a)
457  {
458  return a->text().compare(Action->text(), Qt::CaseInsensitive) > 0;
459  });
460 
461  if (it == Actions.end())
462  {
463  Menu->addAction(Action);
464  }
465  else
466  {
467  Menu->insertAction(*it, Action);
468  }
469  }
470  else
471  {
472  Menu->addAction(Action);
473  }
474 }
475 
476 
477 //============================================================================
478 CDockManager::CDockManager(QWidget *parent) :
479  CDockContainerWidget(this, parent),
480  d(new DockManagerPrivate(this))
481 {
483  QMainWindow* MainWindow = qobject_cast<QMainWindow*>(parent);
484  if (MainWindow)
485  {
486  MainWindow->setCentralWidget(this);
487  }
488 
489  d->ViewMenu = new QMenu(tr("Show View"), this);
490  d->DockAreaOverlay = new CDockOverlay(this, CDockOverlay::ModeDockAreaOverlay);
491  d->ContainerOverlay = new CDockOverlay(this, CDockOverlay::ModeContainerOverlay);
492  d->Containers.append(this);
493  d->loadStylesheet();
494 
496  {
498  }
499 
500 #ifdef Q_OS_LINUX
501  window()->installEventFilter(this);
502 #endif
503 }
504 
505 //============================================================================
507 {
508  auto FloatingWidgets = d->FloatingWidgets;
509  for (auto FloatingWidget : FloatingWidgets)
510  {
511  delete FloatingWidget;
512  }
513  delete d;
514 }
515 
516 //============================================================================
517 #ifdef Q_OS_LINUX
518 bool CDockManager::eventFilter(QObject *obj, QEvent *e)
519 {
520  // Emulate Qt:Tool behaviour.
521  // Required because on some WMs Tool windows can't be maximized.
522 
523  // Window always on top of the MainWindow.
524  if (e->type() == QEvent::WindowActivate)
525  {
526  for (auto _window : floatingWidgets())
527  {
528  if (!_window->isVisible() || window()->isMinimized())
529  {
530  continue;
531  }
532  // setWindowFlags(Qt::WindowStaysOnTopHint) will hide the window and thus requires a show call.
533  // This then leads to flickering and a nasty endless loop (also buggy behaviour on Ubuntu).
534  // So we just do it ourself.
535  internal::xcb_update_prop(true, _window->window()->winId(),
536  "_NET_WM_STATE", "_NET_WM_STATE_ABOVE", "_NET_WM_STATE_STAYS_ON_TOP");
537  }
538  }
539  else if (e->type() == QEvent::WindowDeactivate)
540  {
541  for (auto _window : floatingWidgets())
542  {
543  if (!_window->isVisible() || window()->isMinimized())
544  {
545  continue;
546  }
547  internal::xcb_update_prop(false, _window->window()->winId(),
548  "_NET_WM_STATE", "_NET_WM_STATE_ABOVE", "_NET_WM_STATE_STAYS_ON_TOP");
549  _window->raise();
550  }
551  }
552 
553  // Sync minimize with MainWindow
554  if (e->type() == QEvent::WindowStateChange)
555  {
556  for (auto _window : floatingWidgets())
557  {
558  if (! _window->isVisible())
559  {
560  continue;
561  }
562 
563  if (window()->isMinimized())
564  {
565  _window->showMinimized();
566  }
567  else
568  {
569  _window->setWindowState(_window->windowState() & (~Qt::WindowMinimized));
570  }
571  }
572  if (!window()->isMinimized())
573  {
574  QApplication::setActiveWindow(window());
575  }
576  }
577  return Super::eventFilter(obj, e);
578 }
579 #endif
580 
581 //============================================================================
583 {
584  d->FloatingWidgets.append(FloatingWidget);
585  emit floatingWidgetCreated(FloatingWidget);
586  ADS_PRINT("d->FloatingWidgets.count() " << d->FloatingWidgets.count());
587 }
588 
589 
590 //============================================================================
592 {
593  d->FloatingWidgets.removeAll(FloatingWidget);
594 }
595 
596 
597 //============================================================================
599 {
600  d->Containers.append(DockContainer);
601 }
602 
603 
604 //============================================================================
606 {
607  if (this != DockContainer)
608  {
609  d->Containers.removeAll(DockContainer);
610  }
611 }
612 
613 
614 //============================================================================
615 CDockOverlay* CDockManager::containerOverlay() const
616 {
617  return d->ContainerOverlay;
618 }
619 
620 
621 //============================================================================
622 CDockOverlay* CDockManager::dockAreaOverlay() const
623 {
624  return d->DockAreaOverlay;
625 }
626 
627 
628 //============================================================================
630 {
631  return d->Containers;
632 }
633 
634 
635 //============================================================================
637 {
638  return d->FloatingWidgets;
639 }
640 
641 
642 //============================================================================
643 unsigned int CDockManager::zOrderIndex() const
644 {
645  return 0;
646 }
647 
648 
649 //============================================================================
650 QByteArray CDockManager::saveState(int version) const
651 {
652  QByteArray xmldata;
653  QXmlStreamWriter s(&xmldata);
654  auto ConfigFlags = CDockManager::configFlags();
655  s.setAutoFormatting(ConfigFlags.testFlag(XmlAutoFormattingEnabled));
656  s.writeStartDocument();
657  s.writeStartElement("QtAdvancedDockingSystem");
658  s.writeAttribute("Version", QString::number(CurrentVersion));
659  s.writeAttribute("UserVersion", QString::number(version));
660  s.writeAttribute("Containers", QString::number(d->Containers.count()));
661  if (d->CentralWidget)
662  {
663  s.writeAttribute("CentralWidget", d->CentralWidget->objectName());
664  }
665  for (auto Container : d->Containers)
666  {
667  Container->saveState(s);
668  }
669 
670  s.writeEndElement();
671  s.writeEndDocument();
672 
673  return ConfigFlags.testFlag(XmlCompressionEnabled)
674  ? qCompress(xmldata, 9) : xmldata;
675 }
676 
677 
678 //============================================================================
679 bool CDockManager::restoreState(const QByteArray &state, int version)
680 {
681  // Prevent multiple calls as long as state is not restore. This may
682  // happen, if QApplication::processEvents() is called somewhere
683  if (d->RestoringState)
684  {
685  return false;
686  }
687 
688  // We hide the complete dock manager here. Restoring the state means
689  // that DockWidgets are removed from the DockArea internal stack layout
690  // which in turn means, that each time a widget is removed the stack
691  // will show and raise the next available widget which in turn
692  // triggers show events for the dock widgets. To avoid this we hide the
693  // dock manager. Because there will be no processing of application
694  // events until this function is finished, the user will not see this
695  // hiding
696  bool IsHidden = this->isHidden();
697  if (!IsHidden)
698  {
699  hide();
700  }
701  d->RestoringState = true;
702  emit restoringState();
703  bool Result = d->restoreState(state, version);
704  d->RestoringState = false;
705  if (!IsHidden)
706  {
707  show();
708  }
709  emit stateRestored();
710  return Result;
711 }
712 
713 
714 //============================================================================
716 {
717  d->DockWidgetsMap.insert(Dockwidget->objectName(), Dockwidget);
718  CDockAreaWidget* OldDockArea = Dockwidget->dockAreaWidget();
719  if (OldDockArea)
720  {
721  OldDockArea->removeDockWidget(Dockwidget);
722  }
723 
724  Dockwidget->setDockManager(this);
725  CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(Dockwidget);
726  FloatingWidget->resize(Dockwidget->size());
727  if (isVisible())
728  {
729  FloatingWidget->show();
730  }
731  else
732  {
733  d->UninitializedFloatingWidgets.append(FloatingWidget);
734  }
735  emit dockWidgetAdded(Dockwidget);
736  return FloatingWidget;
737 }
738 
739 
740 //============================================================================
742 {
743  Super::showEvent(event);
744  if (d->UninitializedFloatingWidgets.empty())
745  {
746  return;
747  }
748 
749  for (auto FloatingWidget : d->UninitializedFloatingWidgets)
750  {
751  FloatingWidget->show();
752  }
754 }
755 
756 
757 //============================================================================
759  CDockWidget* Dockwidget, CDockAreaWidget* DockAreaWidget)
760 {
761  d->DockWidgetsMap.insert(Dockwidget->objectName(), Dockwidget);
762  auto Container = DockAreaWidget ? DockAreaWidget->dockContainer(): this;
763  auto AreaOfAddedDockWidget = Container->addDockWidget(area, Dockwidget, DockAreaWidget);
764  emit dockWidgetAdded(Dockwidget);
765  return AreaOfAddedDockWidget;
766 }
767 
768 
769 //============================================================================
771  CDockWidget* Dockwidget)
772 {
773  CDockAreaWidget* AreaWidget = lastAddedDockAreaWidget(area);
774  if (AreaWidget)
775  {
776  return addDockWidget(ads::CenterDockWidgetArea, Dockwidget, AreaWidget);
777  }
778  else if (!openedDockAreas().isEmpty())
779  {
780  return addDockWidget(area, Dockwidget, openedDockAreas().last());
781  }
782  else
783  {
784  return addDockWidget(area, Dockwidget, nullptr);
785  }
786 }
787 
788 
789 //============================================================================
791  CDockAreaWidget* DockAreaWidget)
792 {
793  return addDockWidget(ads::CenterDockWidgetArea, Dockwidget, DockAreaWidget);
794 }
795 
796 
797 //============================================================================
798 CDockWidget* CDockManager::findDockWidget(const QString& ObjectName) const
799 {
800  return d->DockWidgetsMap.value(ObjectName, nullptr);
801 }
802 
803 //============================================================================
805 {
806  emit dockWidgetAboutToBeRemoved(Dockwidget);
807  d->DockWidgetsMap.remove(Dockwidget->objectName());
809  Dockwidget->setDockManager(nullptr);
810  emit dockWidgetRemoved(Dockwidget);
811 }
812 
813 //============================================================================
815 {
816  return d->DockWidgetsMap;
817 }
818 
819 
820 //============================================================================
821 void CDockManager::addPerspective(const QString& UniquePrespectiveName)
822 {
823  d->Perspectives.insert(UniquePrespectiveName, saveState());
824  emit perspectiveListChanged();
825 }
826 
827 
828 //============================================================================
829 void CDockManager::removePerspective(const QString& Name)
830 {
831  removePerspectives({Name});
832 }
833 
834 
835 //============================================================================
836 void CDockManager::removePerspectives(const QStringList& Names)
837 {
838  int Count = 0;
839  for (auto Name : Names)
840  {
841  Count += d->Perspectives.remove(Name);
842  }
843 
844  if (Count)
845  {
846  emit perspectivesRemoved();
847  emit perspectiveListChanged();
848  }
849 }
850 
851 
852 //============================================================================
854 {
855  return d->Perspectives.keys();
856 }
857 
858 
859 //============================================================================
860 void CDockManager::openPerspective(const QString& PerspectiveName)
861 {
862  const auto Iterator = d->Perspectives.find(PerspectiveName);
863  if (d->Perspectives.end() == Iterator)
864  {
865  return;
866  }
867 
868  emit openingPerspective(PerspectiveName);
869  restoreState(Iterator.value());
870  emit perspectiveOpened(PerspectiveName);
871 }
872 
873 
874 //============================================================================
875 void CDockManager::savePerspectives(QSettings& Settings) const
876 {
877  Settings.beginWriteArray("Perspectives", d->Perspectives.size());
878  int i = 0;
879  for (auto it = d->Perspectives.constBegin(); it != d->Perspectives.constEnd(); ++it)
880  {
881  Settings.setArrayIndex(i);
882  Settings.setValue("Name", it.key());
883  Settings.setValue("State", it.value());
884  ++i;
885  }
886  Settings.endArray();
887 }
888 
889 
890 //============================================================================
891 void CDockManager::loadPerspectives(QSettings& Settings)
892 {
893  d->Perspectives.clear();
894  int Size = Settings.beginReadArray("Perspectives");
895  if (!Size)
896  {
897  Settings.endArray();
898  return;
899  }
900 
901  for (int i = 0; i < Size; ++i)
902  {
903  Settings.setArrayIndex(i);
904  QString Name = Settings.value("Name").toString();
905  QByteArray Data = Settings.value("State").toByteArray();
906  if (Name.isEmpty() || Data.isEmpty())
907  {
908  continue;
909  }
910 
911  d->Perspectives.insert(Name, Data);
912  }
913 
914  Settings.endArray();
915 }
916 
917 
918 //============================================================================
920 {
921  return d->CentralWidget;
922 }
923 
924 
925 //============================================================================
927 {
928  if (!widget)
929  {
930  d->CentralWidget = nullptr;
931  return nullptr;
932  }
933 
934  // Setting a new central widget is now allowed if there is already a central
935  // widget or if there are already other dock widgets
936  if (d->CentralWidget)
937  {
938  qWarning("Setting a central widget not possible because there is already a central widget.");
939  return nullptr;
940  }
941 
942  // Setting a central widget is now allowed if there are already other
943  // dock widgets.
944  if (!d->DockWidgetsMap.isEmpty())
945  {
946  qWarning("Setting a central widget not possible - the central widget need to be the first "
947  "dock widget that is added to the dock manager.");
948  return nullptr;
949  }
950 
951 
955  d->CentralWidget = widget;
956  CDockAreaWidget* CentralArea = addDockWidget(CenterDockWidgetArea, widget);
957  CentralArea->setDockAreaFlag(CDockAreaWidget::eDockAreaFlag::HideSingleWidgetTitleBar, true);
958  return CentralArea;
959 }
960 
961 //============================================================================
962 QAction* CDockManager::addToggleViewActionToMenu(QAction* ToggleViewAction,
963  const QString& Group, const QIcon& GroupIcon)
964 {
965  bool AlphabeticallySorted = (MenuAlphabeticallySorted == d->MenuInsertionOrder);
966  if (!Group.isEmpty())
967  {
968  QMenu* GroupMenu = d->ViewMenuGroups.value(Group, 0);
969  if (!GroupMenu)
970  {
971  GroupMenu = new QMenu(Group, this);
972  GroupMenu->setIcon(GroupIcon);
973  d->addActionToMenu(GroupMenu->menuAction(), d->ViewMenu, AlphabeticallySorted);
974  d->ViewMenuGroups.insert(Group, GroupMenu);
975  }
976  else if (GroupMenu->icon().isNull() && !GroupIcon.isNull())
977  {
978  GroupMenu->setIcon(GroupIcon);
979  }
980 
981  d->addActionToMenu(ToggleViewAction, GroupMenu, AlphabeticallySorted);
982  return GroupMenu->menuAction();
983  }
984  else
985  {
986  d->addActionToMenu(ToggleViewAction, d->ViewMenu, AlphabeticallySorted);
987  return ToggleViewAction;
988  }
989 }
990 
991 
992 //============================================================================
994 {
995  return d->ViewMenu;
996 }
997 
998 
999 //============================================================================
1001 {
1002  d->MenuInsertionOrder = Order;
1003 }
1004 
1005 
1006 //===========================================================================
1008 {
1009  return d->RestoringState;
1010 }
1011 
1012 
1013 //===========================================================================
1015 {
1016  return QApplication::startDragDistance() * 1.5;
1017 }
1018 
1019 
1020 //===========================================================================
1021 CDockManager::ConfigFlags CDockManager::configFlags()
1022 {
1023  return StaticConfigFlags;
1024 }
1025 
1026 
1027 //===========================================================================
1028 void CDockManager::setConfigFlags(const ConfigFlags Flags)
1029 {
1030  StaticConfigFlags = Flags;
1031 }
1032 
1033 
1034 //===========================================================================
1036 {
1037  internal::setFlag(StaticConfigFlags, Flag, On);
1038 }
1039 
1040 //===========================================================================
1042 {
1043  return configFlags().testFlag(Flag);
1044 }
1045 
1046 
1047 //===========================================================================
1049 {
1050  static CIconProvider Instance;
1051  return Instance;
1052 }
1053 
1054 
1055 //===========================================================================
1057 {
1058  if (d->FocusController)
1059  {
1061  }
1062 }
1063 
1064 
1065 //===========================================================================
1067 {
1068  if (d->FocusController)
1069  {
1070  d->FocusController->notifyFloatingWidgetDrop(FloatingWidget);
1071  }
1072 }
1073 
1074 
1075 //===========================================================================
1077 {
1078  if (d->FocusController)
1079  {
1080  d->FocusController->setDockWidgetFocused(DockWidget);
1081  }
1082 }
1083 
1084 
1085 //===========================================================================
1087 {
1088  if (!d->FocusController)
1089  {
1090  return nullptr;
1091  }
1092  else
1093  {
1094  return d->FocusController->focusedDockWidget();
1095  }
1096 }
1097 
1098 //===========================================================================
1100 {
1101  if (ContainedArea)
1102  {
1103  auto Splitter = internal::findParent<CDockSplitter*>(ContainedArea);
1104  if (Splitter)
1105  {
1106  return Splitter->sizes();
1107  }
1108  }
1109  return QList<int>();
1110 }
1111 
1112 //===========================================================================
1114 {
1115  if (!ContainedArea)
1116  {
1117  return;
1118  }
1119 
1120  auto Splitter = internal::findParent<CDockSplitter*>(ContainedArea);
1121  if (Splitter && Splitter->count() == sizes.count())
1122  {
1123  Splitter->setSizes(sizes);
1124  }
1125 }
1126 
1127 } // namespace ads
1128 
1129 //---------------------------------------------------------------------------
1130 // EOF DockManager.cpp
static bool testConfigFlag(eConfigFlag Flag)
void registerFloatingWidget(CFloatingDockContainer *FloatingWidget)
static const bool RestoreTesting
Definition: ads_globals.h:132
Declaration of CDockWidgetTab class.
void floatingWidgetCreated(ads::CFloatingDockContainer *FloatingWidget)
void setDockAreaFlag(eDockAreaFlag Flag, bool On)
CDockOverlay * DockAreaOverlay
CDockWidget * focusedDockWidget() const
void notifyFloatingWidgetDrop(CFloatingDockContainer *FloatingWidget)
If enabled, the XML output will be compressed and is not human readable anymore.
Definition: DockManager.h:164
int indexOfFirstOpenDockWidget() const
bool isRestoringState() const
void toggleViewInternal(bool Open)
Definition: DockWidget.cpp:499
static heap_info state
Definition: Heap.c:58
the default configuration for non opaque operations
Definition: DockManager.h:205
void removeDockWidget(CDockWidget *DockWidget)
CDockManager::eViewMenuInsertionOrder MenuInsertionOrder
virtual void showEvent(QShowEvent *event) override
QAction * addToggleViewActionToMenu(QAction *ToggleViewAction, const QString &Group=QString(), const QIcon &GroupIcon=QIcon())
CDockOverlay * ContainerOverlay
void dockWidgetRemoved(ads::CDockWidget *DockWidget)
DockWidgetArea
Definition: ads_globals.h:73
unsigned int zOrderIndex() const override
eStateFileVersion
Definition: DockManager.cpp:85
dock widget has a close button
Definition: DockWidget.h:150
void setFeature(DockWidgetFeature flag, bool on)
Definition: DockWidget.cpp:350
CDockWidget * CentralWidget
static ConfigFlags configFlags()
void perspectiveListChanged()
MQTTClient d
Definition: test10.c:1656
void setDockManager(CDockManager *DockManager)
Definition: DockWidget.cpp:373
CDockAreaWidget * lastAddedDockAreaWidget(DockWidgetArea area) const
CDockAreaWidget * addDockWidget(DockWidgetArea area, CDockWidget *Dockwidget, CDockAreaWidget *DockAreaWidget=nullptr)
Declaration of CDockFocusController class.
void savePerspectives(QSettings &Settings) const
CDockWidget * centralWidget() const
CDockManager(QWidget *parent=nullptr)
enables styling of focused dock widget tabs or floating widget titlebar
Definition: DockManager.h:182
Declaration of CFloatingDockContainer class.
void notifyFloatingWidgetDrop(CFloatingDockContainer *FloatingWidget)
QList< CDockAreaWidget * > openedDockAreas() const
static CDockManager::ConfigFlags StaticConfigFlags
Definition: DockManager.cpp:92
CDockContainerWidget * dockContainer() const
virtual bool event(QEvent *e) override
QMap< QString, QByteArray > Perspectives
void flagAsUnassigned()
Definition: DockWidget.cpp:568
void registerDockContainer(CDockContainerWidget *DockContainer)
If enabled, the XML writer automatically adds line-breaks and indentation to empty sections between e...
Definition: DockManager.h:163
QList< int > splitterSizes(CDockAreaWidget *ContainedArea) const
const QList< CFloatingDockContainer * > floatingWidgets() const
CurrentVersion.
Definition: DockManager.cpp:89
bool isClosed() const
Definition: DockWidget.cpp:431
void perspectivesRemoved()
void internalSetCurrentDockWidget(CDockWidget *DockWidget)
bool restoreState(const QByteArray &state, int version=0)
bool restoreState(const QByteArray &state, int version)
dock widget can be dragged into a floating window
Definition: DockWidget.h:152
static const char *const DirtyProperty
Definition: ads_globals.h:135
Version1.
Definition: DockManager.cpp:88
static void setConfigFlags(const ConfigFlags Flags)
void emitTopLevelChanged(bool Floating)
Definition: DockWidget.cpp:784
bool checkFormat(const QByteArray &state, int version)
DockManagerPrivate(CDockManager *_public)
void setDockWidgetFocused(CDockWidget *DockWidget)
void setFileVersion(int FileVersion)
void setCurrentIndex(int index)
void viewToggled(bool Open)
#define ADS_PRINT(s)
Definition: ads_globals.h:60
void setDockWidgetFocused(CDockWidget *focusedNow)
friend class CFloatingDockContainer
Definition: DockManager.h:75
static CIconProvider & iconProvider()
DockManagerPrivate * d
private data (pimpl)
Definition: DockManager.h:73
CDockAreaWidget * addDockWidgetTabToArea(CDockWidget *Dockwidget, CDockAreaWidget *DockAreaWidget)
Declaration of CDockSplitter.
CDockAreaWidget * addDockWidgetTab(DockWidgetArea area, CDockWidget *Dockwidget)
const QList< CDockContainerWidget * > dockContainers() const
static void setConfigFlag(eConfigFlag Flag, bool On=true)
void removeDockWidget(CDockWidget *Dockwidget)
Declaration of.
Declaration of CIconProvider.
void removeDockWidget(CDockWidget *Dockwidget)
void setFlag(T &Flags, typename T::enum_type flag, bool on=true)
Definition: ads_globals.h:230
CDockAreaWidget * setCentralWidget(CDockWidget *widget)
void notifyWidgetOrAreaRelocation(QWidget *RelocatedWidget)
CDockWidget * focusedDockWidget() const
virtual ~CDockManager() override
version
Definition: setup.py:18
CDockFocusController * FocusController
QMenu * viewMenu() const
void removePerspective(const QString &Name)
CFloatingDockContainer * addDockWidgetFloating(CDockWidget *Dockwidget)
dock widget is movable and can be moved to a new position in the current dock container ...
Definition: DockWidget.h:151
QVector< CFloatingDockContainer * > UninitializedFloatingWidgets
Declaration of CDockingStateReader.
bool restoreState(CDockingStateReader &Stream, bool Testing)
Declaration of CFloatingWidgetTitleBar class.
Declaration of CDockAreaWidget class.
QList< CFloatingDockContainer * > FloatingWidgets
void dockWidgetAdded(ads::CDockWidget *DockWidget)
CDockOverlay * containerOverlay() const
QMap< QString, CDockWidget * > dockWidgetsMap() const
void loadPerspectives(QSettings &Settings)
static const bool Restore
Definition: ads_globals.h:133
static int startDragDistance()
Declaration of CDockWidget class.
QMap< QString, CDockWidget * > DockWidgetsMap
void perspectiveOpened(const QString &PerspectiveName)
bool restoreStateFromXml(const QByteArray &state, int version, bool Testing=internal::Restore)
void openPerspective(const QString &PerspectiveName)
void addActionToMenu(QAction *Action, QMenu *Menu, bool InsertSorted)
void setViewMenuInsertionOrder(eViewMenuInsertionOrder Order)
QStringList perspectiveNames() const
void dockWidgetAboutToBeRemoved(ads::CDockWidget *DockWidget)
QByteArray saveState(int version=0) const
Declaration of CDockManager class.
void removeFloatingWidget(CFloatingDockContainer *FloatingWidget)
CDockOverlay * dockAreaOverlay() const
CDockAreaWidget * addDockWidget(DockWidgetArea area, CDockWidget *Dockwidget, CDockAreaWidget *DockAreaWidget=nullptr)
void removePerspectives(const QStringList &Names)
QMap< QString, QMenu * > ViewMenuGroups
QList< CDockContainerWidget * > Containers
InitialVersion.
Definition: DockManager.cpp:87
CDockAreaWidget * dockAreaWidget() const
Definition: DockWidget.cpp:394
void openingPerspective(const QString &PerspectiveName)
CDockWidget * findDockWidget(const QString &ObjectName) const
Declaration of CDockAreaTitleBar class.
CDockManager * _this
Definition: DockManager.cpp:99
void removeDockContainer(CDockContainerWidget *DockContainer)
void setSplitterSizes(CDockAreaWidget *ContainedArea, const QList< int > &sizes)
static const char *const ClosedProperty
Definition: ads_globals.h:134
static void initResource()
Definition: DockManager.cpp:74
void notifyWidgetOrAreaRelocation(QWidget *RelocatedWidget)
void addPerspective(const QString &UniquePrespectiveName)
bool restoreContainer(int Index, CDockingStateReader &stream, bool Testing)


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:47:34