|
| 1 | +#include "innertabs.h" |
| 2 | + |
| 3 | +#include "DockAreaWidget.h" |
| 4 | + |
| 5 | +#include <QInputDialog> |
| 6 | +#include <QMenu> |
| 7 | + |
| 8 | +///////////////////////////////////// |
| 9 | +// DockManagerWithInnerTabs |
| 10 | +///////////////////////////////////// |
| 11 | +void deleteAllChildren( ads::CDockContainerWidget* areaWidget ) |
| 12 | +{ |
| 13 | + // fix crash on close by manually deleting children |
| 14 | + // maybe due to this issue: https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/307 |
| 15 | + |
| 16 | + std::vector<ads::CDockAreaWidget*> areas; |
| 17 | + for ( int i = 0; i != areaWidget->dockAreaCount(); ++i ) |
| 18 | + { |
| 19 | + areas.push_back( areaWidget->dockArea(i) ); |
| 20 | + } |
| 21 | + |
| 22 | + for ( auto area : areas ) |
| 23 | + { |
| 24 | + for ( auto widget : area->dockWidgets() ) |
| 25 | + { |
| 26 | + ads::CDockContainerWidget* subArea = dynamic_cast<ads::CDockContainerWidget*>( widget->widget() ); |
| 27 | + if ( subArea ) |
| 28 | + deleteAllChildren( subArea ); |
| 29 | + delete widget; |
| 30 | + } |
| 31 | + |
| 32 | + delete area; |
| 33 | + } |
| 34 | +} |
| 35 | + |
| 36 | +DockManagerWithInnerTabs::~DockManagerWithInnerTabs() |
| 37 | +{ |
| 38 | + deleteAllChildren( this ); |
| 39 | +} |
| 40 | + |
| 41 | +std::pair<ads::CDockWidget*,ads::CDockContainerWidget*> DockManagerWithInnerTabs::createGroup( const QString& groupName, ads::CDockAreaWidget*& insertPos ) |
| 42 | +{ |
| 43 | + ads::CDockWidget* groupedDockWidget = new ads::CDockWidget(groupName); |
| 44 | + |
| 45 | + ads::CDockContainerWidget* groupManager = new ads::CDockContainerWidget(this); |
| 46 | + groupedDockWidget->setWidget(groupManager); |
| 47 | + |
| 48 | + insertPos = this->addDockWidget(ads::CenterDockWidgetArea, groupedDockWidget, insertPos); |
| 49 | + |
| 50 | + return { groupedDockWidget, groupManager }; |
| 51 | +} |
| 52 | + |
| 53 | +void DockManagerWithInnerTabs::attachViewMenu( QMenu* menu ) |
| 54 | +{ |
| 55 | + connect( menu, SIGNAL(aboutToShow()), this, SLOT(autoFillAttachedViewMenu()) ); |
| 56 | +} |
| 57 | + |
| 58 | +void DockManagerWithInnerTabs::autoFillAttachedViewMenu() |
| 59 | +{ |
| 60 | + QMenu* menu = dynamic_cast<QMenu*>( QObject::sender() ); |
| 61 | + |
| 62 | + if ( menu ) |
| 63 | + { |
| 64 | + menu->clear(); |
| 65 | + setupViewMenu( menu ); |
| 66 | + } |
| 67 | + else |
| 68 | + { |
| 69 | + assert( false ); |
| 70 | + } |
| 71 | +} |
| 72 | + |
| 73 | +bool SortFunc( ads::CDockWidget* left, ads::CDockWidget* right ) |
| 74 | +{ |
| 75 | + if ( left->windowTitle() == right->windowTitle() ) |
| 76 | + { |
| 77 | + assert( false ); |
| 78 | + return left < right; |
| 79 | + } |
| 80 | + else |
| 81 | + { |
| 82 | + return left->windowTitle() < right->windowTitle(); |
| 83 | + } |
| 84 | +} |
| 85 | + |
| 86 | +void DockManagerWithInnerTabs::setupMenu( QMenu* menu, ads::CDockContainerWidget* areaWidget ) |
| 87 | +{ |
| 88 | + std::vector<ads::CDockWidget*> widgets; |
| 89 | + |
| 90 | + ads::CDockManager* dockManager = dynamic_cast<ads::CDockManager*>( areaWidget ); |
| 91 | + if ( dockManager ) |
| 92 | + { |
| 93 | + for ( ads::CFloatingDockContainer* floating : dockManager->floatingWidgets() ) |
| 94 | + { |
| 95 | + for ( auto floated : floating->dockWidgets() ) |
| 96 | + widgets.push_back( floated ); |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + for ( int i = 0; i != areaWidget->dockAreaCount(); ++i ) |
| 101 | + { |
| 102 | + for ( auto docked : areaWidget->dockArea(i)->dockWidgets() ) |
| 103 | + widgets.push_back( docked ); |
| 104 | + } |
| 105 | + |
| 106 | + std::sort( widgets.begin(), widgets.end(), SortFunc ); |
| 107 | + |
| 108 | + for ( auto widget : widgets ) |
| 109 | + { |
| 110 | + auto action = widget->toggleViewAction(); |
| 111 | + |
| 112 | + ads::CDockContainerWidget* subArea = dynamic_cast<ads::CDockContainerWidget*>( widget->widget() ); |
| 113 | + if ( subArea ) |
| 114 | + { |
| 115 | + auto subMenu = menu->addMenu( widget->windowTitle() ); |
| 116 | + |
| 117 | + subMenu->addAction( action ); |
| 118 | + subMenu->addSeparator(); |
| 119 | + |
| 120 | + setupMenu( subMenu, subArea ); |
| 121 | + } |
| 122 | + else |
| 123 | + { |
| 124 | + menu->addAction(action); |
| 125 | + } |
| 126 | + } |
| 127 | + |
| 128 | + if ( dockManager ) |
| 129 | + { |
| 130 | + menu->addSeparator(); |
| 131 | + int count = areaWidget->dockAreaCount(); |
| 132 | + if ( count == 0 ) |
| 133 | + { |
| 134 | + menu->addAction( new CreateGroupAction( this, NULL, menu ) ); |
| 135 | + } |
| 136 | + else |
| 137 | + { |
| 138 | + for ( int i = 0; i != count; ++i ) |
| 139 | + { |
| 140 | + menu->addAction( new CreateGroupAction( this, areaWidget->dockArea(i), menu ) ); |
| 141 | + } |
| 142 | + } |
| 143 | + } |
| 144 | + // else, don't permit to add groups in groups |
| 145 | + // that would be nice, but it's not handled correctly upon drag/drop of a widget, it cannot be dropped in the inner docking area |
| 146 | +} |
| 147 | + |
| 148 | +void DockManagerWithInnerTabs::setupViewMenu( QMenu* menu ) |
| 149 | +{ |
| 150 | + setupMenu( menu, this ); |
| 151 | +} |
| 152 | + |
| 153 | +///////////////////////////////////// |
| 154 | +// CreateGroupAction |
| 155 | +///////////////////////////////////// |
| 156 | +CreateGroupAction::CreateGroupAction( DockManagerWithInnerTabs* manager, ads::CDockAreaWidget* insertPos, QMenu* menu ) : |
| 157 | + QAction("New group...", menu), |
| 158 | + m_manager( manager), |
| 159 | + m_insertPos( insertPos ) |
| 160 | +{ |
| 161 | + connect( this, SIGNAL(triggered()), this, SLOT(createGroup()) ); |
| 162 | +} |
| 163 | + |
| 164 | +void CreateGroupAction::createGroup() |
| 165 | +{ |
| 166 | + QString name = QInputDialog::getText( NULL, text(), "Enter group name" ); |
| 167 | + if ( !name.isEmpty() ) |
| 168 | + { |
| 169 | + m_manager->createGroup( name, m_insertPos ); |
| 170 | + } |
| 171 | +} |
0 commit comments