Merge branch 'refs/heads/master' into linux_experimental

This commit is contained in:
Uwe Kindler 2019-07-11 15:50:24 +02:00
commit 35c1b04c58
8 changed files with 84 additions and 34 deletions

View File

@ -88,6 +88,32 @@ static ads::CDockWidget* createLongTextLabelDockWidget(QMenu* ViewMenu)
} }
/**
* Function returns a features string with closable (c), movable (m) and floatable (f)
* features. i.e. The following string is for a not closable but movable and floatable
* widget: c- m+ f+
*/
static QString featuresString(ads::CDockWidget* DockWidget)
{
auto f = DockWidget->features();
return QString("c%1 m%2 f%3")
.arg(f.testFlag(ads::CDockWidget::DockWidgetClosable) ? "+" : "-")
.arg(f.testFlag(ads::CDockWidget::DockWidgetMovable) ? "+" : "-")
.arg(f.testFlag(ads::CDockWidget::DockWidgetFloatable) ? "+" : "-");
}
/**
* Appends the string returned by featuresString() to the window title of
* the given DockWidget
*/
static void appendFeaturStringToWindowTitle(ads::CDockWidget* DockWidget)
{
DockWidget->setWindowTitle(DockWidget->windowTitle()
+ QString(" (%1)").arg(featuresString(DockWidget)));
}
//============================================================================ //============================================================================
static ads::CDockWidget* createCalendarDockWidget(QMenu* ViewMenu) static ads::CDockWidget* createCalendarDockWidget(QMenu* ViewMenu)
{ {
@ -110,7 +136,8 @@ static ads::CDockWidget* createFileSystemTreeDockWidget(QMenu* ViewMenu)
QFileSystemModel* m = new QFileSystemModel(w); QFileSystemModel* m = new QFileSystemModel(w);
m->setRootPath(QDir::currentPath()); m->setRootPath(QDir::currentPath());
w->setModel(m); w->setModel(m);
ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Filesystem %1").arg(FileSystemCount++)); ads::CDockWidget* DockWidget = new ads::CDockWidget(QString("Filesystem %1")
.arg(FileSystemCount++));
DockWidget->setWidget(w); DockWidget->setWidget(w);
ViewMenu->addAction(DockWidget->toggleViewAction()); ViewMenu->addAction(DockWidget->toggleViewAction());
return DockWidget; return DockWidget;
@ -185,6 +212,8 @@ void MainWindowPrivate::createContent()
ToolBar->addAction(ui.actionSaveState); ToolBar->addAction(ui.actionSaveState);
ToolBar->addAction(ui.actionRestoreState); ToolBar->addAction(ui.actionRestoreState);
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false); FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetMovable, false);
FileSystemWidget->setFeature(ads::CDockWidget::DockWidgetFloatable, false);
appendFeaturStringToWindowTitle(FileSystemWidget);
auto TopDockArea = DockManager->addDockWidget(ads::TopDockWidgetArea, FileSystemWidget); auto TopDockArea = DockManager->addDockWidget(ads::TopDockWidgetArea, FileSystemWidget);
DockWidget = createCalendarDockWidget(ViewMenu); DockWidget = createCalendarDockWidget(ViewMenu);
DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false); DockWidget->setFeature(ads::CDockWidget::DockWidgetClosable, false);

View File

@ -205,6 +205,13 @@ void CDockAreaTabBar::mouseMoveEvent(QMouseEvent* ev)
return; return;
} }
// If one single dock widget in this area is not floatable then the whole
// area is not floatable
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
int DragDistance = (d->DragStartMousePos - ev->pos()).manhattanLength(); int DragDistance = (d->DragStartMousePos - ev->pos()).manhattanLength();
if (DragDistance >= CDockManager::startDragDistance()) if (DragDistance >= CDockManager::startDragDistance())
{ {
@ -228,6 +235,11 @@ void CDockAreaTabBar::mouseDoubleClickEvent(QMouseEvent *event)
{ {
return; return;
} }
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
makeAreaFloating(event->pos(), DraggingInactive); makeAreaFloating(event->pos(), DraggingInactive);
} }

View File

@ -290,9 +290,12 @@ void CDockAreaTitleBar::onCloseButtonClicked()
//============================================================================ //============================================================================
void CDockAreaTitleBar::onUndockButtonClicked() void CDockAreaTitleBar::onUndockButtonClicked()
{
if (d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
{ {
d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive); d->TabBar->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
} }
}
//============================================================================ //============================================================================
@ -346,9 +349,10 @@ void CDockAreaTitleBar::setVisible(bool Visible)
void CDockAreaTitleBar::showContextMenu(const QPoint& pos) void CDockAreaTitleBar::showContextMenu(const QPoint& pos)
{ {
QMenu Menu(this); QMenu Menu(this);
Menu.addAction(tr("Detach Area"), this, SLOT(onUndockButtonClicked())); auto Action = Menu.addAction(tr("Detach Area"), this, SLOT(onUndockButtonClicked()));
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable));
Menu.addSeparator(); Menu.addSeparator();
auto Action = Menu.addAction(tr("Close Area"), this, SLOT(onCloseButtonClicked())); Action = Menu.addAction(tr("Close Area"), this, SLOT(onCloseButtonClicked()));
Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable)); Action->setEnabled(d->DockArea->features().testFlag(CDockWidget::DockWidgetClosable));
Menu.addAction(tr("Close Other Areas"), d->DockArea, SLOT(closeOtherAreas())); Menu.addAction(tr("Close Other Areas"), d->DockArea, SLOT(closeOtherAreas()));
Menu.exec(mapToGlobal(pos)); Menu.exec(mapToGlobal(pos));

View File

@ -241,7 +241,7 @@ struct DockAreaWidgetPrivate
DockAreaLayout* ContentsLayout = nullptr; DockAreaLayout* ContentsLayout = nullptr;
CDockAreaTitleBar* TitleBar = nullptr; CDockAreaTitleBar* TitleBar = nullptr;
CDockManager* DockManager = nullptr; CDockManager* DockManager = nullptr;
bool UpdateCloseButton = false; bool UpdateTitleBarButtons = false;
/** /**
* Private data constructor * Private data constructor
@ -295,9 +295,9 @@ struct DockAreaWidgetPrivate
} }
/** /**
* Udpates the enable state of the close button * Udpates the enable state of the close and detach button
*/ */
void updateCloseButtonState(); void updateTitleBarButtonStates();
}; };
// struct DockAreaWidgetPrivate // struct DockAreaWidgetPrivate
@ -322,17 +322,19 @@ void DockAreaWidgetPrivate::createTitleBar()
//============================================================================ //============================================================================
void DockAreaWidgetPrivate::updateCloseButtonState() void DockAreaWidgetPrivate::updateTitleBarButtonStates()
{ {
if (_this->isHidden()) if (_this->isHidden())
{ {
UpdateCloseButton = true; UpdateTitleBarButtons = true;
return; return;
} }
TitleBar->button(TitleBarButtonClose)->setEnabled( TitleBar->button(TitleBarButtonClose)->setEnabled(
_this->features().testFlag(CDockWidget::DockWidgetClosable)); _this->features().testFlag(CDockWidget::DockWidgetClosable));
UpdateCloseButton = false; TitleBar->button(TitleBarButtonUndock)->setEnabled(
_this->features().testFlag(CDockWidget::DockWidgetFloatable));
UpdateTitleBarButtons = false;
} }
@ -400,7 +402,7 @@ void CDockAreaWidget::insertDockWidget(int index, CDockWidget* DockWidget,
setCurrentIndex(index); setCurrentIndex(index);
} }
DockWidget->setDockArea(this); DockWidget->setDockArea(this);
d->updateCloseButtonState(); d->updateTitleBarButtonStates();
} }
@ -433,7 +435,7 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
hideAreaWithNoVisibleContent(); hideAreaWithNoVisibleContent();
} }
d->updateCloseButtonState(); d->updateTitleBarButtonStates();
updateTitleBarVisibility(); updateTitleBarVisibility();
auto TopLevelDockWidget = DockContainer->topLevelDockWidget(); auto TopLevelDockWidget = DockContainer->topLevelDockWidget();
if (TopLevelDockWidget) if (TopLevelDockWidget)
@ -765,9 +767,9 @@ void CDockAreaWidget::toggleView(bool Open)
void CDockAreaWidget::setVisible(bool Visible) void CDockAreaWidget::setVisible(bool Visible)
{ {
Super::setVisible(Visible); Super::setVisible(Visible);
if (d->UpdateCloseButton) if (d->UpdateTitleBarButtons)
{ {
d->updateCloseButtonState(); d->updateTitleBarButtonStates();
} }
} }

View File

@ -340,8 +340,9 @@ void DockManagerPrivate::emitTopLevelEvents()
//============================================================================ //============================================================================
bool DockManagerPrivate::restoreState(const QByteArray &state, int version) bool DockManagerPrivate::restoreState(const QByteArray& State, int version)
{ {
QByteArray state = State.startsWith("<?xml") ? State : qUncompress(State);
if (!checkFormat(state, version)) if (!checkFormat(state, version))
{ {
qDebug() << "checkFormat: Error checking format!!!!!!!"; qDebug() << "checkFormat: Error checking format!!!!!!!";
@ -493,11 +494,11 @@ unsigned int CDockManager::zOrderIndex() const
//============================================================================ //============================================================================
QByteArray CDockManager::saveState(eXmlMode XmlMode, int version) const QByteArray CDockManager::saveState(int version) const
{ {
QByteArray xmldata; QByteArray xmldata;
QXmlStreamWriter s(&xmldata); QXmlStreamWriter s(&xmldata);
s.setAutoFormatting(XmlAutoFormattingEnabled == XmlMode); s.setAutoFormatting(d->ConfigFlags.testFlag(XmlAutoFormattingEnabled));
s.writeStartDocument(); s.writeStartDocument();
s.writeStartElement("QtAdvancedDockingSystem"); s.writeStartElement("QtAdvancedDockingSystem");
s.writeAttribute("Version", QString::number(version)); s.writeAttribute("Version", QString::number(version));
@ -510,7 +511,7 @@ QByteArray CDockManager::saveState(eXmlMode XmlMode, int version) const
s.writeEndElement(); s.writeEndElement();
s.writeEndDocument(); s.writeEndDocument();
return xmldata; return d->ConfigFlags.testFlag(XmlCompressionEnabled) ? qCompress(xmldata, 9) : xmldata;
} }

View File

@ -51,7 +51,9 @@ struct DockWidgetTabPrivate;
struct DockAreaWidgetPrivate; struct DockAreaWidgetPrivate;
/** /**
* The central dock manager that maintains the complete docking system * The central dock manager that maintains the complete docking system.
* With the configuration flags you can globally control the functionality
* of the docking system.
**/ **/
class ADS_EXPORT CDockManager : public CDockContainerWidget class ADS_EXPORT CDockManager : public CDockContainerWidget
{ {
@ -108,12 +110,6 @@ public:
MenuAlphabeticallySorted MenuAlphabeticallySorted
}; };
enum eXmlMode
{
XmlAutoFormattingDisabled,
XmlAutoFormattingEnabled
};
/** /**
* These global configuration flags configure some global dock manager * These global configuration flags configure some global dock manager
* settings. * settings.
@ -124,7 +120,9 @@ public:
DockAreaHasCloseButton = 0x02, //!< If the flag is set each dock area has a close button DockAreaHasCloseButton = 0x02, //!< If the flag is set each dock area has a close button
DockAreaCloseButtonClosesTab = 0x04,//!< If the flag is set, the dock area close button closes the active tab, if not set, it closes the complete cock area DockAreaCloseButtonClosesTab = 0x04,//!< If the flag is set, the dock area close button closes the active tab, if not set, it closes the complete cock area
OpaqueSplitterResize = 0x08, //!< See QSplitter::setOpaqueResize() documentation OpaqueSplitterResize = 0x08, //!< See QSplitter::setOpaqueResize() documentation
DefaultConfig = ActiveTabHasCloseButton | DockAreaHasCloseButton | OpaqueSplitterResize, ///< the default configuration XmlAutoFormattingEnabled = 0x10,//!< If enabled, the XML writer automatically adds line-breaks and indentation to empty sections between elements (ignorable whitespace).
XmlCompressionEnabled = 0x20,//!< If enabled, the XML output will be compressed and is not human readable anymore
DefaultConfig = ActiveTabHasCloseButton | DockAreaHasCloseButton | OpaqueSplitterResize | XmlCompressionEnabled, ///< the default configuration
}; };
Q_DECLARE_FLAGS(ConfigFlags, eConfigFlag) Q_DECLARE_FLAGS(ConfigFlags, eConfigFlag)
@ -228,7 +226,7 @@ public:
* The XmlMode XmlAutoFormattingDisabled is better if you would like to have * The XmlMode XmlAutoFormattingDisabled is better if you would like to have
* a more compact XML output - i.e. for storage in ini files. * a more compact XML output - i.e. for storage in ini files.
*/ */
QByteArray saveState(eXmlMode XmlMode = XmlAutoFormattingDisabled, int version = 0) const; QByteArray saveState(int version = 0) const;
/** /**
* Restores the state of this dockmanagers dockwidgets. * Restores the state of this dockmanagers dockwidgets.

View File

@ -141,7 +141,7 @@ public:
enum DockWidgetFeature enum DockWidgetFeature
{ {
DockWidgetClosable = 0x01, DockWidgetClosable = 0x01,
DockWidgetMovable = 0x02, DockWidgetMovable = 0x02,///< this feature is not properly implemented yet and is ignored
DockWidgetFloatable = 0x04, DockWidgetFloatable = 0x04,
AllDockWidgetFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable, AllDockWidgetFeatures = DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable,
NoDockWidgetFeatures = 0x00 NoDockWidgetFeatures = 0x00

View File

@ -328,7 +328,7 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
} }
// Floating is only allowed for widgets that are movable // Floating is only allowed for widgets that are movable
if (d->DockWidget->features().testFlag(CDockWidget::DockWidgetMovable)) if (d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
{ {
d->startFloating(); d->startFloating();
} }
@ -352,9 +352,10 @@ void CDockWidgetTab::contextMenuEvent(QContextMenuEvent* ev)
d->DragStartMousePosition = ev->pos(); d->DragStartMousePosition = ev->pos();
QMenu Menu(this); QMenu Menu(this);
Menu.addAction(tr("Detach"), this, SLOT(onDetachActionTriggered())); auto Action = Menu.addAction(tr("Detach"), this, SLOT(onDetachActionTriggered()));
Action->setEnabled(d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable));
Menu.addSeparator(); Menu.addSeparator();
auto Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested())); Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested()));
Action->setEnabled(isClosable()); Action->setEnabled(isClosable());
Menu.addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested())); Menu.addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested()));
Menu.exec(mapToGlobal(ev->pos())); Menu.exec(mapToGlobal(ev->pos()));
@ -469,7 +470,8 @@ void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event)
// If this is the last dock area in a dock container it does not make // If this is the last dock area in a dock container it does not make
// sense to move it to a new floating widget and leave this one // sense to move it to a new floating widget and leave this one
// empty // empty
if (!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1) if ((!d->DockArea->dockContainer()->isFloating() || d->DockArea->dockWidgetsCount() > 1)
&& d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
{ {
d->DragStartMousePosition = event->pos(); d->DragStartMousePosition = event->pos();
d->startFloating(DraggingInactive); d->startFloating(DraggingInactive);
@ -505,13 +507,15 @@ bool CDockWidgetTab::isClosable() const
//=========================================================================== //===========================================================================
void CDockWidgetTab::onDetachActionTriggered() void CDockWidgetTab::onDetachActionTriggered()
{ {
if (!d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
{
return;
}
d->DragStartMousePosition = mapFromGlobal(QCursor::pos()); d->DragStartMousePosition = mapFromGlobal(QCursor::pos());
d->startFloating(DraggingInactive); d->startFloating(DraggingInactive);
} }
//============================================================================ //============================================================================
bool CDockWidgetTab::event(QEvent *e) bool CDockWidgetTab::event(QEvent *e)
{ {