From 1fdc150116cad39aae5c5da407c3312b47a59e3a Mon Sep 17 00:00:00 2001 From: Unit 193 Date: Fri, 17 Dec 2021 07:06:30 -0500 Subject: New upstream version 3.3.3+dfsg1. --- .../guiSQLiteStudio/dialogs/aboutdialog.cpp | 2 +- .../guiSQLiteStudio/dialogs/columndialog.cpp | 101 ++- .../guiSQLiteStudio/dialogs/columndialog.h | 7 +- .../guiSQLiteStudio/dialogs/columndialog.ui | 78 ++- .../dialogs/columndialogconstraintsmodel.cpp | 17 +- .../dialogs/columndialogconstraintsmodel.h | 1 + .../guiSQLiteStudio/dialogs/configdialog.cpp | 38 +- .../guiSQLiteStudio/dialogs/configdialog.ui | 686 ++------------------- .../guiSQLiteStudio/dialogs/constraintdialog.cpp | 6 + .../guiSQLiteStudio/dialogs/constraintdialog.h | 1 + .../guiSQLiteStudio/dialogs/cssdebugdialog.cpp | 7 +- .../guiSQLiteStudio/dialogs/dbconverterdialog.cpp | 218 ------- .../guiSQLiteStudio/dialogs/dbconverterdialog.h | 52 -- .../guiSQLiteStudio/dialogs/dbconverterdialog.ui | 144 ----- SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.cpp | 68 +- .../dialogs/errorsconfirmdialog.cpp | 3 +- .../guiSQLiteStudio/dialogs/exportdialog.cpp | 10 +- .../guiSQLiteStudio/dialogs/importdialog.cpp | 2 + .../guiSQLiteStudio/dialogs/indexdialog.cpp | 133 ++-- .../guiSQLiteStudio/dialogs/indexdialog.h | 35 +- .../dialogs/indexexprcolumndialog.cpp | 2 +- .../dialogs/newconstraintdialog.cpp | 59 +- .../guiSQLiteStudio/dialogs/newconstraintdialog.h | 6 +- .../guiSQLiteStudio/dialogs/newversiondialog.cpp | 33 +- .../guiSQLiteStudio/dialogs/newversiondialog.h | 7 +- .../guiSQLiteStudio/dialogs/newversiondialog.ui | 110 ++-- .../guiSQLiteStudio/dialogs/populatedialog.cpp | 3 +- .../guiSQLiteStudio/dialogs/triggerdialog.cpp | 30 +- 28 files changed, 543 insertions(+), 1316 deletions(-) delete mode 100644 SQLiteStudio3/guiSQLiteStudio/dialogs/dbconverterdialog.cpp delete mode 100644 SQLiteStudio3/guiSQLiteStudio/dialogs/dbconverterdialog.h delete mode 100644 SQLiteStudio3/guiSQLiteStudio/dialogs/dbconverterdialog.ui (limited to 'SQLiteStudio3/guiSQLiteStudio/dialogs') diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/aboutdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/aboutdialog.cpp index 82d5e14..7e084fb 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/aboutdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/aboutdialog.cpp @@ -120,7 +120,7 @@ QString AboutDialog::readFile(const QString& path) if (!file.open(QIODevice::ReadOnly)) { qCritical() << "Error opening" << file.fileName(); - return QString::null; + return QString(); } QString contents = QString::fromLatin1(file.readAll()).toHtmlEscaped(); file.close(); diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.cpp index 8bf1698..ebf9253 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.cpp @@ -62,6 +62,7 @@ void ColumnDialog::init() connect(ui->fkButton, SIGNAL(clicked()), this, SLOT(configureFk())); connect(ui->checkButton, SIGNAL(clicked()), this, SLOT(configureCheck())); connect(ui->defaultButton, SIGNAL(clicked()), this, SLOT(configureDefault())); + connect(ui->generatedButton, SIGNAL(clicked()), this, SLOT(configureGenerated())); connect(ui->notNullButton, SIGNAL(clicked()), this, SLOT(configureNotNull())); connect(ui->collateButton, SIGNAL(clicked()), this, SLOT(configureCollate())); connect(ui->uniqueButton, SIGNAL(clicked()), this, SLOT(configureUnique())); @@ -95,6 +96,7 @@ void ColumnDialog::createActions() createAction(ADD_CHECK, ICONS.CONSTRAINT_CHECK_ADD, tr("Add a check constraint", "column dialog"), this, SLOT(addCheck()), ui->constraintsToolbar); createAction(ADD_NOT_NULL, ICONS.CONSTRAINT_NOT_NULL_ADD, tr("Add a not null constraint", "column dialog"), this, SLOT(addNotNull()), ui->constraintsToolbar); createAction(ADD_COLLATE, ICONS.CONSTRAINT_COLLATION_ADD, tr("Add a collate constraint", "column dialog"), this, SLOT(addCollate()), ui->constraintsToolbar); + createAction(ADD_GENERATED, ICONS.CONSTRAINT_GENERATED_ADD, tr("Add a generated value constraint", "column dialog"), this, SLOT(addGenerated()), ui->constraintsToolbar); createAction(ADD_DEFAULT, ICONS.CONSTRAINT_DEFAULT_ADD, tr("Add a default constraint", "column dialog"), this, SLOT(addDefault()), ui->constraintsToolbar); } @@ -128,6 +130,7 @@ void ColumnDialog::updateState() ui->notNullButton->setEnabled(ui->notNullCheck->isChecked()); ui->checkButton->setEnabled(ui->checkCheck->isChecked()); ui->collateButton->setEnabled(ui->collateCheck->isChecked()); + ui->generatedButton->setEnabled(ui->generatedCheck->isChecked()); ui->defaultButton->setEnabled(ui->defaultCheck->isChecked()); updateConstraintsToolbarState(); } @@ -135,6 +138,9 @@ void ColumnDialog::updateState() void ColumnDialog::addConstraint(ConstraintDialog::Constraint mode) { NewConstraintDialog dialog(mode, column.data(), db, this); + for (ConstraintDialog::Constraint constraint : disabledConstraints) + dialog.disableMode(constraint); + if (dialog.exec() != QDialog::Accepted) return; @@ -160,6 +166,7 @@ void ColumnDialog::setupConstraintCheckBoxes() ui->notNullCheck->setIcon(ICONS.CONSTRAINT_NOT_NULL); ui->checkCheck->setIcon(ICONS.CONSTRAINT_CHECK); ui->collateCheck->setIcon(ICONS.CONSTRAINT_COLLATION); + ui->generatedCheck->setIcon(ICONS.CONSTRAINT_GENERATED); ui->defaultCheck->setIcon(ICONS.CONSTRAINT_DEFAULT); connect(ui->pkCheck, SIGNAL(clicked(bool)), this, SLOT(pkToggled(bool))); @@ -168,6 +175,7 @@ void ColumnDialog::setupConstraintCheckBoxes() connect(ui->notNullCheck, SIGNAL(clicked(bool)), this, SLOT(notNullToggled(bool))); connect(ui->checkCheck, SIGNAL(clicked(bool)), this, SLOT(checkToggled(bool))); connect(ui->collateCheck, SIGNAL(clicked(bool)), this, SLOT(collateToggled(bool))); + connect(ui->generatedCheck, SIGNAL(clicked(bool)), this, SLOT(generatedToggled(bool))); connect(ui->defaultCheck, SIGNAL(clicked(bool)), this, SLOT(defaultToggled(bool))); for (QCheckBox* cb : { @@ -177,6 +185,7 @@ void ColumnDialog::setupConstraintCheckBoxes() ui->notNullCheck, ui->checkCheck, ui->collateCheck, + ui->generatedCheck, ui->defaultCheck }) { @@ -293,15 +302,7 @@ void ColumnDialog::updateConstraintState(SqliteCreateTable::Column::Constraint* } QString errMsg = tr("Correct the constraint's configuration."); - if (db->getDialect() == Dialect::Sqlite2 && isUnofficialSqlite2Constraint(constraint)) - { - QString tooltip = tr("This constraint is not officially supported by SQLite 2,\nbut it's okay to use it."); - setValidStateWihtTooltip(toolButton, tooltip, result, errMsg); - } - else - { - setValidState(toolButton, result, errMsg); - } + setValidState(toolButton, result, errMsg); if (!result) { @@ -326,6 +327,8 @@ QCheckBox* ColumnDialog::getCheckBoxForConstraint(SqliteCreateTable::Column::Con return ui->defaultCheck; case SqliteCreateTable::Column::Constraint::COLLATE: return ui->collateCheck; + case SqliteCreateTable::Column::Constraint::GENERATED: + return ui->generatedCheck; case SqliteCreateTable::Column::Constraint::FOREIGN_KEY: return ui->fkCheck; case SqliteCreateTable::Column::Constraint::NULL_: @@ -352,6 +355,8 @@ QToolButton* ColumnDialog::getToolButtonForConstraint(SqliteCreateTable::Column: return ui->defaultButton; case SqliteCreateTable::Column::Constraint::COLLATE: return ui->collateButton; + case SqliteCreateTable::Column::Constraint::GENERATED: + return ui->generatedButton; case SqliteCreateTable::Column::Constraint::FOREIGN_KEY: return ui->fkButton; case SqliteCreateTable::Column::Constraint::NULL_: @@ -362,26 +367,6 @@ QToolButton* ColumnDialog::getToolButtonForConstraint(SqliteCreateTable::Column: return nullptr; } -bool ColumnDialog::isUnofficialSqlite2Constraint(SqliteCreateTable::Column::Constraint* constraint) -{ - switch (constraint->type) - { - case SqliteCreateTable::Column::Constraint::FOREIGN_KEY: - case SqliteCreateTable::Column::Constraint::COLLATE: - return true; - case SqliteCreateTable::Column::Constraint::PRIMARY_KEY: - case SqliteCreateTable::Column::Constraint::NOT_NULL: - case SqliteCreateTable::Column::Constraint::UNIQUE: - case SqliteCreateTable::Column::Constraint::CHECK: - case SqliteCreateTable::Column::Constraint::DEFAULT: - case SqliteCreateTable::Column::Constraint::NULL_: - case SqliteCreateTable::Column::Constraint::NAME_ONLY: - case SqliteCreateTable::Column::Constraint::DEFERRABLE_ONLY: - break; - } - return false; -} - void ColumnDialog::updateTypeValidations() { QString scaleErrorMsg = tr("Scale is not allowed for INTEGER PRIMARY KEY columns."); @@ -503,6 +488,11 @@ void ColumnDialog::addNotNull() addConstraint(ConstraintDialog::NOTNULL); } +void ColumnDialog::addGenerated() +{ + addConstraint(ConstraintDialog::GENERATED); +} + void ColumnDialog::addDefault() { addConstraint(ConstraintDialog::DEFAULT); @@ -538,6 +528,11 @@ void ColumnDialog::configureNotNull() configureConstraint(SqliteCreateTable::Column::Constraint::NOT_NULL); } +void ColumnDialog::configureGenerated() +{ + configureConstraint(SqliteCreateTable::Column::Constraint::GENERATED); +} + void ColumnDialog::configureDefault() { configureConstraint(SqliteCreateTable::Column::Constraint::DEFAULT); @@ -569,6 +564,11 @@ void ColumnDialog::collateToggled(bool enabled) constraintToggled(SqliteCreateTable::Column::Constraint::COLLATE, enabled); } +void ColumnDialog::generatedToggled(bool enabled) +{ + constraintToggled(SqliteCreateTable::Column::Constraint::GENERATED, enabled); +} + void ColumnDialog::notNullToggled(bool enabled) { constraintToggled(SqliteCreateTable::Column::Constraint::NOT_NULL, enabled); @@ -596,6 +596,7 @@ void ColumnDialog::updateValidations() ui->notNullCheck, ui->checkCheck, ui->collateCheck, + ui->generatedCheck, ui->defaultCheck }) { @@ -609,6 +610,7 @@ void ColumnDialog::updateValidations() ui->notNullButton, ui->checkButton, ui->collateButton, + ui->generatedButton, ui->defaultButton }) { @@ -663,6 +665,47 @@ QToolBar* ColumnDialog::getToolBar(int toolbar) const return nullptr; } +void ColumnDialog::disableConstraint(ConstraintDialog::Constraint constraint) +{ + disabledConstraints << constraint; + switch (constraint) { + case ConstraintDialog::PK: + ui->pkCheck->setEnabled(false); + actionMap[ADD_PK]->setEnabled(false); + break; + case ConstraintDialog::FK: + ui->fkCheck->setEnabled(false); + actionMap[ADD_FK]->setEnabled(false); + break; + case ConstraintDialog::UNIQUE: + ui->uniqueCheck->setEnabled(false); + actionMap[ADD_UNIQUE]->setEnabled(false); + break; + case ConstraintDialog::NOTNULL: + ui->notNullCheck->setEnabled(false); + actionMap[ADD_NOT_NULL]->setEnabled(false); + break; + case ConstraintDialog::CHECK: + ui->checkCheck->setEnabled(false); + actionMap[ADD_CHECK]->setEnabled(false); + break; + case ConstraintDialog::COLLATE: + ui->collateCheck->setEnabled(false); + actionMap[ADD_COLLATE]->setEnabled(false); + break; + case ConstraintDialog::GENERATED: + ui->generatedCheck->setEnabled(false); + actionMap[ADD_GENERATED]->setEnabled(false); + break; + case ConstraintDialog::DEFAULT: + ui->defaultCheck->setEnabled(false); + actionMap[ADD_DEFAULT]->setEnabled(false); + break; + case ConstraintDialog::UNKNOWN: + break; + } +} + void ColumnDialog::updateDataType() { if (!column) diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.h b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.h index 47615e8..c9faf23 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.h +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.h @@ -34,6 +34,7 @@ class GUI_API_EXPORT ColumnDialog : public QDialog, public ExtActionContainer ADD_CHECK, ADD_DEFAULT, ADD_NOT_NULL, + ADD_GENERATED, ADD_COLLATE }; @@ -48,6 +49,7 @@ class GUI_API_EXPORT ColumnDialog : public QDialog, public ExtActionContainer void setColumn(SqliteCreateTable::Column* value); SqliteCreateTable::Column* getModifiedColumn(); QToolBar* getToolBar(int toolbar) const; + void disableConstraint(ConstraintDialog::Constraint constraint); protected: void changeEvent(QEvent *e); @@ -66,7 +68,6 @@ class GUI_API_EXPORT ColumnDialog : public QDialog, public ExtActionContainer void updateConstraintState(SqliteCreateTable::Column::Constraint* constraint); QCheckBox* getCheckBoxForConstraint(SqliteCreateTable::Column::Constraint* constraint); QToolButton* getToolButtonForConstraint(SqliteCreateTable::Column::Constraint* constraint); - bool isUnofficialSqlite2Constraint(SqliteCreateTable::Column::Constraint* constraint); void updateTypeValidations(); void updateTypeForAutoIncr(); bool hasAutoIncr() const; @@ -77,6 +78,7 @@ class GUI_API_EXPORT ColumnDialog : public QDialog, public ExtActionContainer QCheckBox* modeCheckBox = nullptr; Db* db = nullptr; bool integerTypeEnforced = false; + QSet disabledConstraints; private slots: void updateConstraintsToolbarState(); @@ -93,12 +95,14 @@ class GUI_API_EXPORT ColumnDialog : public QDialog, public ExtActionContainer void addCheck(); void addCollate(); void addNotNull(); + void addGenerated(); void addDefault(); void configurePk(); void configureFk(); void configureUnique(); void configureCheck(); void configureCollate(); + void configureGenerated(); void configureNotNull(); void configureDefault(); void pkToggled(bool enabled); @@ -106,6 +110,7 @@ class GUI_API_EXPORT ColumnDialog : public QDialog, public ExtActionContainer void uniqueToggled(bool enabled); void checkToggled(bool enabled); void collateToggled(bool enabled); + void generatedToggled(bool enabled); void notNullToggled(bool enabled); void defaultToggled(bool enabled); void switchMode(bool advanced); diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.ui b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.ui index 1ac6cbb..6094ab1 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.ui +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialog.ui @@ -6,8 +6,8 @@ 0 0 - 424 - 360 + 467 + 393 @@ -109,31 +109,31 @@ - - + + - Unique + Configure - - + + - Configure + Generated value - - + + - Foreign Key + Not NULL - - + + - Configure + Foreign Key @@ -144,17 +144,24 @@ - - + + - Not NULL + Check condition - - + + - Check condition + Unique + + + + + + + Configure @@ -165,43 +172,50 @@ - - + + - Default + Configure - - + + Configure - - + + Configure - - + + Configure - - + + + + Default + + + + + Configure - + Configure diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialogconstraintsmodel.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialogconstraintsmodel.cpp index 853b680..1107ef5 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialogconstraintsmodel.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialogconstraintsmodel.cpp @@ -147,6 +147,9 @@ QIcon ColumnDialogConstraintsModel::getIcon(int rowIdx) const return ICONS.CONSTRAINT_DEFAULT; case SqliteCreateTable::Column::Constraint::COLLATE: return ICONS.CONSTRAINT_COLLATION; + case SqliteCreateTable::Column::Constraint::GENERATED: + return (constr->generatedType == SqliteCreateTable::Column::Constraint::GeneratedType::STORED) ? + ICONS.CONSTRAINT_GENERATED_STORED : ICONS.CONSTRAINT_GENERATED_VIRTUAL; case SqliteCreateTable::Column::Constraint::FOREIGN_KEY: return ICONS.CONSTRAINT_FOREIGN_KEY; case SqliteCreateTable::Column::Constraint::NULL_: @@ -180,6 +183,8 @@ QString ColumnDialogConstraintsModel::getType(int rowIdx) const return "DEFAULT"; case SqliteCreateTable::Column::Constraint::COLLATE: return "COLLATE"; + case SqliteCreateTable::Column::Constraint::GENERATED: + return "GENERATED"; case SqliteCreateTable::Column::Constraint::FOREIGN_KEY: return "FOREIGN KEY"; case SqliteCreateTable::Column::Constraint::NULL_: @@ -187,7 +192,7 @@ QString ColumnDialogConstraintsModel::getType(int rowIdx) const case SqliteCreateTable::Column::Constraint::DEFERRABLE_ONLY: break; } - return QString::null; + return QString(); } QString ColumnDialogConstraintsModel::getDetails(int rowIdx) const @@ -207,6 +212,8 @@ QString ColumnDialogConstraintsModel::getDetails(int rowIdx) const return getDefaultDetails(constr); case SqliteCreateTable::Column::Constraint::COLLATE: return getCollateDetails(constr); + case SqliteCreateTable::Column::Constraint::GENERATED: + return getGeneratedDetails(constr); case SqliteCreateTable::Column::Constraint::FOREIGN_KEY: return getFkDetails(constr); case SqliteCreateTable::Column::Constraint::NULL_: @@ -214,7 +221,7 @@ QString ColumnDialogConstraintsModel::getDetails(int rowIdx) const case SqliteCreateTable::Column::Constraint::DEFERRABLE_ONLY: break; } - return QString::null; + return QString(); } QString ColumnDialogConstraintsModel::getPkDetails(SqliteCreateTable::Column::Constraint* constr) const @@ -241,6 +248,12 @@ QString ColumnDialogConstraintsModel::getCheckDetails(SqliteCreateTable::Column: return getConstrDetails(constr, idx); } +QString ColumnDialogConstraintsModel::getGeneratedDetails(SqliteCreateTable::Column::Constraint* constr) const +{ + int idx = constr->tokens.indexOf(Token::KEYWORD, "AS", Qt::CaseInsensitive); + return getConstrDetails(constr, idx); +} + QString ColumnDialogConstraintsModel::getDefaultDetails(SqliteCreateTable::Column::Constraint* constr) const { int idx = constr->tokens.indexOf(Token::KEYWORD, "DEFAULT", Qt::CaseInsensitive); diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialogconstraintsmodel.h b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialogconstraintsmodel.h index f37933a..aed7a28 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialogconstraintsmodel.h +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/columndialogconstraintsmodel.h @@ -44,6 +44,7 @@ class GUI_API_EXPORT ColumnDialogConstraintsModel : public QAbstractTableModel QString getNotNullDetails(SqliteCreateTable::Column::Constraint* constr) const; QString getUniqueDetails(SqliteCreateTable::Column::Constraint* constr) const; QString getCheckDetails(SqliteCreateTable::Column::Constraint* constr) const; + QString getGeneratedDetails(SqliteCreateTable::Column::Constraint* constr) const; QString getDefaultDetails(SqliteCreateTable::Column::Constraint* constr) const; QString getCollateDetails(SqliteCreateTable::Column::Constraint* constr) const; QString getFkDetails(SqliteCreateTable::Column::Constraint* constr) const; diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp index 63af58a..be45873 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.cpp @@ -22,6 +22,9 @@ #include "datatype.h" #include "uiutils.h" #include "translations.h" +#include "plugins/uiconfiguredplugin.h" +#include "dbtree/dbtree.h" +#include "common/compatibility.h" #include #include #include @@ -37,8 +40,6 @@ #include #include #include -#include -#include #define GET_FILTER_STRING(Widget, WidgetType, Method) \ if (qobject_cast(Widget))\ @@ -117,7 +118,7 @@ QString ConfigDialog::getFilterString(QWidget *widget) GET_FILTER_STRING2(widget, QListWidget); GET_FILTER_STRING2(widget, QTableWidget); - return QString::null; + return QString(); } QString ConfigDialog::getFilterString(QComboBox *widget) @@ -201,7 +202,9 @@ void ConfigDialog::init() for (CfgEntry* cfg : entries) connect(cfg, SIGNAL(changed(QVariant)), this, SLOT(markRequiresSchemasRefresh())); - ui->activeStyleCombo->addItems(QStyleFactory::keys()); + QStringList styles = QStyleFactory::keys(); + styles.sort(Qt::CaseInsensitive); + ui->activeStyleCombo->addItems(styles); connect(ui->stackedWidget, SIGNAL(currentChanged(int)), this, SLOT(pageSwitched())); @@ -384,7 +387,7 @@ QList ConfigDialog::getDefaultEditorsForType(DataType: sortedPlugins << editorWithPrio; } - qSort(sortedPlugins.begin(), sortedPlugins.end(), [=](const PluginWithPriority& p1, const PluginWithPriority& p2) -> bool + sSort(sortedPlugins, [=](const PluginWithPriority& p1, const PluginWithPriority& p2) -> bool { return p1.first < p2.first; }); @@ -446,7 +449,7 @@ QList ConfigDialog::updateCustomDataTypeEditors(const ui->dataEditorsAvailableList->addItem(item); } - qSort(enabledPlugins.begin(), enabledPlugins.end(), [=](MultiEditorWidgetPlugin* p1, MultiEditorWidgetPlugin* p2) -> bool + sSort(enabledPlugins, [=](MultiEditorWidgetPlugin* p1, MultiEditorWidgetPlugin* p2) -> bool { return editorsOrder.indexOf(p1->getName()) < editorsOrder.indexOf(p2->getName()); }); @@ -920,9 +923,9 @@ void ConfigDialog::updateBuiltInPluginsVisibility() { it.next(); if (PLUGINS->isBuiltIn(it.value())) - ui->pluginsList->setItemHidden(it.key(), hideBuiltIn); + it.key()->setHidden(hideBuiltIn); else - ui->pluginsList->setItemHidden(it.key(), false); + it.key()->setHidden(false); } } @@ -1053,7 +1056,7 @@ void ConfigDialog::refreshFormattersPage() pluginTitles << plugin->getTitle(); } sortedPluginNames = pluginNames; - qSort(sortedPluginNames); + sSort(sortedPluginNames); combo = new QComboBox(ui->formatterPluginsTree); for (int i = 0, total = pluginNames.size(); i < total; ++i) @@ -1092,6 +1095,7 @@ void ConfigDialog::refreshFormattersPage() void ConfigDialog::applyStyle(QWidget *widget, QStyle *style) { widget->setStyle(style); + widget->setPalette(style->standardPalette()); for (QObject* child : widget->children()) { if (!qobject_cast(child)) @@ -1250,7 +1254,7 @@ void ConfigDialog::initPluginsPage() categoryRow = 0; QList pluginTypes = PLUGINS->getPluginTypes(); - qSort(pluginTypes.begin(), pluginTypes.end(), PluginType::nameLessThan); + sSort(pluginTypes, PluginType::nameLessThan); for (PluginType* pluginType : pluginTypes) { category = new QTreeWidgetItem({pluginType->getTitle()}); @@ -1270,7 +1274,7 @@ void ConfigDialog::initPluginsPage() itemRow = 0; pluginNames = pluginType->getAllPluginNames(); - qSort(pluginNames); + sSort(pluginNames); for (const QString& pluginName : pluginNames) { builtIn = PLUGINS->isBuiltIn(pluginName); @@ -1388,10 +1392,10 @@ void ConfigDialog::initDataEditors() ui->dataEditorsAvailableList->setSpacing(1); QHash editorsOrder = CFG_UI.General.DataEditorsOrder.get(); - QSet dataTypeSet = editorsOrder.keys().toSet(); - dataTypeSet += DataType::getAllNames().toSet(); - QStringList dataTypeList = dataTypeSet.toList(); - qSort(dataTypeList); + QSet dataTypeSet = toSet(editorsOrder.keys()); + dataTypeSet += toSet(DataType::getAllNames()); + QStringList dataTypeList = dataTypeSet.values(); + sSort(dataTypeList); QListWidgetItem* item = nullptr; for (const QString& type : dataTypeList) @@ -1452,7 +1456,7 @@ void ConfigDialog::initShortcuts() categories << cat; } - qSort(categories.begin(), categories.end(), [](CfgCategory* cat1, CfgCategory* cat2) -> bool + sSort(categories, [](CfgCategory* cat1, CfgCategory* cat2) -> bool { return cat1->getTitle().compare(cat2->getTitle()) < 0; }); @@ -1503,7 +1507,7 @@ void ConfigDialog::initShortcuts(CfgCategory *cfgCategory) int itemRow = 0; QStringList entryNames = cfgCategory->getEntries().keys(); - qSort(entryNames); + sSort(entryNames); for (const QString& entryName : entryNames) { // Title diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui index fe0b772..4452f63 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui @@ -148,18 +148,6 @@ :/icons/img/config_font.png:/icons/img/config_font.png - - - Colors - - - colorsPage - - - - :/icons/img/config_colors.png:/icons/img/config_colors.png - - @@ -229,7 +217,7 @@ - 3 + 1 @@ -407,8 +395,8 @@ 0 0 - 577 - 472 + 564 + 540 @@ -418,29 +406,6 @@ Data browsing and editing - - - - <p>Maximum number of configurations of Populate Table dialog stored in configuration. Value of 100 should be sufficient.</p> - - - Number of memorized table populating configurations - - - - - - - <p>Maximum number of configurations of Populate Table dialog stored in configuration. Value of 100 should be sufficient.</p> - - - 999999 - - - General.PopulateHistorySize - - - @@ -460,7 +425,7 @@ - + <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> @@ -479,7 +444,14 @@ - + + + + Number of data rows per page: + + + + <p>When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.</p> @@ -489,14 +461,43 @@ - - + + + + <html><head/><body><p>Enable this to always enforce DEFAULT value when committing a NULL value for a column that has DEFAULT value defined, even though the column is allowed to contain NULL values.</p><p>Disable this option to use DEFAULT value exclusively when NULL value is committed for column with NOT NULL constraint.</p></body></html> + - Number of data rows per page: + Use DEFAULT value (if defined), when committing NULL value + + + General.UseDefaultValueForNull - + + + + <p>Maximum number of configurations of Populate Table dialog stored in configuration. Value of 100 should be sufficient.</p> + + + 999999 + + + General.PopulateHistorySize + + + + + + + <p>Maximum number of configurations of Populate Table dialog stored in configuration. Value of 100 should be sufficient.</p> + + + Number of memorized table populating configurations + + + + <p>When this is enabled and user holds mouse pointer over a cell in any data view (query results, a table data, a view data) a tooltip will appear with details about the cell - it includes details like column data type, constraints, ROWID and others.</p> @@ -509,7 +510,7 @@ - + <p>When editing a cell which used to have NULL value and entering empty string as new value, then this option determinates whether the new value should remain NULL (have this option enabled), or should it be overwritten with empty string value (have this option disabled).</p> @@ -522,16 +523,16 @@ - - + + - <html><head/><body><p>Enable this to always enforce DEFAULT value when committing a NULL value for a column that has DEFAULT value defined, even though the column is allowed to contain NULL values.</p><p>Disable this option to use DEFAULT value exclusively when NULL value is committed for column with NOT NULL constraint.</p></body></html> + <html><head/><body><p>If query results contain dozens (or hundreds) of columns, it is more likely that it will exhaust free memory of your computer by loading several gigabytes of data at once. SQLiteStudio may try to limit number of results displayed on one page in such cases to protect your computer. If you know that you don't work with big values in database, you can disable this limit and you will always see as many rows as defined per page.</p></body></html> - Use DEFAULT value (if defined), when committing NULL value + Limit number of rows for in case of dozens of columns - General.UseDefaultValueForNull + General.LimitRowsForManyColumns @@ -934,6 +935,16 @@ + + + + Allow multiple instances of the application at the same time + + + General.AllowMultipleSessions + + + @@ -1021,12 +1032,12 @@ false - - 150 - 16 + + 150 + false @@ -1073,8 +1084,8 @@ 0 0 - 335 - 237 + 339 + 264 @@ -1585,8 +1596,8 @@ p, li { white-space: pre-wrap; } 0 0 - 196 - 263 + 206 + 298 @@ -1689,542 +1700,6 @@ p, li { white-space: pre-wrap; } - - - - - - QFrame::NoFrame - - - 0 - - - true - - - - - 0 - 0 - 247 - 701 - - - - - - - SQL editor colors - - - - - - Current line background - - - - - - - <p>SQL strings are enclosed with single quote characters.</p> - - - String foreground - - - - - - - - 50 - 16777215 - - - - - - - Colors.SqlEditorKeywordFg - - - - - - - - 50 - 16777215 - - - - - - - Colors.SqlEditorStringFg - - - - - - - - 50 - 16777215 - - - - - - - Colors.SqlEditorCommentFg - - - - - - - - 50 - 16777215 - - - - - - - Colors.SqlEditorForeground - - - - - - - - 50 - 16777215 - - - - - - - Colors.SqlEditorCurrentLineBg - - - - - - - - 50 - 16777215 - - - - - - - Colors.SqlEditorLineNumAreaBg - - - - - - - <p>Bind parameters are placeholders for values yet to be provided by the user. They have one of the forms:</p><ul><li>:param_name</li><li>$param_name</li><li>@param_name</li><li>?</li></ul> - - - Bind parameter foreground - - - - - - - - 50 - 16777215 - - - - - - - Colors.SqlEditorParenthesisBg - - - - - - - Highlighted parenthesis background - - - - - - - <p>BLOB values are binary values represented as hexadecimal numbers, like:</p><ul><li>X'12B4'</li><li>x'46A2F4'</li></ul> - - - BLOB value foreground - - - - - - - Regular foreground - - - - - - - Line numbers area background - - - - - - - - 50 - 16777215 - - - - - - - Colors.SqlEditorBlobFg - - - - - - - Keyword foreground - - - - - - - Number foreground - - - - - - - Comment foreground - - - - - - - - 50 - 16777215 - - - - - - - Colors.SqlEditorNumberFg - - - - - - - - 50 - 16777215 - - - - - - - Colors.SqlEditorBindParamFg - - - - - - - <p>Valid objects are name of tables, indexes, triggers, or views that exist in the SQLite database.</p> - - - Valid objects foreground - - - - - - - - 50 - 16777215 - - - - - - - Colors.SqlEditorValidObject - - - - - - - - - - Data view colors - - - - - - <p>Any data changes will be outlined with this color, until they're committed to the database.</p> - - - Uncommitted data outline color - - - - - - - - 50 - 16777215 - - - - - - - Colors.DataUncommitted - - - - - - - <p>In case of error while committing data changes, the problematic cell will be outlined with this color.</p> - - - Commit error outline color - - - - - - - - 50 - 16777215 - - - - - - - Colors.DataUncommittedError - - - - - - - NULL value foreground - - - - - - - - 50 - 16777215 - - - - - - - Colors.DataNullFg - - - - - - - Deleted row background - - - - - - - - 50 - 16777215 - - - - - - - Colors.DataDeletedBg - - - - - - - - - - Database list colors - - - - - - <p>Additional labels are those which tell you SQLite version, number of objects deeper in the tree, etc.</p> - - - Additional labels foreground - - - - - - - - 50 - 16777215 - - - - - - - Colors.DbTreeLabelsFg - - - - - - - - - - Status field colors - - - - - - Information message foreground - - - - - - - - 50 - 16777215 - - - - - - - Colors.StatusFieldInfoFg - - - - - - - Warning message foreground - - - - - - - - 50 - 16777215 - - - - - - - Colors.StatusFieldWarnFg - - - - - - - Error message foreground - - - - - - - - 50 - 16777215 - - - - - - - Colors.StatusFieldErrorFg - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - @@ -2255,11 +1730,6 @@ p, li { white-space: pre-wrap; } - - ColorButton - QPushButton -
common/colorbutton.h
-
FontEdit QWidget @@ -2298,26 +1768,6 @@ p, li { white-space: pre-wrap; } previewComboBox previewTextEdit fontsScrollArea - scrollArea - sqlEditorKeywordFgButton - sqlEditorStringFgButton - sqlEditorCommentFgButton - sqlEditorRegularFgButton - sqlEditorCurrLineBgButton - sqlEditorLineNumAreaBgButton - sqlEditorParBgButton - sqlEditorBlobFgButton - sqlEditorNumberFgButton - sqlEditorBindParamFgButton - sqlEditorValidObjectsButton - dataViewUncommittedButton - dataViewErrorButton - dataViewNullFgButton - dataViewDeletedRowBgButton - dbTreeLabelsButton - statusFieldInfoButton - statusFieldWarnButton - statusFieldErrorButton diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/constraintdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/constraintdialog.cpp index 0094ad0..0333cbc 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/constraintdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/constraintdialog.cpp @@ -136,6 +136,8 @@ ConstraintDialog::Constraint ConstraintDialog::getSelectedConstraint(SqliteCreat return CHECK; case SqliteCreateTable::Column::Constraint::DEFAULT: return DEFAULT; + case SqliteCreateTable::Column::Constraint::GENERATED: + return GENERATED; case SqliteCreateTable::Column::Constraint::COLLATE: return COLLATE; case SqliteCreateTable::Column::Constraint::FOREIGN_KEY: @@ -185,6 +187,10 @@ void ConstraintDialog::updateDefinitionHeader() ui->titleIcon->setPixmap(ICONS.CONSTRAINT_CHECK); ui->titleLabel->setText(tr("Check", "table constraints")); break; + case ConstraintDialog::GENERATED: + ui->titleIcon->setPixmap(ICONS.CONSTRAINT_GENERATED); + ui->titleLabel->setText(tr("Generated", "table constraints")); + break; case ConstraintDialog::COLLATE: ui->titleIcon->setPixmap(ICONS.CONSTRAINT_COLLATION); ui->titleLabel->setText(tr("Collate", "table constraints")); diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/constraintdialog.h b/SQLiteStudio3/guiSQLiteStudio/dialogs/constraintdialog.h index fe24c0f..ef3e9f5 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/constraintdialog.h +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/constraintdialog.h @@ -32,6 +32,7 @@ class GUI_API_EXPORT ConstraintDialog : public QDialog NOTNULL, CHECK, COLLATE, + GENERATED, DEFAULT, UNKNOWN }; diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/cssdebugdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/cssdebugdialog.cpp index 99439e8..6e45138 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/cssdebugdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/cssdebugdialog.cpp @@ -2,6 +2,7 @@ #include "ui_cssdebugdialog.h" #include "mainwindow.h" #include "themetuner.h" +#include "uiconfig.h" #include #include @@ -12,7 +13,10 @@ CssDebugDialog::CssDebugDialog(QWidget *parent) : ui->setupUi(this); connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*))); - appliedCss = MAINWINDOW->styleSheet(); + appliedCss = CFG_UI.General.CustomCss.get(); + if (appliedCss.isEmpty()) + appliedCss = MAINWINDOW->styleSheet(); + ui->cssEdit->setPlainText(appliedCss); updateState(); @@ -33,6 +37,7 @@ void CssDebugDialog::buttonClicked(QAbstractButton* button) else if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::ApplyRole) { appliedCss = ui->cssEdit->toPlainText(); + CFG_UI.General.CustomCss.set(appliedCss); MAINWINDOW->setStyleSheet(appliedCss); } diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/dbconverterdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/dbconverterdialog.cpp deleted file mode 100644 index 8af131e..0000000 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/dbconverterdialog.cpp +++ /dev/null @@ -1,218 +0,0 @@ -#include "dbconverterdialog.h" -#include "ui_dbconverterdialog.h" -#include "common/global.h" -#include "dblistmodel.h" -#include "db/db.h" -#include "common/utils_sql.h" -#include "dbversionconverter.h" -#include "services/dbmanager.h" -#include "iconmanager.h" -#include "uiutils.h" -#include "versionconvertsummarydialog.h" -#include "mainwindow.h" -#include "errorsconfirmdialog.h" -#include "parser/ast/sqlitecreatetable.h" -#include "services/pluginmanager.h" -#include "plugins/dbplugin.h" -#include "db/sqlquery.h" -#include "services/notifymanager.h" -#include "common/widgetcover.h" -#include -#include -#include - -DbConverterDialog::DbConverterDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::DbConverterDialog) -{ - init(); -} - -DbConverterDialog::~DbConverterDialog() -{ - delete ui; - safe_delete(converter); -} - -void DbConverterDialog::setDb(Db* db) -{ - ui->srcDbCombo->setCurrentText(db->getName()); - srcDb = db; - srcDbChanged(); -} - -void DbConverterDialog::init() -{ - ui->setupUi(this); - limitDialogWidth(this); - - widgetCover = new WidgetCover(this); - widgetCover->setVisible(false); - widgetCover->initWithInterruptContainer(); - - ui->trgFileButton->setIcon(ICONS.OPEN_FILE); - - converter = new DbVersionConverter(); - - dbListModel = new DbListModel(this); - ui->srcDbCombo->setModel(dbListModel); - - connect(ui->srcDbCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(srcDbChanged(int))); - connect(ui->trgVersionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateState())); - connect(ui->trgFileEdit, SIGNAL(textChanged(QString)), this, SLOT(updateState())); - connect(ui->trgNameEdit, SIGNAL(textChanged(QString)), this, SLOT(updateState())); - connect(converter, SIGNAL(conversionFailed(QString)), this, SLOT(processingFailed(QString))); - connect(converter, SIGNAL(conversionSuccessful()), this, SLOT(processingSuccessful())); - connect(converter, SIGNAL(conversionAborted()), this, SLOT(processingAborted())); - connect(widgetCover, SIGNAL(cancelClicked()), converter, SLOT(interrupt())); -} - -void DbConverterDialog::srcDbChanged() -{ - dontUpdateState = true; - ui->srcDbVersionCombo->clear(); - ui->trgVersionCombo->clear(); - if (srcDb) - { - // Source version - QList dialects = converter->getSupportedVersions(); - QStringList versionNames = converter->getSupportedVersionNames(); - Dialect dialect = srcDb->getDialect(); - int idx = dialects.indexOf(dialect); - QString type = versionNames[idx]; - ui->srcDbVersionCombo->addItem(type); - ui->srcDbVersionCombo->setCurrentText(type); - - // Target version - QString oldTrgVersion = ui->trgVersionCombo->currentText(); - versionNames.removeAt(idx); - ui->trgVersionCombo->addItems(versionNames); - if (versionNames.contains(oldTrgVersion)) - ui->trgVersionCombo->setCurrentText(oldTrgVersion); - else if (versionNames.size() > 0) - ui->trgVersionCombo->setCurrentIndex(0); - - // File - QString trgFile = srcDb->getPath() + "_new"; - int i = 0; - while (QFileInfo(trgFile).exists()) - { - trgFile = srcDb->getPath() + "_new" + QString::number(i++); - } - - ui->trgFileEdit->setText(trgFile); - - // Name - QString generatedName = generateUniqueName(srcDb->getName() + "_new", DBLIST->getDbNames()); - ui->trgNameEdit->setText(generatedName); - } - else - { - ui->srcDbVersionCombo->setCurrentText(""); - ui->trgFileEdit->setText(""); - ui->trgVersionCombo->setCurrentText(""); - ui->trgNameEdit->setText(""); - } - dontUpdateState = false; - updateState(); -} - -bool DbConverterDialog::validate() -{ - bool srcDbOk = (srcDb != nullptr); - setValidState(ui->srcDbCombo, srcDbOk, tr("Select source database")); - - QString dstDbPath = ui->trgFileEdit->text(); - QFileInfo dstDbFi(dstDbPath); - bool dstDbOk = (!dstDbFi.exists() || dstDbFi.isWritable()) && dstDbFi != QFileInfo(srcDb->getPath()); - bool dstExists = dstDbFi.exists(); - setValidState(ui->trgFileEdit, dstDbOk, tr("Enter valid and writable file path.")); - if (dstExists && dstDbOk) - setValidStateInfo(ui->trgFileEdit, tr("Entered file exists and will be overwritten.")); - - QString name = ui->trgNameEdit->text(); - bool nameOk = !name.isEmpty() && !DBLIST->getDbNames().contains(name); - setValidState(ui->trgNameEdit, nameOk, tr("Enter a not empty, unique name (as in the list of databases on the left).")); - - bool dstDialectOk = ui->trgVersionCombo->currentIndex() > -1; - QString msg; - if (!dstDialectOk && ui->trgVersionCombo->count() == 0) - msg = tr("No valid target dialect available. Conversion not possible."); - else - msg = tr("Select valid target dialect."); - - setValidState(ui->trgVersionCombo, dstDialectOk, msg); - - return (srcDbOk && nameOk && dstDbOk && dstDialectOk); -} - -void DbConverterDialog::accept() -{ - if (!validate()) - return; - - QStringList versionNames = converter->getSupportedVersionNames(); - QList dialects = converter->getSupportedVersions(); - QString trgDialectName = ui->trgVersionCombo->currentText(); - int idx = versionNames.indexOf(trgDialectName); - if (idx == -1) - { - qCritical() << "Could not find target dialect on list of supported dialects in DbConverterDialog::accept()"; - return; - } - - Dialect srcDialect = srcDb->getDialect(); - Dialect trgDialect = dialects[idx]; - QString trgFile = ui->trgFileEdit->text(); - QString trgName = ui->trgNameEdit->text(); - widgetCover->show(); - converter->convert(srcDialect, trgDialect, srcDb, trgFile, trgName, &DbConverterDialog::confirmConversion, &DbConverterDialog::confirmConversionErrors); -} - -void DbConverterDialog::srcDbChanged(int index) -{ - srcDb = dbListModel->getDb(index); - srcDbChanged(); -} - -void DbConverterDialog::updateState() -{ - if (dontUpdateState) - return; - - ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(validate()); -} - -void DbConverterDialog::processingFailed(const QString& errorMessage) -{ - widgetCover->hide(); - notifyError(errorMessage); -} - -void DbConverterDialog::processingSuccessful() -{ - notifyInfo(tr("Database %1 has been successfully converted and now is available under new name: %2").arg(srcDb->getName(), ui->trgNameEdit->text())); - QDialog::accept(); -} - -void DbConverterDialog::processingAborted() -{ - widgetCover->hide(); -} - -bool DbConverterDialog::confirmConversion(const QList >& diffs) -{ - VersionConvertSummaryDialog dialog(MAINWINDOW); - dialog.setWindowTitle(tr("SQL statements conversion")); - dialog.setSides(diffs); - return dialog.exec() == QDialog::Accepted; -} - -bool DbConverterDialog::confirmConversionErrors(const QSet& errors) -{ - ErrorsConfirmDialog dialog(MAINWINDOW); - dialog.setTopLabel(tr("Following error occurred while converting SQL statements to the target SQLite version:")); - dialog.setBottomLabel(tr("Would you like to ignore those errors and proceed?")); - dialog.setErrors(errors); - return dialog.exec() == QDialog::Accepted; -} diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/dbconverterdialog.h b/SQLiteStudio3/guiSQLiteStudio/dialogs/dbconverterdialog.h deleted file mode 100644 index 4267a1b..0000000 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/dbconverterdialog.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef DBCONVERTERDIALOG_H -#define DBCONVERTERDIALOG_H - -#include "guiSQLiteStudio_global.h" -#include - -class DbListModel; -class Db; -class DbVersionConverter; -class WidgetCover; - -namespace Ui { - class DbConverterDialog; -} - -class GUI_API_EXPORT DbConverterDialog : public QDialog -{ - Q_OBJECT - - public: - explicit DbConverterDialog(QWidget *parent = 0); - ~DbConverterDialog(); - - void setDb(Db* db); - - private: - void init(); - void srcDbChanged(); - bool validate(); - - static bool confirmConversion(const QList >& diffs); - static bool confirmConversionErrors(const QSet& errors); - - Ui::DbConverterDialog *ui = nullptr; - DbListModel* dbListModel = nullptr; - Db* srcDb = nullptr; - DbVersionConverter* converter = nullptr; - bool dontUpdateState = false; - WidgetCover* widgetCover = nullptr; - - public slots: - void accept(); - - private slots: - void srcDbChanged(int index); - void updateState(); - void processingFailed(const QString& errorMessage); - void processingSuccessful(); - void processingAborted(); -}; - -#endif // DBCONVERTERDIALOG_H diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/dbconverterdialog.ui b/SQLiteStudio3/guiSQLiteStudio/dialogs/dbconverterdialog.ui deleted file mode 100644 index f6bf009..0000000 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/dbconverterdialog.ui +++ /dev/null @@ -1,144 +0,0 @@ - - - DbConverterDialog - - - - 0 - 0 - 400 - 251 - - - - Convert database - - - - - - Source database - - - - - - - - - Source database version: - - - - - - - false - - - - - - - - - - Target database - - - - - - Target version: - - - - - - - This is the file that will be created as a result of the conversion. - - - - - - - Target file: - - - - - - - Name of the new database: - - - - - - - - - - - - - - - - - This is the name that the converted database will be added to SQLiteStudio with. - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - DbConverterDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - DbConverterDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.cpp index 183f8dd..1e56258 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/dbdialog.cpp @@ -8,6 +8,7 @@ #include "services/dbmanager.h" #include "common/global.h" #include "iconmanager.h" +#include "sqleditor.h" #include "common/unused.h" #include "db/sqlquery.h" #include @@ -199,16 +200,13 @@ void DbDialog::addOption(const DbPluginOption& option, int& row) } QLabel* label = new QLabel(option.label, this); - label->setAlignment(Qt::AlignVCenter|Qt::AlignRight); + label->setAlignment(Qt::AlignTop|Qt::AlignRight); QWidget* editor = nullptr; QWidget* editorHelper = nullptr; // TODO, based on plugins for Url handlers editor = getEditor(option, editorHelper); Q_ASSERT(editor != nullptr); - if (!option.toolTip.isNull()) - editor->setToolTip(option.toolTip); - optionWidgets << label << editor; optionKeyToWidget[option.key] = editor; @@ -240,6 +238,16 @@ QWidget *DbDialog::getEditor(const DbPluginOption& opt, QWidget*& editorHelper) editorHelper = nullptr; switch (opt.type) { + case DbPluginOption::SQL: + { + SqlEditor* sqlEdit = new SqlEditor(this); + editor = sqlEdit; + sqlEdit->setShowLineNumbers(false); + sqlEdit->setPlainText(opt.defaultValue.toString()); + sqlEdit->setMaximumHeight(sqlEdit->fontMetrics().height() * 5); + connect(sqlEdit, SIGNAL(textChanged()), this, SLOT(propertyChanged())); + break; + } case DbPluginOption::STRING: { editor = new QLineEdit(this); @@ -260,8 +268,20 @@ QWidget *DbDialog::getEditor(const DbPluginOption& opt, QWidget*& editorHelper) QComboBox* cb = new QComboBox(this); editor = cb; cb->setEditable(!opt.choiceReadOnly); - cb->addItems(opt.choiceValues); - cb->setCurrentText(opt.defaultValue.toString()); + if (opt.choiceDataValues.isEmpty()) + { + cb->addItems(opt.choiceValues); + cb->setCurrentText(opt.defaultValue.toString()); + } + else + { + for (auto it = opt.choiceDataValues.begin(); it != opt.choiceDataValues.end(); ++it) + { + cb->addItem(it.key(), it.value()); + if (it.value() == opt.defaultValue) + cb->setCurrentText(it.key()); + } + } connect(cb, SIGNAL(currentIndexChanged(QString)), this, SLOT(propertyChanged())); break; } @@ -330,6 +350,9 @@ QWidget *DbDialog::getEditor(const DbPluginOption& opt, QWidget*& editorHelper) le->setText(opt.defaultValue.toString()); } + if (!opt.toolTip.isNull()) + editor->setToolTip(opt.toolTip); + return editor; } @@ -338,6 +361,9 @@ QVariant DbDialog::getValueFrom(DbPluginOption::Type type, QWidget *editor) QVariant value; switch (type) { + case DbPluginOption::SQL: + value = dynamic_cast(editor)->toPlainText(); + break; case DbPluginOption::STRING: case DbPluginOption::PASSWORD: case DbPluginOption::FILE: @@ -353,8 +379,17 @@ QVariant DbDialog::getValueFrom(DbPluginOption::Type type, QWidget *editor) value = dynamic_cast(editor)->value(); break; case DbPluginOption::CHOICE: - value = dynamic_cast(editor)->currentText(); + { + QComboBox* cb = dynamic_cast(editor); + QVariant data = cb->currentData(); + if (data.isValid()) + { + value = data; + break; + } + value = cb->currentText(); break; + } case DbPluginOption::CUSTOM_PATH_BROWSE: break; // should not happen ever default: @@ -369,6 +404,9 @@ void DbDialog::setValueFor(DbPluginOption::Type type, QWidget *editor, const QVa { switch (type) { + case DbPluginOption::SQL: + dynamic_cast(editor)->setPlainText(value.toString()); + break; case DbPluginOption::STRING: case DbPluginOption::FILE: case DbPluginOption::PASSWORD: @@ -384,8 +422,20 @@ void DbDialog::setValueFor(DbPluginOption::Type type, QWidget *editor, const QVa dynamic_cast(editor)->setValue(value.toDouble()); break; case DbPluginOption::CHOICE: - dynamic_cast(editor)->setCurrentText(value.toString()); + { + QComboBox* cb = dynamic_cast(editor); + if (value.isValid()) + { + int idx = cb->findData(value); + if (idx > -1) + { + cb->setCurrentIndex(idx); + break; + } + } + cb->setCurrentText(value.toString()); break; + } case DbPluginOption::CUSTOM_PATH_BROWSE: break; // should not happen ever default: @@ -413,7 +463,7 @@ QHash DbDialog::collectOptions() if (ui->typeCombo->currentIndex() < 0) return options; - for (const QString key : optionKeyToWidget.keys()) + for (const QString& key : optionKeyToWidget.keys()) options[key] = getValueFrom(optionKeyToType[key], optionKeyToWidget[key]); DbPlugin* plugin = nullptr; diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/errorsconfirmdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/errorsconfirmdialog.cpp index c0a73f3..9f53ef1 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/errorsconfirmdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/errorsconfirmdialog.cpp @@ -1,6 +1,7 @@ #include "errorsconfirmdialog.h" #include "ui_errorsconfirmdialog.h" #include "iconmanager.h" +#include "common/compatibility.h" ErrorsConfirmDialog::ErrorsConfirmDialog(QWidget *parent) : QDialog(parent), @@ -31,7 +32,7 @@ void ErrorsConfirmDialog::setErrors(const QHash>& errors) void ErrorsConfirmDialog::setErrors(const QSet& errors) { ui->list->clear(); - ui->list->addItems(errors.toList()); + ui->list->addItems(errors.values()); for (int i = 0, total = ui->list->count(); i < total; ++i) ui->list->item(i)->setIcon(ICONS.STATUS_ERROR); } diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/exportdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/exportdialog.cpp index 7b6a4d0..7dda03e 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/exportdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/exportdialog.cpp @@ -14,6 +14,7 @@ #include "schemaresolver.h" #include "common/widgetcover.h" #include "services/notifymanager.h" +#include "themetuner.h" #include "uiconfig.h" #include #include @@ -49,6 +50,7 @@ ExportDialog::~ExportDialog() void ExportDialog::init() { ui->setupUi(this); + THEME_TUNER->darkThemeFix(this); limitDialogWidth(this); #ifdef Q_OS_MACX @@ -531,7 +533,7 @@ void ExportDialog::updateDbObjTree() ui->dbObjectsTree->expand(root); QModelIndex child; - for (int i = 0; (child = root.child(i, 0)).isValid(); i++) + for (int i = 0; (child = selectableDbListModel->index(i, 0, root)).isValid(); i++) ui->dbObjectsTree->expand(child); } dbObjectsSelectAll(); @@ -718,7 +720,7 @@ void ExportDialog::exportTable(const ExportManager::StandardExportConfig& stdCon EXPORT_MANAGER->configure(format, stdConfig); // TODO when dbnames are fully supported, pass the dbname below - EXPORT_MANAGER->exportTable(db, QString::null, ui->exportTableNameCombo->currentText()); + EXPORT_MANAGER->exportTable(db, QString(), ui->exportTableNameCombo->currentText()); } void ExportDialog::exportQuery(const ExportManager::StandardExportConfig& stdConfig, const QString& format) @@ -741,7 +743,7 @@ ExportManager::StandardExportConfig ExportDialog::getExportConfig() const stdConfig.intoClipboard = clipboard; if (clipboard) - stdConfig.outputFileName = QString::null; + stdConfig.outputFileName = QString(); else if (outputFileSupported) stdConfig.outputFileName = ui->exportFileEdit->text(); @@ -790,7 +792,7 @@ QModelIndex ExportDialog::setupNewDbObjTreeRoot(const QModelIndex& root) if (item->getType() == DbTreeItem::Type::DB) return newRoot; - newRoot = newRoot.child(0, 0); + newRoot = selectableDbListModel->index(0, 0, newRoot); } return newRoot; } diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/importdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/importdialog.cpp index ddb443d..565feb4 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/importdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/importdialog.cpp @@ -13,6 +13,7 @@ #include "formmanager.h" #include "common/utils.h" #include "uiconfig.h" +#include "themetuner.h" #include #include #include @@ -100,6 +101,7 @@ void ImportDialog::readStdConfig() void ImportDialog::init() { ui->setupUi(this); + THEME_TUNER->darkThemeFix(this); limitDialogWidth(this); #ifdef Q_OS_MACX diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.cpp index e3e7701..ebf9beb 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.cpp @@ -9,10 +9,11 @@ #include "uiconfig.h" #include "services/config.h" #include "uiutils.h" -#include "sqlite3.h" +#include "db/sqlite3.h" #include "indexexprcolumndialog.h" #include "windows/editorwindow.h" #include "services/codeformatter.h" +#include "common/compatibility.h" #include #include #include @@ -64,7 +65,7 @@ void IndexDialog::init() { qCritical() << "Created IndexDialog for null or closed database."; notifyError(tr("Tried to open index dialog for closed or inexisting database.")); - reject(); + preReject(); return; } @@ -91,7 +92,7 @@ void IndexDialog::init() connect(columnStateSignalMapping, SIGNAL(mapped(QString)), this, SLOT(updateColumnState(QString))); SchemaResolver resolver(db); - ui->tableCombo->addItem(QString::null); + ui->tableCombo->addItem(QString()); ui->tableCombo->addItems(resolver.getTables()); connect(ui->tableCombo, SIGNAL(currentTextChanged(QString)), this, SLOT(updateTable(QString))); connect(ui->tableCombo, SIGNAL(currentTextChanged(QString)), this, SLOT(updateValidation())); @@ -99,29 +100,15 @@ void IndexDialog::init() if (existingIndex) ui->tableCombo->setEnabled(false); - if (db->getDialect() == Dialect::Sqlite3) - { - connect(ui->partialIndexCheck, SIGNAL(toggled(bool)), this, SLOT(updatePartialConditionState())); - connect(ui->partialIndexEdit, SIGNAL(errorsChecked(bool)), this, SLOT(updateValidation())); - connect(ui->partialIndexEdit, SIGNAL(textChanged()), this, SLOT(updateValidation())); - ui->partialIndexEdit->setVirtualSqlExpression("SELECT %1"); - updatePartialConditionState(); - ui->columnsTable->setColumnHidden(2, false); - } - else - { - ui->partialIndexCheck->setVisible(false); - ui->partialIndexEdit->setVisible(false); - ui->columnsTable->setColumnHidden(2, true); - ui->addExprColumnButton->setVisible(false); - ui->editExprColumnButton->setVisible(false); - ui->delExprColumnButton->setVisible(false); - } + connect(ui->partialIndexCheck, SIGNAL(toggled(bool)), this, SLOT(updatePartialConditionState())); + connect(ui->partialIndexEdit, SIGNAL(errorsChecked(bool)), this, SLOT(updateValidation())); + connect(ui->partialIndexEdit, SIGNAL(textChanged()), this, SLOT(updateValidation())); + ui->partialIndexEdit->setVirtualSqlExpression("SELECT %1"); + updatePartialConditionState(); + ui->columnsTable->setColumnHidden(2, false); readCollations(); - ui->ddlEdit->setSqliteVersion(db->getVersion()); - if (index.isNull()) createIndex = SqliteCreateIndexPtr::create(); else @@ -146,8 +133,9 @@ void IndexDialog::readIndex() SqliteQueryPtr parsedObject = resolver.getParsedObject(index, SchemaResolver::INDEX); if (!parsedObject.dynamicCast()) { + createIndex = SqliteCreateIndexPtr::create(); notifyError(tr("Could not process index %1 correctly. Unable to open an index dialog.").arg(index)); - reject(); + preReject(); return; } @@ -160,9 +148,6 @@ void IndexDialog::buildColumns() clearColumns(); ui->columnsTable->setRowCount(0); - totalColumns = tableColumns.size(); - ui->columnsTable->setRowCount(totalColumns); - int row = 0; for (const QString& column : tableColumns) buildColumn(column, row++); @@ -235,8 +220,12 @@ void IndexDialog::buildColumn(const QString& name, int row) IndexDialog::Column* IndexDialog::buildColumn(SqliteOrderBy* orderBy, int row) { - SqliteExpr* expr = dynamic_cast(orderBy->expr->clone()); - return buildColumn(expr, row); + Column* column = orderBy->isSimpleColumn() ? + new Column(orderBy->getColumnName(), ui->columnsTable) : + new Column(dynamic_cast(orderBy->expr->clone()), ui->columnsTable); + + buildColumn(column, row); + return column; } IndexDialog::Column* IndexDialog::buildColumn(SqliteExpr* expr, int row) @@ -248,6 +237,9 @@ IndexDialog::Column* IndexDialog::buildColumn(SqliteExpr* expr, int row) void IndexDialog::buildColumn(Column* column, int row) { + totalColumns++; + ui->columnsTable->setRowCount(totalColumns); + QString key = column->getKey(); columns[key] = column; columnsByRow << column; @@ -262,20 +254,17 @@ void IndexDialog::buildColumn(Column* column, int row) layout->setContentsMargins(margins); column->getCheckParent()->setLayout(layout); - column->setCheck(new QCheckBox(key)); + column->setCheck(new QCheckBox(column->getKey())); column->getCheckParent()->layout()->addWidget(column->getCheck()); columnStateSignalMapping->setMapping(column->getCheck(), key); connect(column->getCheck(), SIGNAL(toggled(bool)), columnStateSignalMapping, SLOT(map())); connect(column->getCheck(), SIGNAL(toggled(bool)), this, SLOT(updateValidation())); - if (db->getDialect() == Dialect::Sqlite3) - { - column->setCollation(new QComboBox()); - column->getCollation()->setEditable(true); - column->getCollation()->lineEdit()->setPlaceholderText(tr("default", "index dialog")); - column->getCollation()->setModel(&collations); - } + column->setCollation(new QComboBox()); + column->getCollation()->setEditable(true); + column->getCollation()->lineEdit()->setPlaceholderText(tr("default", "index dialog")); + column->getCollation()->setModel(&collations); column->setSort(new QComboBox()); column->getSort()->setToolTip(tr("Sort order", "table constraints")); @@ -286,8 +275,6 @@ void IndexDialog::buildColumn(Column* column, int row) column->prepareForNewRow(); column->assignToNewRow(row); - totalColumns++; - updateColumnState(key); } @@ -297,8 +284,7 @@ void IndexDialog::updateColumnState(const QString& columnKey) bool enabled = col->getCheck()->isChecked(); col->getSort()->setEnabled(enabled); - if (col->hasCollation()) - col->getCollation()->setEnabled(enabled); + col->getCollation()->setEnabled(enabled); } void IndexDialog::updatePartialConditionState() @@ -482,9 +468,11 @@ void IndexDialog::applyColumnValues() int row = 0; int totalRows = tableColumns.size(); bool orderChanged = false; + QStringList orderedIndexKeys; for (SqliteOrderBy* idxCol : createIndex->indexedColumns) { key = getKey(idxCol); + orderedIndexKeys << key; if (idxCol->isSimpleColumn()) { @@ -502,14 +490,13 @@ void IndexDialog::applyColumnValues() column->getCheck()->setChecked(true); updateColumnState(key); column->getSort()->setCurrentText(sqliteSortOrder(idxCol->order)); - if (column->hasCollation()) - column->getCollation()->setCurrentText(idxCol->getCollation()); + column->getCollation()->setCurrentText(idxCol->getCollation()); // Setting proper order - int currentRow = columnsByRow.indexOf(column); - if (currentRow != row) + int intendedRow = columnsByRow.indexOf(column); + if (intendedRow != row) { - columnsByRow.move(currentRow, row); + columnsByRow.move(intendedRow, row); orderChanged = true; } @@ -587,7 +574,7 @@ void IndexDialog::rebuildCreateIndex() else idxCol = addIndexedColumn(column->getName()); - if (column->hasCollation() && !column->getCollation()->currentText().isEmpty()) + if (!column->getCollation()->currentText().isEmpty()) addCollation(idxCol, column->getCollation()->currentText()); if (column->getSort()->currentIndex() > 0) @@ -599,7 +586,7 @@ void IndexDialog::rebuildCreateIndex() if (createIndex->where) delete createIndex->where; - Parser parser(db->getDialect()); + Parser parser; SqliteExpr* expr = parser.parseExpr(ui->partialIndexEdit->toPlainText()); if (expr) @@ -624,8 +611,6 @@ void IndexDialog::queryDuplicates() static QString countColNameTpl = QStringLiteral("count(%1)"); static QString countConditionTpl = QStringLiteral("count(%1) > 1"); - Dialect dialect = db->getDialect(); - QStringList cols; QStringList grpCols; QStringList countCols; @@ -636,10 +621,10 @@ void IndexDialog::queryDuplicates() if (!columns[column]->getCheck()->isChecked()) continue; - wrappedCol = wrapObjIfNeeded(column, dialect); + wrappedCol = wrapObjIfNeeded(column); cols << wrappedCol; grpCols << wrappedCol; - countColName = wrapObjIfNeeded(countColNameTpl.arg(column), dialect); + countColName = wrapObjIfNeeded(countColNameTpl.arg(column)); cols << countTpl.arg(wrappedCol, countColName); countCols << countConditionTpl.arg(wrappedCol); } @@ -650,7 +635,7 @@ void IndexDialog::queryDuplicates() QString sqlCols = cols.join(", "); QString sqlGrpCols = grpCols.join(", "); QString sqlCntCols = countCols.join(" AND "); - QString sqlTable = wrapObjIfNeeded(ui->tableCombo->currentText(), dialect); + QString sqlTable = wrapObjIfNeeded(ui->tableCombo->currentText()); editor->setContents(queryTpl.arg(sqlCols, sqlTable, sqlGrpCols, sqlCntCols)); editor->execute(); } @@ -679,7 +664,15 @@ QString IndexDialog::getKey(SqliteOrderBy* col) const if (col->isSimpleColumn()) return col->getColumnName(); - return col->expr->tokens.filterWhiteSpaces(false).detokenize(); + return buildKey(col->expr); +} + +QString IndexDialog::buildKey(SqliteExpr* expr) +{ + if (expr->mode == SqliteExpr::Mode::COLLATE && expr->expr1) + return expr->expr1->tokens.filterWhiteSpaces(false).detokenize().trimmed(); + + return expr->tokens.filterWhiteSpaces(false).detokenize().trimmed(); } QStringList IndexDialog::getExistingColumnExprs(const QString& exceptThis) const @@ -711,15 +704,18 @@ QStringList IndexDialog::getTableColumns() const return cols; } +void IndexDialog::preReject() +{ + preRejected = true; +} + void IndexDialog::accept() { rebuildCreateIndex(); - Dialect dialect = db->getDialect(); - QStringList sqls; if (existingIndex) - sqls << QString("DROP INDEX %1").arg(wrapObjIfNeeded(originalCreateIndex->index, dialect)); + sqls << QString("DROP INDEX %1").arg(wrapObjIfNeeded(originalCreateIndex->index)); sqls << createIndex->detokenize(); @@ -767,6 +763,14 @@ void IndexDialog::accept() } } +int IndexDialog::exec() +{ + if (preRejected) + return Rejected; + + return QDialog::exec(); +} + IndexDialog::Column::Column(const QString& name, QTableWidget* table) { this->name = name; @@ -795,8 +799,7 @@ void IndexDialog::Column::prepareForNewRow() { column1Contrainer = defineContainer(checkParent); column2Contrainer = defineContainer(sort); - if (collation) - column3Contrainer = defineContainer(collation); + column3Contrainer = defineContainer(collation); } QCheckBox* IndexDialog::Column::getCheck() const @@ -839,11 +842,6 @@ void IndexDialog::Column::setCollation(QComboBox* cb) collation = cb; } -bool IndexDialog::Column::hasCollation() const -{ - return collation != nullptr; -} - QString IndexDialog::Column::getName() const { return name; @@ -851,6 +849,11 @@ QString IndexDialog::Column::getName() const SqliteExpr* IndexDialog::Column::getExpr() const { + // If column's expression contains collation at top level, + // the EXPR for processing is inner expr of collation. + if (expr->mode == SqliteExpr::Mode::COLLATE) + return expr->expr1; + return expr; } @@ -868,7 +871,7 @@ bool IndexDialog::Column::isExpr() const QString IndexDialog::Column::getKey() const { if (expr) - return expr->tokens.filterWhiteSpaces(false).detokenize(); + return IndexDialog::buildKey(expr); else return name; } diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.h b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.h index f29b651..2e586d4 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.h +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.h @@ -36,7 +36,14 @@ class GUI_API_EXPORT IndexDialog : public QDialog class Column { public: + /** + * @brief Constructor for a real column in the table + */ Column(const QString& name, QTableWidget* table); + + /** + * @brief Constructor for an expression column + */ Column(SqliteExpr* expr, QTableWidget* table); ~Column(); @@ -50,11 +57,32 @@ class GUI_API_EXPORT IndexDialog : public QDialog void setSort(QComboBox* cb); QComboBox* getCollation() const; void setCollation(QComboBox* cb); - bool hasCollation() const; + /** + * @brief Gets name of a real column in the table + * @return Name of table's column, or null string if it's expression column. + */ QString getName() const; + + /** + * @brief Gets expression of an expression column. + * @return Either the expression, or null if this is a real table column. + * + * If an expression assigned to the column is a collate expression, + * this method will extract inner expression and return that. + * + * This is done this way, because after parsing SqliteOrderBy, + * the whole expression (including outer COLLATE expression) is passed + * to the column, whereas COLLATE is used for dropdowns, not for actual expression. + */ SqliteExpr* getExpr() const; + void setExpr(SqliteExpr* expr); + + /** + * @brief Tells whether this is an expression column or real table column. + * @return true if it's expression column, or false if it's real table. + */ bool isExpr() const; QString getKey() const; @@ -73,6 +101,8 @@ class GUI_API_EXPORT IndexDialog : public QDialog SqliteExpr* expr = nullptr; }; + static QString buildKey(SqliteExpr* expr); + void init(); void readIndex(); void readCollations(); @@ -92,6 +122,7 @@ class GUI_API_EXPORT IndexDialog : public QDialog QString getKey(SqliteOrderBy* col) const; QStringList getExistingColumnExprs(const QString& exceptThis = QString()) const; QStringList getTableColumns() const; + void preReject(); bool existingIndex = false; Db* db = nullptr; @@ -105,6 +136,7 @@ class GUI_API_EXPORT IndexDialog : public QDialog StrHash columns; QList columnsByRow; int totalColumns = 0; + bool preRejected = false; Ui::IndexDialog *ui = nullptr; private slots: @@ -124,6 +156,7 @@ class GUI_API_EXPORT IndexDialog : public QDialog public slots: void accept(); + int exec(); }; #endif // INDEXDIALOG_H diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp index f041294..3fcbdb9 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/indexexprcolumndialog.cpp @@ -44,7 +44,7 @@ void IndexExprColumnDialog::setOkEnabled(bool enabled) SqliteExpr* IndexExprColumnDialog::parseExpr() { - Parser parser(db->getDialect()); + Parser parser; return parser.parseExpr(ui->sqlEditor->toPlainText()); } diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/newconstraintdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/newconstraintdialog.cpp index 36b400b..f34ff2e 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/newconstraintdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/newconstraintdialog.cpp @@ -50,6 +50,24 @@ SqliteStatement* NewConstraintDialog::getConstraint() return constrStatement; } +void NewConstraintDialog::disableMode(ConstraintDialog::Constraint constraintType) +{ + switch (constraintType) { + case ConstraintDialog::PK: + case ConstraintDialog::FK: + case ConstraintDialog::UNIQUE: + case ConstraintDialog::CHECK: + case ConstraintDialog::NOTNULL: + case ConstraintDialog::COLLATE: + case ConstraintDialog::DEFAULT: + case ConstraintDialog::GENERATED: + modeToButton[constraintType]->setEnabled(false); + break; + case ConstraintDialog::UNKNOWN: + break; + } +} + void NewConstraintDialog::changeEvent(QEvent *e) { QDialog::changeEvent(e); @@ -84,36 +102,32 @@ void NewConstraintDialog::init() void NewConstraintDialog::initTable() { - addButton(ICONS.CONSTRAINT_PRIMARY_KEY, tr("Primary Key", "new constraint dialog"), SLOT(createTablePk())); - if (createTable->dialect == Dialect::Sqlite3) - addButton(ICONS.CONSTRAINT_FOREIGN_KEY, tr("Foreign Key", "new constraint dialog"), SLOT(createTableFk())); - - addButton(ICONS.CONSTRAINT_UNIQUE, tr("Unique", "new constraint dialog"), SLOT(createTableUnique())); - addButton(ICONS.CONSTRAINT_CHECK, tr("Check", "new constraint dialog"), SLOT(createTableCheck())); + modeToButton[ConstraintDialog::Constraint::PK] = addButton(ICONS.CONSTRAINT_PRIMARY_KEY, tr("Primary Key", "new constraint dialog"), SLOT(createTablePk())); + modeToButton[ConstraintDialog::Constraint::FK] = addButton(ICONS.CONSTRAINT_FOREIGN_KEY, tr("Foreign Key", "new constraint dialog"), SLOT(createTableFk())); + modeToButton[ConstraintDialog::Constraint::UNIQUE] = addButton(ICONS.CONSTRAINT_UNIQUE, tr("Unique", "new constraint dialog"), SLOT(createTableUnique())); + modeToButton[ConstraintDialog::Constraint::CHECK] = addButton(ICONS.CONSTRAINT_CHECK, tr("Check", "new constraint dialog"), SLOT(createTableCheck())); } void NewConstraintDialog::initColumn() { - addButton(ICONS.CONSTRAINT_PRIMARY_KEY, tr("Primary Key", "new constraint dialog"), SLOT(createColumnPk())); - if (createTable->dialect == Dialect::Sqlite3) - addButton(ICONS.CONSTRAINT_FOREIGN_KEY, tr("Foreign Key", "new constraint dialog"), SLOT(createColumnFk())); - - addButton(ICONS.CONSTRAINT_UNIQUE, tr("Unique", "new constraint dialog"), SLOT(createColumnUnique())); - addButton(ICONS.CONSTRAINT_CHECK, tr("Check", "new constraint dialog"), SLOT(createColumnCheck())); - addButton(ICONS.CONSTRAINT_NOT_NULL, tr("Not NULL", "new constraint dialog"), SLOT(createColumnNotNull())); - if (createTable->dialect == Dialect::Sqlite3) - addButton(ICONS.CONSTRAINT_COLLATION, tr("Collate", "new constraint dialog"), SLOT(createColumnCollate())); - - addButton(ICONS.CONSTRAINT_DEFAULT, tr("Default", "new constraint dialog"), SLOT(createColumnDefault())); + modeToButton[ConstraintDialog::Constraint::PK] = addButton(ICONS.CONSTRAINT_PRIMARY_KEY, tr("Primary Key", "new constraint dialog"), SLOT(createColumnPk())); + modeToButton[ConstraintDialog::Constraint::FK] = addButton(ICONS.CONSTRAINT_FOREIGN_KEY, tr("Foreign Key", "new constraint dialog"), SLOT(createColumnFk())); + modeToButton[ConstraintDialog::Constraint::UNIQUE] = addButton(ICONS.CONSTRAINT_UNIQUE, tr("Unique", "new constraint dialog"), SLOT(createColumnUnique())); + modeToButton[ConstraintDialog::Constraint::CHECK] = addButton(ICONS.CONSTRAINT_CHECK, tr("Check", "new constraint dialog"), SLOT(createColumnCheck())); + modeToButton[ConstraintDialog::Constraint::NOTNULL] = addButton(ICONS.CONSTRAINT_NOT_NULL, tr("Not NULL", "new constraint dialog"), SLOT(createColumnNotNull())); + modeToButton[ConstraintDialog::Constraint::COLLATE] = addButton(ICONS.CONSTRAINT_COLLATION, tr("Collate", "new constraint dialog"), SLOT(createColumnCollate())); + modeToButton[ConstraintDialog::Constraint::GENERATED] = addButton(ICONS.CONSTRAINT_GENERATED, tr("Generated", "new constraint dialog"), SLOT(createColumnGenerated())); + modeToButton[ConstraintDialog::Constraint::DEFAULT] = addButton(ICONS.CONSTRAINT_DEFAULT, tr("Default", "new constraint dialog"), SLOT(createColumnDefault())); } -void NewConstraintDialog::addButton(const Icon& icon, const QString text, const char* slot) +QCommandLinkButton* NewConstraintDialog::addButton(const Icon& icon, const QString text, const char* slot) { QCommandLinkButton* btn = new QCommandLinkButton(); btn->setIcon(icon); btn->setText(text); connect(btn, SIGNAL(clicked()), this, slot); ui->container->layout()->addWidget(btn); + return btn; } int NewConstraintDialog::createColumnConstraint(ConstraintDialog::Constraint constraintType) @@ -142,6 +156,9 @@ int NewConstraintDialog::createColumnConstraint(ConstraintDialog::Constraint con case ConstraintDialog::DEFAULT: constraint->type = SqliteCreateTable::Column::Constraint::DEFAULT; break; + case ConstraintDialog::GENERATED: + constraint->type = SqliteCreateTable::Column::Constraint::GENERATED; + break; case ConstraintDialog::UNKNOWN: break; } @@ -172,6 +189,7 @@ int NewConstraintDialog::createTableConstraint(ConstraintDialog::Constraint cons case ConstraintDialog::NOTNULL: case ConstraintDialog::COLLATE: case ConstraintDialog::DEFAULT: + case ConstraintDialog::GENERATED: case ConstraintDialog::UNKNOWN: break; } @@ -258,6 +276,11 @@ void NewConstraintDialog::createColumnCollate() createColumnConstraint(ConstraintDialog::COLLATE); } +void NewConstraintDialog::createColumnGenerated() +{ + createColumnConstraint(ConstraintDialog::GENERATED); +} + int NewConstraintDialog::exec() { if (predefinedConstraintType == ConstraintDialog::UNKNOWN) diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/newconstraintdialog.h b/SQLiteStudio3/guiSQLiteStudio/dialogs/newconstraintdialog.h index e374312..daa226c 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/newconstraintdialog.h +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/newconstraintdialog.h @@ -12,6 +12,7 @@ namespace Ui { class NewConstraintDialog; } +class QCommandLinkButton; class GUI_API_EXPORT NewConstraintDialog : public QDialog { @@ -25,6 +26,7 @@ class GUI_API_EXPORT NewConstraintDialog : public QDialog ~NewConstraintDialog(); SqliteStatement* getConstraint(); + void disableMode(ConstraintDialog::Constraint constraintType); int exec(); protected: @@ -34,7 +36,7 @@ class GUI_API_EXPORT NewConstraintDialog : public QDialog void init(); void initTable(); void initColumn(); - void addButton(const Icon& icon, const QString text, const char* slot); + QCommandLinkButton* addButton(const Icon& icon, const QString text, const char* slot); int createColumnConstraint(ConstraintDialog::Constraint constraintType); int createTableConstraint(ConstraintDialog::Constraint constraintType); int editConstraint(); @@ -47,6 +49,7 @@ class GUI_API_EXPORT NewConstraintDialog : public QDialog QPointer createTable; QPointer columnStmt; ConstraintDialog* constraintDialog = nullptr; + QHash modeToButton; private slots: void createTablePk(); @@ -60,6 +63,7 @@ class GUI_API_EXPORT NewConstraintDialog : public QDialog void createColumnNotNull(); void createColumnDefault(); void createColumnCollate(); + void createColumnGenerated(); }; #endif // NEWCONSTRAINTDIALOG_H diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/newversiondialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/newversiondialog.cpp index 020cfef..7ba2c0b 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/newversiondialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/newversiondialog.cpp @@ -5,7 +5,9 @@ #include "sqlitestudio.h" #include "ui_newversiondialog.h" #include "services/config.h" +#include #include +#include NewVersionDialog::NewVersionDialog(QWidget *parent) : QDialog(parent), @@ -19,22 +21,10 @@ NewVersionDialog::~NewVersionDialog() delete ui; } -void NewVersionDialog::setUpdates(const QList& updates) +void NewVersionDialog::setUpdate(const QString& version, const QString& url) { - QTableWidgetItem* item = nullptr; - int row = 0; - ui->updateList->setRowCount(updates.size()); - for (const UpdateManager::UpdateEntry& entry : updates) - { - item = new QTableWidgetItem(entry.compontent); - ui->updateList->setItem(row, 0, item); - - item = new QTableWidgetItem(entry.version); - ui->updateList->setItem(row, 1, item); - - row++; - } - ui->updateList->resizeColumnsToContents(); + downloadUrl = url; + ui->versionLabel->setText(version); } void NewVersionDialog::init() @@ -42,16 +32,23 @@ void NewVersionDialog::init() ui->setupUi(this); connect(ui->abortButton, SIGNAL(clicked()), this, SLOT(reject())); - connect(ui->updateButton, SIGNAL(clicked()), this, SLOT(installUpdates())); + connect(ui->updateButton, SIGNAL(clicked()), this, SLOT(downloadUpdates())); + connect(ui->homepageButton, SIGNAL(clicked()), this, SLOT(openHomePage())); connect(ui->checkOnStartupCheck, &QCheckBox::clicked, [=](bool checked) { CFG_CORE.General.CheckUpdatesOnStartup.set(checked); }); } -void NewVersionDialog::installUpdates() +void NewVersionDialog::downloadUpdates() +{ + QDesktopServices::openUrl(QUrl(downloadUrl)); + close(); +} + +void NewVersionDialog::openHomePage() { - UPDATES->update(); + QDesktopServices::openUrl(QUrl(SQLITESTUDIO->getHomePage())); close(); } diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/newversiondialog.h b/SQLiteStudio3/guiSQLiteStudio/dialogs/newversiondialog.h index fc62d6d..a1b1569 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/newversiondialog.h +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/newversiondialog.h @@ -19,7 +19,7 @@ class GUI_API_EXPORT NewVersionDialog : public QDialog explicit NewVersionDialog(QWidget *parent = 0); ~NewVersionDialog(); - void setUpdates(const QList& updates); + void setUpdate(const QString& version, const QString& url); protected: void showEvent(QShowEvent*); @@ -27,10 +27,13 @@ class GUI_API_EXPORT NewVersionDialog : public QDialog private: void init(); + QString downloadUrl; + Ui::NewVersionDialog *ui = nullptr; private slots: - void installUpdates(); + void downloadUpdates(); + void openHomePage(); }; #endif // PORTABLE_CONFIG diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/newversiondialog.ui b/SQLiteStudio3/guiSQLiteStudio/dialogs/newversiondialog.ui index d5468b3..12794ce 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/newversiondialog.ui +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/newversiondialog.ui @@ -23,7 +23,7 @@ - New updates are available! + New version is available! Qt::AlignCenter @@ -31,73 +31,50 @@ - - - Qt::NoFocus - - - QAbstractItemView::NoEditTriggers - - - false - - - QAbstractItemView::NoSelection - - - QAbstractItemView::SelectRows - - - QAbstractItemView::ScrollPerPixel - - - false - - - true - - - false - - - 20 - - - 20 - - - - Component - - - - - Update version - - + + + + 16 + 75 + true + + + + 0.0.0 + + + Qt::AlignCenter + - - - - - - Check for updates on startup - - - - + + + Download new version! + + + + :/icons/img/get_update.png:/icons/img/get_update.png + + + + 24 + 24 + + + + New version package will be downloaded. It will be up to you to install it whenever you're ready. + - + - Update to new version! + Open SQLiteStudio home page. - :/icons/img/get_update.png:/icons/img/get_update.png + :/icons/img/sqlitestudio.svg:/icons/img/sqlitestudio.svg @@ -106,7 +83,7 @@ - This application will be closed and the update installer will start to download and install all the updates. + Read release notes && download package yourself. @@ -126,10 +103,23 @@ - Don't install the update and close this window. + Just close this window. + + + + + + + Check for updates on startup + + + + + + diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/populatedialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/populatedialog.cpp index 7f4ec20..aae0d58 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/populatedialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/populatedialog.cpp @@ -10,6 +10,7 @@ #include "uiutils.h" #include "services/populatemanager.h" #include "common/widgetcover.h" +#include "common/compatibility.h" #include #include #include @@ -42,7 +43,7 @@ void PopulateDialog::init() ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Populate", "populate dialog button")); plugins = PLUGINS->getLoadedPlugins(); - qSort(plugins.begin(), plugins.end(), [](PopulatePlugin* p1, PopulatePlugin* p2) -> bool + sSort(plugins, [](PopulatePlugin* p1, PopulatePlugin* p2) -> bool { return p1->getTitle().compare(p2->getTitle()) < 0; }); diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/triggerdialog.cpp b/SQLiteStudio3/guiSQLiteStudio/dialogs/triggerdialog.cpp index 255694c..86862e2 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dialogs/triggerdialog.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/triggerdialog.cpp @@ -107,12 +107,6 @@ void TriggerDialog::init() SqliteCreateTrigger::scopeToString(SqliteCreateTrigger::Scope::null), SqliteCreateTrigger::scopeToString(SqliteCreateTrigger::Scope::FOR_EACH_ROW) }); - if (db->getDialect() == Dialect::Sqlite2) - { - ui->scopeCombo->addItems({ - SqliteCreateTrigger::scopeToString(SqliteCreateTrigger::Scope::FOR_EACH_STATEMENT) - }); - } // Event combo - default values ui->whenCombo->addItems(tableEventNames + viewEventNames); @@ -223,7 +217,6 @@ void TriggerDialog::readTrigger() void TriggerDialog::setupVirtualSqls() { - Dialect dialect = db->getDialect(); static QString preconditionVirtSql = QStringLiteral("CREATE TRIGGER %1 BEFORE INSERT ON %2 WHEN %3 BEGIN SELECT 1; END;"); static QString codeVirtSql = QStringLiteral("CREATE TRIGGER %1 BEFORE INSERT ON %2 BEGIN %3 END;"); ui->codeEdit->setVirtualSqlCompleteSemicolon(true); @@ -232,14 +225,14 @@ void TriggerDialog::setupVirtualSqls() if (createTrigger) // if false, then there was a parsing error in parseDdl(). { ui->preconditionEdit->setVirtualSqlExpression( - preconditionVirtSql.arg(wrapObjIfNeeded(trigger, dialect), - wrapObjIfNeeded(createTrigger->table, dialect), + preconditionVirtSql.arg(wrapObjIfNeeded(trigger), + wrapObjIfNeeded(createTrigger->table), "%1")); ui->codeEdit->setVirtualSqlExpression( codeVirtSql.arg( - wrapObjIfNeeded(trigger, dialect), - wrapObjIfNeeded(createTrigger->table, dialect), + wrapObjIfNeeded(trigger), + wrapObjIfNeeded(createTrigger->table), "%1")); } } @@ -247,12 +240,12 @@ void TriggerDialog::setupVirtualSqls() { ui->preconditionEdit->setVirtualSqlExpression( preconditionVirtSql.arg("trig", - wrapObjIfNeeded(getTargetObjectName(), dialect), + wrapObjIfNeeded(getTargetObjectName()), "%1")); ui->codeEdit->setVirtualSqlExpression( codeVirtSql.arg("trig", - wrapObjIfNeeded(getTargetObjectName(), dialect), + wrapObjIfNeeded(getTargetObjectName()), "%1")); } else @@ -292,12 +285,11 @@ void TriggerDialog::rebuildTrigger() */ static const QString tempDdl = QStringLiteral("CREATE TRIGGER %1%2 %3%4 ON %5%6%7 BEGIN %8 END;"); - Dialect dialect = db->getDialect(); - QString trigName = wrapObjIfNeeded(ui->nameEdit->text(), dialect); + QString trigName = wrapObjIfNeeded(ui->nameEdit->text()); QString when = ui->whenCombo->currentText(); QString action = ui->actionCombo->currentText(); QString columns = ""; - QString target = wrapObjIfNeeded(getTargetObjectName(), dialect); + QString target = wrapObjIfNeeded(getTargetObjectName()); QString scope = ui->scopeCombo->currentText(); QString precondition = ""; QString queries = ui->codeEdit->toPlainText(); @@ -308,7 +300,7 @@ void TriggerDialog::rebuildTrigger() { QStringList colNames; for (const QString& colName : selectedColumns) - colNames << wrapObjIfNeeded(colName, dialect); + colNames << wrapObjIfNeeded(colName); columns = " "+colNames.join(", "); } @@ -394,11 +386,9 @@ void TriggerDialog::accept() { rebuildTrigger(); - Dialect dialect = db->getDialect(); - QStringList sqls; if (existingTrigger) - sqls << QString("DROP TRIGGER %1").arg(wrapObjIfNeeded(originalTriggerName, dialect)); + sqls << QString("DROP TRIGGER %1").arg(wrapObjIfNeeded(originalTriggerName)); sqls << ddl; -- cgit v1.2.3