aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/guiSQLiteStudio/windows
diff options
context:
space:
mode:
Diffstat (limited to 'SQLiteStudio3/guiSQLiteStudio/windows')
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.cpp62
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.h3
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.ui27
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/collationseditormodel.cpp27
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/collationseditormodel.h2
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/editorwindow.cpp11
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/editorwindow.h2
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/functionseditor.cpp46
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/functionseditor.h2
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/functionseditormodel.cpp55
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/functionseditormodel.h18
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/sqliteextensioneditor.cpp4
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.cpp31
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.h2
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.cpp6
15 files changed, 250 insertions, 48 deletions
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.cpp b/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.cpp
index df72db2..6624bc5 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.cpp
@@ -105,14 +105,14 @@ void CollationsEditor::init()
connect(ui->nameEdit, SIGNAL(textChanged(QString)), this, SLOT(updateModified()));
connect(ui->allDatabasesRadio, SIGNAL(clicked()), this, SLOT(updateModified()));
connect(ui->selectedDatabasesRadio, SIGNAL(clicked()), this, SLOT(updateModified()));
+ connect(ui->functionBasedRadio, SIGNAL(clicked()), this, SLOT(updateModified()));
+ connect(ui->extensionBasedRadio, SIGNAL(clicked()), this, SLOT(updateModified()));
connect(ui->langCombo, SIGNAL(currentTextChanged(QString)), this, SLOT(updateModified()));
connect(dbListModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(updateModified()));
connect(CFG_UI.Fonts.SqlEditor, SIGNAL(changed(QVariant)), this, SLOT(changeFont(QVariant)));
- // Language plugins
- for (ScriptingPlugin* plugin : PLUGINS->getLoadedPlugins<ScriptingPlugin>())
- ui->langCombo->addItem(plugin->getLanguage());
+ updateLangCombo();
// Syntax highlighting plugins
for (SyntaxHighlighterPlugin* plugin : PLUGINS->getLoadedPlugins<SyntaxHighlighterPlugin>())
@@ -130,9 +130,16 @@ int CollationsEditor::getCurrentCollationRow() const
return idxList.first().row();
}
+CollationManager::CollationType CollationsEditor::getCurrentType() const
+{
+ return ui->extensionBasedRadio->isChecked() ? CollationManager::CollationType::EXTENSION_BASED
+ : CollationManager::CollationType::FUNCTION_BASED;
+}
+
void CollationsEditor::collationDeselected(int row)
{
model->setName(row, ui->nameEdit->text());
+ model->setType(row, getCurrentType());
model->setLang(row, ui->langCombo->currentText());
model->setAllDatabases(row, ui->allDatabasesRadio->isChecked());
model->setCode(row, ui->codeEdit->toPlainText());
@@ -149,6 +156,9 @@ void CollationsEditor::collationSelected(int row)
updatesForSelection = true;
ui->nameEdit->setText(model->getName(row));
ui->codeEdit->setPlainText(model->getCode(row));
+ ui->functionBasedRadio->setChecked(model->getType(row) == CollationManager::CollationType::FUNCTION_BASED);
+ ui->extensionBasedRadio->setChecked(model->getType(row) == CollationManager::CollationType::EXTENSION_BASED);
+ updateLangCombo();
ui->langCombo->setCurrentText(model->getLang(row));
// Databases
@@ -238,7 +248,7 @@ void CollationsEditor::newCollation()
CollationManager::CollationPtr coll = CollationManager::CollationPtr::create();
coll->name = generateUniqueName("collation", model->getCollationNames());
-
+ coll->type = getCurrentType();
if (ui->langCombo->currentIndex() > -1)
coll->lang = ui->langCombo->currentText();
@@ -287,6 +297,8 @@ void CollationsEditor::updateCurrentCollationState()
bool nameOk = model->isAllowedName(row, name) && !name.trimmed().isEmpty();
setValidState(ui->nameEdit, nameOk, tr("Enter a non-empty, unique name of the collation."));
+ updateLangCombo();
+
bool langOk = ui->langCombo->currentIndex() >= 0;
ui->codeGroup->setEnabled(langOk);
ui->databasesGroup->setEnabled(langOk);
@@ -296,7 +308,16 @@ void CollationsEditor::updateCurrentCollationState()
setValidState(ui->langCombo, langOk, tr("Pick the implementation language."));
bool codeOk = !ui->codeEdit->toPlainText().trimmed().isEmpty();
- setValidState(ui->codeEdit, codeOk, tr("Enter a non-empty implementation code."));
+ if (ui->extensionBasedRadio->isChecked())
+ {
+ ui->codeGroup->setTitle(tr("Registration code"));
+ setValidState(ui->codeEdit, codeOk, tr("Enter a non-empty registration code."));
+ }
+ else
+ {
+ ui->codeGroup->setTitle(tr("Implementation code"));
+ setValidState(ui->codeEdit, codeOk, tr("Enter a non-empty implementation code."));
+ }
// Syntax highlighter
QString lang = ui->langCombo->currentText();
@@ -343,6 +364,34 @@ void CollationsEditor::collationSelected(const QItemSelection& selected, const Q
}
}
+void CollationsEditor::updateLangCombo()
+{
+ QComboBox *combo = ui->langCombo;
+ bool alreadyInternalUpdate = updatesForSelection;
+ updatesForSelection = true;
+ if (ui->extensionBasedRadio->isChecked())
+ {
+ if (combo->isEnabled())
+ {
+ combo->setEnabled(false);
+ combo->clear();
+ combo->addItem("SQL");
+ combo->setCurrentIndex(0);
+ }
+ }
+ else
+ {
+ if (!combo->isEnabled())
+ {
+ combo->clear();
+ for (ScriptingPlugin* plugin : PLUGINS->getLoadedPlugins<ScriptingPlugin>())
+ combo->addItem(plugin->getLanguage());
+ combo->setEnabled(true);
+ }
+ }
+ updatesForSelection = alreadyInternalUpdate;
+}
+
void CollationsEditor::updateModified()
{
if (updatesForSelection)
@@ -353,11 +402,12 @@ void CollationsEditor::updateModified()
{
bool nameDiff = model->getName(row) != ui->nameEdit->text();
bool codeDiff = model->getCode(row) != ui->codeEdit->toPlainText();
+ bool typeDiff = model->getType(row) != getCurrentType();
bool langDiff = model->getLang(row) != ui->langCombo->currentText();
bool allDatabasesDiff = model->getAllDatabases(row) != ui->allDatabasesRadio->isChecked();
bool dbDiff = toSet(getCurrentDatabases()) != toSet(model->getDatabases(row)); // QSet to ignore order
- currentModified = (nameDiff || codeDiff || langDiff || allDatabasesDiff || dbDiff);
+ currentModified = (nameDiff || codeDiff || typeDiff || langDiff || allDatabasesDiff || dbDiff);
}
updateCurrentCollationState();
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.h b/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.h
index 61c9165..7f61a82 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.h
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.h
@@ -3,6 +3,7 @@
#include "mdichild.h"
#include "common/extactioncontainer.h"
+#include "services/collationmanager.h"
#include <QItemSelection>
#include <QModelIndex>
#include <QWidget>
@@ -61,12 +62,14 @@ class GUI_API_EXPORT CollationsEditor : public MdiChild
private:
void init();
int getCurrentCollationRow() const;
+ CollationManager::CollationType getCurrentType() const;
void collationDeselected(int row);
void collationSelected(int row);
void clearEdits();
void selectCollation(int row);
QStringList getCurrentDatabases() const;
void setFont(const QFont& font);
+ void updateLangCombo();
Ui::CollationsEditor *ui = nullptr;
CollationsEditorModel* model = nullptr;
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.ui b/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.ui
index 454c12a..123c2ba 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.ui
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.ui
@@ -203,13 +203,38 @@
<widget class="QLineEdit" name="nameEdit"/>
</item>
<item row="0" column="1">
+ <widget class="QLabel" name="typeLabel">
+ <property name="text">
+ <string>Collation type:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_6">
+ <item>
+ <widget class="QRadioButton" name="functionBasedRadio">
+ <property name="text">
+ <string>Function-based</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="extensionBasedRadio">
+ <property name="text">
+ <string>Extension-based</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="2">
<widget class="QLabel" name="langLabel">
<property name="text">
<string>Implementation language:</string>
</property>
</widget>
</item>
- <item row="1" column="1">
+ <item row="1" column="2">
<widget class="QComboBox" name="langCombo"/>
</item>
</layout>
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/collationseditormodel.cpp b/SQLiteStudio3/guiSQLiteStudio/windows/collationseditormodel.cpp
index f04e023..0587d76 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/collationseditormodel.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/collationseditormodel.cpp
@@ -1,6 +1,7 @@
#include "collationseditormodel.h"
#include "common/unused.h"
#include "common/strhash.h"
+#include "iconmanager.h"
#include "services/pluginmanager.h"
#include "plugins/scriptingplugin.h"
#include "icon.h"
@@ -69,6 +70,16 @@ QString CollationsEditorModel::getName(int row) const
GETTER(collationList[row]->data->name, QString());
}
+void CollationsEditorModel::setType(int row, CollationManager::CollationType type)
+{
+ SETTER(collationList[row]->data->type, type);
+}
+
+CollationManager::CollationType CollationsEditorModel::getType(int row) const
+{
+ GETTER(collationList[row]->data->type, CollationManager::CollationType::FUNCTION_BASED);
+}
+
void CollationsEditorModel::setLang(int row, const QString& lang)
{
SETTER(collationList[row]->data->lang, lang);
@@ -248,13 +259,17 @@ QVariant CollationsEditorModel::data(const QModelIndex& index, int role) const
if (role == Qt::DisplayRole)
return collationList[index.row()]->data->name;
- if (role == Qt::DecorationRole && langToIcon.contains(collationList[index.row()]->data->lang))
+ if (role == Qt::DecorationRole)
{
- QIcon icon = langToIcon[collationList[index.row()]->data->lang];
- if (!collationList[index.row()]->valid)
- icon = Icon::merge(icon, Icon::ERROR);
-
- return icon;
+ auto coll = collationList[index.row()]->data;
+ bool isExtension = coll->type == CollationManager::CollationType::EXTENSION_BASED;
+ if (isExtension || langToIcon.contains(coll->lang))
+ {
+ QIcon icon = isExtension ? ICONS.EXTENSION : langToIcon[coll->lang];
+ if (!collationList[index.row()]->valid)
+ icon = Icon::merge(icon, Icon::ERROR);
+ return icon;
+ }
}
return QVariant();
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/collationseditormodel.h b/SQLiteStudio3/guiSQLiteStudio/windows/collationseditormodel.h
index 46f7ab5..47b8b08 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/collationseditormodel.h
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/collationseditormodel.h
@@ -21,6 +21,8 @@ class GUI_API_EXPORT CollationsEditorModel : public QAbstractListModel
void setModified(int row, bool modified);
void setName(int row, const QString& name);
QString getName(int row) const;
+ void setType(int row, CollationManager::CollationType type);
+ CollationManager::CollationType getType(int row) const;
void setLang(int row, const QString& lang);
QString getLang(int row) const;
void setAllDatabases(int row, bool allDatabases);
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/editorwindow.cpp b/SQLiteStudio3/guiSQLiteStudio/windows/editorwindow.cpp
index 23cb651..aa59bb0 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/editorwindow.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/editorwindow.cpp
@@ -211,7 +211,7 @@ QAction* EditorWindow::getAction(EditorWindow::Action action)
return ExtActionContainer::getAction(action);
}
-QString EditorWindow::getQueryToExecute(bool doSelectCurrentQuery, QueryExecMode querySelectionMode)
+QString EditorWindow::getQueryToExecute(QueryExecMode querySelectionMode)
{
QString sql;
if (ui->sqlEdit->textCursor().hasSelection())
@@ -228,9 +228,8 @@ QString EditorWindow::getQueryToExecute(bool doSelectCurrentQuery, QueryExecMode
ui->sqlEdit->saveSelection();
selectCurrentQuery(true);
sql = ui->sqlEdit->textCursor().selectedText();
+ ui->sqlEdit->restoreSelection();
fixTextCursorSelectedText(sql);
- if (!doSelectCurrentQuery)
- ui->sqlEdit->restoreSelection();
}
else
{
@@ -463,7 +462,7 @@ void EditorWindow::updateShortcutTips()
void EditorWindow::execQuery(bool explain, QueryExecMode querySelectionMode)
{
- QString sql = getQueryToExecute(true, querySelectionMode);
+ QString sql = getQueryToExecute(querySelectionMode);
QHash<QString, QVariant> bindParams;
bool proceed = processBindParams(sql, bindParams);
if (!proceed)
@@ -474,7 +473,7 @@ void EditorWindow::execQuery(bool explain, QueryExecMode querySelectionMode)
resultsModel->setQuery(sql);
resultsModel->setParams(bindParams);
resultsModel->setQueryCountLimitForSmartMode(queryLimitForSmartExecution);
- ui->dataView->refreshData();
+ ui->dataView->refreshData(false);
updateState();
if (resultsDisplayMode == ResultsDisplayMode::SEPARATE_TAB)
@@ -741,7 +740,7 @@ void EditorWindow::createViewFromQuery()
return;
}
- QString sql = getQueryToExecute(true);
+ QString sql = getQueryToExecute();
DbObjectDialogs dialogs(getCurrentDb());
dialogs.addView(sql);
}
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/editorwindow.h b/SQLiteStudio3/guiSQLiteStudio/windows/editorwindow.h
index 977784e..0ca2cdf 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/editorwindow.h
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/editorwindow.h
@@ -100,7 +100,7 @@ class GUI_API_EXPORT EditorWindow : public MdiChild
QSize sizeHint() const;
QAction* getAction(Action action);
- QString getQueryToExecute(bool doSelectCurrentQuery = false, QueryExecMode querySelectionMode = DEFAULT);
+ QString getQueryToExecute(QueryExecMode querySelectionMode = DEFAULT);
bool setCurrentDb(Db* db);
void setContents(const QString& sql);
QString getContents() const;
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/functionseditor.cpp b/SQLiteStudio3/guiSQLiteStudio/windows/functionseditor.cpp
index 4d964c8..e349525 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/functionseditor.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/functionseditor.cpp
@@ -170,9 +170,12 @@ int FunctionsEditor::getCurrentFunctionRow() const
void FunctionsEditor::functionDeselected(int row)
{
model->setName(row, ui->nameEdit->text());
+ model->setUndefinedArgs(row, ui->undefArgsCheck->isChecked());
+ if (!ui->undefArgsCheck->isChecked())
+ model->setArguments(row, getCurrentArgList());
+
model->setLang(row, ui->langCombo->currentText());
model->setType(row, getCurrentFunctionType());
- model->setUndefinedArgs(row, ui->undefArgsCheck->isChecked());
model->setAllDatabases(row, ui->allDatabasesRadio->isChecked());
model->setCode(row, ui->mainCodeEdit->toPlainText());
model->setDeterministic(row, ui->deterministicCheck->isChecked());
@@ -189,9 +192,6 @@ void FunctionsEditor::functionDeselected(int row)
model->setFinalCode(row, QString());
}
- if (!ui->undefArgsCheck->isChecked())
- model->setArguments(row, getCurrentArgList());
-
if (ui->selDatabasesRadio->isChecked())
model->setDatabases(row, getCurrentDatabases());
@@ -416,8 +416,10 @@ void FunctionsEditor::updateCurrentFunctionState()
}
QString name = ui->nameEdit->text();
- bool nameOk = model->isAllowedName(row, name) && !name.trimmed().isEmpty();
- setValidState(ui->nameEdit, nameOk, tr("Enter a non-empty, unique name of the function."));
+ QStringList argList = getCurrentArgList();
+ bool undefArgs = ui->undefArgsCheck->isChecked();
+ bool nameOk = model->isAllowedName(row, name, argList, undefArgs) && !name.trimmed().isEmpty();
+ setValidState(ui->nameEdit, nameOk, tr("Enter a unique, non-empty function name. Duplicate names are allowed if the number of input parameters differs."));
bool langOk = ui->langCombo->currentIndex() >= 0;
ui->initCodeGroup->setEnabled(langOk);
@@ -488,8 +490,8 @@ void FunctionsEditor::updateCurrentFunctionState()
currentHighlighterLang = lang;
}
- updateArgsState();
- model->setValid(row, langOk && codeOk && finalCodeOk && nameOk);
+ bool argsOk = updateArgsState();
+ model->setValid(row, langOk && codeOk && finalCodeOk && nameOk && argsOk);
updateState();
}
@@ -576,7 +578,7 @@ void FunctionsEditor::moveFunctionArgDown()
ui->argsList->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::Clear|QItemSelectionModel::SelectCurrent);
}
-void FunctionsEditor::updateArgsState()
+bool FunctionsEditor::updateArgsState()
{
bool argsEnabled = !ui->undefArgsCheck->isChecked();
QModelIndexList indexes = ui->argsList->selectionModel()->selectedIndexes();
@@ -596,6 +598,32 @@ void FunctionsEditor::updateArgsState()
actionMap[ARG_MOVE_UP]->setEnabled(argsEnabled && canMoveUp);
actionMap[ARG_MOVE_DOWN]->setEnabled(argsEnabled && canMoveDown);
ui->argsList->setEnabled(argsEnabled);
+
+ if (argsEnabled)
+ {
+ bool argsOk = true;
+ QSet<QString> usedNames;
+ for (int rowIdx = 0; rowIdx < ui->argsList->model()->rowCount(); rowIdx++)
+ {
+ QListWidgetItem* item = ui->argsList->item(rowIdx);
+ QString argName = item->text().toLower();
+ if (argName.isEmpty())
+ {
+ argsOk = false;
+ break;
+ }
+ if (usedNames.contains(argName))
+ {
+ argsOk = false;
+ break;
+ }
+ usedNames << argName;
+ }
+ setValidState(ui->argsList, argsOk, tr("Function argument cannot be empty and it cannot have duplicated name."));
+ return argsOk;
+ }
+ else
+ return true;
}
void FunctionsEditor::applyFilter(const QString& value)
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/functionseditor.h b/SQLiteStudio3/guiSQLiteStudio/windows/functionseditor.h
index d3fcf12..d513234 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/functionseditor.h
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/functionseditor.h
@@ -105,7 +105,7 @@ class GUI_API_EXPORT FunctionsEditor : public MdiChild
void delFunctionArg();
void moveFunctionArgUp();
void moveFunctionArgDown();
- void updateArgsState();
+ bool updateArgsState();
void applyFilter(const QString& value);
void help();
void changeFont(const QVariant& font);
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/functionseditormodel.cpp b/SQLiteStudio3/guiSQLiteStudio/windows/functionseditormodel.cpp
index 46ae8d9..13ec34f 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/functionseditormodel.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/functionseditormodel.cpp
@@ -266,16 +266,17 @@ QStringList FunctionsEditorModel::getFunctionNames() const
void FunctionsEditorModel::validateNames()
{
- StrHash<QList<int>> counter;
+ QHash<UniqueFunctionName, QList<int>> counter;
int row = 0;
for (Function*& func : functionList)
{
func->valid &= true;
- counter[func->data.name] << row++;
+ UniqueFunctionName uniqueName = func->toUniqueName();
+ counter[uniqueName] << row++;
}
- QHashIterator<QString,QList<int>> cntIt = counter.iterator();
+ QHashIterator<UniqueFunctionName, QList<int>> cntIt(counter);
while (cntIt.hasNext())
{
cntIt.next();
@@ -294,11 +295,18 @@ void FunctionsEditorModel::validateNames()
}
}
-bool FunctionsEditorModel::isAllowedName(int rowToSkip, const QString& nameToValidate)
+bool FunctionsEditorModel::isAllowedName(int rowToSkip, const QString& nameToValidate, const QStringList& argList, bool undefinedArgs)
{
- QStringList names = getFunctionNames();
+ QList<UniqueFunctionName> names = getUniqueFunctionNames();
names.removeAt(rowToSkip);
- return !names.contains(nameToValidate, Qt::CaseInsensitive);
+
+ UniqueFunctionName validatedName;
+ validatedName.name = nameToValidate.toLower();
+ validatedName.undefArg = undefinedArgs;
+ if (!undefinedArgs)
+ validatedName.arguments = argList;
+
+ return !names.contains(validatedName);
}
int FunctionsEditorModel::rowCount(const QModelIndex& parent) const
@@ -347,6 +355,15 @@ void FunctionsEditorModel::emitDataChanged(int row)
emit dataChanged(idx, idx);
}
+QList<FunctionsEditorModel::UniqueFunctionName> FunctionsEditorModel::getUniqueFunctionNames() const
+{
+ QList<UniqueFunctionName> names;
+ for (Function* func : functionList)
+ names << func->toUniqueName();
+
+ return names;
+}
+
FunctionsEditorModel::Function::Function()
{
}
@@ -356,3 +373,29 @@ FunctionsEditorModel::Function::Function(FunctionManager::ScriptFunction* other)
data = FunctionManager::ScriptFunction(*other);
originalName = data.name;
}
+
+FunctionsEditorModel::UniqueFunctionName FunctionsEditorModel::Function::toUniqueName() const
+{
+ UniqueFunctionName uniqName;
+ uniqName.name = data.name.toLower();
+ uniqName.undefArg = data.undefinedArgs;
+ if (!data.undefinedArgs)
+ uniqName.arguments = data.arguments;
+
+ return uniqName;
+}
+
+int FunctionsEditorModel::UniqueFunctionName::argCount() const
+{
+ return undefArg ? -1 : arguments.size();
+}
+
+bool FunctionsEditorModel::UniqueFunctionName::operator==(const UniqueFunctionName &other) const
+{
+ return name == other.name && argCount() == other.argCount();
+}
+
+int qHash(FunctionsEditorModel::UniqueFunctionName fnName)
+{
+ return qHash(fnName.name) ^ fnName.argCount();
+}
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/functionseditormodel.h b/SQLiteStudio3/guiSQLiteStudio/windows/functionseditormodel.h
index 7caf06c..2f90bcc 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/functionseditormodel.h
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/functionseditormodel.h
@@ -60,17 +60,28 @@ class GUI_API_EXPORT FunctionsEditorModel : public QAbstractListModel
QList<FunctionManager::ScriptFunction*> generateFunctions() const;
QStringList getFunctionNames() const;
void validateNames();
- bool isAllowedName(int rowToSkip, const QString& nameToValidate);
+ bool isAllowedName(int rowToSkip, const QString& nameToValidate, const QStringList &argList, bool undefinedArgs);
bool isValidRowIndex(int row) const;
int rowCount(const QModelIndex& parent = QModelIndex()) const;
QVariant data(const QModelIndex& index, int role) const;
private:
+ struct UniqueFunctionName
+ {
+ QString name;
+ QStringList arguments;
+ bool undefArg;
+
+ int argCount() const;
+ bool operator==(const UniqueFunctionName& other) const;
+ };
+
struct Function
{
Function();
Function(FunctionManager::ScriptFunction* other);
+ UniqueFunctionName toUniqueName() const;
FunctionManager::ScriptFunction data;
bool modified = false;
@@ -80,6 +91,9 @@ class GUI_API_EXPORT FunctionsEditorModel : public QAbstractListModel
void init();
void emitDataChanged(int row);
+ QList<UniqueFunctionName> getUniqueFunctionNames() const;
+
+ friend int qHash(FunctionsEditorModel::UniqueFunctionName fnName);
QList<Function*> functionList;
@@ -96,4 +110,6 @@ class GUI_API_EXPORT FunctionsEditorModel : public QAbstractListModel
bool listModified = false;
};
+int qHash(FunctionsEditorModel::UniqueFunctionName fnName);
+
#endif // FUNCTIONSEDITORMODEL_H
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/sqliteextensioneditor.cpp b/SQLiteStudio3/guiSQLiteStudio/windows/sqliteextensioneditor.cpp
index f8dd621..66e6682 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/sqliteextensioneditor.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/sqliteextensioneditor.cpp
@@ -123,6 +123,7 @@ void SqliteExtensionEditor::init()
connect(dbListModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(updateModified()));
probingDb = DBLIST->createInMemDb(true);
+
if (!probingDb->openQuiet())
qWarning() << "Could not open in-memory dtabase for Extension manager window. Probing files will be impossible.";
@@ -308,6 +309,7 @@ void SqliteExtensionEditor::rollback()
if (model->isValidRowIndex(selectedBefore))
selectExtension(selectedBefore);
+ initStateForAll();
updateState();
}
@@ -337,7 +339,7 @@ void SqliteExtensionEditor::deleteExtension()
void SqliteExtensionEditor::updateState()
{
bool modified = model->isModified() || currentModified;
- bool valid = model->isValid() && validateCurrentExtension();
+ bool valid = model->isValid() && (getCurrentExtensionRow() == -1 || validateCurrentExtension());
actionMap[COMMIT]->setEnabled(modified && valid);
actionMap[ROLLBACK]->setEnabled(modified);
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.cpp b/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.cpp
index 86f48bf..b42848a 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.cpp
@@ -865,6 +865,9 @@ void TableWindow::changesSuccessfullyCommitted()
}
}
}
+
+ if (ui->tabWidget->currentIndex() == getDataTabIdx())
+ ui->dataView->refreshData();
}
void TableWindow::changesFailedToCommit(int errorCode, const QString& errorText)
@@ -1047,7 +1050,7 @@ bool TableWindow::validate(bool skipWarning)
QStringList nonStrictColumns;
for (SqliteCreateTable::Column* column : createTable->columns)
{
- if (DataType::isStrict(column->type->name))
+ if (DataType::isStrict(column->type ? column->type->name : QString()))
continue;
nonStrictColumns << column->name;
@@ -1310,7 +1313,7 @@ void TableWindow::importTable()
ImportDialog dialog(this);
dialog.setDbAndTable(db, table);
if (dialog.exec() == QDialog::Accepted && dataLoaded)
- ui->dataView->refreshData();
+ ui->dataView->refreshData(false);
}
void TableWindow::populateTable()
@@ -1318,7 +1321,7 @@ void TableWindow::populateTable()
PopulateDialog dialog(this);
dialog.setDbAndTable(db, table);
if (dialog.exec() == QDialog::Accepted && dataLoaded)
- ui->dataView->refreshData();
+ ui->dataView->refreshData(false);
}
void TableWindow::createSimilarTable()
@@ -1342,15 +1345,16 @@ void TableWindow::tabChanged(int newTab)
"Do you want to commit the structure, or do you want to go back to the structure tab?"),
tr("Go back to structure tab"), tr("Commit modifications and browse data."));
- ui->tabWidget->setCurrentIndex(0);
if (res == 1)
commitStructure(true);
+ else
+ focusStructureTab();
return;
}
if (!dataLoaded)
- ui->dataView->refreshData();
+ ui->dataView->refreshData(false);
}
}
@@ -1393,8 +1397,11 @@ void TableWindow::strictChanged()
{
for (SqliteCreateTable::Column* column : createTable->columns)
{
- column->type->precision = QVariant();
- column->type->scale = QVariant();
+ if (column->type)
+ {
+ column->type->precision = QVariant();
+ column->type->scale = QVariant();
+ }
}
}
@@ -1644,6 +1651,16 @@ void TableWindow::delColumn(const QString& columnName)
delColumn(colIdx);
}
+void TableWindow::focusStructureTab()
+{
+ ui->tabWidget->setCurrentIndex(getStructureTabIdx());
+}
+
+void TableWindow::focusDataTab()
+{
+ ui->tabWidget->setCurrentIndex(getDataTabIdx());
+}
+
void TableWindow::updateTabsOrder()
{
tabsMoving = true;
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.h b/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.h
index e71162d..dda317a 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.h
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/tablewindow.h
@@ -255,6 +255,8 @@ class GUI_API_EXPORT TableWindow : public MdiChild
void addColumn();
void editColumn(const QString& columnName);
void delColumn(const QString& columnName);
+ void focusStructureTab();
+ void focusDataTab();
signals:
void modifyStatusChanged();
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.cpp b/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.cpp
index 44025e5..73575c4 100644
--- a/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/viewwindow.cpp
@@ -299,7 +299,7 @@ void ViewWindow::initView()
if (existingView)
{
dataModel->setDb(db);
- dataModel->setQuery(originalCreateView->select->detokenize());
+ dataModel->setQuery(originalCreateView->equivalentSelectTokens().detokenize());
dataModel->setDatabaseAndView(database, view);
ui->dbCombo->setDisabled(true);
}
@@ -619,7 +619,7 @@ void ViewWindow::tabChanged(int tabIdx)
"Do you want to commit the structure, or do you want to go back to the structure tab?"),
tr("Go back to structure tab"), tr("Commit modifications and browse data."));
- ui->tabWidget->setCurrentIndex(0);
+ ui->tabWidget->setCurrentIndex(CFG_UI.General.DataTabAsFirstInViews.get() ? 1 : 0);
if (res == 1)
commitView(true);
@@ -627,7 +627,7 @@ void ViewWindow::tabChanged(int tabIdx)
}
if (!dataLoaded)
- ui->dataView->refreshData();
+ ui->dataView->refreshData(false);
return;
}