From 3565aad630864ecdbe53fdaa501ea708555b3c7c Mon Sep 17 00:00:00 2001 From: Unit 193 Date: Sun, 30 Apr 2023 18:30:36 -0400 Subject: New upstream version 3.4.4+dfsg. --- .../guiSQLiteStudio/dialogs/configdialog.cpp | 446 +++++++++++++++++---- 1 file changed, 360 insertions(+), 86 deletions(-) (limited to 'SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp') diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp index be45873..8c80f6d 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp @@ -1,6 +1,5 @@ #include "configdialog.h" #include "ui_configdialog.h" -#include "services/config.h" #include "uiconfig.h" #include "customconfigwidgetplugin.h" #include "services/pluginmanager.h" @@ -17,14 +16,18 @@ #include "plugins/confignotifiableplugin.h" #include "mainwindow.h" #include "common/unused.h" -#include "sqlitestudio.h" #include "configmapper.h" #include "datatype.h" #include "uiutils.h" +#include "common/utils.h" #include "translations.h" #include "plugins/uiconfiguredplugin.h" #include "dbtree/dbtree.h" #include "common/compatibility.h" +#include "windows/editorwindow.h" +#include "syntaxhighlighterplugin.h" +#include "sqleditor.h" +#include "style.h" #include #include #include @@ -39,7 +42,9 @@ #include #include #include +#include #include +#include #define GET_FILTER_STRING(Widget, WidgetType, Method) \ if (qobject_cast(Widget))\ @@ -50,6 +55,18 @@ if (w##WidgetType)\ return getFilterString(w##WidgetType) + " " + Widget->toolTip(); +class ConfigDialogItemDelegate : public QItemDelegate +{ + public: + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const + { + QVariant userData = index.data(Qt::UserRole); + bool isCategory = userData.isValid() && userData.toBool(); + QSize size = QItemDelegate::sizeHint(option, index); + return isCategory ? QSize(size.width(), size.height() * 1.7) : size; + } +}; + ConfigDialog::ConfigDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ConfigDialog) @@ -59,12 +76,14 @@ ConfigDialog::ConfigDialog(QWidget *parent) : ConfigDialog::~ConfigDialog() { + rollbackColorsConfig(); + // Cancel transaction on CfgMain objects from plugins rollbackPluginConfigs(); // Notify plugins about dialog being closed UiConfiguredPlugin* cfgPlugin = nullptr; - for (Plugin* plugin : PLUGINS->getLoadedPlugins()) + for (Plugin*& plugin : PLUGINS->getLoadedPlugins()) { cfgPlugin = dynamic_cast(plugin); if (!cfgPlugin) @@ -74,14 +93,14 @@ ConfigDialog::~ConfigDialog() } // Delete UI and other resources + qDeleteAll(colorPreviewEditors); delete ui; safe_delete(configMapper); - for (ConfigMapper* mapper : pluginConfigMappers.values()) + for (ConfigMapper*& mapper : pluginConfigMappers) delete mapper; pluginConfigMappers.clear(); - } void ConfigDialog::configureDataEditors(const QString& dataTypeString) @@ -161,6 +180,23 @@ QString ConfigDialog::getFilterString(QTableWidget *widget) return strList.join(" "); } +void ConfigDialog::showEvent(QShowEvent* event) +{ + UNUSED(event); + ui->categoriesTree->resizeColumnToContents(0); + int adjustedColumnWidth = ui->categoriesTree->columnWidth(0) + 4; + if (adjustedColumnWidth > ui->categoriesTree->width()) { + if (adjustedColumnWidth > (width() / 2)) + adjustedColumnWidth = width() / 2; + + QList sizes = ui->splitter->sizes(); + int rightPartSize = sizes[0] + sizes[1] - adjustedColumnWidth; + sizes[0] = adjustedColumnWidth; + sizes[1] = rightPartSize; + ui->splitter->setSizes(sizes); + } +} + void ConfigDialog::init() { ui->setupUi(this); @@ -184,12 +220,15 @@ void ConfigDialog::init() initDataEditors(); initShortcuts(); initLangs(); + initTooltips(); + initColors(); connect(ui->categoriesTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(switchPage(QTreeWidgetItem*))); connect(ui->previewTabs, SIGNAL(currentChanged(int)), this, SLOT(updateStylePreview())); connect(ui->activeStyleCombo, SIGNAL(currentTextChanged(QString)), this, SLOT(updateStylePreview())); connect(ui->buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply())); connect(ui->hideBuiltInPluginsCheck, SIGNAL(toggled(bool)), this, SLOT(updateBuiltInPluginsVisibility())); + connect(ui->codeColorsResetBtn, SIGNAL(pressed()), this, SLOT(resetCodeSyntaxColors())); QList entries; entries << CFG_UI.General.SortObjects @@ -199,12 +238,13 @@ void ConfigDialog::init() << CFG_UI.General.ShowSystemObjects << CFG_UI.General.ShowVirtualTableLabels; - for (CfgEntry* cfg : entries) + for (CfgEntry*& cfg : entries) connect(cfg, SIGNAL(changed(QVariant)), this, SLOT(markRequiresSchemasRefresh())); QStringList styles = QStyleFactory::keys(); styles.sort(Qt::CaseInsensitive); ui->activeStyleCombo->addItems(styles); + ui->activeStyleCombo->setCurrentText(STYLE->name()); connect(ui->stackedWidget, SIGNAL(currentChanged(int)), this, SLOT(pageSwitched())); @@ -214,8 +254,14 @@ void ConfigDialog::init() ui->updatesGroup->setVisible(false); #endif + resettingColors = true; load(); + resettingColors = false; + colorChanged(); updateStylePreview(); + updateColorsAfterLoad(); + + ui->categoriesTree->expandAll(); } void ConfigDialog::load() @@ -229,14 +275,28 @@ void ConfigDialog::load() void ConfigDialog::save() { if (MainWindow::getInstance()->currentStyle().compare(ui->activeStyleCombo->currentText(), Qt::CaseInsensitive) != 0) + { + QList unmodifiedColors = prepareCodeSyntaxColorsForStyle(); + bool wasDark = STYLE->isDark(); + MainWindow::getInstance()->setStyle(ui->activeStyleCombo->currentText()); + if (STYLE->isDark() != wasDark) + { + resettingColors = true; // to avoid mass events of color change on syntax page + adjustSyntaxColorsForStyle(unmodifiedColors); + resettingColors = false; + colorChanged(); + } + } + QString loadedPlugins = collectLoadedPlugins(); storeSelectedFormatters(); CFG->beginMassSave(); CFG_CORE.General.LoadedPlugins.set(loadedPlugins); configMapper->saveFromWidget(ui->stackedWidget, true); commitPluginConfigs(); + commitColorsConfig(); CFG->commitMassSave(); if (requiresSchemasRefresh) @@ -302,7 +362,7 @@ void ConfigDialog::applyFilter(const QString &filter) QColor disabledColor = ui->categoriesTree->palette().color(QPalette::Disabled, QPalette::WindowText); if (filter.isEmpty()) { - for (QTreeWidgetItem* item : getAllCategoryItems()) + for (QTreeWidgetItem*& item : getAllCategoryItems()) item->setForeground(0, normalColor); return; @@ -318,10 +378,11 @@ void ConfigDialog::applyFilter(const QString &filter) QHash pageToCategoryItem = buildPageToCategoryItemMap(); QSet matchedCategories; - for (QWidget* page : pageToCategoryItem.keys()) + for (auto it = pageToCategoryItem.keyBegin(), end = pageToCategoryItem.keyEnd(); it != end; ++it) { - for (QWidget* matched : matchedWidgets) + for (QWidget* matched : qAsConst(matchedWidgets)) { + QWidget* page = *it; if (page->isAncestorOf(matched)) { if (!pageToCategoryItem.contains(page)) @@ -336,10 +397,10 @@ void ConfigDialog::applyFilter(const QString &filter) } } - for (QTreeWidgetItem* item : getAllCategoryItems()) + for (QTreeWidgetItem*& item : getAllCategoryItems()) item->setForeground(0, disabledColor); - for (QTreeWidgetItem* item : matchedCategories) + for (QTreeWidgetItem* item : qAsConst(matchedCategories)) { item->setForeground(0, normalColor); while ((item = item->parent()) != nullptr) @@ -350,7 +411,7 @@ void ConfigDialog::applyFilter(const QString &filter) QHash ConfigDialog::buildPageToCategoryItemMap() const { QHash pageNameToCategoryItem; - for (QTreeWidgetItem* item : getAllCategoryItems()) + for (QTreeWidgetItem*& item : getAllCategoryItems()) pageNameToCategoryItem[item->statusTip(0)] = item; QWidget* page = nullptr; @@ -393,7 +454,7 @@ QList ConfigDialog::getDefaultEditorsForType(DataType: }); QList results; - for (const PluginWithPriority& p: sortedPlugins) + for (PluginWithPriority& p: sortedPlugins) results << p.second; return results; @@ -427,7 +488,7 @@ void ConfigDialog::updateDataTypeEditors() ui->dataEditorsAvailableList->sortItems(); - for (MultiEditorWidgetPlugin* plugin : sortedPlugins) + for (MultiEditorWidgetPlugin*& plugin : sortedPlugins) addDataTypeEditor(plugin); } @@ -557,7 +618,7 @@ void ConfigDialog::addDataType(const QString& typeStr) void ConfigDialog::rollbackPluginConfigs() { CfgMain* mainCfg = nullptr; - for (UiConfiguredPlugin* plugin : pluginConfigMappers.keys()) + for (UiConfiguredPlugin*& plugin : pluginConfigMappers.keys()) { mainCfg = plugin->getMainUiConfig(); if (mainCfg) @@ -565,24 +626,68 @@ void ConfigDialog::rollbackPluginConfigs() } } +void ConfigDialog::rollbackColorsConfig() +{ + CFG_UI.Colors.rollback(); +} + void ConfigDialog::commitPluginConfigs() { CfgMain* mainCfg = nullptr; - for (UiConfiguredPlugin* plugin : pluginConfigMappers.keys()) + for (auto it = pluginConfigMappers.keyBegin(), end = pluginConfigMappers.keyEnd(); it != end; ++it) { - mainCfg = plugin->getMainUiConfig(); + mainCfg = (*it)->getMainUiConfig(); if (mainCfg) { mainCfg->commit(); mainCfg->begin(); // be prepared for further changes after "Apply" } } + + auto it = highlightingPluginForPreviewEditor.iterator(); + while (it.hasNext()) + { + auto item = it.next(); + if (item.value()->getLanguageName() == "SQL") + continue; + + item.value()->refreshFormats(); + } +} + +void ConfigDialog::commitColorsConfig() +{ + CFG_UI.Colors.commit(); + CFG_UI.Colors.begin(); } void ConfigDialog::connectMapperSignals(ConfigMapper* mapper) { - connect(mapper, SIGNAL(modified()), this, SLOT(markModified())); - connect(mapper, SIGNAL(notifyEnabledWidgetModified(QWidget*, CfgEntry*, const QVariant&)), this, SLOT(notifyPluginsAboutModification(QWidget*, CfgEntry*, const QVariant&))); + connect(mapper, SIGNAL(modified(QWidget*)), this, SLOT(markModified())); + connect(mapper, SIGNAL(notifyEnabledWidgetModified(QWidget*,CfgEntry*,QVariant)), this, SLOT(notifyPluginsAboutModification(QWidget*,CfgEntry*,QVariant))); +} + +QList ConfigDialog::getShortcutsCfgMains() const +{ + static const QString metaName = CFG_SHORTCUTS_METANAME; + QList mains; + for (CfgMain*& cfgMain : CfgMain::getInstances()) + { + if (cfgMain->getMetaName() != metaName) + continue; + + mains << cfgMain; + } + return mains; +} + +QList ConfigDialog::getShortcutsCfgCategories() const +{ + QList categories; + for (CfgMain*& cfgMain : getShortcutsCfgMains()) + categories.append(cfgMain->getCategories().values()); + + return categories; } void ConfigDialog::updateDataTypeListState() @@ -792,23 +897,23 @@ void ConfigDialog::detailsClicked(const QString& pluginName) // Rows QStringList rows; - rows << row.arg(tr("Description:", "plugin details")).arg(PLUGINS->getDescription(pluginName)); - rows << row.arg(tr("Category:", "plugin details")).arg(type->getTitle()); - rows << row.arg(tr("Version:", "plugin details")).arg(PLUGINS->getPrintableVersion(pluginName)); - rows << row.arg(tr("Author:", "plugin details")).arg(PLUGINS->getAuthor(pluginName)); + rows << row.arg(tr("Description:", "plugin details"), PLUGINS->getDescription(pluginName)); + rows << row.arg(tr("Category:", "plugin details"), type->getTitle()); + rows << row.arg(tr("Version:", "plugin details"), PLUGINS->getPrintableVersion(pluginName)); + rows << row.arg(tr("Author:", "plugin details"), PLUGINS->getAuthor(pluginName)); rows << hline; - rows << row.arg(tr("Internal name:", "plugin details")).arg(pluginName); - rows << row.arg(tr("Dependencies:", "plugin details")).arg(PLUGINS->getDependencies(pluginName).join(", ")); - rows << row.arg(tr("Conflicts:", "plugin details")).arg(PLUGINS->getConflicts(pluginName).join(", ")); + rows << row.arg(tr("Internal name:", "plugin details"), pluginName); + rows << row.arg(tr("Dependencies:", "plugin details"), PLUGINS->getDependencies(pluginName).join(", ")); + rows << row.arg(tr("Conflicts:", "plugin details"), PLUGINS->getConflicts(pluginName).join(", ")); // Message - QString pluginDetails = details.arg(PLUGINS->getTitle(pluginName)).arg(rows.join("")); + QString pluginDetails = details.arg(PLUGINS->getTitle(pluginName), rows.join("")); QMessageBox::information(this, tr("Plugin details"), pluginDetails); } void ConfigDialog::failedToLoadPlugin(const QString& pluginName) { - QTreeWidgetItem* theItem = itemToPluginNameMap.valueByRight(pluginName); + QTreeWidgetItem* theItem = pluginListItemToPluginNameMap.valueByRight(pluginName); if (!theItem) { qWarning() << "Plugin" << pluginName << "failed to load, but it could not be found on the plugins list in ConfigDialog."; @@ -833,7 +938,7 @@ void ConfigDialog::loadUnloadPlugin(QTreeWidgetItem* item, int column) if (column != 0) return; - QString pluginName = itemToPluginNameMap.valueByLeft(item); + QString pluginName = pluginListItemToPluginNameMap.valueByLeft(item); if (PLUGINS->isBuiltIn(pluginName)) return; @@ -866,6 +971,10 @@ void ConfigDialog::pluginAboutToUnload(Plugin* plugin, PluginType* type) if (notifiablePlugin && notifiablePlugins.contains(notifiablePlugin)) notifiablePlugins.removeOne(notifiablePlugin); + // Update code colors page + if (type->isForPluginType()) + highlighterPluginUnloaded(dynamic_cast(plugin)); + // Deinit page deinitPluginPage(plugin); @@ -879,6 +988,14 @@ void ConfigDialog::pluginLoaded(Plugin* plugin, PluginType* type, bool skipConfi if (type->isForPluginType()) codeFormatterLoaded(); + // Update code colors page + if (type->isForPluginType()) + highlighterPluginLoaded(dynamic_cast(plugin)); + + QTreeWidgetItem* listItem = pluginListItemToPluginNameMap.valueByRight(plugin->getName()); + if (listItem && listItem->checkState(0) == Qt::Unchecked) + listItem->setCheckState(0, Qt::Checked); + // Init page if (!initPluginPage(plugin, skipConfigLoading)) return; @@ -901,7 +1018,9 @@ void ConfigDialog::pluginLoaded(Plugin* plugin, PluginType* type, bool skipConfi void ConfigDialog::pluginUnloaded(const QString& pluginName, PluginType* type) { - UNUSED(pluginName); + QTreeWidgetItem* item = pluginListItemToPluginNameMap.valueByRight(pluginName); + if (item && item->checkState(0) == Qt::Checked) + item->setCheckState(0, Qt::Unchecked); // Update formatters page if (type->isForPluginType()) @@ -918,7 +1037,7 @@ void ConfigDialog::updatePluginCategoriesVisibility() void ConfigDialog::updateBuiltInPluginsVisibility() { bool hideBuiltIn = ui->hideBuiltInPluginsCheck->isChecked(); - QHashIterator it = itemToPluginNameMap.iterator(); + QHashIterator it = pluginListItemToPluginNameMap.iterator(); while (it.hasNext()) { it.next(); @@ -929,6 +1048,13 @@ void ConfigDialog::updateBuiltInPluginsVisibility() } } +void ConfigDialog::refreshColorsInSyntaxHighlighters() +{ + auto it = highlightingPluginForPreviewEditor.iterator(); + while (it.hasNext()) + it.next().value()->refreshFormats(); +} + void ConfigDialog::applyShortcutsFilter(const QString &filter) { QTreeWidgetItem* categoryItem = nullptr; @@ -964,10 +1090,144 @@ void ConfigDialog::markRequiresSchemasRefresh() void ConfigDialog::notifyPluginsAboutModification(QWidget*, CfgEntry* key, const QVariant& value) { - for (ConfigNotifiablePlugin* plugin : notifiablePlugins) + for (ConfigNotifiablePlugin*& plugin : notifiablePlugins) plugin->configModified(key, value); } +void ConfigDialog::resetCodeSyntaxColors() +{ + resettingColors = true; + for (QWidget*& widget : configMapper->getAllConfigWidgets(ui->commonCodeColorsGroup)) + configMapper->applyConfigDefaultValueToWidget(widget); + + resettingColors = false; + colorChanged(); +} + +void ConfigDialog::colorChanged() +{ + refreshColorsInSyntaxHighlighters(); + for (QSyntaxHighlighter*& highligter : colorPreviewHighlighters) + highligter->rehighlight(); + + if (codePreviewSqlEditor) + codePreviewSqlEditor->colorsConfigChanged(); +} + +void ConfigDialog::adjustSyntaxColorsForStyle(QList& unmodifiedColors) +{ + for (QWidget*& w : unmodifiedColors) + configMapper->applyConfigDefaultValueToWidget(w); +} + +void ConfigDialog::highlighterPluginLoaded(SyntaxHighlighterPlugin* plugin) +{ + QPlainTextEdit* editor = nullptr; + if (plugin->getLanguageName() == "SQL") + { + // For SQL there is assumed just one, built-in plugin + codePreviewSqlEditor = new SqlEditor(ui->codeColorsPreviewTabWidget); + codePreviewSqlEditor->setShowLineNumbers(false); + codePreviewSqlEditor->setCurrentQueryHighlighting(true); + editor = codePreviewSqlEditor; + } + else + { + editor = new QPlainTextEdit(ui->codeColorsPreviewTabWidget); + editor->setFont(CFG_UI.Fonts.SqlEditor.get()); + colorPreviewHighlighters << plugin->createSyntaxHighlighter(editor); + } + + editor->setPlainText(plugin->previewSampleCode()); + editor->setReadOnly(true); + colorPreviewEditors << editor; + highlightingPluginForPreviewEditor.insert(editor, plugin); + ui->codeColorsPreviewTabWidget->addTab(editor, plugin->getLanguageName()); +} + +void ConfigDialog::highlighterPluginUnloaded(SyntaxHighlighterPlugin* plugin) +{ + QPlainTextEdit* editor = highlightingPluginForPreviewEditor.valueByRight(plugin); + if (!editor) + { + qCritical() << "Highlighter plugin unloaded for which there is no preview editor! Application crash is possible. Plugin:" << plugin->getName(); + return; + } + + QTextDocument* document = editor->document(); + QSyntaxHighlighter* highlighter = findFirst(colorPreviewHighlighters, [document](auto highlighter) {return highlighter->document() == document;}); + + ui->codeColorsPreviewTabWidget->removeTab(ui->codeColorsPreviewTabWidget->indexOf(editor)); + colorPreviewHighlighters.removeOne(highlighter); + colorPreviewEditors.removeOne(editor); + delete editor; + + highlightingPluginForPreviewEditor.removeRight(plugin); +} + +QList ConfigDialog::prepareCodeSyntaxColorsForStyle() +{ + QList unmodified; + for (QWidget*& w : configMapper->getAllConfigWidgets(ui->commonCodeColorsGroup)) + { + CfgEntry* entry = configMapper->getConfigForWidget(w); + if (entry->getDefaultValue() == entry->get()) + unmodified << w; + } + return unmodified; +} + +void ConfigDialog::initColors() +{ + CFG_UI.Colors.begin(); + connect(configMapper, &ConfigMapper::modified, this, + [this](QWidget* widget) + { + CfgEntry* key = configMapper->getBindConfigForWidget(widget); + if (!key) + { + qCritical() << "Missing CfgEntry in Colors configuration for widget" << widget->objectName(); + return; + } + + if (key->getCategory() != CFG_UI.Colors) + return; + + configMapper->saveFromWidget(widget, key); + if (key->getName().endsWith("Custom")) + toggleColorButtonState(key); + + if (resettingColors) + return; + + colorChanged(); + }); +} + +void ConfigDialog::updateColorsAfterLoad() +{ + QHash entries = CFG_UI.Colors.getEntries(); + auto it = entries.begin(); + while (it != entries.end()) + { + if (it.key().endsWith("Custom")) + toggleColorButtonState(it.value()); + + it++; + } +} + +void ConfigDialog::toggleColorButtonState(CfgEntry* colorCheckEntry) +{ + CfgEntry* colorKey = colorCheckEntry->getCategory()->getEntryByName(colorCheckEntry->getName().chopped(6)); + if (colorKey) + { + QWidget* button = configMapper->getBindWidgetForConfig(colorKey); + if (button) + button->setEnabled(colorCheckEntry->get().toBool()); + } +} + void ConfigDialog::updatePluginCategoriesVisibility(QTreeWidgetItem* categoryItem) { categoryItem->setHidden(categoryItem->childCount() == 0); @@ -976,7 +1236,7 @@ void ConfigDialog::updatePluginCategoriesVisibility(QTreeWidgetItem* categoryIte QString ConfigDialog::collectLoadedPlugins() const { QStringList loaded; - QHashIterator it = itemToPluginNameMap.iterator(); + QHashIterator it = pluginListItemToPluginNameMap.iterator(); while (it.hasNext()) { it.next(); @@ -1147,8 +1407,7 @@ QTreeWidgetItem* ConfigDialog::createPluginsTypeItem(const QString& widgetName, if (item->statusTip(0) == widgetName) return item; } - return nullptr; - + return new QTreeWidgetItem({title}); } QTreeWidgetItem* ConfigDialog::getItemByTitle(const QString& title) const @@ -1195,23 +1454,24 @@ void ConfigDialog::initPlugins() // Recreate QTreeWidgetItem *typeItem = nullptr; - for (PluginType* pluginType : PLUGINS->getPluginTypes()) + for (PluginType*& pluginType : PLUGINS->getPluginTypes()) { typeItem = createPluginsTypeItem(pluginType->getConfigUiForm(), pluginType->getTitle()); - if (!typeItem) - continue; item->addChild(typeItem); pluginTypeToItemMap[pluginType] = typeItem; - for (Plugin* plugin : pluginType->getLoadedPlugins()) + for (Plugin*& plugin : pluginType->getLoadedPlugins()) pluginLoaded(plugin, pluginType, true); } updatePluginCategoriesVisibility(); + // Using old connect() syntax, becase the pointer syntax does not work correctly with signals declared in an interface class. + // At least that's the case with Qt 5.15.2. connect(PLUGINS, SIGNAL(loaded(Plugin*,PluginType*)), this, SLOT(pluginLoaded(Plugin*,PluginType*))); connect(PLUGINS, SIGNAL(aboutToUnload(Plugin*,PluginType*)), this, SLOT(pluginAboutToUnload(Plugin*,PluginType*))); + connect(PLUGINS, SIGNAL(unloaded(QString,PluginType*)), this, SLOT(pluginUnloaded(QString,PluginType*))); } void ConfigDialog::initPluginsPage() @@ -1255,7 +1515,7 @@ void ConfigDialog::initPluginsPage() categoryRow = 0; QList pluginTypes = PLUGINS->getPluginTypes(); sSort(pluginTypes, PluginType::nameLessThan); - for (PluginType* pluginType : pluginTypes) + for (PluginType*& pluginType : pluginTypes) { category = new QTreeWidgetItem({pluginType->getTitle()}); font.setItalic(false); @@ -1275,7 +1535,7 @@ void ConfigDialog::initPluginsPage() itemRow = 0; pluginNames = pluginType->getAllPluginNames(); sSort(pluginNames); - for (const QString& pluginName : pluginNames) + for (QString& pluginName : pluginNames) { builtIn = PLUGINS->isBuiltIn(pluginName); title = PLUGINS->getTitle(pluginName); @@ -1290,10 +1550,10 @@ void ConfigDialog::initPluginsPage() category->addChild(item); - itemToPluginNameMap.insert(item, pluginName); + pluginListItemToPluginNameMap.insert(item, pluginName); // Details button - detailsLabel = new QLabel(QString("%2 ").arg(pluginName).arg(tr("Details")), ui->pluginsList); + detailsLabel = new QLabel(QString("%2 ").arg(pluginName, tr("Details")), ui->pluginsList); detailsLabel->setAlignment(Qt::AlignRight); itemIndex = ui->pluginsList->model()->index(itemRow, 1, categoryIndex); ui->pluginsList->setIndexWidget(itemIndex, detailsLabel); @@ -1322,10 +1582,10 @@ void ConfigDialog::initPluginsPage() bool ConfigDialog::initPluginPage(Plugin* plugin, bool skipConfigLoading) { - if (!dynamic_cast(plugin)) + UiConfiguredPlugin* cfgPlugin = dynamic_cast(plugin); + if (!cfgPlugin) return false; - UiConfiguredPlugin* cfgPlugin = dynamic_cast(plugin); QString pluginName = plugin->getName(); QString formName = cfgPlugin->getConfigUiForm(); QWidget* widget = FORMS->createWidget(formName); @@ -1398,7 +1658,7 @@ void ConfigDialog::initDataEditors() sSort(dataTypeList); QListWidgetItem* item = nullptr; - for (const QString& type : dataTypeList) + for (QString& type : dataTypeList) { item = new QListWidgetItem(type); if (!DataType::getAllNames().contains(type)) @@ -1441,49 +1701,30 @@ void ConfigDialog::initShortcuts() ui->shortcutsTable->header()->setSectionResizeMode(2, QHeaderView::Fixed); ui->shortcutsTable->header()->resizeSection(1, 150); ui->shortcutsTable->header()->resizeSection(2, 26); + ui->shortcutsTable->header()->resizeSection(3, 26); ui->shortcutsFilterEdit->setClearButtonEnabled(true); new UserInputFilter(ui->shortcutsFilterEdit, this, SLOT(applyShortcutsFilter(QString))); - static const QString metaName = CFG_SHORTCUTS_METANAME; - QList categories; - for (CfgMain* cfgMain : CfgMain::getInstances()) - { - if (cfgMain->getMetaName() != metaName) - continue; - - for (CfgCategory* cat : cfgMain->getCategories().values()) - categories << cat; - } + QList categories = getShortcutsCfgCategories(); + ui->shortcutsTable->setItemDelegate(new ConfigDialogItemDelegate()); sSort(categories, [](CfgCategory* cat1, CfgCategory* cat2) -> bool { return cat1->getTitle().compare(cat2->getTitle()) < 0; }); - for (CfgCategory* cat : categories) + for (CfgCategory*& cat : categories) initShortcuts(cat); } void ConfigDialog::initShortcuts(CfgCategory *cfgCategory) { - QTreeWidgetItem* item = nullptr; - QFont font; - QModelIndex categoryIndex; - QModelIndex itemIndex; - QKeySequenceEdit *sequenceEdit = nullptr; - QToolButton* clearButton = nullptr; - QString title; - QSize itemSize; - // Font and metrics - item = new QTreeWidgetItem({""}); - font = item->font(0); - - QFontMetrics fm(font); - itemSize = QSize(-1, (fm.ascent() + fm.descent() + 4)); - - delete item; + QTreeWidgetItem item({""}); + QFont font = item.font(0); +// QFontMetrics fm(font); +// QSize itemSize = QSize(-1, -1); // Creating... QBrush categoryBg = ui->shortcutsTable->palette().button(); @@ -1493,47 +1734,63 @@ void ConfigDialog::initShortcuts(CfgCategory *cfgCategory) font.setItalic(false); font.setBold(true); category->setFont(0, font); - for (int i = 0; i < 3; i++) + for (int i = 0; i < 4; i++) { + category->setData(i, Qt::UserRole, true); category->setBackground(i, categoryBg); category->setForeground(i, categoryFg); } - category->setSizeHint(0, itemSize); +// category->setSizeHint(0, itemSize); category->setFlags(category->flags() ^ Qt::ItemIsSelectable); ui->shortcutsTable->addTopLevelItem(category); int categoryRow = ui->shortcutsTable->topLevelItemCount() - 1; - categoryIndex = ui->shortcutsTable->model()->index(categoryRow, 0); + QModelIndex categoryIndex = ui->shortcutsTable->model()->index(categoryRow, 0); int itemRow = 0; QStringList entryNames = cfgCategory->getEntries().keys(); sSort(entryNames); - for (const QString& entryName : entryNames) + for (QString& entryName : entryNames) { + CfgEntry* cfgEntry = cfgCategory->getEntries()[entryName]; + // Title - title = cfgCategory->getEntries()[entryName]->getTitle(); - item = new QTreeWidgetItem(category, {title}); + QString title = cfgEntry->getTitle(); + new QTreeWidgetItem(category, {title}); // Key edit - sequenceEdit = new QKeySequenceEdit(ui->shortcutsTable); + QKeySequenceEdit* sequenceEdit = new QKeySequenceEdit(ui->shortcutsTable); sequenceEdit->setFixedWidth(150); - sequenceEdit->setProperty("cfg", cfgCategory->getEntries()[entryName]->getFullKey()); - itemIndex = ui->shortcutsTable->model()->index(itemRow, 1, categoryIndex); + sequenceEdit->setProperty("cfg", cfgEntry->getFullKey()); + QModelIndex itemIndex = ui->shortcutsTable->model()->index(itemRow, 1, categoryIndex); ui->shortcutsTable->setIndexWidget(itemIndex, sequenceEdit); configMapper->addExtraWidget(sequenceEdit); // Clear button - clearButton = new QToolButton(ui->shortcutsTable); + QToolButton* clearButton = new QToolButton(ui->shortcutsTable); clearButton->setIcon(ICONS.CLEAR_LINEEDIT); - connect(clearButton, &QToolButton::clicked, [this, sequenceEdit]() + clearButton->setToolTip(tr("Clear hotkey for this action")); + connect(clearButton, &QToolButton::clicked, this, [this, sequenceEdit]() { sequenceEdit->clear(); this->markModified(); - }); itemIndex = ui->shortcutsTable->model()->index(itemRow, 2, categoryIndex); ui->shortcutsTable->setIndexWidget(itemIndex, clearButton); + // Restore default value button + QToolButton* defaultButton = new QToolButton(ui->shortcutsTable); + defaultButton->setIcon(ICONS.RESTORE_DEFAULT); + defaultButton->setToolTip(tr("Restore original hotkey for this action")); + connect(defaultButton, &QToolButton::clicked, this, [this, sequenceEdit, cfgEntry]() + { + cfgEntry->reset(); + sequenceEdit->setKeySequence(QKeySequence::fromString(cfgEntry->get().toString())); + this->markModified(); + }); + itemIndex = ui->shortcutsTable->model()->index(itemRow, 3, categoryIndex); + ui->shortcutsTable->setIndexWidget(itemIndex, defaultButton); + itemRow++; } @@ -1545,7 +1802,9 @@ void ConfigDialog::initLangs() QMap langs = getAvailableLanguages(); int idx = 0; int selected = -1; - for (const QString& lang : langs.keys()) + QStringList langList = langs.keys(); + strSort(langList, Qt::CaseInsensitive); + for (QString& lang : langList) { ui->langCombo->addItem(lang, langs[lang]); if (langs[lang] == SQLITESTUDIO->getCurrentLang()) @@ -1557,6 +1816,21 @@ void ConfigDialog::initLangs() ui->langCombo->setCurrentIndex(selected); } +void ConfigDialog::initTooltips() +{ + ui->execQueryUnderCursorCheck->setToolTip(ui->execQueryUnderCursorCheck->toolTip().arg( + GET_SHORTCUT_ENTRY(EditorWindow, EXEC_ONE_QUERY)->get().toString(), + GET_SHORTCUT_ENTRY(EditorWindow, EXEC_ALL_QUERIES)->get().toString() + )); + + setValidStateTooltip(ui->commonCodeColorsGroup, + tr("Here you can configure colors for code syntax highlighting. " + "They are shared across different languages - not only for SQL, but also JavaScript and others. " + "By default a theme-based color is used. To define your own color, enable a custom color " + "by selecting a checkbox next to a particular color.")); + +} + bool ConfigDialog::isPluginCategoryItem(QTreeWidgetItem *item) const { return item->parent() && item->parent()->parent() && item->parent()->parent() == getPluginsCategoryItem(); -- cgit v1.2.3