diff --git a/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_de.ts b/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_de.ts
index 554a8c5c7..1e431f98f 100644
--- a/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_de.ts
+++ b/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_de.ts
@@ -2146,7 +2146,7 @@ p, li { white-space: pre-wrap; }
-
+
diff --git a/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_es.ts b/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_es.ts
index 32554073c..183101e99 100644
--- a/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_es.ts
+++ b/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_es.ts
@@ -2147,7 +2147,7 @@ p, li { white-space: pre-wrap; }
-
+
diff --git a/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_fr.ts b/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_fr.ts
index 529fd4f7a..7463d76bf 100644
--- a/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_fr.ts
+++ b/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_fr.ts
@@ -2175,8 +2175,8 @@ p, li { white-space: pre-wrap; }
-
- Plugin de Notification
+
+ Notification
diff --git a/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_ru.ts b/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_ru.ts
index 611533c3e..e26c74211 100644
--- a/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_ru.ts
+++ b/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_ru.ts
@@ -2256,7 +2256,7 @@ p, li { white-space: pre-wrap; }
-
+
Оповещения
diff --git a/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_zh_CN.ts b/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_zh_CN.ts
index a27bc2920..4d92f3c34 100644
--- a/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_zh_CN.ts
+++ b/ground/openpilotgcs/share/openpilotgcs/translations/openpilotgcs_zh_CN.ts
@@ -3189,7 +3189,7 @@ p, li { white-space: pre-wrap; }
-
+
diff --git a/ground/openpilotgcs/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/ground/openpilotgcs/src/plugins/coreplugin/dialogs/settingsdialog.cpp
index fd772b0bb..d5581ff75 100644
--- a/ground/openpilotgcs/src/plugins/coreplugin/dialogs/settingsdialog.cpp
+++ b/ground/openpilotgcs/src/plugins/coreplugin/dialogs/settingsdialog.cpp
@@ -32,7 +32,6 @@
#include "icore.h"
#include "coreplugin/uavgadgetinstancemanager.h"
#include "coreplugin/uavgadgetoptionspagedecorator.h"
-// #include "coreimpl.h"
#include
#include
@@ -40,49 +39,58 @@
#include
#include
+using namespace Core;
+using namespace Core::Internal;
+
namespace {
-struct PageData {
- int index;
- QString category;
- QString id;
-};
+
+ struct PageData {
+ int index;
+ QString category;
+ QString id;
+
+ };
+
+ // helper to sort by translated category and name
+ bool compareOptionsPageByCategoryAndNameTr(const IOptionsPage *p1, const IOptionsPage *p2)
+ {
+ const UAVGadgetOptionsPageDecorator *gp1 = qobject_cast(p1);
+ const UAVGadgetOptionsPageDecorator *gp2 = qobject_cast(p2);
+ if (gp1 && !gp2) {
+ return false;
+ }
+ if (gp2 && !gp1) {
+ return true;
+ }
+ if (const int cc = QString::localeAwareCompare(p1->trCategory(), p2->trCategory())) {
+ return cc < 0;
+ }
+ return QString::localeAwareCompare(p1->trName(), p2->trName()) < 0;
+ }
+
+ // helper to sort by category and id
+ bool compareOptionsPageByCategoryAndId(const IOptionsPage *p1, const IOptionsPage *p2)
+ {
+ const UAVGadgetOptionsPageDecorator *gp1 = qobject_cast(p1);
+ const UAVGadgetOptionsPageDecorator *gp2 = qobject_cast(p2);
+ if (gp1 && !gp2) {
+ return false;
+ }
+ if (gp2 && !gp1) {
+ return true;
+ }
+ if (const int cc = QString::localeAwareCompare(p1->category(), p2->category())) {
+ return cc < 0;
+ }
+ return QString::localeAwareCompare(p1->id(), p2->id()) < 0;
+ }
+
}
Q_DECLARE_METATYPE(::PageData)
-using namespace Core;
-using namespace Core::Internal;
-
-// Helpers to sort by category. id
-bool optionsPageLessThan(const IOptionsPage *p1, const IOptionsPage *p2)
-{
- const UAVGadgetOptionsPageDecorator *gp1 = qobject_cast(p1);
- const UAVGadgetOptionsPageDecorator *gp2 = qobject_cast(p2);
-
- if (gp1 && (gp2 == NULL)) {
- return false;
- }
-
- if (gp2 && (gp1 == NULL)) {
- return true;
- }
-
- if (const int cc = QString::localeAwareCompare(p1->trCategory(), p2->trCategory())) {
- return cc < 0;
- }
-
- return QString::localeAwareCompare(p1->trName(), p2->trName()) < 0;
-}
-
-static inline QList sortedOptionsPages()
-{
- QList rc = ExtensionSystem::PluginManager::instance()->getObjects();
- qStableSort(rc.begin(), rc.end(), optionsPageLessThan);
- return rc;
-}
-
-SettingsDialog::SettingsDialog(QWidget *parent, const QString &categoryId, const QString &pageId)
- : QDialog(parent), m_applied(false)
+SettingsDialog::SettingsDialog(QWidget *parent, const QString &categoryId, const QString &pageId) :
+ QDialog(parent), m_applied(false)
{
setupUi(this);
#ifdef Q_OS_MAC
@@ -92,6 +100,7 @@ SettingsDialog::SettingsDialog(QWidget *parent, const QString &categoryId, const
#endif
QSettings *settings = ICore::instance()->settings();
+
settings->beginGroup("General");
// restore last displayed category and page
@@ -104,6 +113,7 @@ SettingsDialog::SettingsDialog(QWidget *parent, const QString &categoryId, const
initialPage = settings->value("LastPreferencePage", QVariant(QString())).toString();
qDebug() << "SettingsDialog settings initial category:" << initialCategory << ", initial page: " << initialPage;
}
+
// restore window size
int windowWidth = settings->value("SettingsWindowWidth", 0).toInt();
int windowHeight = settings->value("SettingsWindowHeight", 0).toInt();
@@ -111,114 +121,99 @@ SettingsDialog::SettingsDialog(QWidget *parent, const QString &categoryId, const
if (windowWidth > 0 && windowHeight > 0) {
resize(windowWidth, windowHeight);
}
+
+ // restore splitter size
+ int size0 = settings->value("SettingsSplitterSize0", 0).toInt();
+ int size1 = settings->value("SettingsSplitterSize1", 0).toInt();
+ qDebug() << "SettingsDialog splitter size0:" << size0 << ", size1:" << size1;
+ QList sizes;
+ if (size0 > 0 && size1 > 0) {
+ sizes << size0 << size1;
+ }
+ else {
+ sizes << 150 << 300;
+ }
+ splitter->setSizes(sizes);
+
settings->endGroup();
+ // all extra space must go to the option page and none to the tree
+ splitter->setStretchFactor(splitter->indexOf(pageTree), 0);
+ splitter->setStretchFactor(splitter->indexOf(layoutWidget), 1);
+
buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
connect(buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply()));
m_instanceManager = Core::ICore::instance()->uavGadgetInstanceManager();
- connect(this, SIGNAL(settingsDialogShown(Core::Internal::SettingsDialog *)), m_instanceManager, SLOT(settingsDialogShown(Core::Internal::SettingsDialog *)));
+ connect(this, SIGNAL(settingsDialogShown(Core::Internal::SettingsDialog *)), m_instanceManager,
+ SLOT(settingsDialogShown(Core::Internal::SettingsDialog *)));
connect(this, SIGNAL(settingsDialogRemoved()), m_instanceManager, SLOT(settingsDialogRemoved()));
- connect(this, SIGNAL(categoryItemSelected()), this, SLOT(categoryItemSelectedShowChildInstead()), Qt::QueuedConnection);
+ connect(this, SIGNAL(categoryItemSelected()), this, SLOT(categoryItemSelectedShowChildInstead()),
+ Qt::QueuedConnection);
splitter->setCollapsible(0, false);
splitter->setCollapsible(1, false);
pageTree->header()->setVisible(false);
-// pageTree->setIconSize(QSize(24, 24));
- connect(pageTree, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
- this, SLOT(pageSelected()));
+ connect(pageTree, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(pageSelected()));
- QMap categories;
+ QList pluginPages;
+ QList gadgetPages;
- QList pages = sortedOptionsPages();
+ // get all pages and split them between plugin and gadget list
+ QList pages = ExtensionSystem::PluginManager::instance()->getObjects();
+ foreach(IOptionsPage *page, pages) {
+ if (qobject_cast(page)) {
+ gadgetPages.append(page);
+ } else {
+ pluginPages.append(page);
+ }
+ }
- int index = 0;
- bool firstUavGadgetOptionsPageFound = false;
+ // the plugin options page list sorted by untranslated names to facilitate access to the language settings when GCS
+ // is not running in a language understood by the user.
+ qStableSort(pluginPages.begin(), pluginPages.end(), compareOptionsPageByCategoryAndId);
+ // the plugin options page list sorted is sorted by translated names
+ qStableSort(gadgetPages.begin(), gadgetPages.end(), compareOptionsPageByCategoryAndNameTr);
+
+ // will hold the initially selected item if any
QTreeWidgetItem *initialItem = 0;
- foreach(IOptionsPage * page, pages) {
- PageData pageData;
- pageData.index = index;
- pageData.category = page->category();
- pageData.id = page->id();
-
- QTreeWidgetItem *item = new QTreeWidgetItem;
- item->setText(0, page->trName());
- item->setData(0, Qt::UserRole, qVariantFromValue(pageData));
-
- QString trCategories = page->trCategory();
- QString currentCategory = page->category();
-
- QTreeWidgetItem *categoryItem;
- if (!categories.contains(currentCategory)) {
- // Above the first gadget option we insert a separator
- if (!firstUavGadgetOptionsPageFound) {
- UAVGadgetOptionsPageDecorator *pd = qobject_cast(page);
- if (pd) {
- firstUavGadgetOptionsPageFound = true;
- QTreeWidgetItem *separator = new QTreeWidgetItem(pageTree);
- separator->setFlags(separator->flags() & ~Qt::ItemIsSelectable & ~Qt::ItemIsEnabled);
- separator->setText(0, QString(30, 0xB7));
- }
- }
- categoryItem = new QTreeWidgetItem(pageTree);
- categoryItem->setIcon(0, page->icon());
- categoryItem->setText(0, trCategories);
- categoryItem->setData(0, Qt::UserRole, qVariantFromValue(pageData));
- categories.insert(currentCategory, categoryItem);
- }
-
- QList *categoryItemList = m_categoryItemsMap.value(currentCategory);
- if (!categoryItemList) {
- categoryItemList = new QList();
- m_categoryItemsMap.insert(currentCategory, categoryItemList);
- }
- categoryItemList->append(item);
-
- m_pages.append(page);
-
- // creating all option pages upfront is slow, so we create place holder widgets instead
- // the real option page widget will be created later when the user selects it
- // the place holder is a QLabel and we assume that no option page will be a QLabel...
- QLabel *placeholderWidget = new QLabel(stackedPages);
- stackedPages->addWidget(placeholderWidget);
-
- if (page->id() == initialPage && currentCategory == initialCategory) {
+ // add plugin pages
+ foreach(IOptionsPage *page, pluginPages) {
+ QTreeWidgetItem *item = addPage(page);
+ // to automatically expand all plugin categories, uncomment next line
+ //item->parent()->setExpanded(true);
+ if (page->id() == initialPage && page->category() == initialCategory) {
initialItem = item;
}
-
- index++;
}
- foreach(QString category, m_categoryItemsMap.keys()) {
- QList *categoryItemList = m_categoryItemsMap.value(category);
- if (categoryItemList->size() > 1) {
- foreach(QTreeWidgetItem * item, *categoryItemList) {
- QTreeWidgetItem *categoryItem = categories.value(category);
+ // insert separator bewteen plugin and gadget pages
+ QTreeWidgetItem *separator = new QTreeWidgetItem(pageTree);
+ separator->setFlags(separator->flags() & ~Qt::ItemIsSelectable & ~Qt::ItemIsEnabled);
+ separator->setText(0, QString(30, 0xB7));
- categoryItem->addChild(item);
- }
+ // add gadget pages
+ foreach(IOptionsPage *page, gadgetPages) {
+ QTreeWidgetItem *item = addPage(page);
+ if (page->id() == initialPage && page->category() == initialCategory) {
+ initialItem = item;
}
}
+ // handle initially selected item
if (initialItem) {
- if (!initialItem->parent()) {
- // item has no parent, meaning it is single child
- // so select category item instead as single child are not added to the tree
- initialItem = categories.value(initialCategory);
+ if (initialItem->isHidden()) {
+ // item is hidden, meaning it is single child
+ // so select parent category item instead
+ initialItem = initialItem->parent();
}
pageTree->setCurrentItem(initialItem);
}
- QList sizes;
- sizes << 150 << 300;
- splitter->setSizes(sizes);
-
- splitter->setStretchFactor(splitter->indexOf(pageTree), 0);
- splitter->setStretchFactor(splitter->indexOf(layoutWidget), 1);
}
SettingsDialog::~SettingsDialog()
@@ -236,6 +231,64 @@ SettingsDialog::~SettingsDialog()
}
}
+QTreeWidgetItem *SettingsDialog::addPage(IOptionsPage *page) {
+ PageData pageData;
+ pageData.index = m_pages.count();
+ pageData.category = page->category();
+ pageData.id = page->id();
+
+ QString category = page->category();
+
+ QList *categoryItemList = m_categoryItemsMap.value(category);
+ if (!categoryItemList) {
+ categoryItemList = new QList();
+ m_categoryItemsMap.insert(category, categoryItemList);
+ }
+
+ QTreeWidgetItem *categoryItem = NULL;
+ for (int i = 0; i < pageTree->topLevelItemCount(); ++i) {
+ QTreeWidgetItem *tw = pageTree->topLevelItem(i);
+ PageData data = tw->data(0, Qt::UserRole).value();
+ if (data.category == page->category()) {
+ categoryItem = tw;
+ break;
+ }
+ }
+ if (!categoryItem) {
+ categoryItem = new QTreeWidgetItem(pageTree);
+ categoryItem->setIcon(0, page->icon());
+ categoryItem->setText(0, page->trCategory());
+ categoryItem->setData(0, Qt::UserRole, qVariantFromValue(pageData));
+ }
+
+ QTreeWidgetItem *item = new QTreeWidgetItem(categoryItem);
+ item->setText(0, page->trName());
+ item->setData(0, Qt::UserRole, qVariantFromValue(pageData));
+
+ switch (categoryItemList->size()) {
+ case 0:
+ item->setHidden(true);
+ break;
+ case 1:
+ categoryItemList->at(0)->setHidden(false);
+ break;
+ default:
+ break;
+ }
+
+ categoryItemList->append(item);
+
+ m_pages.append(page);
+
+ // creating all option pages upfront is slow, so we create place holder widgets instead
+ // the real option page widget will be created later when the user selects it
+ // the place holder is a QLabel and we assume that no option page will be a QLabel...
+ QLabel *placeholderWidget = new QLabel(stackedPages);
+ stackedPages->addWidget(placeholderWidget);
+
+ return item;
+}
+
void SettingsDialog::pageSelected()
{
QTreeWidgetItem *item = pageTree->currentItem();
@@ -281,15 +334,18 @@ void SettingsDialog::deletePage()
QString category = data.category;
QList *categoryItemList = m_categoryItemsMap.value(category);
- QTreeWidgetItem *parentItem = item->parent();
- parentItem->removeChild(item);
- categoryItemList->removeOne(item);
- if (parentItem->childCount() == 1) {
- parentItem->removeChild(parentItem->child(0));
+ if (categoryItemList) {
+ categoryItemList->removeOne(item);
+ QTreeWidgetItem *parentItem = item->parent();
+ parentItem->removeChild(item);
+ if (parentItem->childCount() == 1) {
+ parentItem->child(0)->setHidden(true);
+ }
}
pageSelected();
}
+// TODO duplicates a lot of the addPage code...
void SettingsDialog::insertPage(IOptionsPage *page)
{
PageData pageData;
@@ -314,9 +370,9 @@ void SettingsDialog::insertPage(IOptionsPage *page)
// If this category has no child right now
// we need to add the "default child"
QList *categoryItemList = m_categoryItemsMap.value(page->category());
- if (categoryItem->childCount() == 0) {
+ if (categoryItem->childCount() == 1) {
QTreeWidgetItem *defaultItem = categoryItemList->at(0);
- categoryItem->addChild(defaultItem);
+ defaultItem->setHidden(false);
}
QTreeWidgetItem *item = new QTreeWidgetItem;
@@ -396,10 +452,18 @@ bool SettingsDialog::execDialog()
void SettingsDialog::done(int val)
{
QSettings *settings = ICore::instance()->settings();
+ settings->beginGroup("General");
+
+ settings->setValue("LastPreferenceCategory", m_currentCategory);
+ settings->setValue("LastPreferencePage", m_currentPage);
+ settings->setValue("SettingsWindowWidth", this->width());
+ settings->setValue("SettingsWindowHeight", this->height());
+ QList sizes = splitter->sizes();
+ qDebug() << "SettingsDialog splitter saving size0:" << sizes[0] << ", size1:" << sizes[1];
+ settings->setValue("SettingsSplitterSize0", sizes[0]);
+ settings->setValue("SettingsSplitterSize1", sizes[1]);
+
+ settings->endGroup();
- settings->setValue("General/LastPreferenceCategory", m_currentCategory);
- settings->setValue("General/LastPreferencePage", m_currentPage);
- settings->setValue("General/SettingsWindowWidth", this->width());
- settings->setValue("General/SettingsWindowHeight", this->height());
QDialog::done(val);
}
diff --git a/ground/openpilotgcs/src/plugins/coreplugin/dialogs/settingsdialog.h b/ground/openpilotgcs/src/plugins/coreplugin/dialogs/settingsdialog.h
index ade61b525..7333844a4 100644
--- a/ground/openpilotgcs/src/plugins/coreplugin/dialogs/settingsdialog.h
+++ b/ground/openpilotgcs/src/plugins/coreplugin/dialogs/settingsdialog.h
@@ -36,9 +36,11 @@
#include "coreplugin/dialogs/ioptionspage.h"
namespace Core {
+
class UAVGadgetInstanceManager;
namespace Internal {
+
class SettingsDialog : public QDialog, public::Ui::SettingsDialog {
Q_OBJECT
@@ -75,8 +77,12 @@ private:
bool m_applied;
QString m_currentCategory;
QString m_currentPage;
+
+ QTreeWidgetItem *addPage(IOptionsPage *page);
};
+
} // namespace Internal
+
} // namespace Core
#endif // SETTINGSDIALOG_H
diff --git a/ground/openpilotgcs/src/plugins/coreplugin/workspacesettings.cpp b/ground/openpilotgcs/src/plugins/coreplugin/workspacesettings.cpp
index 62279fd1a..43d552f44 100644
--- a/ground/openpilotgcs/src/plugins/coreplugin/workspacesettings.cpp
+++ b/ground/openpilotgcs/src/plugins/coreplugin/workspacesettings.cpp
@@ -60,12 +60,12 @@ QString WorkspaceSettings::trName() const
QString WorkspaceSettings::category() const
{
- return QLatin1String("GCS");
+ return QLatin1String("Environment");
}
QString WorkspaceSettings::trCategory() const
{
- return tr("GCS");
+ return tr("Environment");
}
QWidget *WorkspaceSettings::createPage(QWidget *parent)
diff --git a/ground/openpilotgcs/src/plugins/ipconnection/ipconnectionoptionspage.h b/ground/openpilotgcs/src/plugins/ipconnection/ipconnectionoptionspage.h
index d0110339c..b00c585f4 100644
--- a/ground/openpilotgcs/src/plugins/ipconnection/ipconnectionoptionspage.h
+++ b/ground/openpilotgcs/src/plugins/ipconnection/ipconnectionoptionspage.h
@@ -58,7 +58,7 @@ public:
}
QString category() const
{
- return "IP Network Telemetry";
+ return "Telemetry - IP Network";
};
QString trCategory() const
{
diff --git a/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.h b/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.h
index adeadde9a..9c39639e5 100644
--- a/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.h
+++ b/ground/openpilotgcs/src/plugins/notify/notifypluginoptionspage.h
@@ -76,7 +76,7 @@ public:
}
QString trCategory() const
{
- return tr("Notify Plugin");
+ return tr("Notification");
}
QWidget *createPage(QWidget *parent);
diff --git a/ground/openpilotgcs/src/plugins/serialconnection/serialpluginoptionspage.h b/ground/openpilotgcs/src/plugins/serialconnection/serialpluginoptionspage.h
index 1a0475f48..28e6b94b3 100644
--- a/ground/openpilotgcs/src/plugins/serialconnection/serialpluginoptionspage.h
+++ b/ground/openpilotgcs/src/plugins/serialconnection/serialpluginoptionspage.h
@@ -62,7 +62,7 @@ public:
}
QString category() const
{
- return "Serial Telemetry";
+ return "Telemetry - Serial";
}
QString trCategory() const
{