diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index fcf375d399d2fe112f6ea55d17a8d4911f4853c8..bf5ace6e15875d528032676054c96a743f53a8a4 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -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 diff --git a/src/ui/HDDisplay.cc b/src/ui/HDDisplay.cc index 7c11cd86bd8b5bcc2c736fc9689a1f3974f68280..d3c12290aacc01b6db03377f51cc1f29d95e76aa 100644 --- a/src/ui/HDDisplay.cc +++ b/src/ui/HDDisplay.cc @@ -27,7 +27,7 @@ #include "MainWindow.h" #include -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 diff --git a/src/ui/HDDisplay.h b/src/ui/HDDisplay.h index f6c5295d79edfc53b2c175ce9f1990e9682fffd3..e39090d7c499d1ee674345dfdf6adba954fea5e0 100644 --- a/src/ui/HDDisplay.h +++ b/src/ui/HDDisplay.h @@ -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: diff --git a/src/ui/HSIDisplay.cc b/src/ui/HSIDisplay.cc index a1e0cc1c89ba1d6950f83463a4bf49b9e3d0ca86..4e05a479a6068578c6d521f623216e916f81289f 100644 --- a/src/ui/HSIDisplay.cc +++ b/src/ui/HSIDisplay.cc @@ -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), diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index f3d65230bde412ab17311442f5232b7dc04b4bfb..31662b8ba2d3aa467222e31c9b5e8f6314c19f2e 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -39,8 +39,6 @@ This file is part of the QGROUNDCONTROL project #include #include #include -#include "dockwidgettitlebareventfilter.h" -#include "dockwidgeteventfilter.h" #include "QGC.h" #include "MAVLinkSimulationLink.h" #include "SerialLink.h" @@ -72,6 +70,7 @@ This file is part of the QGROUNDCONTROL project #include #include "SerialSettingsDialog.h" #include "terminalconsole.h" +#include "menuactionhelper.h" #ifdef QGC_OSG_ENABLED #include "Q3DWidgetFactory.h" @@ -128,12 +127,12 @@ MainWindow::MainWindow(QWidget *parent): autoReconnect(false), simulationLink(NULL), lowPowerMode(false), - isAdvancedMode(false), mavlink(new MAVLinkProtocol()), - dockWidgetTitleBarEnabled(true), - customMode(CUSTOM_MODE_NONE) + customMode(CUSTOM_MODE_NONE), + menuActionHelper(new MenuActionHelper()) { this->setAttribute(Qt::WA_DeleteOnClose); + connect(menuActionHelper, SIGNAL(needToShowDockWidget(QString,bool)),SLOT(showDockWidget(QString,bool))); //TODO: move protocol outside UI connect(mavlink, SIGNAL(protocolStatusMessage(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection); loadSettings(); @@ -155,7 +154,7 @@ void MainWindow::init() if (settings.contains("ADVANCED_MODE")) { - isAdvancedMode = settings.value("ADVANCED_MODE").toBool(); + menuActionHelper->setAdvancedMode(settings.value("ADVANCED_MODE").toBool()); } if (!settings.contains("CURRENT_VIEW")) @@ -182,6 +181,7 @@ void MainWindow::init() // Setup user interface ui.setupUi(this); hide(); + menuActionHelper->setMenu(ui.menuTools); // We only need this menu if we have more than one system // ui.menuConnected_Systems->setEnabled(false); @@ -386,12 +386,8 @@ MainWindow::~MainWindow() } } // Delete all UAS objects - - - if (debugConsole) - { - delete debugConsole; - } + delete debugConsole; + delete menuActionHelper; for (int i=0;ideleteLater(); @@ -439,17 +435,6 @@ void MainWindow::buildCustomWidget() QSettings settings; settings.beginGroup("QGC_MAINWINDOW"); - /*QDockWidget* dock = new QDockWidget(tool->windowTitle(), this); - dock->setObjectName(tool->objectName()+"_DOCK"); - dock->setWidget(tool); - connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater())); - QAction* showAction = new QAction(widgets.at(i)->windowTitle(), this); - showAction->setCheckable(true); - connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool))); - connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool))); - widgets.at(i)->setMainMenuAction(showAction); - ui.menuTools->addAction(showAction);*/ - // Load dock widget location (default is bottom) Qt::DockWidgetArea location = tool->getDockWidgetArea(currentView); @@ -577,36 +562,19 @@ void MainWindow::buildCommonWidgets() } // Dock widgets - QAction* tempAction = ui.menuTools->addAction(tr("Control")); - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - createDockWidget(simView,new UASControlWidget(this),tr("Control"),"UNMANNED_SYSTEM_CONTROL_DOCKWIDGET",VIEW_SIMULATION,Qt::LeftDockWidgetArea); createDockWidget(plannerView,new UASListWidget(this),tr("Unmanned Systems"),"UNMANNED_SYSTEM_LIST_DOCKWIDGET",VIEW_MISSION,Qt::LeftDockWidgetArea); createDockWidget(plannerView,new QGCWaypointListMulti(this),tr("Mission Plan"),"WAYPOINT_LIST_DOCKWIDGET",VIEW_MISSION,Qt::BottomDockWidgetArea); - { - //createDockWidget(plannerView,new QGCWaypointListMulti(this),tr("Mission Plan"),"WAYPOINT_LIST_DOCKWIDGET",VIEW_MISSION,Qt::BottomDockWidgetArea); - QAction* tempAction = ui.menuTools->addAction(tr("Mission Plan")); - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - menuToDockNameMap[tempAction] = "WAYPOINT_LIST_DOCKWIDGET"; - } - createDockWidget(simView,new QGCWaypointListMulti(this),tr("Mission Plan"),"WAYPOINT_LIST_DOCKWIDGET",VIEW_SIMULATION,Qt::BottomDockWidgetArea); createDockWidget(engineeringView,new QGCMAVLinkInspector(mavlink,this),tr("MAVLink Inspector"),"MAVLINK_INSPECTOR_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea); createDockWidget(engineeringView,new ParameterInterface(this),tr("Onboard Parameters"),"PARAMETER_INTERFACE_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea); createDockWidget(simView,new ParameterInterface(this),tr("Onboard Parameters"),"PARAMETER_INTERFACE_DOCKWIDGET",VIEW_SIMULATION,Qt::RightDockWidgetArea); + menuActionHelper->createToolAction(tr("Status Details"), "UAS_STATUS_DETAILS_DOCKWIDGET"); - { - QAction* tempAction = ui.menuTools->addAction(tr("Status Details")); - menuToDockNameMap[tempAction] = "UAS_STATUS_DETAILS_DOCKWIDGET"; - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - } { if (!debugConsole) { @@ -614,40 +582,22 @@ void MainWindow::buildCommonWidgets() debugConsole->setWindowTitle("Communications Console"); debugConsole->hide(); QAction* tempAction = ui.menuTools->addAction(tr("Communication Console")); - //menuToDockNameMap[tempAction] = "COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET"; tempAction->setCheckable(true); connect(tempAction,SIGNAL(triggered(bool)),debugConsole,SLOT(setShown(bool))); - } } createDockWidget(simView,new HSIDisplay(this),tr("Horizontal Situation"),"HORIZONTAL_SITUATION_INDICATOR_DOCKWIDGET",VIEW_SIMULATION,Qt::BottomDockWidgetArea); - { - QAction* tempAction = ui.menuTools->addAction(tr("Flight Display")); - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - menuToDockNameMap[tempAction] = "HEAD_DOWN_DISPLAY_1_DOCKWIDGET"; - } - - { - QAction* tempAction = ui.menuTools->addAction(tr("Actuator Status")); - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - menuToDockNameMap[tempAction] = "HEAD_DOWN_DISPLAY_2_DOCKWIDGET"; - } - - { - QAction* tempAction = ui.menuTools->addAction(tr("Radio Control")); - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - } + menuActionHelper->createToolAction(tr("Flight Display"), "HEAD_DOWN_DISPLAY_1_DOCKWIDGET"); + menuActionHelper->createToolAction(tr("Actuator Status"), "HEAD_DOWN_DISPLAY_2_DOCKWIDGET"); + menuActionHelper->createToolAction(tr("Radio Control")); - createDockWidget(engineeringView,new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea,this->width()/1.5); + createDockWidget(engineeringView,new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea,QSize(this->width()/1.5,0)); - createDockWidget(engineeringView,new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea,this->width()/1.5); + createDockWidget(engineeringView,new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea,QSize(this->width()/1.5,0)); - createDockWidget(simView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_SIMULATION,Qt::RightDockWidgetArea,this->width()/1.5); - createDockWidget(pilotView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea,this->width()/1.8); + createDockWidget(simView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_SIMULATION,Qt::RightDockWidgetArea,QSize(this->width()/1.5,0)); + createDockWidget(pilotView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea,QSize(this->width()/1.8,0)); QGCTabbedInfoView *infoview = new QGCTabbedInfoView(this); infoview->addSource(mavlinkDecoder); @@ -730,83 +680,38 @@ void MainWindow::buildCommonWidgets() void MainWindow::addTool(SubMainWindow *parent,VIEW_SECTIONS view,QDockWidget* widget, const QString& title, Qt::DockWidgetArea area) { - QList actionlist = ui.menuTools->actions(); - bool found = false; - QAction *targetAction; - for (int i=0;itext() == title) - { - found = true; - targetAction = actionlist[i]; - } - } - if (!found) - { - QAction* tempAction = ui.menuTools->addAction(title); - tempAction->setCheckable(true); - menuToDockNameMap[tempAction] = widget->objectName(); - if (!centralWidgetToDockWidgetsMap.contains(view)) - { - centralWidgetToDockWidgetsMap[view] = QMap(); - } - centralWidgetToDockWidgetsMap[view][widget->objectName()]= widget; - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); - connect(widget, SIGNAL(visibilityChanged(bool)), tempAction, SLOT(setChecked(bool))); - connect(widget, SIGNAL(destroyed()), tempAction, SLOT(deleteLater())); - tempAction->setChecked(widget->isVisible()); - } - else - { - if (!menuToDockNameMap.contains(targetAction)) - { - menuToDockNameMap[targetAction] = widget->objectName(); - //menuToDockNameMap[targetAction] = title; - } - if (!centralWidgetToDockWidgetsMap.contains(view)) - { - centralWidgetToDockWidgetsMap[view] = QMap(); - } - centralWidgetToDockWidgetsMap[view][widget->objectName()]= widget; - connect(widget, SIGNAL(visibilityChanged(bool)), targetAction, SLOT(setChecked(bool))); - } + menuActionHelper->createToolActionForCustomDockWidget(title, widget->objectName(), widget, view); parent->addDockWidget(area,widget); } -QDockWidget* MainWindow::createDockWidget(QWidget *parent,QWidget *child,QString title,QString objectname,VIEW_SECTIONS view,Qt::DockWidgetArea area,int minwidth,int minheight) +QDockWidget* MainWindow::createDockWidget(QWidget *subMainWindowParent,QWidget *child,const QString& title,const QString& objectName,VIEW_SECTIONS view,Qt::DockWidgetArea area,const QSize& minSize) { - child->setObjectName(objectname); - QDockWidget *widget = new QDockWidget(title,this); - dockWidgets.append(widget); - setDockWidgetTitleBar(widget); - widget->setObjectName(child->objectName()); - widget->setWidget(child); - if (minheight != 0 || minwidth != 0) - { - widget->setMinimumHeight(minheight); - widget->setMinimumWidth(minwidth); - } - addTool(qobject_cast(parent),view,widget,title,area); - connect(child, SIGNAL(destroyed()), widget, SLOT(deleteLater())); - connect(widget, SIGNAL(destroyed()), this, SLOT(dockWidgetDestroyed())); + SubMainWindow *parent = qobject_cast(subMainWindowParent); + Q_ASSERT(parent); + QDockWidget* dockWidget = menuActionHelper->createDockWidget(title, objectName); + child->setObjectName(objectName); + dockWidget->setWidget(child); //Set child objectName before setting dockwidget, since the dock widget might react to object name changes + connect(child, SIGNAL(destroyed()), dockWidget, SLOT(deleteLater())); //Our dockwidget only has only child widget, so kill the dock widget if the child is deleted - return widget; + if (!minSize.isNull()) + dockWidget->setMinimumSize(minSize); + addTool(parent,view,dockWidget,title,area); + return dockWidget; } -void MainWindow::dockWidgetDestroyed() -{ - QDockWidget *dock = dynamic_cast(QObject::sender()); - Q_ASSERT(dock); - if(!dock) return; - dockWidgets.removeAll(dock); +void MainWindow::showDockWidget(const QString& name, bool show) +{ + QDockWidget *dockWidget = menuActionHelper->getDockWidget(currentView, name); + if(dockWidget) + dockWidget->setVisible(show); + else if (show) + loadDockWidget(name); } -void MainWindow::loadDockWidget(QString name) +void MainWindow::loadDockWidget(const QString& name) { - if (centralWidgetToDockWidgetsMap[currentView].contains(name)) - { + if(menuActionHelper->containsDockWidget(currentView, name)) return; - } if (name.startsWith("HIL_CONFIG")) { //It's a HIL widget. @@ -839,8 +744,6 @@ void MainWindow::loadDockWidget(QString name) else if (name == "COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET") { //This is now a permanently detached window. - //centralWidgetToDockWidgetsMap[currentView][name] = console; - //createDockWidget(centerStack->currentWidget(),new DebugConsole(this),tr("Communication Console"),"COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET",currentView,Qt::BottomDockWidgetArea); } else if (name == "HORIZONTAL_SITUATION_INDICATOR_DOCKWIDGET") { @@ -848,21 +751,19 @@ void MainWindow::loadDockWidget(QString name) } else if (name == "HEAD_DOWN_DISPLAY_1_DOCKWIDGET") { - //FIXME: memory of acceptList will never be freed again - QStringList* acceptList = new QStringList(); - acceptList->append("-3.3,ATTITUDE.roll,rad,+3.3,s"); - acceptList->append("-3.3,ATTITUDE.pitch,deg,+3.3,s"); - acceptList->append("-3.3,ATTITUDE.yaw,deg,+3.3,s"); + QStringList acceptList; + acceptList.append("-3.3,ATTITUDE.roll,rad,+3.3,s"); + acceptList.append("-3.3,ATTITUDE.pitch,deg,+3.3,s"); + acceptList.append("-3.3,ATTITUDE.yaw,deg,+3.3,s"); HDDisplay *hddisplay = new HDDisplay(acceptList,"Flight Display",this); hddisplay->addSource(mavlinkDecoder); createDockWidget(centerStack->currentWidget(),hddisplay,tr("Flight Display"),"HEAD_DOWN_DISPLAY_1_DOCKWIDGET",currentView,Qt::RightDockWidgetArea); } else if (name == "HEAD_DOWN_DISPLAY_2_DOCKWIDGET") { - //FIXME: memory of acceptList2 will never be freed again - QStringList* acceptList2 = new QStringList(); - acceptList2->append("0,RAW_PRESSURE.pres_abs,hPa,65500"); - HDDisplay *hddisplay = new HDDisplay(acceptList2,"Actuator Status",this); + QStringList acceptList; + acceptList.append("0,RAW_PRESSURE.pres_abs,hPa,65500"); + HDDisplay *hddisplay = new HDDisplay(acceptList,"Actuator Status",this); hddisplay->addSource(mavlinkDecoder); createDockWidget(centerStack->currentWidget(),hddisplay,tr("Actuator Status"),"HEAD_DOWN_DISPLAY_2_DOCKWIDGET",currentView,Qt::RightDockWidgetArea); } @@ -873,7 +774,6 @@ void MainWindow::loadDockWidget(QString name) } else if (name == "PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET") { - // createDockWidget(centerStack->currentWidget(),new HUD(320,240,this),tr("Head Up Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",currentView,Qt::RightDockWidgetArea); createDockWidget(centerStack->currentWidget(),new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"HEAD_UP_DISPLAY_DOCKWIDGET",currentView,Qt::RightDockWidgetArea); } else if (name == "UAS_INFO_QUICKVIEW_DOCKWIDGET") @@ -894,80 +794,6 @@ void MainWindow::loadDockWidget(QString name) } } -void MainWindow::setDockWidgetTitleBar(QDockWidget* widget) -{ - QWidget* oldTitleBar = widget->titleBarWidget(); - - // In advanced mode, we use the default titlebar provided by Qt. - if (isAdvancedMode) - { - widget->setTitleBarWidget(0); - } - // Otherwise, if just a textlabel should be shown, make that the titlebar. - else if (dockWidgetTitleBarEnabled) - { - QLabel* label = new QLabel(this); - label->setText(widget->windowTitle()); - label->installEventFilter(new DockWidgetTitleBarEventFilter()); //Ignore mouse clicks - widget->installEventFilter(new DockWidgetEventFilter()); //Update label if window title changes - widget->setTitleBarWidget(label); - } - // And if nothing should be shown, use an empty widget. - else - { - QWidget* newTitleBar = new QWidget(this); - widget->setTitleBarWidget(newTitleBar); - } - - // Be sure to clean up the old titlebar. When using QDockWidget::setTitleBarWidget(), - // it doesn't delete the old titlebar object. - if (oldTitleBar) - { - delete oldTitleBar; - } -} - -void MainWindow::showTool(bool show) -{ - //Called when a menu item is clicked on, regardless of view. - - QAction* act = qobject_cast(sender()); - if (menuToDockNameMap.contains(act)) - { - QString name = menuToDockNameMap[act]; - if (centralWidgetToDockWidgetsMap.contains(currentView)) - { - if (centralWidgetToDockWidgetsMap[currentView].contains(name)) - { - if (show) - { - centralWidgetToDockWidgetsMap[currentView][name]->show(); - } - else - { - centralWidgetToDockWidgetsMap[currentView][name]->hide(); - } - } - else if (show) - { - loadDockWidget(name); - } - } - } - //QWidget* widget = qVariantValue(act->data()); - //widget->setVisible(show); -} -/*void addToolByName(QString name,SubMainWindow parent,const QString& title, Qt::DockWidgetArea area) -{ - if (name == "Control") - { - QDockWidget *widget = new QDockWidget(tr("Control"),this); - dockToTitleBarMap[widget] = widget->titleBarWidget(); - widget->setObjectName("UNMANNED_SYSTEM_CONTROL_DOCKWIDGET"); - widget->setWidget(new UASControlWidget(this)); - addTool(parent,VIEW_SIMULATION,widget,tr("Control"),area); - } -}*/ void MainWindow::addToCentralStackedWidget(QWidget* widget, VIEW_SECTIONS viewSection, const QString& title) { Q_UNUSED(title); @@ -977,7 +803,6 @@ void MainWindow::addToCentralStackedWidget(QWidget* widget, VIEW_SECTIONS viewSe if (centerStack->indexOf(widget) == -1) { centerStack->addWidget(widget); - centralWidgetToDockWidgetsMap[viewSection] = QMap(); } } @@ -996,18 +821,10 @@ void MainWindow::showHILConfigurationWidget(UASInterface* uas) if (mav && !hilDocks.contains(mav->getUASID())) { - //QGCToolWidget* tool = new QGCToolWidget("Unnamed Tool " + QString::number(ui.menuTools->actions().size())); - //createDockWidget(centerStack->currentWidget(),tool,"Unnamed Tool " + QString::number(ui.menuTools->actions().size()),"UNNAMED_TOOL_" + QString::number(ui.menuTools->actions().size())+"DOCK",currentView,Qt::BottomDockWidgetArea); - QGCHilConfiguration* hconf = new QGCHilConfiguration(mav, this); QString hilDockName = tr("HIL Config %1").arg(uas->getUASName()); QDockWidget* hilDock = createDockWidget(simView, hconf,hilDockName, hilDockName.toUpper().replace(" ", "_"),VIEW_SIMULATION,Qt::LeftDockWidgetArea); hilDocks.insert(mav->getUASID(), hilDock); - - // if (currentView != VIEW_SIMULATION) - // hilDock->hide(); - // else - // hilDock->show(); } } @@ -1035,33 +852,20 @@ void MainWindow::connectCommonWidgets() void MainWindow::createCustomWidget() { - //void MainWindow::createDockWidget(QWidget *parent,QWidget *child,QString title,QString objectname,VIEW_SECTIONS view,Qt::DockWidgetArea area,int minwidth,int minheight) - //QDockWidget* dock = new QDockWidget("Unnamed Tool", this); - if (QGCToolWidget::instances()->isEmpty()) { // This is the first widget ui.menuTools->addSeparator(); } - QGCToolWidget* tool = new QGCToolWidget("Unnamed Tool " + QString::number(ui.menuTools->actions().size())); - createDockWidget(centerStack->currentWidget(),tool,"Unnamed Tool " + QString::number(ui.menuTools->actions().size()),"UNNAMED_TOOL_" + QString::number(ui.menuTools->actions().size())+"DOCK",currentView,Qt::BottomDockWidgetArea); - //tool->setObjectName("UNNAMED_TOOL_" + QString::number(ui.menuTools->actions().size())); + QString title = "Unnamed Tool " + QString::number(ui.menuTools->actions().size()); + QString objectName = "UNNAMED_TOOL_" + QString::number(ui.menuTools->actions().size())+"DOCK"; + QGCToolWidget* tool = new QGCToolWidget(objectName, title); + createDockWidget(centerStack->currentWidget(),tool,title,objectName,currentView,Qt::BottomDockWidgetArea); + QSettings settings; settings.beginGroup("QGC_MAINWINDOW"); settings.setValue(QString("TOOL_PARENT_") + tool->objectName(),currentView); settings.endGroup(); - - //connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater())); - //dock->setWidget(tool); - - //QAction* showAction = new QAction(tool->getTitle(), this); - //showAction->setCheckable(true); - //connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool))); - //connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool))); - //tool->setMainMenuAction(showAction); - //ui.menuTools->addAction(showAction); - //this->addDockWidget(Qt::BottomDockWidgetArea, dock); - //dock->setVisible(true); } void MainWindow::loadCustomWidget() @@ -1072,7 +876,7 @@ void MainWindow::loadCustomWidget() } void MainWindow::loadCustomWidget(const QString& fileName, int view) { - QGCToolWidget* tool = new QGCToolWidget("", this); + QGCToolWidget* tool = new QGCToolWidget("", "", this); if (tool->loadSettings(fileName, true)) { qDebug() << "Loading custom tool:" << tool->getTitle() << tool->objectName(); @@ -1091,16 +895,12 @@ void MainWindow::loadCustomWidget(const QString& fileName, int view) createDockWidget(plannerView,tool,tool->getTitle(),tool->objectName()+"DOCK",(VIEW_SECTIONS)view,Qt::LeftDockWidgetArea); break; default: - { + { //Delete tool, create menu item to tie it to. customWidgetNameToFilenameMap[tool->objectName()+"DOCK"] = fileName; - QAction* tempAction = ui.menuTools->addAction(tool->getTitle()); - menuToDockNameMap[tempAction] = tool->objectName()+"DOCK"; - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); + menuActionHelper->createToolAction(tool->getTitle(), tool->objectName()+"DOCK"); tool->deleteLater(); - //createDockWidget(centerStack->currentWidget(),tool,tool->getTitle(),tool->objectName()+"DOCK",(VIEW_SECTIONS)view,Qt::LeftDockWidgetArea); - } + } break; } } @@ -1112,7 +912,7 @@ void MainWindow::loadCustomWidget(const QString& fileName, int view) void MainWindow::loadCustomWidget(const QString& fileName, bool singleinstance) { - QGCToolWidget* tool = new QGCToolWidget("", this); + QGCToolWidget* tool = new QGCToolWidget("", "", this); if (tool->loadSettings(fileName, true) || !singleinstance) { qDebug() << "Loading custom tool:" << tool->getTitle() << tool->objectName(); @@ -1136,35 +936,18 @@ void MainWindow::loadCustomWidget(const QString& fileName, bool singleinstance) createDockWidget(plannerView,tool,tool->getTitle(),tool->objectName()+"DOCK",(VIEW_SECTIONS)view,Qt::LeftDockWidgetArea); break; default: - { + { //Delete tool, create menu item to tie it to. customWidgetNameToFilenameMap[tool->objectName()+"DOCK"] = fileName; - QAction* tempAction = ui.menuTools->addAction(tool->getTitle()); - menuToDockNameMap[tempAction] = tool->objectName()+"DOCK"; - tempAction->setCheckable(true); - connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool))); + QAction *action = menuActionHelper->createToolAction(tool->getTitle(), tool->objectName()+"DOCK"); + ui.menuTools->addAction(action); tool->deleteLater(); - //createDockWidget(centerStack->currentWidget(),tool,tool->getTitle(),tool->objectName()+"DOCK",(VIEW_SECTIONS)view,Qt::LeftDockWidgetArea); - } + } break; } settings.endGroup(); - // Add widget to UI - /*QDockWidget* dock = new QDockWidget(tool->getTitle(), this); - connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater())); - dock->setWidget(tool); - tool->setParent(dock); - - QAction* showAction = new QAction(tool->getTitle(), this); - showAction->setCheckable(true); - connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool))); - connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool))); - tool->setMainMenuAction(showAction); - ui.menuTools->addAction(showAction); - this->addDockWidget(Qt::BottomDockWidgetArea, dock); - dock->hide();*/ } else { @@ -1214,7 +997,7 @@ void MainWindow::loadSettings() darkStyleFileName = settings.value("DARK_STYLE_FILENAME", darkStyleFileName).toString(); lightStyleFileName = settings.value("LIGHT_STYLE_FILENAME", lightStyleFileName).toString(); lowPowerMode = settings.value("LOW_POWER_MODE", lowPowerMode).toBool(); - dockWidgetTitleBarEnabled = settings.value("DOCK_WIDGET_TITLEBARS",dockWidgetTitleBarEnabled).toBool(); + bool dockWidgetTitleBarEnabled = settings.value("DOCK_WIDGET_TITLEBARS",menuActionHelper->dockWidgetTitleBarsEnabled()).toBool(); settings.endGroup(); enableDockWidgetTitleBars(dockWidgetTitleBarEnabled); } @@ -1308,17 +1091,12 @@ void MainWindow::saveScreen() } void MainWindow::enableDockWidgetTitleBars(bool enabled) { - dockWidgetTitleBarEnabled = enabled; + menuActionHelper->setDockWidgetTitleBarsEnabled(enabled); QSettings settings; settings.beginGroup("QGC_MAINWINDOW"); - settings.setValue("DOCK_WIDGET_TITLEBARS",dockWidgetTitleBarEnabled); + settings.setValue("DOCK_WIDGET_TITLEBARS",enabled); settings.endGroup(); settings.sync(); - - for (int i = 0; i < dockWidgets.size(); i++) - { - setDockWidgetTitleBar(dockWidgets[i]); - } } void MainWindow::enableAutoReconnect(bool enabled) @@ -1488,8 +1266,8 @@ void MainWindow::connectCommonActions() // Connect actions from ui connect(ui.actionAdd_Link, SIGNAL(triggered()), this, SLOT(addLink())); - ui.actionAdvanced_Mode->setChecked(isAdvancedMode); - connect(ui.actionAdvanced_Mode,SIGNAL(triggered()),this,SLOT(setAdvancedMode())); + ui.actionAdvanced_Mode->setChecked(menuActionHelper->isAdvancedMode()); + connect(ui.actionAdvanced_Mode,SIGNAL(toggled(bool)),this,SLOT(setAdvancedMode(bool))); // Connect internal actions connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(UASCreated(UASInterface*))); @@ -2085,16 +1863,11 @@ void MainWindow::loadViewState() win->restoreState(settings.value(getWindowStateKey()).toByteArray(), QGC::applicationVersion()); } } -void MainWindow::setAdvancedMode() +void MainWindow::setAdvancedMode(bool isAdvancedMode) { - isAdvancedMode = !isAdvancedMode; + menuActionHelper->setAdvancedMode(isAdvancedMode); ui.actionAdvanced_Mode->setChecked(isAdvancedMode); settings.setValue("ADVANCED_MODE",isAdvancedMode); - - for (int i = 0; i < dockWidgets.size(); i++) - { - setDockWidgetTitleBar(dockWidgets[i]); - } } void MainWindow::loadEngineerView() @@ -2217,11 +1990,16 @@ void MainWindow::loadMAVLinkView() //} -QList MainWindow::listLinkMenuActions(void) +QList MainWindow::listLinkMenuActions() { return ui.menuNetwork->actions(); } +bool MainWindow::dockWidgetTitleBarsEnabled() const +{ + return menuActionHelper->dockWidgetTitleBarsEnabled(); +} + #ifdef MOUSE_ENABLED_LINUX bool MainWindow::x11Event(XEvent *event) { diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index b5a5b50304cde6ce358c402df64054418aaf2884..9390d6fd2c9c78109fc0da2b39c6b1d9c0222e54 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -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 listLinkMenuActions(void); + QList 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 commsWidgetList; QMap customWidgetNameToFilenameMap; - QMap menuToDockNameMap; - QList dockWidgets; - QMap > 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_ */ diff --git a/src/ui/QGCPX4VehicleConfig.cc b/src/ui/QGCPX4VehicleConfig.cc index d2419ec37a383d4c18f45c861176f178b3c1dfbf..3cc3603b794b0e5dee295b8341769fa0c75648ec 100644 --- a/src/ui/QGCPX4VehicleConfig.cc +++ b/src/ui/QGCPX4VehicleConfig.cc @@ -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 paramlist = tool->getParamList(); for (int i=0;igeneralRightContents; } - tool = new QGCToolWidget("", parent); + tool = new QGCToolWidget(parametersname, parametersname, parent); tool->addUAS(mav); - tool->setTitle(parametersname); - tool->setObjectName(parametersname); tool->setSettings(advset); QList paramlist = tool->getParamList(); for (int i=0;igeneralLeftContents: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 paramlist = tool->getParamList(); for (int i=0;igeneralRightContents; } - tool = new QGCToolWidget("", parent); + tool = new QGCToolWidget(parametersname, parametersname, parent); tool->addUAS(mav); - tool->setTitle(parametersname); - tool->setObjectName(parametersname); tool->setSettings(advset); QList paramlist = tool->getParamList(); for (int i=0;i 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); diff --git a/src/ui/designer/QGCToolWidget.cc b/src/ui/designer/QGCToolWidget.cc index 73eae34c9805d3b1435d5488e53b45f7fcf29f0d..6610e03d509c9219eac0182084de3df48205e05f 100644 --- a/src/ui/designer/QGCToolWidget.cc +++ b/src/ui/designer/QGCToolWidget.cc @@ -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::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(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"); diff --git a/src/ui/designer/QGCToolWidget.h b/src/ui/designer/QGCToolWidget.h index 5d1f56d0c94781353070237fe589c99e28087f08..2e08337c2baa2731356a8ec4c3cc2be4ad36fc10 100644 --- a/src/ui/designer/QGCToolWidget.h +++ b/src/ui/designer/QGCToolWidget.h @@ -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 dockWidgetArea; ///< Dock widget area desired by this widget QMap 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; }; diff --git a/src/ui/dockwidgeteventfilter.cpp b/src/ui/dockwidgeteventfilter.cpp deleted file mode 100644 index 260e3a5466614e1eb81f9827f6feb55a0ddfa238..0000000000000000000000000000000000000000 --- a/src/ui/dockwidgeteventfilter.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include - -#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(object); - if(dock) { - QLabel *label = dynamic_cast(dock->titleBarWidget()); - if(label) - label->setText(dock->windowTitle()); - } - } - return QObject::eventFilter(object,event); -} diff --git a/src/ui/dockwidgeteventfilter.h b/src/ui/dockwidgeteventfilter.h deleted file mode 100644 index 60de1e4002bb942f609cb2fe859c8d18b82d9d24..0000000000000000000000000000000000000000 --- a/src/ui/dockwidgeteventfilter.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef DOCKWIDGETEVENTFILTER_H -#define DOCKWIDGETEVENTFILTER_H - -#include - -/** 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 diff --git a/src/ui/dockwidgettitlebareventfilter.cpp b/src/ui/dockwidgettitlebareventfilter.cpp deleted file mode 100644 index 52519215ade4e5fb6d1fcb8927a4366fdf6f7da5..0000000000000000000000000000000000000000 --- a/src/ui/dockwidgettitlebareventfilter.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "dockwidgettitlebareventfilter.h" -#include -#include -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); -} diff --git a/src/ui/dockwidgettitlebareventfilter.h b/src/ui/dockwidgettitlebareventfilter.h deleted file mode 100644 index d57edef1fb862711ba55d810b34614bc38dfad0f..0000000000000000000000000000000000000000 --- a/src/ui/dockwidgettitlebareventfilter.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef DOCKWIDGETTITLEBAREVENTFILTER_H -#define DOCKWIDGETTITLEBAREVENTFILTER_H - -#include - -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 diff --git a/src/ui/menuactionhelper.cpp b/src/ui/menuactionhelper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a9b3a8d766adade0551a099972b3400889fee488 --- /dev/null +++ b/src/ui/menuactionhelper.cpp @@ -0,0 +1,184 @@ +#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 >::iterator it; + for (it = m_centralWidgetToDockWidgetsMap.begin(); it != m_centralWidgetToDockWidgetsMap.end(); ++it) { + QMap::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(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(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(object); + if(dock) { + // Update the dock title bar label + QLabel *label = dynamic_cast(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 >::iterator it; + for (it = m_centralWidgetToDockWidgetsMap.begin(); it != m_centralWidgetToDockWidgetsMap.end(); ++it) { + QMap &map = it.value(); + map[newObjectName] = map[oldObjectName]; + map.remove(oldObjectName); + }*/ + } + } else if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) + { + if(qobject_cast(object)) + return true; + } + return QObject::eventFilter(object,event); +} diff --git a/src/ui/menuactionhelper.h b/src/ui/menuactionhelper.h new file mode 100644 index 0000000000000000000000000000000000000000..cde788348868daa6581b481128b222bb4003fb8d --- /dev/null +++ b/src/ui/menuactionhelper.h @@ -0,0 +1,50 @@ +#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 m_menuToDockNameMap; + QList m_dockWidgets; + QMap > 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