Skip to content
Snippets Groups Projects
QGCToolWidget.cc 21.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "QGCToolWidget.h"
    #include "ui_QGCToolWidget.h"
    
    #include <QMenu>
    #include <QList>
    #include <QInputDialog>
    #include <QDockWidget>
    #include <QContextMenuEvent>
    
    lm's avatar
    lm committed
    #include <QSettings>
    
    #include <QFileDialog>
    #include <QDesktopServices>
    
    lm's avatar
    lm committed
    
    
    lm's avatar
    lm committed
    #include "QGCCommandButton.h"
    
    QGCToolWidget::QGCToolWidget(const QString& title, QWidget *parent, QSettings* settings) :
    
            QWidget(parent),
            mav(NULL),
            mainMenuAction(NULL),
    
            ui(new Ui::QGCToolWidget)
    
        ui->setupUi(this);
        if (settings) loadSettings(*settings);
    
    
        if (title == "Unnamed Tool")
        {
            widgetTitle = QString("%1 %2").arg(title).arg(QGCToolWidget::instances()->count());
        }
    
    Lorenz Meier's avatar
    Lorenz Meier committed
        //qDebug() << "WidgetTitle" << widgetTitle;
    
    
        setObjectName(widgetTitle);
    
    lm's avatar
    lm committed
        toolLayout = ui->toolLayout;
    
    lm's avatar
    lm committed
        QDockWidget* dock = dynamic_cast<QDockWidget*>(this->parentWidget());
    
        if (dock) {
    
            dock->setWindowTitle(widgetTitle);
            dock->setObjectName(widgetTitle+"DOCK");
    
    lm's avatar
    lm committed
        }
    
        dock = dynamic_cast<QDockWidget*>(parent);
    
        if (dock) {
    
            dock->setWindowTitle(widgetTitle);
            dock->setObjectName(widgetTitle+"DOCK");
    
        this->setWindowTitle(widgetTitle);
    
        QList<UASInterface*> systems = UASManager::instance()->getUASList();
    
        foreach (UASInterface* uas, systems)
        {
    
                addUAS(uas);
            }
        }
        connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(addUAS(UASInterface*)));
    
        if (!instances()->contains(widgetTitle)) instances()->insert(widgetTitle, this);
    
        // Enforce storage if this not loaded from settings
        // is MUST NOT BE SAVED if it was loaded from settings!
    
        //if (!settings) storeWidgetsToSettings();
    
        if (mainMenuAction) mainMenuAction->deleteLater();
        if (QGCToolWidget::instances()) QGCToolWidget::instances()->remove(widgetTitle);
    
    void QGCToolWidget::setParent(QWidget *parent)
    {
        QWidget::setParent(parent);
        // Try with parent
        QDockWidget* dock = dynamic_cast<QDockWidget*>(parent);
        if (dock)
        {
            dock->setWindowTitle(getTitle());
            dock->setObjectName(getTitle()+"DOCK");
        }
    }
    
    
    lm's avatar
    lm committed
    /**
     * @param parent Object later holding these widgets, usually the main window
     * @return List of all widgets
     */
    
    QList<QGCToolWidget*> QGCToolWidget::createWidgetsFromSettings(QWidget* parent, QString settingsFile)
    
    lm's avatar
    lm committed
    {
    
        // Load widgets from application settings
        QSettings* settings;
    
        // Or load them from a settings file
        if (!settingsFile.isEmpty())
        {
            settings = new QSettings(settingsFile, QSettings::IniFormat);
    
    Lorenz Meier's avatar
    Lorenz Meier committed
           //qDebug() << "LOADING SETTINGS FROM" << settingsFile;
    
        }
        else
        {
            settings = new QSettings();
    
    Lorenz Meier's avatar
    Lorenz Meier committed
            //qDebug() << "LOADING SETTINGS FROM DEFAULT" << settings->fileName();
    
    lm's avatar
    lm committed
        QList<QGCToolWidget*> newWidgets;
    
        int size = settings->beginReadArray("QGC_TOOL_WIDGET_NAMES");
    
        for (int i = 0; i < size; i++)
        {
    
            settings->setArrayIndex(i);
    
            QString name = settings->value("TITLE", "").toString();
    
            QString objname = settings->value("OBJECT_NAME", "").toString();
    
    lm's avatar
    lm committed
    
    
            if (!instances()->contains(name) && name.length() != 0)
    
    Lorenz Meier's avatar
    Lorenz Meier committed
                //qDebug() << "CREATED WIDGET:" << name;
    
                QGCToolWidget* tool = new QGCToolWidget(name, parent, settings);
    
    lm's avatar
    lm committed
                newWidgets.append(tool);
            }
    
            else if (name.length() == 0)
            {
                // Silently catch empty widget name - sanity check
                // to survive broken settings (e.g. from user manipulation)
            }
    
    Lorenz Meier's avatar
    Lorenz Meier committed
                //qDebug() << "WIDGET" << name << "DID ALREADY EXIST, REJECTING";
    
    lm's avatar
    lm committed
        }
    
        settings->endArray();
    
    lm's avatar
    lm committed
    
    
    Lorenz Meier's avatar
    Lorenz Meier committed
        //qDebug() << "NEW WIDGETS: " << newWidgets.size();
    
    lm's avatar
    lm committed
    
        // Load individual widget items
    
        for (int i = 0; i < newWidgets.size(); i++)
        {
    
            newWidgets.at(i)->loadSettings(*settings);
    
    lm's avatar
    lm committed
        }
    
        delete settings;
    
    lm's avatar
    lm committed
    
        return instances()->values();
    }
    
    void QGCToolWidget::showLabel(QString name,int num)
    {
        for (int i=0;i<toolItemList.size();i++)
        {
            if (toolItemList[i]->objectName() == name)
            {
                QGCTextLabel *label = qobject_cast<QGCTextLabel*>(toolItemList[i]);
                if (label)
                {
                    label->enableText(num);
                }
            }
        }
    }
    
    lm's avatar
    lm committed
    
    
    LM's avatar
    LM committed
    /**
     * @param singleinstance If this is set to true, the widget settings will only be loaded if not another widget with the same title exists
     */
    bool QGCToolWidget::loadSettings(const QString& settings, bool singleinstance)
    
        QSettings set(settings, QSettings::IniFormat);
        QStringList groups = set.childGroups();
    
        if (groups.length() > 0)
        {
            QString widgetName = groups.first();
    
    	this->setObjectName(widgetName);
    
            if (singleinstance && QGCToolWidget::instances()->keys().contains(widgetName)) return false;
    
            // Do not use setTitle() here,
            // interferes with loading settings
            widgetTitle = widgetName;
    
    Lorenz Meier's avatar
    Lorenz Meier committed
            //qDebug() << "WIDGET TITLE LOADED: " << widgetName;
    
            loadSettings(set);
            return true;
        }
        else
        {
            return false;
        }
    
    void QGCToolWidget::setSettings(QVariantMap& settings)
    {
    
        settingsMap = settings;
        QString widgetName = getTitle();
        int size = settingsMap["count"].toInt();
        for (int j = 0; j < size; j++)
        {
            QString type = settings.value(widgetName + "\\" + QString::number(j) + "\\" + "TYPE", "UNKNOWN").toString();
            if (type == "SLIDER")
            {
                QString checkparam = settingsMap.value(widgetName + "\\" + QString::number(j) + "\\" + "QGC_PARAM_SLIDER_PARAMID").toString();
                paramList.append(checkparam);
            }
            else if (type == "COMBO")
            {
                QString checkparam = settingsMap.value(widgetName + "\\" + QString::number(j) + "\\" + "QGC_PARAM_COMBOBOX_PARAMID").toString();
                paramList.append(checkparam);
            }
        }
    }
    QList<QString> QGCToolWidget::getParamList()
    {
        return paramList;
    }
    void QGCToolWidget::setParameterValue(int uas, int component, QString parameterName, const QVariant value)
    {
        QString widgetName = getTitle();
        int size = settingsMap["count"].toInt();
    
        if (paramToItemMap.contains(parameterName))
        {
    
            //If we already have an item for this parameter, updates are handled internally.
    
    
        for (int j = 0; j < size; j++)
        {
            QString type = settingsMap.value(widgetName + "\\" + QString::number(j) + "\\" + "TYPE", "UNKNOWN").toString();
            QGCToolWidgetItem* item = NULL;
            if (type == "COMMANDBUTTON")
            {
    
                //This shouldn't happen, but I'm not sure... so lets test for it.
                continue;
    
            }
            else if (type == "SLIDER")
            {
                QString checkparam = settingsMap.value(widgetName + "\\" + QString::number(j) + "\\" + "QGC_PARAM_SLIDER_PARAMID").toString();
                if (checkparam == parameterName)
                {
                    item = new QGCParamSlider(this);
    
                    addToolWidget(item);
                    item->readSettings(widgetName + "\\" + QString::number(j) + "\\",settingsMap);
                    return;
                }
            }
            else if (type == "COMBO")
            {
                QString checkparam = settingsMap.value(widgetName + "\\" + QString::number(j) + "\\" + "QGC_PARAM_COMBOBOX_PARAMID").toString();
                if (checkparam == parameterName)
                {
                    item = new QGCComboBox(this);
                    addToolWidget(item);
                    item->readSettings(widgetName + "\\" + QString::number(j) + "\\",settingsMap);
    
                    return;
                }
            }
        }
    }
    
    void QGCToolWidget::loadSettings(QVariantMap& settings)
    {
    
        QString widgetName = getTitle();
        //settings.beginGroup(widgetName);
        qDebug() << "LOADING FOR" << widgetName;
        //int size = settings.beginReadArray("QGC_TOOL_WIDGET_ITEMS");
        int size = settings["count"].toInt();
        qDebug() << "CHILDREN SIZE:" << size;
        for (int j = 0; j < size; j++)
        {
            QApplication::processEvents();
            //settings.setArrayIndex(j);
            QString type = settings.value(widgetName + "\\" + QString::number(j) + "\\" + "TYPE", "UNKNOWN").toString();
            if (type != "UNKNOWN")
            {
                QGCToolWidgetItem* item = NULL;
                if (type == "COMMANDBUTTON")
                {
                    item = new QGCCommandButton(this);
                    //qDebug() << "CREATED COMMANDBUTTON";
                }
    
                else if (type == "TEXT")
                {
                    item = new QGCTextLabel(this);
                    item->setActiveUAS(mav);
                }
    
                else if (type == "SLIDER")
                {
                    item = new QGCParamSlider(this);
                    //qDebug() << "CREATED PARAM SLIDER";
                }
                else if (type == "COMBO")
                {
                    item = new QGCComboBox(this);
    
                    //qDebug() << "CREATED COMBOBOX";
    
                }
                if (item)
                {
                    // Configure and add to layout
                    addToolWidget(item);
                    item->readSettings(widgetName + "\\" + QString::number(j) + "\\",settings);
    
                    //qDebug() << "Created tool widget";
                }
            }
            else
            {
                qDebug() << "UNKNOWN TOOL WIDGET TYPE" << type;
            }
        }
        //settings.endArray();
        //settings.endGroup();
    }
    
    
    void QGCToolWidget::loadSettings(QSettings& settings)
    {
        QString widgetName = getTitle();
        settings.beginGroup(widgetName);
    
    Lorenz Meier's avatar
    Lorenz Meier committed
        //qDebug() << "LOADING FOR" << widgetName;
    
        int size = settings.beginReadArray("QGC_TOOL_WIDGET_ITEMS");
    
    Lorenz Meier's avatar
    Lorenz Meier committed
        //qDebug() << "CHILDREN SIZE:" << size;
    
        for (int j = 0; j < size; j++)
        {
    
            settings.setArrayIndex(j);
            QString type = settings.value("TYPE", "UNKNOWN").toString();
    
            if (type != "UNKNOWN")
            {
    
                QGCToolWidgetItem* item = NULL;
    
                if (type == "COMMANDBUTTON")
                {
    
                    QGCCommandButton *button = new QGCCommandButton(this);
                    connect(button,SIGNAL(showLabel(QString,int)),this,SLOT(showLabel(QString,int)));
                    item = button;
                    item->setActiveUAS(mav);
    
    Lorenz Meier's avatar
    Lorenz Meier committed
                    //qDebug() << "CREATED COMMANDBUTTON";
    
                }
                else if (type == "SLIDER")
                {
    
                    item = new QGCParamSlider(this);
    
    Lorenz Meier's avatar
    Lorenz Meier committed
                    //qDebug() << "CREATED PARAM SLIDER";
    
                else if (type == "COMBO")
                {
                    item = new QGCComboBox(this);
    
                else if (type == "TEXT")
                {
                    item = new QGCTextLabel(this);
                    item->setObjectName(settings.value("QGC_TEXT_ID").toString());
                    item->setActiveUAS(mav);
                }
    
                    // Configure and add to layout
                    addToolWidget(item);
                    item->readSettings(settings);
    
    
    Lorenz Meier's avatar
    Lorenz Meier committed
                    //qDebug() << "Created tool widget";
    
    Lorenz Meier's avatar
    Lorenz Meier committed
                //qDebug() << "UNKNOWN TOOL WIDGET TYPE";
    
            }
        }
        settings.endArray();
        settings.endGroup();
    }
    
    void QGCToolWidget::storeWidgetsToSettings(QString settingsFile)
    
    lm's avatar
    lm committed
    {
        // Store list of widgets
    
        QSettings* settings;
        if (!settingsFile.isEmpty())
        {
            settings = new QSettings(settingsFile, QSettings::IniFormat);
    
    Lorenz Meier's avatar
    Lorenz Meier committed
            //qDebug() << "STORING SETTINGS TO" << settings->fileName();
    
        }
        else
        {
            settings = new QSettings();
    
    Lorenz Meier's avatar
    Lorenz Meier committed
            //qDebug() << "STORING SETTINGS TO DEFAULT" << settings->fileName();
    
        int preArraySize = settings->beginReadArray("QGC_TOOL_WIDGET_NAMES");
        settings->endArray();
    
    
        settings->beginWriteArray("QGC_TOOL_WIDGET_NAMES");
    
        for (int i = 0; i < qMax(preArraySize, instances()->size()); ++i)
    
            if (i < instances()->size())
            {
                // Updating value
    
                if (!instances()->values().at(i)->fromMetaData())
                {
                    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();
                }
    
            }
            else
            {
                // Deleting old value
                settings->remove("TITLE");
            }
    
    lm's avatar
    lm committed
        }
    
        settings->endArray();
    
    lm's avatar
    lm committed
    
        // Store individual widget items
    
        for (int i = 0; i < instances()->size(); ++i)
        {
    
            instances()->values().at(i)->storeSettings(*settings);
        }
    
        delete settings;
    }
    
    
    void QGCToolWidget::storeSettings()
    {
        QSettings settings;
        storeSettings(settings);
    }
    
    
    void QGCToolWidget::storeSettings(const QString& settingsFile)
    {
        QSettings settings(settingsFile, QSettings::IniFormat);
        storeSettings(settings);
    }
    
    void QGCToolWidget::storeSettings(QSettings& settings)
    {
    
        if (isFromMetaData)
        {
            //Refuse to store if this is loaded from metadata or dynamically generated.
            return;
        }
    
    Lorenz Meier's avatar
    Lorenz Meier committed
        //qDebug() << "WRITING WIDGET" << widgetTitle << "TO SETTINGS";
    
        settings.beginGroup(widgetTitle);
    
        settings.beginWriteArray("QGC_TOOL_WIDGET_ITEMS");
        int k = 0; // QGCToolItem counter
    
        for (int j = 0; j  < children().size(); ++j)
        {
    
            // Store only QGCToolWidgetItems
            QGCToolWidgetItem* item = dynamic_cast<QGCToolWidgetItem*>(children().at(j));
    
                // Only count actual tool widget item children
    
                settings.setArrayIndex(k++);
                // Store the ToolWidgetItem
                item->writeSettings(settings);
    
    lm's avatar
    lm committed
            }
        }
    
    Lorenz Meier's avatar
    Lorenz Meier committed
        //qDebug() << "WROTE" << k << "SUB-WIDGETS TO SETTINGS";
    
        settings.endArray();
        settings.endGroup();
    
    void QGCToolWidget::addUAS(UASInterface* uas)
    {
        UAS* newMav = dynamic_cast<UAS*>(uas);
    
            // FIXME Convert to list
            if (mav == NULL) mav = newMav;
        }
    }
    
    void QGCToolWidget::contextMenuEvent (QContextMenuEvent* event)
    {
        QMenu menu(this);
    
        menu.addAction(addParamAction);
    
    lm's avatar
    lm committed
        menu.addAction(addCommandAction);
    
        menu.addAction(addLabelAction);
    
        menu.addAction(exportAction);
    
        menu.addAction(importAction);
    
    lm's avatar
    lm committed
        menu.addAction(deleteAction);
    
    void QGCToolWidget::hideEvent(QHideEvent* event)
    {
        // Store settings
        QWidget::hideEvent(event);
    }
    
    /**
     * The widgets current view and the applied dock widget area.
     * Both values are only stored internally and allow an external
     * widget to configure it accordingly
     */
    void QGCToolWidget::setViewVisibilityAndDockWidgetArea(int view, bool visible, Qt::DockWidgetArea area)
    {
        viewVisible.insert(view, visible);
        dockWidgetArea.insert(view, area);
    }
    
    
    void QGCToolWidget::createActions()
    {
        addParamAction = new QAction(tr("New &Parameter Slider"), this);
        addParamAction->setStatusTip(tr("Add a parameter setting slider widget to the tool"));
        connect(addParamAction, SIGNAL(triggered()), this, SLOT(addParam()));
    
    
    lm's avatar
    lm committed
        addCommandAction = new QAction(tr("New MAV &Command Button"), this);
        addCommandAction->setStatusTip(tr("Add a new action button to the tool"));
        connect(addCommandAction, SIGNAL(triggered()), this, SLOT(addCommand()));
    
        addLabelAction = new QAction(tr("New &Text Label"), this);
        addLabelAction->setStatusTip(tr("Add a new label to the tool"));
        connect(addLabelAction, SIGNAL(triggered()), this, SLOT(addLabel()));
    
    
        setTitleAction = new QAction(tr("Set Widget Title"), this);
        setTitleAction->setStatusTip(tr("Set the title caption of this tool widget"));
        connect(setTitleAction, SIGNAL(triggered()), this, SLOT(setTitle()));
    
    lm's avatar
    lm committed
    
        deleteAction = new QAction(tr("Delete this widget"), this);
        deleteAction->setStatusTip(tr("Delete this widget permanently"));
        connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteWidget()));
    
    
        exportAction = new QAction(tr("Export this widget"), this);
        exportAction->setStatusTip(tr("Export this widget to be reused by others"));
        connect(exportAction, SIGNAL(triggered()), this, SLOT(exportWidget()));
    
        importAction = new QAction(tr("Import widget"), this);
        importAction->setStatusTip(tr("Import this widget from a file (current content will be removed)"));
    
        connect(importAction, SIGNAL(triggered()), this, SLOT(importWidget()));
    
    lm's avatar
    lm committed
    }
    
    QMap<QString, QGCToolWidget*>* QGCToolWidget::instances()
    {
        static QMap<QString, QGCToolWidget*>* instances;
        if (!instances) instances = new QMap<QString, QGCToolWidget*>();
        return instances;
    }
    
    QList<QGCToolWidgetItem*>* QGCToolWidget::itemList()
    {
        static QList<QGCToolWidgetItem*>* instances;
        if (!instances) instances = new QList<QGCToolWidgetItem*>();
        return instances;
    
    void QGCToolWidget::addParam(int uas,int component,QString paramname,QVariant value)
    {
    
        QGCParamSlider* slider = new QGCParamSlider(this);
        connect(slider, SIGNAL(destroyed()), this, SLOT(storeSettings()));
        if (ui->hintLabel)
        {
            ui->hintLabel->deleteLater();
            ui->hintLabel = NULL;
        }
        toolLayout->addWidget(slider);
        slider->setActiveUAS(mav);
        slider->setParameterValue(uas,component,0,-1,paramname,value);
    
    
    }
    
    
    void QGCToolWidget::addParam()
    {
        QGCParamSlider* slider = new QGCParamSlider(this);
    
        connect(slider, SIGNAL(destroyed()), this, SLOT(storeSettings()));
    
        if (ui->hintLabel)
        {
    
    lm's avatar
    lm committed
            ui->hintLabel->deleteLater();
    
    lm's avatar
    lm committed
        }
    
        toolLayout->addWidget(slider);
        slider->startEditMode();
    }
    
    
    lm's avatar
    lm committed
    void QGCToolWidget::addCommand()
    {
        QGCCommandButton* button = new QGCCommandButton(this);
    
        connect(button, SIGNAL(destroyed()), this, SLOT(storeSettings()));
    
        if (ui->hintLabel)
        {
    
    lm's avatar
    lm committed
            ui->hintLabel->deleteLater();
            ui->hintLabel = NULL;
        }
        toolLayout->addWidget(button);
        button->startEditMode();
    }
    
    
    void QGCToolWidget::addLabel()
    {
        QGCTextLabel* label= new QGCTextLabel(this);
        connect(label, SIGNAL(destroyed()), this, SLOT(storeSettings()));
        toolLayout->addWidget(label);
        label->startEditMode();
    }
    
    
    lm's avatar
    lm committed
    void QGCToolWidget::addToolWidget(QGCToolWidgetItem* widget)
    {
    
        if (ui->hintLabel)
        {
    
    lm's avatar
    lm committed
            ui->hintLabel->deleteLater();
    
    lm's avatar
    lm committed
        }
    
        connect(widget, SIGNAL(destroyed()), this, SLOT(storeSettings()));
    
    lm's avatar
    lm committed
        toolLayout->addWidget(widget);
    
    void QGCToolWidget::exportWidget()
    {
    
        const QString widgetFileExtension(".qgw");
        QString fileName = QFileDialog::getSaveFileName(this, tr("Specify File Name"), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), tr("QGroundControl Widget (*%1);;").arg(widgetFileExtension));
        if (!fileName.endsWith(widgetFileExtension))
        {
            fileName = fileName.append(widgetFileExtension);
        }
        storeSettings(fileName);
    
    void QGCToolWidget::importWidget()
    
        const QString widgetFileExtension(".qgw");
        QString fileName = QFileDialog::getOpenFileName(this, tr("Specify File Name"), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), tr("QGroundControl Widget (*%1);;").arg(widgetFileExtension));
        loadSettings(fileName);
    
    lm's avatar
    lm committed
    const QString QGCToolWidget::getTitle()
    {
    
    void QGCToolWidget::setTitle()
    {
        QDockWidget* parent = dynamic_cast<QDockWidget*>(this->parentWidget());
    
    lm's avatar
    lm committed
            bool ok;
    
            QString text = QInputDialog::getText(this, tr("Enter Widget Title"),
    
                                                 tr("Widget title:"), QLineEdit::Normal,
                                                 parent->windowTitle(), &ok);
    
            if (ok && !text.isEmpty())
            {
                setTitle(text);
    
    lm's avatar
    lm committed
            }
    
    lm's avatar
    lm committed
    
    
    void QGCToolWidget::setWindowTitle(const QString& title)
    {
        // Sets title and calls setWindowTitle on QWidget
    
        widgetTitle = title;
        QWidget::setWindowTitle(title);
    
    void QGCToolWidget::setTitle(QString title)
    {
    
        // Remove references to old title
    
        settings.beginGroup(widgetTitle);
        settings.remove("");
        settings.endGroup();
    
        if (instances()->contains(widgetTitle)) instances()->remove(widgetTitle);
    
        // Switch to new title
        widgetTitle = title;
    
        if (!instances()->contains(title)) instances()->insert(title, this);
        QWidget::setWindowTitle(title);
    
        QDockWidget* parent = dynamic_cast<QDockWidget*>(this->parentWidget());
    
        if (parent) parent->setWindowTitle(title);
    
        // Store all widgets
    
    
        emit titleChanged(title);
        if (mainMenuAction) mainMenuAction->setText(title);
    }
    
    
    lm's avatar
    lm committed
    void QGCToolWidget::setMainMenuAction(QAction* action)
    {
        this->mainMenuAction = action;
    }
    
    void QGCToolWidget::deleteWidget()
    {
        // Remove from settings
    
        // Hide
        this->hide();
        instances()->remove(getTitle());
    
    lm's avatar
    lm committed
        settings.beginGroup(getTitle());
        settings.remove("");
        settings.endGroup();
    
    lm's avatar
    lm committed
        storeWidgetsToSettings();
    
        // Delete
        this->deleteLater();
    }