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 "DockManager.h"
#include <algorithm>
#include <QMainWindow>
#include <QList>
@ -43,6 +45,7 @@
#include <QXmlStreamWriter>
#include <QXmlStreamReader>
#include <QSettings>
#include <QMenu>
#include "FloatingDockContainer.h"
#include "DockOverlay.h"
@ -51,6 +54,8 @@
#include "DockStateSerialization.h"
#include "DockAreaWidget.h"
#include <iostream>
namespace ads
{
/**
@ -65,6 +70,9 @@ struct DockManagerPrivate
CDockOverlay* DockAreaOverlay;
QMap<QString, CDockWidget*> DockWidgetsMap;
QMap<QString, QByteArray> Perspectives;
QMap<QString, QMenu*> ViewMenuGroups;
QMenu* ViewMenu;
CDockManager::eViewMenuInsertionOrder MenuInsertionOrder = CDockManager::MenuAlphabeticallySorted;
/**
* Private data constructor
@ -91,6 +99,11 @@ struct DockManagerPrivate
* Loads the stylesheet
*/
void loadStylesheet();
/**
* Adds action to menu - optionally in sorted order
*/
void addActionToMenu(QAction* Action, QMenu* Menu, bool InsertSorted);
};
// 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) :
CDockContainerWidget(this, parent),
@ -208,6 +250,7 @@ CDockManager::CDockManager(QWidget *parent) :
MainWindow->setCentralWidget(this);
}
d->ViewMenu = new QMenu(tr("Show View"), this);
d->DockAreaOverlay = new CDockOverlay(this, CDockOverlay::ModeDockAreaOverlay);
d->ContainerOverlay = new CDockOverlay(this, CDockOverlay::ModeContainerOverlay);
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;
QXmlStreamWriter s(&xmldata);
s.setAutoFormatting(true);
s.setAutoFormatting(XmlAutoFormattingEnabled == XmlMode);
s.writeStartDocument();
s.writeStartElement("QtAdvancedDockingSystem");
s.writeAttribute("Version", QString::number(version));
@ -483,6 +526,45 @@ void CDockManager::loadPerspectives(QSettings& Settings)
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
//---------------------------------------------------------------------------

View File

@ -31,10 +31,12 @@
// INCLUDES
//============================================================================
#include "DockContainerWidget.h"
#include <QIcon>
#include "ads_globals.h"
class QSettings;
class QMenu;
namespace ads
{
@ -100,6 +102,18 @@ protected:
CDockOverlay* dockAreaOverlay() const;
public:
enum eViewMenuInsertionOrder
{
MenuSortedByInsertion,
MenuAlphabeticallySorted
};
enum eXmlMode
{
XmlAutoFormattingDisabled,
XmlAutoFormattingEnabled
};
/**
* Default Constructor.
* 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
* 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.
@ -208,6 +226,41 @@ public:
*/
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:
/**
* Opens the perspective with the given name.

View File

@ -379,8 +379,17 @@ bool CFloatingDockContainer::event(QEvent *e)
case QEvent::Resize:
// If the first event after the mouse press is a resize event, then
// the user resizes the window instead of dragging it around
d->setState(StateInactive);
// the user resizes the window instead of dragging it around.
// 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;
default: