Commit 257f547c authored by John Tapsell's avatar John Tapsell

Move all the menu/action manipulation over to a new class, so that it's self contained

This fixes a bunch of bugs with setting the title for widgets, deleting
widgets, etc.  It also reduces the amount of code duplication, which is
always a good thing.
parent 5f37d6c9
......@@ -449,7 +449,6 @@ HEADERS += src/MG.h \
src/ui/designer/QGCComboBox.h \
src/ui/designer/QGCTextLabel.h \
src/ui/submainwindow.h \
src/ui/dockwidgettitlebareventfilter.h \
src/ui/uas/UASQuickView.h \
src/ui/uas/UASQuickViewItem.h \
src/ui/linechart/ChartPlot.h \
......@@ -507,7 +506,7 @@ HEADERS += src/MG.h \
src/ui/QGCBaseParamWidget.h \
src/ui/px4_configuration/QGCPX4MulticopterConfig.h \
src/ui/px4_configuration/QGCPX4SensorCalibration.h \
src/ui/dockwidgeteventfilter.h
src/ui/menuactionhelper.h
# Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler
macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h
......@@ -672,7 +671,6 @@ SOURCES += src/main.cc \
src/ui/designer/QGCComboBox.cc \
src/ui/designer/QGCTextLabel.cc \
src/ui/submainwindow.cpp \
src/ui/dockwidgettitlebareventfilter.cpp \
src/ui/uas/UASQuickViewItem.cc \
src/ui/uas/UASQuickView.cc \
src/ui/linechart/ChartPlot.cc \
......@@ -730,7 +728,7 @@ SOURCES += src/main.cc \
src/ui/QGCBaseParamWidget.cc \
src/ui/px4_configuration/QGCPX4MulticopterConfig.cc \
src/ui/px4_configuration/QGCPX4SensorCalibration.cc \
src/ui/dockwidgeteventfilter.cpp
src/ui/menuactionhelper.cpp
# Enable Google Earth only on Mac OS and Windows with Visual Studio compiler
macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc
......
......@@ -27,7 +27,7 @@
#include "MainWindow.h"
#include <QDebug>
HDDisplay::HDDisplay(QStringList* plotList, QString title, QWidget *parent) :
HDDisplay::HDDisplay(const QStringList &plotList, QString title, QWidget *parent) :
QGraphicsView(parent),
uas(NULL),
xCenterOffset(0.0f),
......@@ -60,11 +60,8 @@ HDDisplay::HDDisplay(QStringList* plotList, QString title, QWidget *parent) :
setAutoFillBackground(true);
// Add all items in accept list to gauge
if (plotList) {
for(int i = 0; i < plotList->length(); ++i) {
addGauge(plotList->at(i));
}
}
for(int i = 0; i < plotList.length(); ++i)
addGauge(plotList.at(i));
restoreState();
// Set preferred size
......
......@@ -60,7 +60,7 @@ class HDDisplay : public QGraphicsView
{
Q_OBJECT
public:
HDDisplay(QStringList* plotList, QString title="", QWidget *parent = 0);
HDDisplay(const QStringList& plotList, QString title="", QWidget *parent = 0);
~HDDisplay();
public slots:
......
......@@ -49,7 +49,7 @@ This file is part of the QGROUNDCONTROL project
HSIDisplay::HSIDisplay(QWidget *parent) :
HDDisplay(NULL, "HSI", parent),
HDDisplay(QStringList(), "HSI", parent),
dragStarted(false),
leftDragStarted(false),
mouseHasMoved(false),
......
This diff is collapsed.
......@@ -86,6 +86,7 @@ class QGCStatusBar;
class Linecharts;
class QGCDataPlot2D;
class JoystickWidget;
class MenuActionHelper;
/**
* @brief Main Application Window
......@@ -142,41 +143,38 @@ public:
static const QString defaultLightStyle;
/** @brief Get current visual style */
QGC_MAINWINDOW_STYLE getStyle()
QGC_MAINWINDOW_STYLE getStyle() const
{
return currentStyle;
}
/** @brief Get current light visual stylesheet */
QString getLightStyleSheet()
QString getLightStyleSheet() const
{
return lightStyleFileName;
}
/** @brief Get current dark visual stylesheet */
QString getDarkStyleSheet()
QString getDarkStyleSheet() const
{
return darkStyleFileName;
}
/** @brief Get auto link reconnect setting */
bool autoReconnectEnabled()
bool autoReconnectEnabled() const
{
return autoReconnect;
}
/** @brief Get title bar mode setting */
bool dockWidgetTitleBarsEnabled()
{
return dockWidgetTitleBarEnabled;
}
bool dockWidgetTitleBarsEnabled() const;
/** @brief Get low power mode setting */
bool lowPowerModeEnabled()
bool lowPowerModeEnabled() const
{
return lowPowerMode;
}
void setCustomMode(enum MainWindow::CUSTOM_MODE mode)
void setCustomMode(MainWindow::CUSTOM_MODE mode)
{
if (mode != CUSTOM_MODE_UNCHANGED)
{
......@@ -184,12 +182,12 @@ public:
}
}
enum MainWindow::CUSTOM_MODE getCustomMode()
MainWindow::CUSTOM_MODE getCustomMode() const
{
return customMode;
}
QList<QAction*> listLinkMenuActions(void);
QList<QAction*> listLinkMenuActions();
public slots:
/** @brief Shows a status message on the bottom status bar */
......@@ -224,7 +222,7 @@ public slots:
void saveScreen();
/** @brief Sets advanced mode, allowing for editing of tool widget locations */
void setAdvancedMode();
void setAdvancedMode(bool isAdvancedMode);
/** @brief Load configuration views */
void loadHardwareConfigView();
void loadSoftwareConfigView();
......@@ -283,16 +281,6 @@ public slots:
/** @brief Load data view, allowing to plot flight data */
// void loadDataView(QString fileName);
/**
* @brief Shows a Docked Widget based on the action sender
*
* This slot is written to be used in conjunction with the addTool() function
* It shows the QDockedWidget based on the action sender
*
*/
void showTool(bool visible);
/**
* @brief Shows a Widget from the center stack based on the action sender
*
......@@ -308,8 +296,7 @@ public slots:
void commsWidgetDestroyed(QObject *obj);
protected slots:
/** @brief Called by a dock widget when it is has been deleted */
void dockWidgetDestroyed();
void showDockWidget(const QString &name, bool show);
signals:
void styleChanged(MainWindow::QGC_MAINWINDOW_STYLE newTheme);
......@@ -362,8 +349,9 @@ protected:
* @param location The default location for the QDockedWidget in case there is no previous key in the settings
*/
void addTool(SubMainWindow *parent,VIEW_SECTIONS view,QDockWidget* widget, const QString& title, Qt::DockWidgetArea area);
void loadDockWidget(QString name);
QDockWidget* createDockWidget(QWidget *parent,QWidget *child,QString title,QString objectname,VIEW_SECTIONS view,Qt::DockWidgetArea area,int minwidth=0,int minheight=0);
void loadDockWidget(const QString &name);
QDockWidget* createDockWidget(QWidget *subMainWindowParent,QWidget *child,const QString& title,const QString& objectname,VIEW_SECTIONS view,Qt::DockWidgetArea area,const QSize& minSize = QSize());
/**
* @brief Adds an already instantiated QWidget to the center stack
*
......@@ -514,11 +502,7 @@ protected:
private:
QList<QObject*> commsWidgetList;
QMap<QString,QString> customWidgetNameToFilenameMap;
QMap<QAction*,QString > menuToDockNameMap;
QList<QDockWidget*> dockWidgets;
QMap<VIEW_SECTIONS,QMap<QString,QWidget*> > centralWidgetToDockWidgetsMap;
bool isAdvancedMode; ///< If enabled dock widgets can be moved and floated.
bool dockWidgetTitleBarEnabled; ///< If enabled, dock widget titlebars are displayed when NOT in advanced mode.
MenuActionHelper *menuActionHelper;
Ui::MainWindow ui;
/** @brief Set the appropriate titlebar for a given dock widget.
......@@ -529,6 +513,7 @@ private:
QString getWindowStateKey();
QString getWindowGeometryKey();
friend class MenuActionHelper; //For VIEW_SECTIONS
};
#endif /* _MAINWINDOW_H_ */
......@@ -576,7 +576,7 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary)
{
if (file.toLower().endsWith(".qgw")) {
QWidget* parent = left?ui->generalLeftContents:ui->generalRightContents;
tool = new QGCToolWidget("", parent);
tool = new QGCToolWidget("", "", parent);
if (tool->loadSettings(generaldir.absoluteFilePath(file), false))
{
toolWidgets.append(tool);
......@@ -651,7 +651,7 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary)
foreach (QString file,newdir.entryList(QDir::Files| QDir::NoDotAndDotDot))
{
if (file.toLower().endsWith(".qgw")) {
tool = new QGCToolWidget("", tab);
tool = new QGCToolWidget("", "", tab);
if (tool->loadSettings(newdir.absoluteFilePath(file), false))
{
toolWidgets.append(tool);
......@@ -698,7 +698,7 @@ void QGCPX4VehicleConfig::loadQgcConfig(bool primary)
foreach (QString file,newdir.entryList(QDir::Files| QDir::NoDotAndDotDot))
{
if (file.toLower().endsWith(".qgw")) {
tool = new QGCToolWidget("", tab);
tool = new QGCToolWidget("", "", tab);
tool->addUAS(mav);
if (tool->loadSettings(newdir.absoluteFilePath(file), false))
{
......@@ -953,10 +953,8 @@ void QGCPX4VehicleConfig::loadConfig()
{
parent = ui->generalRightContents;
}
tool = new QGCToolWidget("", parent);
tool = new QGCToolWidget(parametersname, parametersname, parent);
tool->addUAS(mav);
tool->setTitle(parametersname);
tool->setObjectName(parametersname);
tool->setSettings(genset);
QList<QString> paramlist = tool->getParamList();
for (int i=0;i<paramlist.size();i++)
......@@ -1007,10 +1005,8 @@ void QGCPX4VehicleConfig::loadConfig()
{
parent = ui->generalRightContents;
}
tool = new QGCToolWidget("", parent);
tool = new QGCToolWidget(parametersname, parametersname, parent);
tool->addUAS(mav);
tool->setTitle(parametersname);
tool->setObjectName(parametersname);
tool->setSettings(advset);
QList<QString> paramlist = tool->getParamList();
for (int i=0;i<paramlist.size();i++)
......
......@@ -261,7 +261,7 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
{
if (file.toLower().endsWith(".qgw")) {
QWidget* parent = left?ui->generalLeftContents:ui->generalRightContents;
tool = new QGCToolWidget("", parent);
tool = new QGCToolWidget("", "", parent);
if (tool->loadSettings(generaldir.absoluteFilePath(file), false))
{
toolWidgets.append(tool);
......@@ -291,7 +291,7 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
{
if (file.toLower().endsWith(".qgw")) {
QWidget* parent = left?ui->advancedLeftContents:ui->advancedRightContents;
tool = new QGCToolWidget("", parent);
tool = new QGCToolWidget("", "", parent);
if (tool->loadSettings(vehicledir.absoluteFilePath(file), false))
{
toolWidgets.append(tool);
......@@ -342,7 +342,7 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
foreach (QString file,newdir.entryList(QDir::Files| QDir::NoDotAndDotDot))
{
if (file.toLower().endsWith(".qgw")) {
tool = new QGCToolWidget("", tab);
tool = new QGCToolWidget("", "", tab);
if (tool->loadSettings(newdir.absoluteFilePath(file), false))
{
toolWidgets.append(tool);
......@@ -389,7 +389,7 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
foreach (QString file,newdir.entryList(QDir::Files| QDir::NoDotAndDotDot))
{
if (file.toLower().endsWith(".qgw")) {
tool = new QGCToolWidget("", tab);
tool = new QGCToolWidget("","", tab);
tool->addUAS(mav);
if (tool->loadSettings(newdir.absoluteFilePath(file), false))
{
......@@ -411,7 +411,7 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
// Load general calibration for autopilot
//TODO: Handle this more gracefully, maybe have it scan the directory for multiple calibration entries?
tool = new QGCToolWidget("", ui->sensorContents);
tool = new QGCToolWidget("", "", ui->sensorContents);
tool->addUAS(mav);
if (tool->loadSettings(autopilotdir.absolutePath() + "/general/calibration/calibration.qgw", false))
{
......@@ -426,7 +426,7 @@ void QGCVehicleConfig::loadQgcConfig(bool primary)
}
// Load vehicle-specific autopilot configuration
tool = new QGCToolWidget("", ui->sensorContents);
tool = new QGCToolWidget("", "", ui->sensorContents);
tool->addUAS(mav);
if (tool->loadSettings(autopilotdir.absolutePath() + "/" + mav->getSystemTypeName().toLower() + "/calibration/calibration.qgw", false))
{
......@@ -681,10 +681,8 @@ void QGCVehicleConfig::loadConfig()
{
parent = ui->generalRightContents;
}
tool = new QGCToolWidget("", parent);
tool = new QGCToolWidget(parametersname, parametersname, parent);
tool->addUAS(mav);
tool->setTitle(parametersname);
tool->setObjectName(parametersname);
tool->setSettings(genset);
QList<QString> paramlist = tool->getParamList();
for (int i=0;i<paramlist.size();i++)
......@@ -735,10 +733,8 @@ void QGCVehicleConfig::loadConfig()
{
parent = ui->generalRightContents;
}
tool = new QGCToolWidget("", parent);
tool = new QGCToolWidget(parametersname, parametersname, parent);
tool->addUAS(mav);
tool->setTitle(parametersname);
tool->setObjectName(parametersname);
tool->setSettings(advset);
QList<QString> paramlist = tool->getParamList();
for (int i=0;i<paramlist.size();i++)
......@@ -1175,14 +1171,12 @@ void QGCVehicleConfig::parameterChanged(int uas, int component, QString paramete
}
// Create the tool, attaching it to the QGroupBox
QGCToolWidget *tool = new QGCToolWidget("", parent);
QString tooltitle = parameterName;
if (parameterName.split("_").size() > 1)
{
tooltitle = parameterName.split("_")[0] + "_";
}
tool->setTitle(tooltitle);
tool->setObjectName(tooltitle);
QGCToolWidget *tool = new QGCToolWidget(tooltitle, tooltitle, parent);
//tool->setSettings(set);
libParamToWidgetMap.insert(parameterName,tool);
toolWidgets.append(tool);
......
......@@ -16,7 +16,7 @@
#include "QGCCommandButton.h"
#include "UASManager.h"
QGCToolWidget::QGCToolWidget(const QString& title, QWidget *parent, QSettings* settings) :
QGCToolWidget::QGCToolWidget(const QString& objectName, const QString& title, QWidget *parent, QSettings* settings) :
QWidget(parent),
mav(NULL),
mainMenuAction(NULL),
......@@ -50,6 +50,11 @@ QGCToolWidget::QGCToolWidget(const QString& title, QWidget *parent, QSettings* s
}
connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(addUAS(UASInterface*)));
if(!objectName.isEmpty()) {
instances()->insert(objectName, this);
setObjectName(objectName);
} //Otherwise we must call loadSettings() immediately to set the object name
// Enforce storage if this not loaded from settings
// is MUST NOT BE SAVED if it was loaded from settings!
//if (!settings) storeWidgetsToSettings();
......@@ -58,7 +63,7 @@ QGCToolWidget::QGCToolWidget(const QString& title, QWidget *parent, QSettings* s
QGCToolWidget::~QGCToolWidget()
{
if (mainMenuAction) mainMenuAction->deleteLater();
if (QGCToolWidget::instances()) QGCToolWidget::instances()->remove(widgetTitle);
if (QGCToolWidget::instances()) QGCToolWidget::instances()->remove(objectName());
delete ui;
}
......@@ -98,11 +103,10 @@ QList<QGCToolWidget*> QGCToolWidget::createWidgetsFromSettings(QWidget* parent,
QString name = settings->value("TITLE", "").toString();
QString objname = settings->value("OBJECT_NAME", "").toString();
if (!instances()->contains(name) && name.length() != 0)
if (!instances()->contains(objname) && !objname.isEmpty())
{
//qDebug() << "CREATED WIDGET:" << name;
QGCToolWidget* tool = new QGCToolWidget(name, parent, settings);
tool->setObjectName(objname);
QGCToolWidget* tool = new QGCToolWidget(objname, name, parent, settings);
newWidgets.append(tool);
}
else if (name.length() == 0)
......@@ -154,12 +158,13 @@ bool QGCToolWidget::loadSettings(const QString& settings, bool singleinstance)
QStringList groups = set.childGroups();
if (groups.length() > 0)
{
QString widgetName = groups.first();
this->setObjectName(widgetName);
if (singleinstance && QGCToolWidget::instances()->keys().contains(widgetName)) return false;
QString objectName = groups.first();
setObjectName(objectName);
if (singleinstance && QGCToolWidget::instances()->contains(objectName)) return false;
instances()->insert(objectName, this);
// Do not use setTitle() here,
// interferes with loading settings
widgetTitle = widgetName;
widgetTitle = objectName;
//qDebug() << "WIDGET TITLE LOADED: " << widgetName;
loadSettings(set);
return true;
......@@ -385,7 +390,7 @@ void QGCToolWidget::storeWidgetsToSettings(QString settingsFile)
settings->setArrayIndex(num++);
settings->setValue("TITLE", instances()->values().at(i)->getTitle());
settings->setValue("OBJECT_NAME", instances()->values().at(i)->objectName());
//qDebug() << "WRITING TITLE" << instances()->values().at(i)->getTitle();
qDebug() << "WRITING TITLE" << instances()->values().at(i)->getTitle() << "object:" << instances()->values().at(i)->objectName();
}
}
else
......@@ -640,20 +645,16 @@ void QGCToolWidget::setTitle()
void QGCToolWidget::setTitle(const QString& title)
{
if (instances()->contains(widgetTitle)) instances()->remove(widgetTitle);
if (!instances()->contains(title)) instances()->insert(title, this);
// Sets title and calls setWindowTitle on QWidget
widgetTitle = title;
QWidget::setWindowTitle(title);
setObjectName(widgetTitle);
QDockWidget* dock = dynamic_cast<QDockWidget*>(this->parentWidget());
if (dock) {
if (dock)
dock->setWindowTitle(widgetTitle);
dock->setObjectName(widgetTitle+"DOCK");
}
emit titleChanged(title);
if (mainMenuAction) mainMenuAction->setText(title);
storeWidgetsToSettings();
}
void QGCToolWidget::setMainMenuAction(QAction* action)
......@@ -667,7 +668,7 @@ void QGCToolWidget::deleteWidget()
// Hide
this->hide();
instances()->remove(getTitle());
instances()->remove(objectName());
QSettings settings;
settings.beginGroup("QGC_MAINWINDOW");
......
......@@ -19,7 +19,7 @@ class QGCToolWidget : public QWidget
Q_OBJECT
public:
explicit QGCToolWidget(const QString& title=QString("Unnamed Tool"), QWidget *parent = 0, QSettings* settings = 0);
explicit QGCToolWidget(const QString& objectName, const QString& title, QWidget *parent = 0, QSettings* settings = 0);
~QGCToolWidget();
/** @brief Factory method to instantiate all tool widgets */
......@@ -85,7 +85,6 @@ protected:
QMap<int, Qt::DockWidgetArea> dockWidgetArea; ///< Dock widget area desired by this widget
QMap<int, bool> viewVisible; ///< Visibility in one view
QString widgetTitle;
static int instanceCount; ///< Number of instances around
void contextMenuEvent(QContextMenuEvent* event);
void createActions();
......@@ -104,6 +103,12 @@ protected slots:
void setTitle();
private:
/** Do not use this from outside the class to set the object name,
* because we cannot track changes to the object name, and the
* QObject::setObjectName() function is not virtual. Instead only
* pass in the object name to the constructor, or use the , then
* never change it again. */
void setObjectName(const QString &name) { QWidget::setObjectName(name); }
Ui::QGCToolWidget *ui;
};
......
#include <QDockWidget>
#include <QEvent>
#include <QLabel>
#include "dockwidgeteventfilter.h"
DockWidgetEventFilter::DockWidgetEventFilter(QObject *parent) : QObject(parent) {}
bool DockWidgetEventFilter::eventFilter(QObject *object,QEvent *event)
{
if (event->type() == QEvent::WindowTitleChange)
{
QDockWidget *dock = dynamic_cast<QDockWidget *>(object);
if(dock) {
QLabel *label = dynamic_cast<QLabel *>(dock->titleBarWidget());
if(label)
label->setText(dock->windowTitle());
}
}
return QObject::eventFilter(object,event);
}
#ifndef DOCKWIDGETEVENTFILTER_H
#define DOCKWIDGETEVENTFILTER_H
#include <QObject>
/** Event filter to update a QLabel titleBarWidget if the window's title changes */
class DockWidgetEventFilter : public QObject
{
Q_OBJECT
public:
DockWidgetEventFilter(QObject *parent = 0);
protected:
virtual bool eventFilter(QObject *object,QEvent *event) override;
};
#endif // DOCKWIDGETEVENTFILTER_H
#include "dockwidgettitlebareventfilter.h"
#include <QDebug>
#include <QEvent>
DockWidgetTitleBarEventFilter::DockWidgetTitleBarEventFilter(QObject *parent) : QObject(parent)
{
}
bool DockWidgetTitleBarEventFilter::eventFilter(QObject *object,QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)
{
return true;
}
return QObject::eventFilter(object,event);
}
#ifndef DOCKWIDGETTITLEBAREVENTFILTER_H
#define DOCKWIDGETTITLEBAREVENTFILTER_H
#include <QObject>
class DockWidgetTitleBarEventFilter : public QObject
{
Q_OBJECT
public:
explicit DockWidgetTitleBarEventFilter(QObject *parent = 0);
protected:
bool eventFilter(QObject *object,QEvent *event);
signals:
public slots:
};
#endif // DOCKWIDGETTITLEBAREVENTFILTER_H
#include "menuactionhelper.h"
MenuActionHelper::MenuActionHelper(QObject *parent) : QObject(parent),
m_isAdvancedMode(false),
m_dockWidgetTitleBarsEnabled(true),
m_addedCustomSeperator(false)
{
}
QAction *MenuActionHelper::createToolAction(const QString &title, const QString &name)
{
QAction *action = m_menuToDockNameMap.key(name); //For sanity, check that the action is not NULL
if(action) {
qWarning() << "createToolAction was called for action" << name << "which already exists in the menu";
return action;
}
action = new QAction(title, NULL);
action->setCheckable(true);
connect(action,SIGNAL(triggered(bool)),this,SLOT(showTool(bool)));
m_menuToDockNameMap[action] = name;
m_menu->addAction(action);
return action;
}
void MenuActionHelper::removeDockWidget()
{
QObject *dockWidget = QObject::sender(); //Note that we can't cast to QDockWidget because we are in its destructor
Q_ASSERT(dockWidget);
qDebug() << "Dockwidget:" << dockWidget->objectName() << "of type" << dockWidget->metaObject()->className();
QAction *action = m_menuToDockNameMap.key(dockWidget->objectName());
if(action) {
m_menuToDockNameMap.remove(action);
action->deleteLater();
}
QMap<MainWindow::VIEW_SECTIONS,QMap<QString,QDockWidget*> >::iterator it;
for (it = m_centralWidgetToDockWidgetsMap.begin(); it != m_centralWidgetToDockWidgetsMap.end(); ++it) {
QMap<QString,QDockWidget*>::iterator it2 = it.value().begin();
while( it2 != it.value().end()) {
if(it2.value() == dockWidget)
it2 = it.value().erase(it2);
else
++it2;
}
}
//Don't delete the dockWidget because this could have been called from the dockWidget destructor
m_dockWidgets.removeAll(static_cast<QDockWidget*>(dockWidget));
}
QAction *MenuActionHelper::createToolActionForCustomDockWidget(const QString &title, const QString& name, QDockWidget* dockWidget, MainWindow::VIEW_SECTIONS view) {
bool found = false;
QAction *action = NULL;
foreach(QAction *act, m_menuToDockNameMap.keys()) {
if(act->text() == title) {
found = true;
action = act;
}
}
if(!found)
action = createToolAction(title, name);
else
m_menuToDockNameMap[action] = name;
m_centralWidgetToDockWidgetsMap[view][name] = dockWidget;
connect(dockWidget, SIGNAL(destroyed()), SLOT(removeDockWidget()),Qt::UniqueConnection); //Use UniqueConnection since we might have already created this connection in createDockWidget
connect(dockWidget, SIGNAL(visibilityChanged(bool)), action, SLOT(setChecked(bool)));
action->setChecked(dockWidget->isVisible());
return action;
}
QDockWidget* MenuActionHelper::createDockWidget(const QString& title,const QString& name)
{
QDockWidget *dockWidget = new QDockWidget(title);
m_dockWidgets.append(dockWidget);
setDockWidgetTitleBar(dockWidget);
dockWidget->setObjectName(name);
connect(dockWidget, SIGNAL(destroyed()), SLOT(removeDockWidget()));
return dockWidget;
}
bool MenuActionHelper::containsDockWidget(MainWindow::VIEW_SECTIONS view, const QString &name) const {
return m_centralWidgetToDockWidgetsMap.contains(view) && m_centralWidgetToDockWidgetsMap[view].contains(name);
}
QDockWidget *MenuActionHelper::getDockWidget(MainWindow::VIEW_SECTIONS view, const QString &name) const {
if(!m_centralWidgetToDockWidgetsMap.contains(view))
return NULL;
return m_centralWidgetToDockWidgetsMap[view].value(name);
}
void MenuActionHelper::showTool(bool show) {
//Called when a menu item is clicked on, regardless of view.
QAction* act = qobject_cast<QAction *>(sender());
Q_ASSERT(act);
if (m_menuToDockNameMap.contains(act)) {
QString name = m_menuToDockNameMap[act];
emit needToShowDockWidget(name, show);
}
}
void MenuActionHelper::setDockWidgetTitleBarsEnabled(bool enabled)
{
m_dockWidgetTitleBarsEnabled = enabled;
for (int i = 0; i < m_dockWidgets.size(); i++)
setDockWidgetTitleBar(m_dockWidgets[i]);
}
void MenuActionHelper::setAdvancedMode(bool advancedMode)
{
m_isAdvancedMode = advancedMode;
for (int i = 0; i < m_dockWidgets.size(); i++)
setDockWidgetTitleBar(m_dockWidgets[i]);
}
void MenuActionHelper::setDockWidgetTitleBar(QDockWidget* widget)
{
Q_ASSERT(widget);
QWidget* oldTitleBar = widget->titleBarWidget();
// In advanced mode, we use the default titlebar provided by Qt.
if (m_isAdvancedMode)
{
widget->setTitleBarWidget(0);
}
// Otherwise, if just a textlabel should be shown, make that the titlebar.
else if (m_dockWidgetTitleBarsEnabled)
{
QLabel* label = new QLabel(widget);
label->setText(widget->windowTitle());
label->installEventFilter(this); //Ignore mouse clicks
widget->installEventFilter(this); //Update label if window title changes. See eventFilter below
widget->setTitleBarWidget(label);
}
// And if nothing should be shown, use an empty widget.
else
{
QWidget* newTitleBar = new QWidget(widget);
widget->setTitleBarWidget(newTitleBar);
}
// Be sure to clean up the old titlebar. When using QDockWidget::setTitleBarWidget(),
// it doesn't delete the old titlebar object.
delete oldTitleBar;
}
bool MenuActionHelper::eventFilter(QObject *object,QEvent *event)
{
if (event->type() == QEvent::WindowTitleChange)
{
QDockWidget *dock = qobject_cast<QDockWidget *>(object);
if(dock) {
// Update the dock title bar label
QLabel *label = dynamic_cast<QLabel *>(dock->titleBarWidget());
if(label)
label->setText(dock->windowTitle());
// Now update the action label
QString oldObjectName = dock->objectName();
QAction *action = m_menuToDockNameMap.key(oldObjectName);
if(action)
action->setText(dock->windowTitle());
//Now modify the object name - it is a strange naming scheme..
/* QString newObjectName = widgetTitle+"DOCK";
dock->setObjectName(newObjectName);
m_menuToDockNameMap[action] = newObjectName;
QMap<MainWindow::VIEW_SECTIONS,QMap<QString,QDockWidget*> >::iterator it;
for (it = m_centralWidgetToDockWidgetsMap.begin(); it != m_centralWidgetToDockWidgetsMap.end(); ++it) {
QMap<QString,QDockWidget*> &map = it.value();
map[newObjectName] = map[oldObjectName];
map.remove(oldObjectName);
}*/
}
} else if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)
{
if(qobject_cast<QLabel *>(object))
return true;
}
return QObject::eventFilter(object,event);
}
#ifndef MENUACTIONHELPER_H
#define MENUACTIONHELPER_H
#include "MainWindow.h"
class MenuActionHelper : public QObject
{
Q_OBJECT
public:
MenuActionHelper(QObject *parent = NULL);
~MenuActionHelper() {}
/** @brief Get title bar mode setting */
bool dockWidgetTitleBarsEnabled() const { return m_dockWidgetTitleBarsEnabled; }
void setDockWidgetTitleBarsEnabled(bool enabled);
bool isAdvancedMode() const { return m_isAdvancedMode; }
void setAdvancedMode(bool advancedMode);
QAction *createToolAction(const QString &title, const QString &name = QString());
QAction *createToolActionForCustomDockWidget(const QString& title, const QString& name, QDockWidget* dockWidget, MainWindow::VIEW_SECTIONS view);
QDockWidget *createDockWidget(const QString& title, const QString& name);
bool containsDockWidget(MainWindow::VIEW_SECTIONS view, const QString &name) const;
QDockWidget *getDockWidget(MainWindow::VIEW_SECTIONS view, const QString &name) const;
/** QMenu to add QActions to */
void setMenu(QMenu *menu) { m_menu = menu; }
protected:
virtual bool eventFilter(QObject *object,QEvent *event);
private slots:
void removeDockWidget();
/** @brief Shows a Docked Widget based on the action sender */
void showTool(bool show);
signals:
void needToShowDockWidget(const QString& name, bool show);
private:
QMap<QAction*,QString > m_menuToDockNameMap;
QList<QDockWidget*> m_dockWidgets;
QMap<MainWindow::VIEW_SECTIONS,QMap<QString,QDockWidget*> > m_centralWidgetToDockWidgetsMap;
bool m_isAdvancedMode; ///< If enabled dock widgets can be moved and floated.
bool m_dockWidgetTitleBarsEnabled; ///< If enabled, dock widget titlebars are displayed when NOT in advanced mode.
QMenu *m_menu; ///< \see setMenu()
bool m_addedCustomSeperator; ///< Whether we have added a seperator between the actions and the custom actions
void setDockWidgetTitleBar(QDockWidget* widget);
};
#endif // MENUACTIONHELPER_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment