summaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.cpp
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2014-12-06 17:33:25 -0500
committerLibravatarUnit 193 <unit193@ubuntu.com>2014-12-06 17:33:25 -0500
commit7167ce41b61d2ba2cdb526777a4233eb84a3b66a (patch)
treea35c14143716e1f2c98f808c81f89426045a946f /SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.cpp
Imported Upstream version 2.99.6upstream/2.99.6
Diffstat (limited to 'SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.cpp')
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.cpp389
1 files changed, 389 insertions, 0 deletions
diff --git a/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.cpp b/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.cpp
new file mode 100644
index 0000000..1d0594d
--- /dev/null
+++ b/SQLiteStudio3/guiSQLiteStudio/windows/collationseditor.cpp
@@ -0,0 +1,389 @@
+#include "collationseditor.h"
+#include "ui_collationseditor.h"
+#include "common/unused.h"
+#include "selectabledbmodel.h"
+#include "dbtree/dbtree.h"
+#include "dbtree/dbtreemodel.h"
+#include "collationseditormodel.h"
+#include "common/utils.h"
+#include "uiutils.h"
+#include "services/pluginmanager.h"
+#include "syntaxhighlighterplugin.h"
+#include "plugins/scriptingplugin.h"
+#include "uiconfig.h"
+#include <QDesktopServices>
+#include <QSyntaxHighlighter>
+
+CollationsEditor::CollationsEditor(QWidget *parent) :
+ MdiChild(parent),
+ ui(new Ui::CollationsEditor)
+{
+ init();
+}
+
+CollationsEditor::~CollationsEditor()
+{
+ delete ui;
+}
+
+bool CollationsEditor::restoreSessionNextTime()
+{
+ return false;
+}
+
+QVariant CollationsEditor::saveSession()
+{
+ return QVariant();
+}
+
+bool CollationsEditor::restoreSession(const QVariant& sessionValue)
+{
+ UNUSED(sessionValue);
+ return true;
+}
+
+Icon* CollationsEditor::getIconNameForMdiWindow()
+{
+ return ICONS.CONSTRAINT_COLLATION;
+}
+
+QString CollationsEditor::getTitleForMdiWindow()
+{
+ return tr("Collations editor");
+}
+
+void CollationsEditor::createActions()
+{
+ createAction(COMMIT, ICONS.COMMIT, tr("Commit all collation changes"), this, SLOT(commit()), ui->toolbar);
+ createAction(ROLLBACK, ICONS.ROLLBACK, tr("Rollback all collation changes"), this, SLOT(rollback()), ui->toolbar);
+ ui->toolbar->addSeparator();
+ createAction(ADD, ICONS.NEW_COLLATION, tr("Create new collation"), this, SLOT(newCollation()), ui->toolbar);
+ createAction(DELETE, ICONS.DELETE_COLLATION, tr("Delete selected collation"), this, SLOT(deleteCollation()), ui->toolbar);
+ ui->toolbar->addSeparator();
+ createAction(HELP, ICONS.HELP, tr("Editing collations manual"), this, SLOT(help()), ui->toolbar);
+}
+
+void CollationsEditor::setupDefShortcuts()
+{
+
+}
+
+QToolBar* CollationsEditor::getToolBar(int toolbar) const
+{
+ UNUSED(toolbar);
+ return ui->toolbar;
+}
+
+void CollationsEditor::init()
+{
+ ui->setupUi(this);
+ initActions();
+
+ setFont(CFG_UI.Fonts.SqlEditor.get());
+
+ model = new CollationsEditorModel(this);
+ collationFilterModel = new QSortFilterProxyModel(this);
+ collationFilterModel->setSourceModel(model);
+ ui->collationList->setModel(collationFilterModel);
+
+ dbListModel = new SelectableDbModel(this);
+ dbListModel->setDisabledVersion(2);
+ dbListModel->setSourceModel(DBTREE->getModel());
+ ui->databaseList->setModel(dbListModel);
+ ui->databaseList->expandAll();
+
+ model->setData(COLLATIONS->getAllCollations());
+
+ connect(ui->collationList->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(collationSelected(QItemSelection,QItemSelection)));
+ connect(ui->collationList->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(updateState()));
+ connect(ui->codeEdit, SIGNAL(textChanged()), this, SLOT(updateModified()));
+ 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->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
+ foreach (ScriptingPlugin* plugin, PLUGINS->getLoadedPlugins<ScriptingPlugin>())
+ ui->langCombo->addItem(plugin->getLanguage());
+
+ // Syntax highlighting plugins
+ foreach (SyntaxHighlighterPlugin* plugin, PLUGINS->getLoadedPlugins<SyntaxHighlighterPlugin>())
+ highlighterPlugins[plugin->getLanguageName()] = plugin;
+
+ updateState();
+}
+
+int CollationsEditor::getCurrentCollationRow() const
+{
+ QModelIndexList idxList = ui->collationList->selectionModel()->selectedIndexes();
+ if (idxList.size() == 0)
+ return -1;
+
+ return idxList.first().row();
+}
+
+void CollationsEditor::collationDeselected(int row)
+{
+ model->setName(row, ui->nameEdit->text());
+ model->setLang(row, ui->langCombo->currentText());
+ model->setAllDatabases(row, ui->allDatabasesRadio->isChecked());
+ model->setCode(row, ui->codeEdit->toPlainText());
+ model->setModified(row, currentModified);
+
+ if (ui->selectedDatabasesRadio->isChecked())
+ model->setDatabases(row, getCurrentDatabases());
+
+ model->validateNames();
+}
+
+void CollationsEditor::collationSelected(int row)
+{
+ updatesForSelection = true;
+ ui->nameEdit->setText(model->getName(row));
+ ui->codeEdit->setPlainText(model->getCode(row));
+ ui->langCombo->setCurrentText(model->getLang(row));
+
+ // Databases
+ dbListModel->setDatabases(model->getDatabases(row));
+ ui->databaseList->expandAll();
+
+ if (model->getAllDatabases(row))
+ ui->allDatabasesRadio->setChecked(true);
+ else
+ ui->selectedDatabasesRadio->setChecked(true);
+
+ updatesForSelection = false;
+ currentModified = false;
+
+ updateCurrentCollationState();
+}
+
+void CollationsEditor::clearEdits()
+{
+ ui->nameEdit->setText(QString::null);
+ ui->codeEdit->setPlainText(QString::null);
+ ui->langCombo->setCurrentText(QString::null);
+ ui->allDatabasesRadio->setChecked(true);
+ ui->langCombo->setCurrentIndex(-1);
+}
+
+void CollationsEditor::selectCollation(int row)
+{
+ if (!model->isValidRowIndex(row))
+ return;
+
+ ui->collationList->selectionModel()->setCurrentIndex(model->index(row), QItemSelectionModel::Clear|QItemSelectionModel::SelectCurrent);
+}
+
+QStringList CollationsEditor::getCurrentDatabases() const
+{
+ return dbListModel->getDatabases();
+}
+
+void CollationsEditor::setFont(const QFont& font)
+{
+ ui->codeEdit->setFont(font);
+}
+
+void CollationsEditor::help()
+{
+ static const QString url = QStringLiteral("http://wiki.sqlitestudio.pl/index.php/User_Manual#Custom_collations");
+ QDesktopServices::openUrl(QUrl(url, QUrl::StrictMode));
+}
+
+void CollationsEditor::commit()
+{
+ int row = getCurrentCollationRow();
+ if (model->isValidRowIndex(row))
+ collationDeselected(row);
+
+ QList<CollationManager::CollationPtr> collations = model->getCollations();
+
+ COLLATIONS->setCollations(collations);
+ model->clearModified();
+ currentModified = false;
+
+ if (model->isValidRowIndex(row))
+ selectCollation(row);
+
+ updateState();
+}
+
+void CollationsEditor::rollback()
+{
+ int selectedBefore = getCurrentCollationRow();
+
+ model->setData(COLLATIONS->getAllCollations());
+ currentModified = false;
+ clearEdits();
+
+ if (model->isValidRowIndex(selectedBefore))
+ selectCollation(selectedBefore);
+
+ updateState();
+}
+
+void CollationsEditor::newCollation()
+{
+ if (ui->langCombo->currentIndex() == -1 && ui->langCombo->count() > 0)
+ ui->langCombo->setCurrentIndex(0);
+
+ CollationManager::CollationPtr coll = CollationManager::CollationPtr::create();
+ coll->name = generateUniqueName("collation", model->getCollationNames());
+
+ if (ui->langCombo->currentIndex() > -1)
+ coll->lang = ui->langCombo->currentText();
+
+ model->addCollation(coll);
+
+ selectCollation(model->rowCount() - 1);
+}
+
+void CollationsEditor::deleteCollation()
+{
+ int row = getCurrentCollationRow();
+ model->deleteCollation(row);
+ clearEdits();
+
+ row = getCurrentCollationRow();
+ if (model->isValidRowIndex(row))
+ collationSelected(row);
+
+ updateState();
+}
+
+void CollationsEditor::updateState()
+{
+ bool modified = model->isModified() || currentModified;
+ bool valid = model->isValid();
+
+ actionMap[COMMIT]->setEnabled(modified && valid);
+ actionMap[ROLLBACK]->setEnabled(modified);
+ actionMap[DELETE]->setEnabled(ui->collationList->selectionModel()->selectedIndexes().size() > 0);
+}
+
+void CollationsEditor::updateCurrentCollationState()
+{
+ int row = getCurrentCollationRow();
+ bool validRow = model->isValidRowIndex(row);
+ ui->rightWidget->setEnabled(validRow);
+ if (!validRow)
+ {
+ setValidState(ui->langCombo, true);
+ setValidState(ui->nameEdit, true);
+ setValidState(ui->codeEdit, true);
+ return;
+ }
+
+ 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 collation."));
+
+ bool langOk = ui->langCombo->currentIndex() >= 0;
+ ui->codeGroup->setEnabled(langOk);
+ ui->databasesGroup->setEnabled(langOk);
+ ui->nameEdit->setEnabled(langOk);
+ ui->nameLabel->setEnabled(langOk);
+ ui->databaseList->setEnabled(ui->selectedDatabasesRadio->isChecked());
+ 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."));
+
+ // Syntax highlighter
+ QString lang = ui->langCombo->currentText();
+ if (lang != currentHighlighterLang)
+ {
+ QSyntaxHighlighter* highlighter = nullptr;
+ if (currentHighlighter)
+ {
+ // A pointers swap with local var - this is necessary, cause deleting highlighter
+ // triggers textChanged on QPlainTextEdit, which then calls this method,
+ // so it becomes an infinite recursion with deleting the same pointer.
+ // We set the pointer to null first, then delete it. That way it's safe.
+ highlighter = currentHighlighter;
+ currentHighlighter = nullptr;
+ delete highlighter;
+ }
+
+ if (langOk && highlighterPlugins.contains(lang))
+ {
+ currentHighlighter = highlighterPlugins[lang]->createSyntaxHighlighter(ui->codeEdit);
+ }
+
+ currentHighlighterLang = lang;
+ }
+ model->setValid(row, langOk && codeOk && nameOk);
+ updateState();
+}
+
+void CollationsEditor::collationSelected(const QItemSelection& selected, const QItemSelection& deselected)
+{
+ int deselCnt = deselected.indexes().size();
+ int selCnt = selected.indexes().size();
+
+ if (deselCnt > 0)
+ collationDeselected(deselected.indexes().first().row());
+
+ if (selCnt > 0)
+ collationSelected(selected.indexes().first().row());
+
+ if (deselCnt > 0 && selCnt == 0)
+ {
+ currentModified = false;
+ clearEdits();
+ }
+}
+
+void CollationsEditor::updateModified()
+{
+ if (updatesForSelection)
+ return;
+
+ int row = getCurrentCollationRow();
+ if (model->isValidRowIndex(row))
+ {
+ bool nameDiff = model->getName(row) != ui->nameEdit->text();
+ bool codeDiff = model->getCode(row) != ui->codeEdit->toPlainText();
+ bool langDiff = model->getLang(row) != ui->langCombo->currentText();
+ bool allDatabasesDiff = model->getAllDatabases(row) != ui->allDatabasesRadio->isChecked();
+ bool dbDiff = getCurrentDatabases().toSet() != model->getDatabases(row).toSet(); // QSet to ignore order
+
+ currentModified = (nameDiff || codeDiff || langDiff || allDatabasesDiff || dbDiff);
+ }
+
+ updateCurrentCollationState();
+}
+
+void CollationsEditor::applyFilter(const QString& value)
+{
+ //
+ // See FunctionsEditor::applyFilter() for details why we remember current selection and restore it at the end.
+ //
+
+ int row = getCurrentCollationRow();
+ ui->collationList->selectionModel()->clearSelection();
+
+ collationFilterModel->setFilterFixedString(value);
+
+ selectCollation(row);
+}
+
+void CollationsEditor::changeFont(const QVariant& font)
+{
+ setFont(font.value<QFont>());
+}
+
+
+bool CollationsEditor::isUncommited() const
+{
+ return model->isModified();
+}
+
+QString CollationsEditor::getQuitUncommitedConfirmMessage() const
+{
+ return tr("Collations editor window has uncommited modifications.");
+}