mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-12-25 23:51:33 +08:00
3969d28d92
* Add dockdepth1 example * Fix compilation (include assert.h) * Replace dockdepth1 by dockindock * Fix crash when dockindock example is closed. Due to code in dockindock supposed to fix memory leaks: now leaks were fixed in CDockManager (https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/307), the code from dockindock ends up deleting objects already deleted by parent.
335 lines
9.1 KiB
C++
335 lines
9.1 KiB
C++
#include "dockindockmanager.h"
|
|
#include "dockindock.h"
|
|
|
|
#include "DockAreaWidget.h"
|
|
|
|
#include <QMenu>
|
|
#include <QInputDialog>
|
|
#include <QSettings>
|
|
#include <QMessageBox>
|
|
|
|
#include <assert.h>
|
|
|
|
using namespace QtAdsUtl;
|
|
|
|
/////////////////////////////////////
|
|
// DockInDockManager
|
|
/////////////////////////////////////
|
|
DockInDockManager::DockInDockManager( DockInDockWidget& parent ) :
|
|
baseClass( &parent ),
|
|
m_parent( parent )
|
|
{
|
|
|
|
}
|
|
|
|
DockInDockManager::~DockInDockManager()
|
|
{
|
|
|
|
}
|
|
|
|
void DockInDockManager::fillViewMenu( QMenu* menu, const std::vector<DockInDockManager*>& moveTo )
|
|
{
|
|
auto widgetsMap = dockWidgetsMap();
|
|
for ( auto iter = widgetsMap.begin(); iter != widgetsMap.end(); ++iter )
|
|
{
|
|
auto widget = iter.value()->widget();
|
|
auto action = iter.value()->toggleViewAction();
|
|
|
|
DockInDockWidget* asMgr = dynamic_cast<DockInDockWidget*>( widget );
|
|
if ( asMgr )
|
|
{
|
|
auto subMenu = menu->addMenu( iter.key() );
|
|
|
|
subMenu->addAction( action );
|
|
subMenu->addSeparator();
|
|
|
|
asMgr->setupMenu( subMenu, moveTo );
|
|
}
|
|
else
|
|
{
|
|
menu->addAction(action);
|
|
}
|
|
}
|
|
|
|
if ( parent().canCreateNewGroups() )
|
|
{
|
|
// see how this works, to create it in the right place,
|
|
// and also to have load perspective work when some groups are missing
|
|
menu->addSeparator();
|
|
menu->addAction( new QtAdsUtl::CreateChildDockAction( m_parent, menu ) );
|
|
|
|
if ( parent().getTopLevelDockWidget()->getManager() != this )
|
|
menu->addAction( new QtAdsUtl::DestroyGroupAction( &m_parent, menu ) );
|
|
}
|
|
}
|
|
|
|
void DockInDockManager::fillMoveMenu( QMenu* menu, const std::vector<DockInDockManager*>& moveTo )
|
|
{
|
|
auto widgetsMap = dockWidgetsMap();
|
|
for ( auto iter = widgetsMap.begin(); iter != widgetsMap.end(); ++iter )
|
|
{
|
|
auto subMenu = menu->addMenu( iter.key() );
|
|
|
|
for ( auto mgr : moveTo )
|
|
{
|
|
// iterate over all possible target managers
|
|
if ( mgr == this )
|
|
{
|
|
// if dock is already in mgr, no reason to move it there
|
|
}
|
|
else if ( mgr == dockInAManager( iter.value() ) )
|
|
{
|
|
// if target is the group itself, can't move it there, would make no sense
|
|
}
|
|
else
|
|
{
|
|
subMenu->addAction( new MoveDockWidgetAction( iter.value(), mgr, subMenu ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DockInDockManager::addPerspectiveRec( const QString& name )
|
|
{
|
|
std::vector<DockInDockManager*> managers = allManagers( true, true );
|
|
|
|
for ( auto child : managers )
|
|
child->addPerspective( name );
|
|
}
|
|
|
|
void DockInDockManager::openPerspectiveRec( const QString& name )
|
|
{
|
|
std::vector<DockInDockManager*> managers = allManagers( true, true );
|
|
|
|
for ( auto child : managers )
|
|
child->openPerspective( name );
|
|
}
|
|
|
|
QString DockInDockManager::getGroupName()
|
|
{
|
|
return parent().objectName();
|
|
}
|
|
|
|
#define CHILD_PREFIX QString("Child-")
|
|
QString DockInDockManager::getPersistGroupName()
|
|
{
|
|
QString group = "Top";
|
|
if ( !getGroupName().isEmpty() )
|
|
group = CHILD_PREFIX + getGroupName();
|
|
return group;
|
|
}
|
|
|
|
QString DockInDockManager::getGroupNameFromPersistGroupName( QString persistGroupName )
|
|
{
|
|
if ( persistGroupName.startsWith( CHILD_PREFIX ) )
|
|
{
|
|
persistGroupName = persistGroupName.mid( CHILD_PREFIX.size() );
|
|
}
|
|
else
|
|
{
|
|
assert( false );
|
|
}
|
|
return persistGroupName;
|
|
}
|
|
|
|
void DockInDockManager::loadPerspectivesRec(QSettings& Settings)
|
|
{
|
|
std::vector<DockInDockManager*> children = allManagers( true, true );
|
|
|
|
for ( auto mgr : children )
|
|
{
|
|
Settings.beginGroup(mgr->getPersistGroupName());
|
|
mgr->loadPerspectives( Settings );
|
|
Settings.endGroup();
|
|
}
|
|
}
|
|
|
|
void DockInDockManager::savePerspectivesRec(QSettings& Settings) const
|
|
{
|
|
std::vector<DockInDockManager*> children = allManagers( true, true );
|
|
|
|
for ( auto mgr : children )
|
|
{
|
|
Settings.beginGroup(mgr->getPersistGroupName());
|
|
mgr->savePerspectives( Settings );
|
|
Settings.endGroup();
|
|
}
|
|
}
|
|
|
|
void DockInDockManager::removePerspectivesRec()
|
|
{
|
|
std::vector<DockInDockManager*> managers = allManagers( true, true );
|
|
|
|
for ( auto child : managers )
|
|
child->removePerspectives( child->perspectiveNames() );
|
|
}
|
|
|
|
DockInDockManager* DockInDockManager::dockInAManager( ads::CDockWidget* widget )
|
|
{
|
|
DockInDockWidget* dockWidget = widget ? dynamic_cast<DockInDockWidget*>( widget->widget() ) : NULL;
|
|
return ( dockWidget ) ? dockWidget->getManager() : NULL;
|
|
}
|
|
|
|
void DockInDockManager::childManagers( std::vector<DockInDockManager*>& managers, bool rec ) const
|
|
{
|
|
auto widgets = getWidgetsInGUIOrder();
|
|
for ( auto widget : widgets )
|
|
{
|
|
DockInDockManager* asMgr = dockInAManager( widget );
|
|
if ( asMgr )
|
|
{
|
|
managers.push_back( asMgr );
|
|
if ( rec )
|
|
asMgr->childManagers( managers, rec );
|
|
}
|
|
}
|
|
}
|
|
|
|
std::vector<DockInDockManager*> DockInDockManager::allManagers( bool includeThis, bool rec ) const
|
|
{
|
|
std::vector<DockInDockManager*> managers;
|
|
if ( includeThis )
|
|
managers.push_back( const_cast<DockInDockManager*>(this) );
|
|
childManagers( managers, rec );
|
|
return managers;
|
|
}
|
|
|
|
std::vector<std::pair<DockInDockManager*,ads::CDockWidget*>> DockInDockManager::allDockWidgets( bool includeThis, bool rec ) const
|
|
{
|
|
std::vector<std::pair<DockInDockManager*,ads::CDockWidget*>> widgets;
|
|
for ( auto mgr : allManagers( includeThis, rec ) )
|
|
{
|
|
for ( auto widget : mgr->getWidgetsInGUIOrder() )
|
|
widgets.push_back( std::make_pair(mgr, widget) );
|
|
}
|
|
return widgets;
|
|
}
|
|
|
|
QMap<QString,QStringList> DockInDockManager::getGroupContents()
|
|
{
|
|
QMap<QString,QStringList> result;
|
|
std::vector<DockInDockManager*> managers = allManagers( true, true );
|
|
for ( auto mgr : managers )
|
|
{
|
|
result[mgr->getPersistGroupName()] = mgr->dockWidgetsMap().keys();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
ads::CDockAreaWidget* DockInDockManager::getInsertDefaultPos()
|
|
{
|
|
ads::CDockAreaWidget* defaultPos = NULL;
|
|
if ( dockAreaCount() != 0 )
|
|
defaultPos = dockArea(dockAreaCount()-1);
|
|
return defaultPos;
|
|
}
|
|
|
|
std::vector<ads::CDockWidget*> DockInDockManager::getWidgetsInGUIOrder() const
|
|
{
|
|
std::vector<ads::CDockWidget*> result;
|
|
result.reserve( dockWidgetsMap().size() );
|
|
for ( int i = 0; i != dockAreaCount(); ++i )
|
|
{
|
|
for ( auto widget : dockArea(i)->dockWidgets() )
|
|
result.push_back( widget );
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/////////////////////////////////////
|
|
// CreateChildDockAction
|
|
/////////////////////////////////////
|
|
CreateChildDockAction::CreateChildDockAction( DockInDockWidget& dockInDock, QMenu* menu ) :
|
|
QAction("New group...", menu),
|
|
m_dockInDock( dockInDock )
|
|
{
|
|
connect( this, SIGNAL(triggered()), this, SLOT(createGroup()) );
|
|
}
|
|
|
|
void CreateChildDockAction::createGroup()
|
|
{
|
|
QString name = "";
|
|
while ( true )
|
|
{
|
|
bool ok = false;
|
|
name = QInputDialog::getText( NULL, this->text(), "Enter group name", QLineEdit::Normal, name, &ok );
|
|
if ( ok )
|
|
{
|
|
QString error = "";
|
|
if ( m_dockInDock.getTopLevelDockWidget() )
|
|
error = m_dockInDock.getTopLevelDockWidget()->getGroupNameError( name );
|
|
else
|
|
assert( false );
|
|
|
|
if ( error.isEmpty() )
|
|
{
|
|
ads::CDockAreaWidget* insertPos = NULL;
|
|
m_dockInDock.createGroup( name, insertPos );
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
QMessageBox::critical( NULL, "Error", error );
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////
|
|
// DestroyGroupAction
|
|
/////////////////////////////////////
|
|
DestroyGroupAction::DestroyGroupAction( DockInDockWidget* widget, QMenu* menu ) :
|
|
QAction("Destroy " + widget->getManager()->getGroupName(), menu),
|
|
m_widget( widget )
|
|
{
|
|
connect( this, SIGNAL(triggered()), this, SLOT(destroyGroup()) );
|
|
}
|
|
|
|
void DestroyGroupAction::destroyGroup()
|
|
{
|
|
m_widget->getTopLevelDockWidget()->destroyGroup( m_widget );
|
|
}
|
|
|
|
|
|
/////////////////////////////////////
|
|
// MoveDockWidgetAction
|
|
/////////////////////////////////////
|
|
MoveDockWidgetAction::MoveDockWidgetAction( ads::CDockWidget* widget, DockInDockManager* moveTo, QMenu* menu ) :
|
|
QAction(menu),
|
|
m_widget( widget ),
|
|
m_moveTo( moveTo )
|
|
{
|
|
if ( moveTo->parent().isTopLevel() )
|
|
{
|
|
setText( "To top" );
|
|
}
|
|
else
|
|
{
|
|
setText( "To " + moveTo->parent().objectName() );
|
|
}
|
|
connect( this, SIGNAL(triggered()), this, SLOT(move()) );
|
|
}
|
|
|
|
void MoveDockWidgetAction::move()
|
|
{
|
|
move( m_widget, m_moveTo );
|
|
}
|
|
|
|
void MoveDockWidgetAction::move( ads::CDockWidget* widget, DockInDockManager* moveTo )
|
|
{
|
|
if ( widget && moveTo )
|
|
{
|
|
widget->dockManager()->removeDockWidget( widget );
|
|
moveTo->addDockWidget(ads::CenterDockWidgetArea, widget, moveTo->getInsertDefaultPos());
|
|
}
|
|
else
|
|
{
|
|
assert( false );
|
|
}
|
|
}
|