Fixed problem in FloatingDockContainer.cpp that caused problem when dragging a maximized window, added support for sorted insertion of toggleView actions into vieMenu

This commit is contained in:
Uwe Kindler 2018-09-13 22:19:13 +02:00
parent 1a47918bdb
commit b93e723a83
3 changed files with 150 additions and 6 deletions

View File

@ -31,6 +31,8 @@
#include <DockWidgetTab.h> #include <DockWidgetTab.h>
#include "DockManager.h" #include "DockManager.h"
#include <algorithm>
#include <QMainWindow> #include <QMainWindow>
#include <QList> #include <QList>
@ -43,6 +45,7 @@
#include <QXmlStreamWriter> #include <QXmlStreamWriter>
#include <QXmlStreamReader> #include <QXmlStreamReader>
#include <QSettings> #include <QSettings>
#include <QMenu>
#include "FloatingDockContainer.h" #include "FloatingDockContainer.h"
#include "DockOverlay.h" #include "DockOverlay.h"
@ -51,6 +54,8 @@
#include "DockStateSerialization.h" #include "DockStateSerialization.h"
#include "DockAreaWidget.h" #include "DockAreaWidget.h"
#include <iostream>
namespace ads namespace ads
{ {
/** /**
@ -65,6 +70,9 @@ struct DockManagerPrivate
CDockOverlay* DockAreaOverlay; CDockOverlay* DockAreaOverlay;
QMap<QString, CDockWidget*> DockWidgetsMap; QMap<QString, CDockWidget*> DockWidgetsMap;
QMap<QString, QByteArray> Perspectives; QMap<QString, QByteArray> Perspectives;
QMap<QString, QMenu*> ViewMenuGroups;
QMenu* ViewMenu;
CDockManager::eViewMenuInsertionOrder MenuInsertionOrder = CDockManager::MenuAlphabeticallySorted;
/** /**
* Private data constructor * Private data constructor
@ -91,6 +99,11 @@ struct DockManagerPrivate
* Loads the stylesheet * Loads the stylesheet
*/ */
void loadStylesheet(); void loadStylesheet();
/**
* Adds action to menu - optionally in sorted order
*/
void addActionToMenu(QAction* Action, QMenu* Menu, bool InsertSorted);
}; };
// struct DockManagerPrivate // struct DockManagerPrivate
@ -197,6 +210,35 @@ bool DockManagerPrivate::restoreState(const QByteArray &state, int version,
} }
//============================================================================
void DockManagerPrivate::addActionToMenu(QAction* Action, QMenu* Menu, bool InsertSorted)
{
if (InsertSorted)
{
auto Actions = Menu->actions();
auto it = std::find_if(Actions.begin(), Actions.end(),
[&Action](const QAction* a)
{
return a->text().compare(Action->text(), Qt::CaseInsensitive) > 0;
});
if (it == Actions.end())
{
Menu->addAction(Action);
}
else
{
Menu->insertAction(*it, Action);
}
}
else
{
Menu->addAction(Action);
}
}
//============================================================================ //============================================================================
CDockManager::CDockManager(QWidget *parent) : CDockManager::CDockManager(QWidget *parent) :
CDockContainerWidget(this, parent), CDockContainerWidget(this, parent),
@ -208,6 +250,7 @@ CDockManager::CDockManager(QWidget *parent) :
MainWindow->setCentralWidget(this); MainWindow->setCentralWidget(this);
} }
d->ViewMenu = new QMenu(tr("Show View"), this);
d->DockAreaOverlay = new CDockOverlay(this, CDockOverlay::ModeDockAreaOverlay); d->DockAreaOverlay = new CDockOverlay(this, CDockOverlay::ModeDockAreaOverlay);
d->ContainerOverlay = new CDockOverlay(this, CDockOverlay::ModeContainerOverlay); d->ContainerOverlay = new CDockOverlay(this, CDockOverlay::ModeContainerOverlay);
d->Containers.append(this); d->Containers.append(this);
@ -294,11 +337,11 @@ unsigned int CDockManager::zOrderIndex() const
//============================================================================ //============================================================================
QByteArray CDockManager::saveState(int version) const QByteArray CDockManager::saveState(eXmlMode XmlMode, int version) const
{ {
QByteArray xmldata; QByteArray xmldata;
QXmlStreamWriter s(&xmldata); QXmlStreamWriter s(&xmldata);
s.setAutoFormatting(true); s.setAutoFormatting(XmlAutoFormattingEnabled == XmlMode);
s.writeStartDocument(); s.writeStartDocument();
s.writeStartElement("QtAdvancedDockingSystem"); s.writeStartElement("QtAdvancedDockingSystem");
s.writeAttribute("Version", QString::number(version)); s.writeAttribute("Version", QString::number(version));
@ -483,6 +526,45 @@ void CDockManager::loadPerspectives(QSettings& Settings)
Settings.endArray(); Settings.endArray();
} }
//============================================================================
void CDockManager::addToggleViewActionToMenu(QAction* ToggleViewAction,
const QString& Group, const QIcon& GroupIcon)
{
bool AlphabeticallySorted = (MenuAlphabeticallySorted == d->MenuInsertionOrder);
if (!Group.isEmpty())
{
QMenu* GroupMenu = d->ViewMenuGroups.value(Group, 0);
if (!GroupMenu)
{
GroupMenu = new QMenu(Group, this);
GroupMenu->setIcon(GroupIcon);
d->addActionToMenu(GroupMenu->menuAction(), d->ViewMenu, AlphabeticallySorted);
d->ViewMenuGroups.insert(Group, GroupMenu);
}
d->addActionToMenu(ToggleViewAction, GroupMenu, AlphabeticallySorted);
}
else
{
d->addActionToMenu(ToggleViewAction, d->ViewMenu, AlphabeticallySorted);
}
}
//============================================================================
QMenu* CDockManager::viewMenu() const
{
return d->ViewMenu;
}
//============================================================================
void CDockManager::setViewMenuInsertionOrder(eViewMenuInsertionOrder Order)
{
d->MenuInsertionOrder = Order;
}
} // namespace ads } // namespace ads
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -31,10 +31,12 @@
// INCLUDES // INCLUDES
//============================================================================ //============================================================================
#include "DockContainerWidget.h" #include "DockContainerWidget.h"
#include <QIcon>
#include "ads_globals.h" #include "ads_globals.h"
class QSettings; class QSettings;
class QMenu;
namespace ads namespace ads
{ {
@ -100,6 +102,18 @@ protected:
CDockOverlay* dockAreaOverlay() const; CDockOverlay* dockAreaOverlay() const;
public: public:
enum eViewMenuInsertionOrder
{
MenuSortedByInsertion,
MenuAlphabeticallySorted
};
enum eXmlMode
{
XmlAutoFormattingDisabled,
XmlAutoFormattingEnabled
};
/** /**
* Default Constructor. * Default Constructor.
* If the given parent is a QMainWindow, the dock manager sets itself as the * If the given parent is a QMainWindow, the dock manager sets itself as the
@ -170,9 +184,13 @@ public:
/** /**
* Saves the current state of the dockmanger and all its dock widgets * Saves the current state of the dockmanger and all its dock widgets
* into the returned QByteArray * into the returned QByteArray.
* The XmlMode enables / disables the auto formatting for the XmlStreamWriter.
* If auto formatting is enabled, the output is intended and line wrapped.
* The XmlMode XmlAutoFormattingDisabled is better if you would like to have
* a more compact XML output - i.e. for storage in ini files.
*/ */
QByteArray saveState(int version = 0) const; QByteArray saveState(eXmlMode XmlMode = XmlAutoFormattingDisabled, int version = 0) const;
/** /**
* Restores the state of this dockmanagers dockwidgets. * Restores the state of this dockmanagers dockwidgets.
@ -208,6 +226,41 @@ public:
*/ */
void loadPerspectives(QSettings& Settings); void loadPerspectives(QSettings& Settings);
/**
* Adds a toggle view action to the the internal view menu.
* You can either manage the insertion of the toggle view actions in your
* application or you can add the actions to the internal view menu and
* then simply insert the menu object into your.
* \param[in] ToggleViewAction The action to insert. If no group is provided
* the action is directly inserted into the menu. If a group
* is provided, the action is inserted into the group and the
* group is inserted into the menu if it is not existing yet.
* \param[in] Group This is the text used for the group menu item
* \param[in] GroupIcon The icon used for grouping the workbenches in the
* view menu. I.e. if there is a workbench for each device
* like for spectrometer devices, it is good to group all these
* workbenches under a menu item
*/
void addToggleViewActionToMenu(QAction* ToggleViewAction,
const QString& Group = QString(), const QIcon& GroupIcon = QIcon());
/**
* This function returns the internal view menu.
* To fill the view menu, you can use the addToggleViewActionToMenu()
* function.
*/
QMenu* viewMenu() const;
/**
* Define the insertion order for toggle view menu items.
* The order defines how the actions are added to the view menu.
* The default insertion order is MenuAlphabeticallySorted to make it
* easier for users to find the menu entry for a certain dock widget.
* You need to call this function befor you insert the first menu item
* into the view menu.
*/
void setViewMenuInsertionOrder(eViewMenuInsertionOrder Order);
public slots: public slots:
/** /**
* Opens the perspective with the given name. * Opens the perspective with the given name.

View File

@ -379,8 +379,17 @@ bool CFloatingDockContainer::event(QEvent *e)
case QEvent::Resize: case QEvent::Resize:
// If the first event after the mouse press is a resize event, then // If the first event after the mouse press is a resize event, then
// the user resizes the window instead of dragging it around // the user resizes the window instead of dragging it around.
d->setState(StateInactive); // But there is one exception. If the window is maximized,
// then dragging the window via title bar will cause the widget to
// leave the maximized state. This in turn will trigger a resize event.
// To know, if the resize event was triggered by user via moving a
// corner of the window frame or if it was caused by a windows state
// change, we check, if we are not in maximized state.
if (!isMaximized())
{
d->setState(StateInactive);
}
break; break;
default: default: