Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
487e23e190 | ||
|
|
511132ee4f | ||
|
|
edc89555bc | ||
|
|
ad30211dae | ||
|
|
48406da6ea | ||
|
|
aff0bd6e25 | ||
|
|
3969d28d92 | ||
|
|
b39cd2d81b | ||
|
|
0e8e563654 | ||
|
|
2f041a0eed | ||
|
|
ffa0105d3e | ||
|
|
6179832a2b |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -383,3 +383,4 @@ FodyWeavers.xsd
|
||||
/ build
|
||||
/Settings.ini
|
||||
.vscode/settings.json
|
||||
/.settings
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
<configuration id="cdt.managedbuild.toolchain.gnu.mingw.base.1119687795" name="Default">
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser" keep-relative-paths="false" name="CDT GCC Build Output Parser" parameter="(g?cc)|([gc]\+\+)|(clang)" prefer-non-shared="true"/>
|
||||
<provider class="org.eclipse.cdt.managedbuilder.internal.language.settings.providers.GCCBuiltinSpecsDetectorMinGW" console="false" env-hash="-1242828358748104657" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetectorMinGW" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings MinGW" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
</extension>
|
||||
</configuration>
|
||||
</project>
|
||||
@@ -354,7 +354,7 @@ Taken from the [Qt Blog](https://www.qt.io/blog/qt-design-studio-1.5-beta-releas
|
||||
|
||||
> The most obvious change in [Qt Design Studio 1.5](https://www.qt.io/blog/qt-design-studio-1.5-beta-released) is the integration of dock widgets using the Qt Advanced Docking System. This allows the user to fully customize the workspace and also to undock any view into its own top level window. This especially improves the usability when using multiple screens.
|
||||
|
||||

|
||||
[](https://youtu.be/za9KBWcFXEw?t=84)
|
||||
|
||||
### [QmixElements](https://www.cetoni.com/products/qmixelements/)
|
||||
|
||||
|
||||
23
ads.pri
23
ads.pri
@@ -1,23 +1,16 @@
|
||||
|
||||
lessThan(QT_MAJOR_VERSION, 6) {
|
||||
CONFIG(debug, debug|release){
|
||||
win32 {
|
||||
LIBS += -lqtadvanceddockingd
|
||||
}
|
||||
else:mac {
|
||||
LIBS += -lqtadvanceddocking_debug
|
||||
}
|
||||
else {
|
||||
LIBS += -lqtadvanceddocking
|
||||
}
|
||||
CONFIG(debug, debug|release){
|
||||
win32 {
|
||||
LIBS += -lqtadvanceddockingd
|
||||
}
|
||||
else{
|
||||
else:mac {
|
||||
LIBS += -lqtadvanceddocking_debug
|
||||
}
|
||||
else {
|
||||
LIBS += -lqtadvanceddocking
|
||||
}
|
||||
}
|
||||
else {
|
||||
# qt$$qtLibraryTarget(qtadvanceddocking) does not produce an advanceddockingd.dll file on Windows
|
||||
# for Qt6 - I don't know if this is a bug and I have to investigate
|
||||
else{
|
||||
LIBS += -lqtadvanceddocking
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(ads_demo VERSION ${VERSION_SHORT})
|
||||
|
||||
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
if(WIN32)
|
||||
find_package(Qt5 5.5 COMPONENTS AxContainer REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
if(WIN32 AND QT_VERSION_MAJOR LESS 6)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS AxContainer REQUIRED)
|
||||
endif()
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(ads_demo_SRCS
|
||||
@@ -16,9 +17,11 @@ set(ads_demo_SRCS
|
||||
)
|
||||
add_executable(AdvancedDockingSystemDemo WIN32 ${ads_demo_SRCS})
|
||||
target_include_directories(AdvancedDockingSystemDemo PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../src")
|
||||
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||
if(WIN32)
|
||||
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt5::AxContainer)
|
||||
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
if(WIN32 AND QT_VERSION_MAJOR LESS 6)
|
||||
target_link_libraries(AdvancedDockingSystemDemo PUBLIC Qt${QT_VERSION_MAJOR}::AxContainer)
|
||||
endif()
|
||||
target_link_libraries(AdvancedDockingSystemDemo PRIVATE qtadvanceddocking)
|
||||
set_target_properties(AdvancedDockingSystemDemo PROPERTIES
|
||||
|
||||
BIN
doc/showcase_qt_design_studio_video.png
Normal file
BIN
doc/showcase_qt_design_studio_video.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 816 KiB |
@@ -4,4 +4,5 @@ add_subdirectory(simple)
|
||||
add_subdirectory(sidebar)
|
||||
add_subdirectory(deleteonclose)
|
||||
add_subdirectory(centralwidget)
|
||||
add_subdirectory(emptydockarea)
|
||||
add_subdirectory(emptydockarea)
|
||||
add_subdirectory(dockindock)
|
||||
@@ -1,6 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(ads_example_centralwidget VERSION ${VERSION_SHORT})
|
||||
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
add_executable(CentralWidgetExample WIN32
|
||||
main.cpp
|
||||
@@ -9,7 +10,9 @@ add_executable(CentralWidgetExample WIN32
|
||||
)
|
||||
target_include_directories(CentralWidgetExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(CentralWidgetExample PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(CentralWidgetExample PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||
target_link_libraries(CentralWidgetExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
set_target_properties(CentralWidgetExample PROPERTIES
|
||||
AUTOMOC ON
|
||||
AUTORCC ON
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(ads_example_deleteonclose VERSION ${VERSION_SHORT})
|
||||
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
add_executable(DeleteOnCloseTest WIN32
|
||||
main.cpp
|
||||
)
|
||||
target_include_directories(DeleteOnCloseTest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(DeleteOnCloseTest PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(DeleteOnCloseTest PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||
target_link_libraries(DeleteOnCloseTest PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
set_target_properties(DeleteOnCloseTest PROPERTIES
|
||||
AUTOMOC ON
|
||||
CXX_STANDARD 14
|
||||
|
||||
31
examples/dockindock/CMakeLists.txt
Normal file
31
examples/dockindock/CMakeLists.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(ads_example_dockindock VERSION ${VERSION_SHORT})
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
add_executable(DockInDockExample WIN32
|
||||
dockindock.cpp
|
||||
dockindockmanager.cpp
|
||||
perspectiveactions.cpp
|
||||
perspectives.cpp
|
||||
main.cpp
|
||||
mainframe.cpp
|
||||
)
|
||||
target_include_directories(DockInDockExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(DockInDockExample PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(DockInDockExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
set_target_properties(DockInDockExample PROPERTIES
|
||||
AUTOMOC ON
|
||||
AUTORCC ON
|
||||
AUTOUIC ON
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS OFF
|
||||
VERSION ${VERSION_SHORT}
|
||||
EXPORT_NAME "Qt Advanced Docking System Simple Example"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin"
|
||||
)
|
||||
296
examples/dockindock/dockindock.cpp
Normal file
296
examples/dockindock/dockindock.cpp
Normal file
@@ -0,0 +1,296 @@
|
||||
#include "dockindock.h"
|
||||
#include "perspectives.h"
|
||||
#include "dockindockmanager.h"
|
||||
#include "perspectiveactions.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QDir>
|
||||
#include <QVBoxLayout>
|
||||
#include <QMainWindow>
|
||||
#include <QMessageBox>
|
||||
#include <QInputDialog>
|
||||
|
||||
#include <set>
|
||||
#include <assert.h>
|
||||
|
||||
using namespace QtAdsUtl;
|
||||
|
||||
DockInDockWidget::DockInDockWidget( QWidget* parent, bool canCreateNewGroups, PerspectivesManager* perspectivesManager ) :
|
||||
DockInDockWidget( parent, (DockInDockWidget*)NULL, perspectivesManager )
|
||||
{
|
||||
m_canCreateNewGroups = canCreateNewGroups;
|
||||
m_topLevelDockWidget = this;
|
||||
}
|
||||
|
||||
DockInDockWidget::DockInDockWidget( QWidget* parent, DockInDockWidget* topLevelDockWidget, PerspectivesManager* perspectivesManager ) :
|
||||
baseClass( parent ),
|
||||
m_topLevelDockWidget( topLevelDockWidget ),
|
||||
m_canCreateNewGroups( (topLevelDockWidget) ? topLevelDockWidget->m_canCreateNewGroups : false ),
|
||||
m_perspectivesManager( perspectivesManager )
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins( 0,0,0,0 );
|
||||
layout->addWidget( m_mgr = new DockInDockManager(*this) );
|
||||
}
|
||||
|
||||
DockInDockWidget::~DockInDockWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ads::CDockAreaWidget* DockInDockWidget::addTabWidget( QWidget* widget, const QString& name, ads::CDockAreaWidget* after )
|
||||
{
|
||||
return addTabWidget( widget, name, QIcon(), after );
|
||||
}
|
||||
|
||||
ads::CDockAreaWidget* DockInDockWidget::addTabWidget( QWidget* widget, const QString& name, QIcon icon, ads::CDockAreaWidget* after )
|
||||
{
|
||||
for ( auto existing : getTopLevelDockWidget()->getManager()->allDockWidgets(true,true) )
|
||||
{
|
||||
if ( existing.second->objectName() == name )
|
||||
{
|
||||
QMessageBox::critical( this, "Error", "Name '" + name + "' already in use" );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(name);
|
||||
DockWidget->setWidget(widget);
|
||||
DockWidget->setIcon( icon );
|
||||
|
||||
// Add the dock widget to the top dock widget area
|
||||
return m_mgr->addDockWidget(ads::CenterDockWidgetArea, DockWidget, after);
|
||||
}
|
||||
|
||||
bool DockInDockWidget::isTopLevel()
|
||||
{
|
||||
return objectName().isEmpty();
|
||||
}
|
||||
|
||||
QString DockInDockWidget::getGroupNameError( const QString& groupName )
|
||||
{
|
||||
if ( groupName.isEmpty() )
|
||||
{
|
||||
return "Group must have a non-empty name";
|
||||
}
|
||||
|
||||
std::vector<DockInDockManager*> dockManagers = m_mgr->allManagers( true, true );
|
||||
for ( auto mgr : dockManagers )
|
||||
{
|
||||
if ( mgr->getGroupName() == groupName )
|
||||
return "Group name '" + groupName + "' already used";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
DockInDockWidget* DockInDockWidget::createGroup( const QString& groupName, ads::CDockAreaWidget*& insertPos )
|
||||
{
|
||||
return createGroup( groupName, QIcon(), insertPos );
|
||||
}
|
||||
|
||||
DockInDockWidget* DockInDockWidget::createGroup( const QString& groupName, QIcon icon, ads::CDockAreaWidget*& insertPos )
|
||||
{
|
||||
QString error = getGroupNameError( groupName );
|
||||
if ( !error.isEmpty() )
|
||||
{
|
||||
QMessageBox::critical( NULL, "Error", error );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DockInDockWidget* child = new DockInDockWidget( this, m_topLevelDockWidget, m_perspectivesManager );
|
||||
child->setObjectName( groupName );
|
||||
|
||||
ads::CDockWidget* DockWidget = new ads::CDockWidget(groupName);
|
||||
DockWidget->setWidget(child);
|
||||
DockWidget->setIcon(icon);
|
||||
|
||||
insertPos = m_mgr->addDockWidget(ads::CenterDockWidgetArea, DockWidget, insertPos);
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
void DockInDockWidget::destroyGroup( DockInDockWidget* widgetToRemove )
|
||||
{
|
||||
auto topLevelWidget = widgetToRemove->getTopLevelDockWidget();
|
||||
|
||||
if ( topLevelWidget && topLevelWidget != widgetToRemove )
|
||||
{
|
||||
// reaffect all child docks to top-level
|
||||
for ( auto dockwidget : widgetToRemove->getManager()->getWidgetsInGUIOrder() ) // don't use allDockWidgets to preserve sub-groups
|
||||
{
|
||||
MoveDockWidgetAction::move( dockwidget, topLevelWidget->getManager() );
|
||||
}
|
||||
assert( widgetToRemove->getManager()->allDockWidgets( true, true ).empty() );
|
||||
|
||||
// find widget's parent:
|
||||
for ( auto dockwidget : topLevelWidget->getManager()->allDockWidgets( true, true ) )
|
||||
{
|
||||
if ( dockwidget.second->widget() == widgetToRemove )
|
||||
{
|
||||
dockwidget.first->removeDockWidget( dockwidget.second );
|
||||
delete dockwidget.second;
|
||||
//delete widgetToRemove; automatically deleted when dockWidget is deleted
|
||||
widgetToRemove = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert( widgetToRemove == NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( false );
|
||||
}
|
||||
}
|
||||
|
||||
void DockInDockWidget::attachViewMenu( QMenu* menu )
|
||||
{
|
||||
connect( menu, SIGNAL(aboutToShow()), this, SLOT(autoFillAttachedViewMenu()) );
|
||||
}
|
||||
|
||||
void DockInDockWidget::autoFillAttachedViewMenu()
|
||||
{
|
||||
QMenu* menu = dynamic_cast<QMenu*>( QObject::sender() );
|
||||
|
||||
if ( menu )
|
||||
{
|
||||
menu->clear();
|
||||
setupViewMenu( menu );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( false );
|
||||
}
|
||||
}
|
||||
|
||||
void DockInDockWidget::setupViewMenu( QMenu* menu )
|
||||
{
|
||||
std::vector<DockInDockManager*> dockManagers = m_mgr->allManagers( true, true );
|
||||
|
||||
bool hasPerspectivesMenu = false;
|
||||
if ( getTopLevelDockWidget() == this )
|
||||
hasPerspectivesMenu = (m_perspectivesManager != NULL);
|
||||
else
|
||||
assert( false );
|
||||
|
||||
QMenu* organize = menu;
|
||||
if ( hasPerspectivesMenu )
|
||||
organize = menu->addMenu( "Organize" );
|
||||
|
||||
setupMenu( organize, dockManagers );
|
||||
|
||||
if ( hasPerspectivesMenu )
|
||||
{
|
||||
QMenu* perspectives = menu->addMenu( "Perspectives" );
|
||||
fillPerspectivesMenu( perspectives );
|
||||
}
|
||||
}
|
||||
|
||||
void DockInDockWidget::setupMenu( QMenu* menu, const std::vector<DockInDockManager*>& moveTo )
|
||||
{
|
||||
m_mgr->fillViewMenu( menu, moveTo );
|
||||
menu->addSeparator();
|
||||
auto moveMenu = menu->addMenu( "Move" );
|
||||
m_mgr->fillMoveMenu( moveMenu, moveTo );
|
||||
}
|
||||
|
||||
void DockInDockWidget::fillPerspectivesMenu( QMenu* menu )
|
||||
{
|
||||
menu->addAction( "Create perspective...", this, SLOT(createPerspective()) );
|
||||
|
||||
QStringList perspectiveNames;
|
||||
if ( m_perspectivesManager )
|
||||
perspectiveNames = m_perspectivesManager->perspectiveNames();
|
||||
|
||||
if ( !perspectiveNames.isEmpty() )
|
||||
{
|
||||
QMenu* load = menu->addMenu( "Load perspective" );
|
||||
for ( auto name : perspectiveNames )
|
||||
load->addAction( new LoadPerspectiveAction( load, name, *this ) );
|
||||
QMenu* remove = menu->addMenu( "Remove perspective" );
|
||||
for ( auto name : perspectiveNames )
|
||||
remove->addAction( new RemovePerspectiveAction( remove, name, *this ) );
|
||||
}
|
||||
}
|
||||
|
||||
void DockInDockWidget::setNewPerspectiveDefaultName( const QString& defaultName )
|
||||
{
|
||||
m_newPerspectiveDefaultName = defaultName;
|
||||
}
|
||||
|
||||
void DockInDockWidget::createPerspective()
|
||||
{
|
||||
if ( !m_perspectivesManager )
|
||||
return;
|
||||
|
||||
QString name = m_newPerspectiveDefaultName;
|
||||
if ( !m_newPerspectiveDefaultName.isEmpty() )
|
||||
{
|
||||
int index = 2;
|
||||
while ( m_perspectivesManager->perspectiveNames().contains( name ) )
|
||||
{
|
||||
name = m_newPerspectiveDefaultName + " (" + QString::number(index) + ")";
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
while ( true )
|
||||
{
|
||||
bool ok = false;
|
||||
name = QInputDialog::getText( NULL, "Create perspective", "Enter perspective name", QLineEdit::Normal, name, &ok );
|
||||
if ( ok )
|
||||
{
|
||||
if ( name.isEmpty() )
|
||||
{
|
||||
QMessageBox::critical( NULL, "Error", "Perspective name cannot be empty" );
|
||||
continue;
|
||||
}
|
||||
else if ( m_perspectivesManager->perspectiveNames().contains( name ) )
|
||||
{
|
||||
if ( QMessageBox::critical( NULL, "Error", "Perspective '" + name + "' already exists, overwrite it?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == QMessageBox::No )
|
||||
continue;
|
||||
}
|
||||
|
||||
m_perspectivesManager->addPerspective( name, *this );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dumpStatus( std::ostream& str, ads::CDockWidget* widget, const std::string& tab, std::string suffix )
|
||||
{
|
||||
DockInDockManager* asMgr = DockInDockManager::dockInAManager( widget );
|
||||
if ( asMgr )
|
||||
{
|
||||
asMgr->parent().dumpStatus( str, tab );
|
||||
}
|
||||
else
|
||||
{
|
||||
str << tab << widget->objectName().toStdString() << suffix << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void DockInDockWidget::dumpStatus( std::ostream& str, std::string tab )
|
||||
{
|
||||
str << tab << "Group: " << getManager()->getGroupName().toStdString() << std::endl;
|
||||
tab += " ";
|
||||
std::set<ads::CDockWidget*> visibleWidgets;
|
||||
for ( auto widget : getManager()->getWidgetsInGUIOrder() )
|
||||
{
|
||||
visibleWidgets.insert( widget );
|
||||
::dumpStatus( str, widget, tab, "" );
|
||||
}
|
||||
|
||||
for ( auto closed : getManager()->dockWidgetsMap() )
|
||||
{
|
||||
if ( visibleWidgets.find( closed ) == visibleWidgets.end() )
|
||||
{
|
||||
::dumpStatus( str, closed, tab, " (closed)" );
|
||||
}
|
||||
}
|
||||
}
|
||||
80
examples/dockindock/dockindock.h
Normal file
80
examples/dockindock/dockindock.h
Normal file
@@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QMap>
|
||||
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
|
||||
class QMenu;
|
||||
|
||||
namespace ads
|
||||
{
|
||||
class CDockAreaWidget;
|
||||
}
|
||||
|
||||
namespace QtAdsUtl
|
||||
{
|
||||
|
||||
class DockInDockManager;
|
||||
class PerspectivesManager;
|
||||
// tab of tab example for https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/306
|
||||
class DockInDockWidget : public QWidget
|
||||
{
|
||||
typedef QWidget baseClass;
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DockInDockWidget( QWidget* parent, bool canCreateNewGroups, PerspectivesManager* perspectivesManager );
|
||||
~DockInDockWidget() override;
|
||||
|
||||
ads::CDockAreaWidget* addTabWidget( QWidget* widget, const QString& name, ads::CDockAreaWidget* after );
|
||||
DockInDockWidget* createGroup( const QString& groupName, ads::CDockAreaWidget*& insertPos );
|
||||
|
||||
ads::CDockAreaWidget* addTabWidget( QWidget* widget, const QString& name, QIcon icon, ads::CDockAreaWidget* after );
|
||||
DockInDockWidget* createGroup( const QString& groupName, QIcon icon, ads::CDockAreaWidget*& insertPos );
|
||||
|
||||
QString getGroupNameError( const QString& groupName );
|
||||
void destroyGroup( DockInDockWidget* widget );
|
||||
|
||||
/** Manually fill a given view menu */
|
||||
void setupViewMenu( QMenu* menu );
|
||||
|
||||
/** Attach a view menu that will be automatically fill */
|
||||
void attachViewMenu( QMenu* menu );
|
||||
|
||||
bool isTopLevel();
|
||||
void setupMenu( QMenu* menu, const std::vector<DockInDockManager*>& moveTo );
|
||||
|
||||
inline DockInDockManager* getManager() { return m_mgr; }
|
||||
inline DockInDockWidget* getTopLevelDockWidget() { return m_topLevelDockWidget; }
|
||||
|
||||
inline bool canCreateNewGroups() const { return m_canCreateNewGroups; }
|
||||
|
||||
void dumpStatus( std::ostream& str, std::string tab = "" );
|
||||
|
||||
inline PerspectivesManager* getPerspectivesManager() { return m_perspectivesManager; }
|
||||
|
||||
void setNewPerspectiveDefaultName( const QString& defaultName );
|
||||
|
||||
private slots:
|
||||
void autoFillAttachedViewMenu();
|
||||
void createPerspective();
|
||||
|
||||
private:
|
||||
DockInDockManager* m_mgr;
|
||||
DockInDockWidget* m_topLevelDockWidget;
|
||||
|
||||
bool m_canCreateNewGroups;
|
||||
|
||||
DockInDockWidget( QWidget* parent, DockInDockWidget* topLevelDockWidget, PerspectivesManager* perspectivesManager );
|
||||
|
||||
PerspectivesManager* m_perspectivesManager;
|
||||
QString m_newPerspectiveDefaultName;
|
||||
|
||||
void fillPerspectivesMenu( QMenu* menu );
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
35
examples/dockindock/dockindock.pro
Normal file
35
examples/dockindock/dockindock.pro
Normal file
@@ -0,0 +1,35 @@
|
||||
ADS_OUT_ROOT = $${OUT_PWD}/../..
|
||||
|
||||
QT += core gui widgets
|
||||
|
||||
TARGET = DockInDock
|
||||
DESTDIR = $${ADS_OUT_ROOT}/lib
|
||||
TEMPLATE = app
|
||||
CONFIG += c++14
|
||||
CONFIG += debug_and_release
|
||||
adsBuildStatic {
|
||||
DEFINES += ADS_STATIC
|
||||
}
|
||||
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
SOURCES += \
|
||||
dockindock.cpp \
|
||||
dockindockmanager.cpp \
|
||||
perspectiveactions.cpp \
|
||||
perspectives.cpp \
|
||||
main.cpp \
|
||||
mainframe.cpp
|
||||
|
||||
HEADERS += \
|
||||
dockindock.h \
|
||||
dockindockmanager.h \
|
||||
perspectiveactions.h \
|
||||
perspectives.h \
|
||||
mainframe.h
|
||||
|
||||
LIBS += -L$${ADS_OUT_ROOT}/lib
|
||||
include(../../ads.pri)
|
||||
INCLUDEPATH += ../../src
|
||||
DEPENDPATH += ../../src
|
||||
|
||||
334
examples/dockindock/dockindockmanager.cpp
Normal file
334
examples/dockindock/dockindockmanager.cpp
Normal file
@@ -0,0 +1,334 @@
|
||||
#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 );
|
||||
}
|
||||
}
|
||||
96
examples/dockindock/dockindockmanager.h
Normal file
96
examples/dockindock/dockindockmanager.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
#include "DockManager.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QMap>
|
||||
|
||||
namespace QtAdsUtl
|
||||
{
|
||||
|
||||
class DockInDockWidget;
|
||||
class DockInDockManager : public ads::CDockManager
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
typedef ads::CDockManager baseClass;
|
||||
|
||||
public:
|
||||
DockInDockManager( DockInDockWidget& parent );
|
||||
~DockInDockManager() override;
|
||||
|
||||
void fillViewMenu( QMenu* menu, const std::vector<DockInDockManager*>& moveTo );
|
||||
void fillMoveMenu( QMenu* menu, const std::vector<DockInDockManager*>& moveTo );
|
||||
|
||||
void addPerspectiveRec( const QString& name );
|
||||
void openPerspectiveRec( const QString& name );
|
||||
void removePerspectivesRec();
|
||||
void loadPerspectivesRec(QSettings& Settings);
|
||||
void savePerspectivesRec(QSettings& Settings) const;
|
||||
|
||||
static DockInDockManager* dockInAManager( ads::CDockWidget* widget );
|
||||
|
||||
inline DockInDockWidget& parent() { return m_parent; }
|
||||
|
||||
void childManagers( std::vector<DockInDockManager*>& managers, bool rec ) const;
|
||||
std::vector<DockInDockManager*> allManagers( bool includeThis, bool rec ) const;
|
||||
std::vector<std::pair<DockInDockManager*,ads::CDockWidget*>> allDockWidgets( bool includeThis, bool rec ) const;
|
||||
|
||||
QString getGroupName();
|
||||
QString getPersistGroupName();
|
||||
static QString getGroupNameFromPersistGroupName( QString persistGroupName );
|
||||
|
||||
QMap<QString,QStringList> getGroupContents();
|
||||
|
||||
ads::CDockAreaWidget* getInsertDefaultPos();
|
||||
|
||||
std::vector<ads::CDockWidget*> getWidgetsInGUIOrder() const;
|
||||
|
||||
private:
|
||||
DockInDockWidget& m_parent;
|
||||
};
|
||||
|
||||
class CreateChildDockAction : public QAction
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CreateChildDockAction( DockInDockWidget& dockInDock, QMenu* menu );
|
||||
|
||||
public slots:
|
||||
void createGroup();
|
||||
|
||||
private:
|
||||
DockInDockWidget& m_dockInDock;
|
||||
};
|
||||
|
||||
class DestroyGroupAction : public QAction
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DestroyGroupAction( DockInDockWidget* widget, QMenu* menu );
|
||||
|
||||
public slots:
|
||||
void destroyGroup();
|
||||
|
||||
private:
|
||||
DockInDockWidget* m_widget;
|
||||
};
|
||||
|
||||
class MoveDockWidgetAction : public QAction
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MoveDockWidgetAction( ads::CDockWidget* widget, DockInDockManager* moveTo, QMenu* menu );
|
||||
|
||||
static void move( ads::CDockWidget* widget, DockInDockManager* moveTo );
|
||||
|
||||
public slots:
|
||||
void move();
|
||||
|
||||
private:
|
||||
ads::CDockWidget* m_widget;
|
||||
DockInDockManager* m_moveTo;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
11
examples/dockindock/main.cpp
Normal file
11
examples/dockindock/main.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <QApplication>
|
||||
#include "../../examples/simple/MainWindow.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
76
examples/dockindock/mainframe.cpp
Normal file
76
examples/dockindock/mainframe.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "mainframe.h"
|
||||
|
||||
#include "dockindock.h"
|
||||
#include "perspectives.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QSettings>
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
m_perspectivesManager( new QtAdsUtl::PerspectivesManager( "persist" ) )
|
||||
{
|
||||
resize( 400, 400 );
|
||||
|
||||
setCentralWidget( m_dockManager = new QtAdsUtl::DockInDockWidget(this,true,m_perspectivesManager.get()) );
|
||||
|
||||
m_dockManager->attachViewMenu( menuBar()->addMenu( "View" ) );
|
||||
|
||||
ads::CDockAreaWidget* previousDockWidget = NULL;
|
||||
for ( int i = 0; i != 3; ++i )
|
||||
{
|
||||
// Create example content label - this can be any application specific
|
||||
// widget
|
||||
QLabel* l = new QLabel();
|
||||
l->setWordWrap(true);
|
||||
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
|
||||
|
||||
previousDockWidget = m_dockManager->addTabWidget( l, "Top label " + QString::number(i), previousDockWidget );
|
||||
}
|
||||
|
||||
auto lastTopLevelDock = previousDockWidget;
|
||||
|
||||
for ( int j = 0; j != 2; ++j )
|
||||
{
|
||||
QtAdsUtl::DockInDockWidget* groupManager = m_dockManager->createGroup( "Group " + QString::number(j), lastTopLevelDock );
|
||||
|
||||
previousDockWidget = NULL;
|
||||
for ( int i = 0; i != 3; ++i )
|
||||
{
|
||||
// Create example content label - this can be any application specific
|
||||
// widget
|
||||
QLabel* l = new QLabel();
|
||||
l->setWordWrap(true);
|
||||
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
|
||||
|
||||
previousDockWidget = groupManager->addTabWidget( l, "ZInner " + QString::number(j) + "/" + QString::number(i), previousDockWidget );
|
||||
}
|
||||
|
||||
// create sub-group
|
||||
auto subGroup = groupManager->createGroup( "SubGroup " + QString::number(j), previousDockWidget );
|
||||
previousDockWidget = NULL;
|
||||
for ( int i = 0; i != 3; ++i )
|
||||
{
|
||||
// Create example content label - this can be any application specific
|
||||
// widget
|
||||
QLabel* l = new QLabel();
|
||||
l->setWordWrap(true);
|
||||
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
|
||||
|
||||
previousDockWidget = subGroup->addTabWidget( l, "SubInner " + QString::number(j) + "/" + QString::number(i), previousDockWidget );
|
||||
}
|
||||
}
|
||||
|
||||
m_perspectivesManager->loadPerspectives();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
m_perspectivesManager->savePerspectives();
|
||||
}
|
||||
|
||||
30
examples/dockindock/mainframe.h
Normal file
30
examples/dockindock/mainframe.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QAction>
|
||||
#include <QSettings>
|
||||
|
||||
#include <memory>
|
||||
namespace QtAdsUtl
|
||||
{
|
||||
class DockInDockWidget;
|
||||
class PerspectivesManager;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
QtAdsUtl::DockInDockWidget* m_dockManager;
|
||||
std::unique_ptr<QtAdsUtl::PerspectivesManager> m_perspectivesManager;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
39
examples/dockindock/perspectiveactions.cpp
Normal file
39
examples/dockindock/perspectiveactions.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "perspectiveactions.h"
|
||||
#include "dockindock.h"
|
||||
#include "perspectives.h"
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
using namespace QtAdsUtl;
|
||||
|
||||
//////////////////////////////
|
||||
// LoadPerspectiveAction
|
||||
//////////////////////////////
|
||||
LoadPerspectiveAction::LoadPerspectiveAction( QMenu* parent, const QString& name, QtAdsUtl::DockInDockWidget& dockManager ) :
|
||||
QAction( name, parent ),
|
||||
name( name ),
|
||||
dockManager( dockManager )
|
||||
{
|
||||
connect( this, SIGNAL(triggered()), this, SLOT(load()) );
|
||||
}
|
||||
|
||||
void LoadPerspectiveAction::load()
|
||||
{
|
||||
dockManager.getPerspectivesManager()->openPerspective( name, dockManager );
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// RemovePerspectiveAction
|
||||
//////////////////////////////
|
||||
RemovePerspectiveAction::RemovePerspectiveAction( QMenu* parent, const QString& name, QtAdsUtl::DockInDockWidget& dockManager ) :
|
||||
QAction( name, parent ),
|
||||
name( name ),
|
||||
dockManager( dockManager )
|
||||
{
|
||||
connect( this, SIGNAL(triggered()), this, SLOT(remove()) );
|
||||
}
|
||||
|
||||
void RemovePerspectiveAction::remove()
|
||||
{
|
||||
dockManager.getPerspectivesManager()->removePerspective( name );
|
||||
}
|
||||
38
examples/dockindock/perspectiveactions.h
Normal file
38
examples/dockindock/perspectiveactions.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <QAction>
|
||||
|
||||
namespace QtAdsUtl
|
||||
{
|
||||
|
||||
class DockInDockWidget;
|
||||
class LoadPerspectiveAction : public QAction
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LoadPerspectiveAction( QMenu* parent, const QString& name, QtAdsUtl::DockInDockWidget& dockManager );
|
||||
|
||||
public slots:
|
||||
void load();
|
||||
|
||||
private:
|
||||
QString name;
|
||||
QtAdsUtl::DockInDockWidget& dockManager;
|
||||
};
|
||||
|
||||
class RemovePerspectiveAction : public QAction
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RemovePerspectiveAction( QMenu* parent, const QString& name, QtAdsUtl::DockInDockWidget& dockManager );
|
||||
|
||||
public slots:
|
||||
void remove();
|
||||
|
||||
private:
|
||||
QString name;
|
||||
QtAdsUtl::DockInDockWidget& dockManager;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
278
examples/dockindock/perspectives.cpp
Normal file
278
examples/dockindock/perspectives.cpp
Normal file
@@ -0,0 +1,278 @@
|
||||
#include "perspectives.h"
|
||||
#include "dockindock.h"
|
||||
#include "dockindockmanager.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define GROUP_PREFIX QString("Group")
|
||||
|
||||
using namespace QtAdsUtl;
|
||||
|
||||
PerspectivesManager::PerspectivesManager( const QString& perspectivesFolder ) :
|
||||
m_perspectivesFolder( perspectivesFolder )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PerspectivesManager::~PerspectivesManager()
|
||||
{
|
||||
// remove temp files:
|
||||
for ( auto perspective : m_perspectives )
|
||||
{
|
||||
QString fileName = perspective.settings->fileName();
|
||||
perspective.settings.reset();
|
||||
QFile::remove(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QStringList PerspectivesManager::perspectiveNames() const
|
||||
{
|
||||
return m_perspectives.keys();
|
||||
}
|
||||
|
||||
void PerspectivesManager::addPerspective( const QString& name, DockInDockWidget& widget )
|
||||
{
|
||||
if ( !m_perspectivesFolder.isEmpty() )
|
||||
{
|
||||
m_perspectives[name].settings = getSettingsObject( getSettingsFileName( name, true ) );
|
||||
m_perspectives[name].groups = widget.getManager()->getGroupContents();
|
||||
|
||||
// save perspective internally
|
||||
widget.getManager()->addPerspectiveRec( name );
|
||||
// store it in QSettings object
|
||||
widget.getManager()->savePerspectivesRec( *(m_perspectives[name].settings) );
|
||||
// remove internal perspectives
|
||||
widget.getManager()->removePerspectives( widget.getManager()->perspectiveNames() );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( false );
|
||||
}
|
||||
|
||||
emit perspectivesListChanged();
|
||||
}
|
||||
|
||||
|
||||
ads::CDockWidget* findWidget( QString name, const std::vector<DockInDockManager*>& managers )
|
||||
{
|
||||
for ( auto mgr : managers )
|
||||
{
|
||||
auto widget = mgr->findDockWidget(name);
|
||||
if ( widget )
|
||||
return widget;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void PerspectivesManager::openPerspective( const QString& name, DockInDockWidget& widget )
|
||||
{
|
||||
assert( widget.getTopLevelDockWidget() == &widget );
|
||||
|
||||
if ( !m_perspectivesFolder.isEmpty() )
|
||||
{
|
||||
if ( m_perspectives.contains( name ) )
|
||||
{
|
||||
emit openingPerspective();
|
||||
|
||||
if ( widget.canCreateNewGroups() )
|
||||
{
|
||||
auto curGroups = widget.getManager()->allManagers(true,true);
|
||||
for ( auto group : m_perspectives[name].groups.keys() )
|
||||
{
|
||||
bool found = false;
|
||||
for ( auto curgroup : curGroups )
|
||||
{
|
||||
if ( curgroup->getPersistGroupName() == group )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !found )
|
||||
{
|
||||
group = DockInDockManager::getGroupNameFromPersistGroupName( group );
|
||||
|
||||
// restore group in file but not in GUI yet
|
||||
ads::CDockAreaWidget* insertPos = NULL;
|
||||
widget.createGroup( group, insertPos );
|
||||
}
|
||||
}
|
||||
|
||||
curGroups = widget.getManager()->allManagers(false,true);
|
||||
for ( auto curgroup : curGroups )
|
||||
{
|
||||
if ( !m_perspectives[name].groups.keys().contains( curgroup->getPersistGroupName() ) )
|
||||
{
|
||||
widget.destroyGroup( &curgroup->parent() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto managers = widget.getManager()->allManagers(true,true);
|
||||
for ( auto group : m_perspectives[name].groups.keys() )
|
||||
{
|
||||
for ( auto mgr : managers )
|
||||
{
|
||||
if ( mgr->getPersistGroupName() == group )
|
||||
{
|
||||
for ( QString widgetName : m_perspectives[name].groups[group] )
|
||||
{
|
||||
ads::CDockWidget* widget = findWidget( widgetName, { mgr } );
|
||||
if ( widget )
|
||||
{
|
||||
// OK, widget is already in the good manager!
|
||||
}
|
||||
else
|
||||
{
|
||||
widget = findWidget( widgetName, managers );
|
||||
if ( widget )
|
||||
{
|
||||
// move dock widget in the same group as it used to be when perspective was saved
|
||||
// this guarantee load/open perspectives will work smartly
|
||||
MoveDockWidgetAction::move( widget, mgr );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// internally load perspectives from QSettings
|
||||
widget.getManager()->loadPerspectivesRec( *(m_perspectives[name].settings) );
|
||||
// load perspective (update GUI)
|
||||
widget.getManager()->openPerspectiveRec( name );
|
||||
// remove internal perspectives
|
||||
widget.getManager()->removePerspectives( widget.getManager()->perspectiveNames() );
|
||||
|
||||
emit openedPerspective();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( false );
|
||||
}
|
||||
}
|
||||
|
||||
void PerspectivesManager::removePerspectives()
|
||||
{
|
||||
m_perspectives.clear();
|
||||
emit perspectivesListChanged();
|
||||
}
|
||||
|
||||
void PerspectivesManager::removePerspective( const QString& name )
|
||||
{
|
||||
m_perspectives.remove( name );
|
||||
emit perspectivesListChanged();
|
||||
}
|
||||
|
||||
QString PerspectivesManager::getSettingsFileName( const QString& perspective, bool temp ) const
|
||||
{
|
||||
auto name = ( perspective.isEmpty() ) ? "perspectives.ini" : "perspective_" + perspective + (temp?".tmp":".ini");
|
||||
|
||||
return m_perspectivesFolder + "/" + name;
|
||||
}
|
||||
|
||||
std::shared_ptr<QSettings> PerspectivesManager::getSettingsObject( const QString& filePath ) const
|
||||
{
|
||||
return std::make_shared<QSettings>(filePath, QSettings::IniFormat);
|
||||
}
|
||||
|
||||
void PerspectivesManager::loadPerspectives()
|
||||
{
|
||||
if ( !m_perspectivesFolder.isEmpty() )
|
||||
{
|
||||
QDir().mkpath( m_perspectivesFolder );
|
||||
|
||||
m_perspectives.clear();
|
||||
|
||||
auto mainSettings = getSettingsObject( getSettingsFileName( "", false ) );
|
||||
std::string debug = mainSettings->fileName().toStdString();
|
||||
|
||||
int Size = mainSettings->beginReadArray("Perspectives");
|
||||
|
||||
for (int i = 0; i < Size; ++i)
|
||||
{
|
||||
mainSettings->setArrayIndex(i);
|
||||
QString perspective = mainSettings->value("Name").toString();
|
||||
|
||||
if ( !perspective.isEmpty() )
|
||||
{
|
||||
// load perspective file:
|
||||
auto toLoad = getSettingsFileName( perspective, false );
|
||||
auto loaded = getSettingsFileName( perspective, true );
|
||||
|
||||
#ifdef _DEBUG
|
||||
std::string debug1 = loaded.toStdString();
|
||||
std::string debug2 = toLoad.toStdString();
|
||||
#endif
|
||||
|
||||
QFile::remove( loaded );
|
||||
if ( !QFile::copy( toLoad, loaded ) )
|
||||
assert( false );
|
||||
|
||||
m_perspectives[perspective].settings = getSettingsObject( loaded );
|
||||
|
||||
// load group info:
|
||||
mainSettings->beginGroup(GROUP_PREFIX);
|
||||
for ( auto key : mainSettings->allKeys() )
|
||||
m_perspectives[perspective].groups[key] = mainSettings->value( key ).toStringList();
|
||||
mainSettings->endGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( false );
|
||||
}
|
||||
}
|
||||
|
||||
mainSettings->endArray();
|
||||
}
|
||||
|
||||
emit perspectivesListChanged();
|
||||
}
|
||||
|
||||
void PerspectivesManager::savePerspectives() const
|
||||
{
|
||||
if ( !m_perspectivesFolder.isEmpty() )
|
||||
{
|
||||
auto mainSettings = getSettingsObject( getSettingsFileName( "", false ) );
|
||||
|
||||
// Save list of perspective and group organization
|
||||
mainSettings->beginWriteArray("Perspectives", m_perspectives.size());
|
||||
int i = 0;
|
||||
for ( auto perspective : m_perspectives.keys() )
|
||||
{
|
||||
mainSettings->setArrayIndex(i);
|
||||
mainSettings->setValue("Name", perspective);
|
||||
mainSettings->beginGroup(GROUP_PREFIX);
|
||||
for ( auto group : m_perspectives[perspective].groups.keys() )
|
||||
{
|
||||
mainSettings->setValue( group, m_perspectives[perspective].groups[group] );
|
||||
}
|
||||
mainSettings->endGroup();
|
||||
++i;
|
||||
}
|
||||
mainSettings->endArray();
|
||||
|
||||
// Save perspectives themselves
|
||||
for ( auto perspectiveName : m_perspectives.keys() )
|
||||
{
|
||||
auto toSave = getSettingsFileName( perspectiveName, false );
|
||||
QSettings& settings = *(m_perspectives[perspectiveName].settings);
|
||||
settings.sync();
|
||||
|
||||
#ifdef _DEBUG
|
||||
std::string debug1 = settings.fileName().toStdString();
|
||||
std::string debug2 = toSave.toStdString();
|
||||
#endif
|
||||
|
||||
QFile::remove( toSave );
|
||||
if ( !QFile::copy( settings.fileName(), toSave ) )
|
||||
assert( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
59
examples/dockindock/perspectives.h
Normal file
59
examples/dockindock/perspectives.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class QMenu;
|
||||
class QSettings;
|
||||
|
||||
namespace QtAdsUtl
|
||||
{
|
||||
|
||||
class DockInDockWidget;
|
||||
class PerspectivesManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PerspectivesManager( const QString& perspectivesFolder );
|
||||
virtual ~PerspectivesManager();
|
||||
|
||||
QStringList perspectiveNames() const;
|
||||
|
||||
void addPerspective( const QString& name, DockInDockWidget& widget );
|
||||
void openPerspective( const QString& name, DockInDockWidget& widget );
|
||||
void removePerspectives();
|
||||
void removePerspective( const QString& name );
|
||||
|
||||
void loadPerspectives();
|
||||
void savePerspectives() const;
|
||||
|
||||
signals:
|
||||
void perspectivesListChanged();
|
||||
void openingPerspective();
|
||||
void openedPerspective();
|
||||
|
||||
private:
|
||||
|
||||
// Partially bypass ADS perspective management, store list here
|
||||
// and then ADS will only have one perspective loaded
|
||||
// this is because all docking widgets must exist when a perspective is loaded
|
||||
// we will guarantee that!
|
||||
class PerspectiveInfo
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<QSettings> settings;
|
||||
QMap<QString,QStringList> groups;
|
||||
};
|
||||
QMap<QString,PerspectiveInfo> m_perspectives;
|
||||
|
||||
QString m_perspectivesFolder;
|
||||
QString getSettingsFileName( const QString& perspective, bool temp ) const;
|
||||
std::shared_ptr<QSettings> getSettingsObject( const QString& filePath ) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(ads_example_centralwidget VERSION ${VERSION_SHORT})
|
||||
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
add_executable(EmptyDockAreaExample WIN32
|
||||
main.cpp
|
||||
@@ -9,7 +10,9 @@ add_executable(EmptyDockAreaExample WIN32
|
||||
)
|
||||
target_include_directories(EmptyDockAreaExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(EmptyDockAreaExample PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(EmptyDockAreaExample PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||
target_link_libraries(EmptyDockAreaExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
set_target_properties(EmptyDockAreaExample PROPERTIES
|
||||
AUTOMOC ON
|
||||
AUTORCC ON
|
||||
|
||||
@@ -56,7 +56,7 @@ CMainWindow::CMainWindow(QWidget *parent)
|
||||
TableDockWidget->resize(250, 150);
|
||||
TableDockWidget->setMinimumSize(200,150);
|
||||
DockManager->addDockWidgetTabToArea(TableDockWidget, CentralDockArea);
|
||||
//auto TableArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, TableDockWidget);
|
||||
auto TableArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, TableDockWidget);
|
||||
ui->menuView->addAction(TableDockWidget->toggleViewAction());
|
||||
|
||||
table = new QTableWidget();
|
||||
@@ -67,8 +67,7 @@ CMainWindow::CMainWindow(QWidget *parent)
|
||||
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
|
||||
TableDockWidget->resize(250, 150);
|
||||
TableDockWidget->setMinimumSize(200,150);
|
||||
auto TableArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, TableDockWidget);
|
||||
//DockManager->addDockWidget(DockWidgetArea::BottomDockWidgetArea, TableDockWidget, TableArea);
|
||||
DockManager->addDockWidget(DockWidgetArea::BottomDockWidgetArea, TableDockWidget, TableArea);
|
||||
ui->menuView->addAction(TableDockWidget->toggleViewAction());
|
||||
|
||||
QTableWidget* propertiesTable = new QTableWidget();
|
||||
|
||||
@@ -5,4 +5,5 @@ SUBDIRS = \
|
||||
simple \
|
||||
sidebar \
|
||||
deleteonclose \
|
||||
emptydockarea
|
||||
emptydockarea \
|
||||
dockindock
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(ads_example_sidebar VERSION ${VERSION_SHORT})
|
||||
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
add_executable(SidebarExample WIN32
|
||||
main.cpp
|
||||
@@ -9,7 +10,9 @@ add_executable(SidebarExample WIN32
|
||||
)
|
||||
target_include_directories(SidebarExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(SidebarExample PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(SidebarExample PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||
target_link_libraries(SidebarExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
set_target_properties(SidebarExample PROPERTIES
|
||||
AUTOMOC ON
|
||||
AUTORCC ON
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(ads_example_simple VERSION ${VERSION_SHORT})
|
||||
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
add_executable(SimpleExample WIN32
|
||||
main.cpp
|
||||
@@ -9,7 +10,9 @@ add_executable(SimpleExample WIN32
|
||||
)
|
||||
target_include_directories(SimpleExample PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(SimpleExample PRIVATE qtadvanceddocking)
|
||||
target_link_libraries(SimpleExample PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||
target_link_libraries(SimpleExample PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
set_target_properties(SimpleExample PROPERTIES
|
||||
AUTOMOC ON
|
||||
AUTORCC ON
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(QtAdvancedDockingSystem LANGUAGES CXX VERSION ${VERSION_SHORT})
|
||||
find_package(Qt5 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS Core Gui Widgets REQUIRED)
|
||||
if (UNIX AND NOT APPLE)
|
||||
find_package(Qt5 5.5 COMPONENTS X11Extras REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} 5.5 COMPONENTS X11Extras REQUIRED)
|
||||
endif()
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
if(BUILD_STATIC)
|
||||
@@ -60,12 +61,14 @@ else()
|
||||
add_library(qtadvanceddocking SHARED ${ads_SRCS} ${ads_HEADERS})
|
||||
target_compile_definitions(qtadvanceddocking PRIVATE ADS_SHARED_EXPORT)
|
||||
endif()
|
||||
target_link_libraries(qtadvanceddocking PUBLIC Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||
target_link_libraries(qtadvanceddocking PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(qtadvanceddocking PUBLIC Qt5::X11Extras)
|
||||
target_link_libraries(qtadvanceddocking PUBLIC Qt${QT_VERSION_MAJOR}::X11Extras)
|
||||
target_link_libraries(qtadvanceddocking PRIVATE xcb)
|
||||
endif()
|
||||
set_target_properties(qtadvanceddocking PROPERTIES
|
||||
set_target_properties(qtadvanceddocking PROPERTIES
|
||||
AUTOMOC ON
|
||||
AUTORCC ON
|
||||
CXX_STANDARD 14
|
||||
@@ -84,13 +87,13 @@ write_basic_package_version_file(
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
install(FILES ${ads_HEADERS}
|
||||
DESTINATION include
|
||||
DESTINATION include
|
||||
COMPONENT headers
|
||||
)
|
||||
install(FILES
|
||||
install(FILES
|
||||
"${CMAKE_SOURCE_DIR}/LICENSE"
|
||||
"${CMAKE_SOURCE_DIR}/gnu-lgpl-v2.1.md"
|
||||
DESTINATION license
|
||||
DESTINATION license
|
||||
COMPONENT license
|
||||
)
|
||||
install(TARGETS qtadvanceddocking
|
||||
|
||||
@@ -1030,6 +1030,21 @@ void CDockAreaWidget::onDockWidgetFeaturesChanged()
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
//============================================================================
|
||||
bool CDockAreaWidget::event(QEvent *e)
|
||||
{
|
||||
switch (e->type())
|
||||
{
|
||||
case QEvent::PlatformSurface: return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Super::event(e);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ads
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -77,6 +77,17 @@ private Q_SLOTS:
|
||||
void reorderDockWidget(int fromIndex, int toIndex);
|
||||
|
||||
protected:
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
/**
|
||||
* Reimplements QWidget::event to handle QEvent::PlatformSurface
|
||||
* This is here to fix issue #294 Tab refresh problem with a QGLWidget
|
||||
* that exists since Qt version 5.12.7. So this function is here to
|
||||
* work around a Qt issue.
|
||||
*/
|
||||
virtual bool event(QEvent *event) override;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Inserts a dock widget into dock area.
|
||||
* All dockwidgets in the dock area tabified in a stacked layout with tabs.
|
||||
|
||||
@@ -505,6 +505,20 @@ CDockManager::CDockManager(QWidget *parent) :
|
||||
//============================================================================
|
||||
CDockManager::~CDockManager()
|
||||
{
|
||||
// fix memory leaks, see https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/307
|
||||
std::vector<ads::CDockAreaWidget*> areas;
|
||||
for ( int i = 0; i != dockAreaCount(); ++i )
|
||||
{
|
||||
areas.push_back( dockArea(i) );
|
||||
}
|
||||
for ( auto area : areas )
|
||||
{
|
||||
for ( auto widget : area->dockWidgets() )
|
||||
delete widget;
|
||||
|
||||
delete area;
|
||||
}
|
||||
|
||||
auto FloatingWidgets = d->FloatingWidgets;
|
||||
for (auto FloatingWidget : FloatingWidgets)
|
||||
{
|
||||
@@ -912,6 +926,8 @@ void CDockManager::loadPerspectives(QSettings& Settings)
|
||||
}
|
||||
|
||||
Settings.endArray();
|
||||
Q_EMIT perspectiveListChanged();
|
||||
Q_EMIT perspectiveListLoaded();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -521,10 +521,17 @@ public Q_SLOTS:
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal is emitted if the list of perspectives changed
|
||||
* This signal is emitted if the list of perspectives changed.
|
||||
* The list of perspectives changes if perspectives are added, removed
|
||||
* or if the perspective list has been loaded
|
||||
*/
|
||||
void perspectiveListChanged();
|
||||
|
||||
/**
|
||||
* This signal is emitted if the perspective list has been loaded
|
||||
*/
|
||||
void perspectiveListLoaded();
|
||||
|
||||
/**
|
||||
* This signal is emitted if perspectives have been removed
|
||||
*/
|
||||
|
||||
@@ -677,6 +677,9 @@ bool CDockWidgetTab::event(QEvent *e)
|
||||
{
|
||||
const auto text = toolTip();
|
||||
d->TitleLabel->setToolTip(text);
|
||||
if (d->IconLabel) {
|
||||
d->IconLabel->setToolTip(text);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Super::event(e);
|
||||
|
||||
Reference in New Issue
Block a user