From 7167ce41b61d2ba2cdb526777a4233eb84a3b66a Mon Sep 17 00:00:00 2001 From: Unit 193 Date: Sat, 6 Dec 2014 17:33:25 -0500 Subject: Imported Upstream version 2.99.6 --- .../guiSQLiteStudio/multieditor/multieditor.cpp | 366 +++++++++++++++++++++ .../guiSQLiteStudio/multieditor/multieditor.h | 96 ++++++ .../multieditor/multieditorbool.cpp | 215 ++++++++++++ .../guiSQLiteStudio/multieditor/multieditorbool.h | 68 ++++ .../multieditor/multieditordate.cpp | 87 +++++ .../guiSQLiteStudio/multieditor/multieditordate.h | 37 +++ .../multieditor/multieditordatetime.cpp | 275 ++++++++++++++++ .../multieditor/multieditordatetime.h | 84 +++++ .../multieditor/multieditordialog.cpp | 49 +++ .../multieditor/multieditordialog.h | 29 ++ .../guiSQLiteStudio/multieditor/multieditorhex.cpp | 94 ++++++ .../guiSQLiteStudio/multieditor/multieditorhex.h | 50 +++ .../multieditor/multieditornumeric.cpp | 109 ++++++ .../multieditor/multieditornumeric.h | 42 +++ .../multieditor/multieditortext.cpp | 184 +++++++++++ .../guiSQLiteStudio/multieditor/multieditortext.h | 87 +++++ .../multieditor/multieditortime.cpp | 90 +++++ .../guiSQLiteStudio/multieditor/multieditortime.h | 38 +++ .../multieditor/multieditorwidget.cpp | 23 ++ .../multieditor/multieditorwidget.h | 33 ++ .../multieditor/multieditorwidgetplugin.h | 17 + 21 files changed, 2073 insertions(+) create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditor.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditor.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorbool.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorbool.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordate.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordate.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordatetime.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordatetime.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordialog.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordialog.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorhex.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorhex.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditornumeric.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditornumeric.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortext.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortext.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortime.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortime.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorwidget.cpp create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorwidget.h create mode 100644 SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorwidgetplugin.h (limited to 'SQLiteStudio3/guiSQLiteStudio/multieditor') diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditor.cpp b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditor.cpp new file mode 100644 index 0000000..2bae2f9 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditor.cpp @@ -0,0 +1,366 @@ +#include "multieditor.h" +#include "multieditortext.h" +#include "multieditornumeric.h" +#include "multieditordatetime.h" +#include "multieditordate.h" +#include "multieditortime.h" +#include "multieditorbool.h" +#include "multieditorhex.h" +#include "mainwindow.h" +#include "common/unused.h" +#include "services/notifymanager.h" +#include "services/pluginmanager.h" +#include "multieditorwidgetplugin.h" +#include "uiconfig.h" +#include "dialogs/configdialog.h" +#include "formview.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static QHash missingEditorPluginsAlreadyWarned; + +MultiEditor::MultiEditor(QWidget *parent) : + QWidget(parent) +{ + init(); +} + +void MultiEditor::init() +{ + QVBoxLayout* vbox = new QVBoxLayout(); + vbox->setMargin(margins); + vbox->setSpacing(spacing); + setLayout(vbox); + + QWidget* top = new QWidget(); + layout()->addWidget(top); + + QHBoxLayout* hbox = new QHBoxLayout(); + hbox->setMargin(0); + hbox->setSpacing(0); + top->setLayout(hbox); + + nullCheck = new QCheckBox(tr("Null value", "multieditor")); + hbox->addWidget(nullCheck); + + hbox->addStretch(); + + stateLabel = new QLabel(); + hbox->addWidget(stateLabel); + + hbox->addSpacing(50); + + tabs = new QTabWidget(); + layout()->addWidget(tabs); + tabs->tabBar()->installEventFilter(this); + + configBtn = new QToolButton(); + configBtn->setToolTip(tr("Configure editors for this data type")); + configBtn->setIcon(ICONS.CONFIGURE); + configBtn->setFocusPolicy(Qt::NoFocus); + configBtn->setAutoRaise(true); + configBtn->setEnabled(false); + connect(configBtn, SIGNAL(clicked()), this, SLOT(configClicked())); + tabs->setCornerWidget(configBtn); + + QGraphicsColorizeEffect* effect = new QGraphicsColorizeEffect(); + effect->setColor(Qt::black); + effect->setStrength(0.5); + nullEffect = effect; + tabs->setGraphicsEffect(effect); + + connect(tabs, &QTabWidget::currentChanged, this, &MultiEditor::tabChanged); + connect(nullCheck, &QCheckBox::stateChanged, this, &MultiEditor::nullStateChanged); + connect(this, SIGNAL(modified()), this, SLOT(setModified())); +} + +void MultiEditor::tabChanged(int idx) +{ + int prevTab = currentTab; + currentTab = idx; + + MultiEditorWidget* newEditor = editors[idx]; + newEditor->setFocus(); + + if (prevTab < 0) + return; + + if (newEditor->isUpToDate()) + return; + + MultiEditorWidget* prevEditor = editors[prevTab]; + newEditor->setValue(prevEditor->getValue()); + newEditor->setUpToDate(true); +} + +void MultiEditor::nullStateChanged(int state) +{ + bool checked = (state == Qt::Checked); + + if (checked) + valueBeforeNull = getValueOmmitNull(); + + updateNullEffect(); + updateValue(checked ? QVariant() : valueBeforeNull); + + if (!checked) + valueBeforeNull.clear(); + + tabs->setEnabled(!checked); + emit modified(); +} + +void MultiEditor::invalidateValue() +{ + if (invalidatingDisabled) + return; + + QObject* obj = sender(); + if (!obj) + { + qWarning() << "No sender object while invalidating MultiEditor value."; + return; + } + + QWidget* editorWidget = nullptr; + for (int i = 0; i < tabs->count(); i++) + { + editorWidget = tabs->widget(i); + if (editorWidget == obj) + continue; // skip sender + + dynamic_cast(editorWidget)->setUpToDate(false); + } + + emit modified(); +} + +void MultiEditor::setModified() +{ + valueModified = true; +} + +void MultiEditor::addEditor(MultiEditorWidget* editorWidget) +{ + editorWidget->setReadOnly(readOnly); + connect(editorWidget, SIGNAL(valueModified()), this, SLOT(invalidateValue())); + editors << editorWidget; + tabs->addTab(editorWidget, editorWidget->getTabLabel().replace("&", "&&")); + editorWidget->installEventFilter(this); +} + +void MultiEditor::showTab(int idx) +{ + tabs->setCurrentIndex(idx); +} + +void MultiEditor::setValue(const QVariant& value) +{ + nullCheck->setChecked(!value.isValid() || value.isNull()); + valueBeforeNull = value; + updateVisibility(); + updateValue(value); + valueModified = false; +} + +QVariant MultiEditor::getValue() const +{ + if (nullCheck->isChecked()) + return QVariant(); + + return getValueOmmitNull(); +} + +bool MultiEditor::isModified() const +{ + return valueModified; +} + +bool MultiEditor::eventFilter(QObject* obj, QEvent* event) +{ + if (event->type() == QEvent::Wheel) + { + QWidget::event(event); + return true; + } + + return QWidget::eventFilter(obj, event); +} + +bool MultiEditor::getReadOnly() const +{ + return readOnly; +} + +void MultiEditor::setReadOnly(bool value) +{ + readOnly = value; + + for (int i = 0; i < tabs->count(); i++) + dynamic_cast(tabs->widget(i))->setReadOnly(value); + + stateLabel->setVisible(readOnly); + nullCheck->setEnabled(!readOnly); + updateVisibility(); + updateLabel(); +} + +void MultiEditor::setDeletedRow(bool value) +{ + deleted = value; + updateLabel(); +} + +void MultiEditor::setDataType(const DataType& dataType) +{ + this->dataType = dataType; + + foreach (MultiEditorWidget* editorWidget, getEditorTypes(dataType)) + addEditor(editorWidget); + + showTab(0); + configBtn->setEnabled(true); +} + +void MultiEditor::focusThisEditor() +{ + MultiEditorWidget* w = dynamic_cast(tabs->currentWidget()); + if (!w) + return; + + w->focusThisWidget(); +} + +void MultiEditor::loadBuiltInEditors() +{ + PLUGINS->loadBuiltInPlugin(new MultiEditorBoolPlugin); + PLUGINS->loadBuiltInPlugin(new MultiEditorDateTimePlugin); + PLUGINS->loadBuiltInPlugin(new MultiEditorDatePlugin); + PLUGINS->loadBuiltInPlugin(new MultiEditorHexPlugin); + PLUGINS->loadBuiltInPlugin(new MultiEditorTextPlugin); + PLUGINS->loadBuiltInPlugin(new MultiEditorTimePlugin); + PLUGINS->loadBuiltInPlugin(new MultiEditorNumericPlugin); +} + +QList MultiEditor::getEditorTypes(const DataType& dataType) +{ + QList editors; + + QString typeStr = dataType.toString().trimmed().toUpper(); + QHash editorsOrder = CFG_UI.General.DataEditorsOrder.get(); + if (editorsOrder.contains(typeStr)) + { + MultiEditorWidgetPlugin* plugin = nullptr; + for (const QString& editorPluginName : editorsOrder[typeStr].toStringList()) + { + plugin = dynamic_cast(PLUGINS->getLoadedPlugin(editorPluginName)); + if (!plugin) + { + if (!missingEditorPluginsAlreadyWarned.contains(editorPluginName)) + { + notifyWarn(tr("Data editor plugin '%1' not loaded, while it is defined for editing '%1' data type.")); + missingEditorPluginsAlreadyWarned[editorPluginName] = true; + } + continue; + } + + editors << plugin->getInstance(); + } + } + + if (editors.size() > 0) + return editors; + + // + // Prepare default list of editors + // + QList plugins = PLUGINS->getLoadedPlugins(); + + typedef QPair EditorWithPriority; + + QList sortedEditors; + EditorWithPriority editorWithPrio; + for (MultiEditorWidgetPlugin* plugin : plugins) + { + if (!plugin->validFor(dataType)) + continue; + + editorWithPrio.first = plugin->getPriority(dataType); + editorWithPrio.second = plugin->getInstance(); + sortedEditors << editorWithPrio; + } + + qSort(sortedEditors.begin(), sortedEditors.end(), [=](const EditorWithPriority& ed1, const EditorWithPriority& ed2) -> bool + { + return ed1.first < ed2.first; + }); + + for (const EditorWithPriority& e : sortedEditors) + editors << e.second; + + return editors; +} + +void MultiEditor::configClicked() +{ + ConfigDialog config(MAINWINDOW); + config.configureDataEditors(dataType.toString()); + config.exec(); +} + +void MultiEditor::updateVisibility() +{ + tabs->setVisible(!readOnly || !nullCheck->isChecked()); + nullCheck->setVisible(!readOnly || nullCheck->isChecked()); + updateNullEffect(); +} + +void MultiEditor::updateNullEffect() +{ + nullEffect->setEnabled(tabs->isVisible() && nullCheck->isChecked()); + if (tabs->isVisible()) + { + for (int i = 0; i < tabs->count(); i++) + dynamic_cast(tabs->widget(i))->update(); + + nullEffect->update(); + } +} + +void MultiEditor::updateValue(const QVariant& newValue) +{ + invalidatingDisabled = true; + MultiEditorWidget* editorWidget = nullptr; + for (int i = 0; i < tabs->count(); i++) + { + editorWidget = dynamic_cast(tabs->widget(i)); + editorWidget->setValue(newValue); + editorWidget->setUpToDate(true); + } + invalidatingDisabled = false; +} + +void MultiEditor::updateLabel() +{ + if (deleted) + stateLabel->setText(""+tr("Deleted", "multieditor")+""); + else if (readOnly) + stateLabel->setText(""+tr("Read only", "multieditor")+""); + else + stateLabel->setText(""); +} + +QVariant MultiEditor::getValueOmmitNull() const +{ + return dynamic_cast(tabs->currentWidget())->getValue(); +} diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditor.h b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditor.h new file mode 100644 index 0000000..2576c97 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditor.h @@ -0,0 +1,96 @@ +#ifndef MULTIEDITOR_H +#define MULTIEDITOR_H + +#include "guiSQLiteStudio_global.h" +#include "datagrid/sqlquerymodelcolumn.h" +#include +#include + +class QCheckBox; +class QTabWidget; +class MultiEditorWidget; +class QLabel; +class MultiEditorWidgetPlugin; +class QToolButton; + +class GUI_API_EXPORT MultiEditor : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(QVariant value READ getValue WRITE setValue) + + public: + enum BuiltInEditor + { + TEXT, + NUMERIC, + BOOLEAN, + DATE, + TIME, + DATETIME, + HEX + }; + + explicit MultiEditor(QWidget *parent = 0); + + void addEditor(MultiEditorWidget* editorWidget); + void showTab(int idx); + + void setValue(const QVariant& value); + QVariant getValue() const; + bool isModified() const; + bool eventFilter(QObject* obj, QEvent* event); + bool getReadOnly() const; + void setReadOnly(bool value); + void setDeletedRow(bool value); + void setDataType(const DataType& dataType); + void focusThisEditor(); + + static void loadBuiltInEditors(); + + private: + void init(); + void updateVisibility(); + void updateNullEffect(); + void updateValue(const QVariant& newValue); + void updateLabel(); + QVariant getValueOmmitNull() const; + + static QList getEditorTypes(const DataType& dataType); + + static const int margins = 2; + static const int spacing = 2; + + QCheckBox* nullCheck = nullptr; + QTabWidget* tabs = nullptr; + QList editors; + QLabel* stateLabel = nullptr; + bool readOnly = false; + bool deleted = false; + bool invalidatingDisabled = false; + QGraphicsEffect* nullEffect = nullptr; + bool valueModified = false; + QVariant valueBeforeNull; + QToolButton* configBtn = nullptr; + DataType dataType; + + /** + * @brief currentTab + * Hold current tab index. It might seem as duplicate for tabs->currentIndex, + * but this is necessary when we want to know what was the previous tab, + * while being in tabChanged() slot. + */ + int currentTab = -1; + + private slots: + void configClicked(); + void tabChanged(int idx); + void nullStateChanged(int state); + void invalidateValue(); + void setModified(); + + signals: + void modified(); +}; + +#endif // MULTIEDITOR_H diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorbool.cpp b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorbool.cpp new file mode 100644 index 0000000..ed7c260 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorbool.cpp @@ -0,0 +1,215 @@ +#include "multieditorbool.h" +#include +#include +#include + +QStringList MultiEditorBool::validValues; + +MultiEditorBool::MultiEditorBool(QWidget* parent) + : MultiEditorWidget(parent) +{ + setLayout(new QVBoxLayout()); + checkBox = new QCheckBox(); + layout()->addWidget(checkBox); + connect(checkBox, &QCheckBox::stateChanged, this, &MultiEditorBool::stateChanged); +} + +void MultiEditorBool::staticInit() +{ + validValues << "true" << "false" + << "yes" << "no" + << "on" << "off" + << "1" << "0"; +} + +void MultiEditorBool::setValue(const QVariant& value) +{ + switch (value.userType()) + { + case QVariant::Bool: + case QVariant::Int: + case QVariant::LongLong: + case QVariant::UInt: + case QVariant::ULongLong: + boolValue = value.toBool(); + upperCaseValue = false; + valueFormat = BOOL; + break; + default: + boolValue = valueFromString(value.toString()); + break; + } + + updateLabel(); + checkBox->setChecked(boolValue); +} + +bool MultiEditorBool::valueFromString(const QString& strValue) +{ + if (strValue.isEmpty()) + { + upperCaseValue = false; + valueFormat = BOOL; + return false; + } + + int idx = validValues.indexOf(strValue.toLower()); + if (idx < 0) + { + upperCaseValue = false; + valueFormat = BOOL; + return true; + } + + upperCaseValue = strValue[0].isUpper(); + switch (idx) + { + case 0: + case 1: + valueFormat = TRUE_FALSE; + break; + case 2: + case 3: + valueFormat = YES_NO; + break; + case 4: + case 5: + valueFormat = ON_OFF; + break; + case 6: + case 7: + valueFormat = ONE_ZERO; + break; + } + return !(bool)(idx % 2); +} + +QVariant MultiEditorBool::getValue() +{ + QString value; + switch (valueFormat) + { + case MultiEditorBool::TRUE_FALSE: + value = boolValue ? "true" : "false"; + break; + case MultiEditorBool::ON_OFF: + value = boolValue ? "on" : "off"; + break; + case MultiEditorBool::YES_NO: + value = boolValue ? "yes" : "no"; + break; + case MultiEditorBool::ONE_ZERO: + case MultiEditorBool::BOOL: + value = boolValue ? "1" : "0"; + break; + } + + if (value.isNull()) + value = boolValue ? "1" : "0"; + + if (upperCaseValue) + value = value.toUpper(); + + return value; +} + +void MultiEditorBool::setReadOnly(bool value) +{ + readOnly = value; +} + +QList MultiEditorBool::getNoScrollWidgets() +{ + QList list; + list << checkBox; + return list; +} + +QString MultiEditorBool::getTabLabel() +{ + return tr("Boolean"); +} + +void MultiEditorBool::focusThisWidget() +{ + checkBox->setFocus(); +} + +void MultiEditorBool::updateLabel() +{ + checkBox->setText(getValue().toString()); +} + +void MultiEditorBool::stateChanged(int state) +{ + if (readOnly && ((bool)state) != boolValue) + { + checkBox->setChecked(boolValue); + return; + } + + boolValue = checkBox->isChecked(); + updateLabel(); + emit valueModified(); +} + +MultiEditorWidget* MultiEditorBoolPlugin::getInstance() +{ + return new MultiEditorBool(); +} + +bool MultiEditorBoolPlugin::validFor(const DataType& dataType) +{ + switch (dataType.getType()) + { + case DataType::BOOLEAN: + return true; + case DataType::BLOB: + case DataType::BIGINT: + case DataType::DECIMAL: + case DataType::DOUBLE: + case DataType::INTEGER: + case DataType::INT: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::NONE: + case DataType::STRING: + case DataType::TEXT: + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::DATE: + case DataType::DATETIME: + case DataType::TIME: + case DataType::unknown: + break; + } + return false; +} + +int MultiEditorBoolPlugin::getPriority(const DataType& dataType) +{ + switch (dataType.getType()) + { + case DataType::BOOLEAN: + return 1; + case DataType::BLOB: + case DataType::BIGINT: + case DataType::DECIMAL: + case DataType::DOUBLE: + case DataType::INTEGER: + case DataType::INT: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::NONE: + case DataType::STRING: + case DataType::TEXT: + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::DATE: + case DataType::DATETIME: + case DataType::TIME: + case DataType::unknown: + break; + } + return 100; +} diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorbool.h b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorbool.h new file mode 100644 index 0000000..f328cf0 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorbool.h @@ -0,0 +1,68 @@ +#ifndef MULTIEDITORBOOL_H +#define MULTIEDITORBOOL_H + +#include "guiSQLiteStudio_global.h" +#include "multieditorwidget.h" +#include "multieditorwidgetplugin.h" +#include "plugins/builtinplugin.h" +#include + +class QCheckBox; + +class GUI_API_EXPORT MultiEditorBool : public MultiEditorWidget +{ + Q_OBJECT + + public: + explicit MultiEditorBool(QWidget* parent = 0); + + static void staticInit(); + + void setValue(const QVariant& boolValue); + QVariant getValue(); + void setReadOnly(bool boolValue); + QList getNoScrollWidgets(); + QString getTabLabel(); + void focusThisWidget(); + + private: + enum Format + { + TRUE_FALSE, + ON_OFF, + YES_NO, + ONE_ZERO, + BOOL + }; + + bool valueFromString(const QString& strValue); + void updateLabel(); + + static QStringList validValues; + + QCheckBox* checkBox = nullptr; + Format valueFormat = ONE_ZERO; + bool upperCaseValue = false; + bool readOnly = false; + bool boolValue = false; + + private slots: + void stateChanged(int state); +}; + +class GUI_API_EXPORT MultiEditorBoolPlugin : public BuiltInPlugin, public MultiEditorWidgetPlugin +{ + Q_OBJECT + + SQLITESTUDIO_PLUGIN_AUTHOR("sqlitestudio.pl") + SQLITESTUDIO_PLUGIN_DESC("Boolean data editor.") + SQLITESTUDIO_PLUGIN_TITLE("Boolean") + SQLITESTUDIO_PLUGIN_VERSION(10000) + + public: + MultiEditorWidget* getInstance(); + bool validFor(const DataType& dataType); + int getPriority(const DataType& dataType); +}; + +#endif // MULTIEDITORBOOL_H diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordate.cpp b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordate.cpp new file mode 100644 index 0000000..44178f8 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordate.cpp @@ -0,0 +1,87 @@ +#include "multieditordate.h" +#include + +QStringList MultiEditorDate::formats; + +MultiEditorDate::MultiEditorDate(QWidget* parent) + : MultiEditorDateTime(parent) +{ + setDisplayFormat(formats.first()); +} + +QString MultiEditorDate::getTabLabel() +{ + return tr("Date"); +} + +void MultiEditorDate::staticInit() +{ + formats << "yyyy-MM-dd"; +} + +QStringList MultiEditorDate::getParsingFormats() +{ + return MultiEditorDateTime::getParsingFormats(); +} + + +MultiEditorWidget*MultiEditorDatePlugin::getInstance() +{ + return new MultiEditorDate(); +} + +bool MultiEditorDatePlugin::validFor(const DataType& dataType) +{ + switch (dataType.getType()) + { + case DataType::BLOB: + case DataType::BOOLEAN: + case DataType::BIGINT: + case DataType::DECIMAL: + case DataType::DOUBLE: + case DataType::INTEGER: + case DataType::INT: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::NONE: + case DataType::STRING: + case DataType::TEXT: + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::DATETIME: + case DataType::TIME: + case DataType::unknown: + break; + case DataType::DATE: + return true; + } + return false; +} + +int MultiEditorDatePlugin::getPriority(const DataType& dataType) +{ + switch (dataType.getType()) + { + case DataType::BLOB: + case DataType::BOOLEAN: + case DataType::BIGINT: + case DataType::DECIMAL: + case DataType::DOUBLE: + case DataType::INTEGER: + case DataType::INT: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::NONE: + case DataType::STRING: + case DataType::TEXT: + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::TIME: + case DataType::DATETIME: + case DataType::unknown: + break; + case DataType::DATE: + return 1; + } + return 10; +} diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordate.h b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordate.h new file mode 100644 index 0000000..b6f6d7c --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordate.h @@ -0,0 +1,37 @@ +#ifndef MULTIEDITORDATE_H +#define MULTIEDITORDATE_H + +#include "multieditordatetime.h" + +class GUI_API_EXPORT MultiEditorDate : public MultiEditorDateTime +{ + public: + explicit MultiEditorDate(QWidget *parent = 0); + + QString getTabLabel(); + + static void staticInit(); + + protected: + QStringList getParsingFormats(); + + private: + static QStringList formats; +}; + +class GUI_API_EXPORT MultiEditorDatePlugin : public BuiltInPlugin, public MultiEditorWidgetPlugin +{ + Q_OBJECT + + SQLITESTUDIO_PLUGIN_AUTHOR("sqlitestudio.pl") + SQLITESTUDIO_PLUGIN_DESC("Date data editor.") + SQLITESTUDIO_PLUGIN_TITLE("Date") + SQLITESTUDIO_PLUGIN_VERSION(10000) + + public: + MultiEditorWidget* getInstance(); + bool validFor(const DataType& dataType); + int getPriority(const DataType& dataType); +}; + +#endif // MULTIEDITORDATE_H diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordatetime.cpp b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordatetime.cpp new file mode 100644 index 0000000..bd1e244 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordatetime.cpp @@ -0,0 +1,275 @@ +#include "multieditordatetime.h" +#include "common/utils.h" +#include "common/unused.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QStringList MultiEditorDateTime::formats; + +MultiEditorDateTime::MultiEditorDateTime(QWidget *parent) : + MultiEditorWidget(parent) +{ + QVBoxLayout* vbox = new QVBoxLayout(); + setLayout(vbox); + dateTimeEdit = new QDateTimeEdit(); + dateTimeLabel = new QLabel(); + calendar = new QCalendarWidget(); + // Extending width, becuase day labels are truncated on some systems. + calendar->setFixedSize(calendar->sizeHint() + QSize(80, 0)); + + vbox->addWidget(dateTimeEdit); + vbox->addWidget(dateTimeLabel); + vbox->addWidget(calendar); + + setDisplayFormat(formats.first()); + + connect(calendar, &QCalendarWidget::selectionChanged, this, &MultiEditorDateTime::calendarDateChanged); + connect(dateTimeEdit, &QDateTimeEdit::dateChanged, this, &MultiEditorDateTime::dateChanged); + connect(dateTimeEdit, &QDateTimeEdit::timeChanged, this, &MultiEditorDateTime::timeChanged); + + setFocusProxy(dateTimeEdit); + updateCalendarDisplay(); +} + +void MultiEditorDateTime::staticInit() +{ + formats << "yyyy-MM-dd hh:mm:ss" + << "yyyy-MM-dd hh:mm" + << "yyyy-MM-dd" + << "yyyy-MM-dd hh:mm:ss.z" + << "yyyy-MM-ddThh:mm" + << "yyyy-MM-ddThh:mm:ss" + << "yyyy-MM-ddThh:mm:ss.z"; +} + +void MultiEditorDateTime::setDisplayFormat(const QString& format) +{ + dateTimeEdit->setDisplayFormat(format); + dateTimeEdit->setMaximumWidth(dateTimeEdit->sizeHint().width()); +} + +void MultiEditorDateTime::setValue(const QVariant& value) +{ + switch (value.userType()) + { + case QVariant::DateTime: + dateTimeEdit->setDateTime(value.toDateTime()); + break; + case QVariant::Date: + dateTimeEdit->setDate(value.toDate()); + break; + default: + { + dateTimeEdit->setDateTime(fromString(value.toString())); + break; + } + } + updateReadOnlyDisplay(); +} + +QVariant MultiEditorDateTime::getValue() +{ + if (formatType == STRING) + return dateTimeEdit->dateTime().toString(originalValueFormat); + else if (formatType == UNIXTIME) + return dateTimeEdit->dateTime().toTime_t(); + else if (formatType == JULIAN_DAY) + return toJulian(dateTimeEdit->dateTime()); + else + return dateTimeEdit->dateTime().toString(dateTimeEdit->displayFormat()); +} + +QList MultiEditorDateTime::getNoScrollWidgets() +{ + QList list; + list << dateTimeEdit << calendar; + + QObject* obj = calendar->findChild("qt_calendar_calendarview"); + if (obj) + { + QTableView* view = dynamic_cast(obj); + if (view) + list << view->viewport(); + } + + return list; +} + +QDateTime MultiEditorDateTime::fromString(const QString& value) +{ + QDateTime dateTime; + foreach (const QString& format, getParsingFormats()) + { + dateTime = QDateTime::fromString(value, format); + if (dateTime.isValid()) + { + formatType = STRING; + originalValueFormat = format; + return dateTime; + } + } + + // Try with unixtime + bool ok; + uint unixtime = value.toUInt(&ok); + if (ok) + { + dateTime = QDateTime::fromTime_t(unixtime); + formatType = UNIXTIME; + return dateTime; + } + + // Try with Julian day + double jd = value.toDouble(&ok); + if (ok) + { + dateTime = toGregorian(jd); + formatType = JULIAN_DAY; + return dateTime; + } + + formatType = OTHER; + return QDateTime(); +} + +void MultiEditorDateTime::calendarDateChanged() +{ + if (updatingCalendar) + return; + + dateTimeEdit->setDate(calendar->selectedDate()); + emit valueModified(); +} + +void MultiEditorDateTime::dateChanged(const QDate& date) +{ + updatingCalendar = true; + calendar->setSelectedDate(date); + updatingCalendar = false; + emit valueModified(); +} + +void MultiEditorDateTime::timeChanged(const QTime& time) +{ + UNUSED(time); + emit valueModified(); +} + +bool MultiEditorDateTime::getReadOnly() const +{ + return readOnly; +} + +void MultiEditorDateTime::setReadOnly(bool value) +{ + readOnly = value; + dateTimeEdit->setVisible(!readOnly); + dateTimeLabel->setVisible(readOnly); + updateReadOnlyDisplay(); +} + +QString MultiEditorDateTime::getTabLabel() +{ + return tr("Date & time"); +} + +void MultiEditorDateTime::focusThisWidget() +{ + dateTimeEdit->setFocus(); +} + +QStringList MultiEditorDateTime::getParsingFormats() +{ + return formats; +} + +void MultiEditorDateTime::updateReadOnlyDisplay() +{ + if (!readOnly) + return; + + dateTimeLabel->setText(getValue().toString()); + QDate date = dateTimeEdit->date(); + calendar->setMinimumDate(date); + calendar->setMaximumDate(date); + calendar->setSelectedDate(date); +} + +void MultiEditorDateTime::updateCalendarDisplay() +{ + if (!showCalendars) + { + calendar->setVisible(false); + return; + } +} + +MultiEditorWidget*MultiEditorDateTimePlugin::getInstance() +{ + return new MultiEditorDateTime(); +} + +bool MultiEditorDateTimePlugin::validFor(const DataType& dataType) +{ + switch (dataType.getType()) + { + case DataType::BLOB: + case DataType::BOOLEAN: + case DataType::BIGINT: + case DataType::DECIMAL: + case DataType::DOUBLE: + case DataType::INTEGER: + case DataType::INT: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::NONE: + case DataType::STRING: + case DataType::TEXT: + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::TIME: + case DataType::unknown: + break; + case DataType::DATE: + case DataType::DATETIME: + return true; + } + return false; +} + +int MultiEditorDateTimePlugin::getPriority(const DataType& dataType) +{ + switch (dataType.getType()) + { + case DataType::BLOB: + case DataType::BOOLEAN: + case DataType::BIGINT: + case DataType::DECIMAL: + case DataType::DOUBLE: + case DataType::INTEGER: + case DataType::INT: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::NONE: + case DataType::STRING: + case DataType::TEXT: + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::TIME: + case DataType::unknown: + break; + case DataType::DATE: + return 2; + case DataType::DATETIME: + return 1; + } + return 10; +} diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordatetime.h b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordatetime.h new file mode 100644 index 0000000..59bd111 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordatetime.h @@ -0,0 +1,84 @@ +#ifndef MULTIEDITORDATETIME_H +#define MULTIEDITORDATETIME_H + +#include "multieditorwidget.h" +#include "multieditorwidgetplugin.h" +#include "plugins/builtinplugin.h" +#include +#include + +class QCalendarWidget; +class QDateTimeEdit; +class QLabel; + +class GUI_API_EXPORT MultiEditorDateTime : public MultiEditorWidget +{ + Q_OBJECT + public: + explicit MultiEditorDateTime(QWidget *parent = 0); + + static void staticInit(); + + void setValue(const QVariant& value); + QVariant getValue(); + bool needsValueUpdate(); + + QList getNoScrollWidgets(); + + bool getReadOnly() const; + void setReadOnly(bool value); + QString getTabLabel(); + void focusThisWidget(); + + protected: + void updateCalendarDisplay(); + void setDisplayFormat(const QString& format); + + virtual QStringList getParsingFormats(); + + QDateTimeEdit* dateTimeEdit = nullptr; + bool showCalendars = true; + + private: + enum FormatType + { + STRING, + JULIAN_DAY, + UNIXTIME, + OTHER + }; + + void updateReadOnlyDisplay(); + QDateTime fromString(const QString& value); + + static QStringList formats; + + QLabel* dateTimeLabel = nullptr; + QCalendarWidget* calendar = nullptr; + QString originalValueFormat; + FormatType formatType; + bool updatingCalendar = false; + bool readOnly = false; + + private slots: + void calendarDateChanged(); + void dateChanged(const QDate& date); + void timeChanged(const QTime& time); +}; + +class GUI_API_EXPORT MultiEditorDateTimePlugin : public BuiltInPlugin, public MultiEditorWidgetPlugin +{ + Q_OBJECT + + SQLITESTUDIO_PLUGIN_AUTHOR("sqlitestudio.pl") + SQLITESTUDIO_PLUGIN_DESC("Date and time data editor.") + SQLITESTUDIO_PLUGIN_TITLE("Date and time") + SQLITESTUDIO_PLUGIN_VERSION(10000) + + public: + MultiEditorWidget* getInstance(); + bool validFor(const DataType& dataType); + int getPriority(const DataType& dataType); +}; + +#endif // MULTIEDITORDATETIME_H diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordialog.cpp b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordialog.cpp new file mode 100644 index 0000000..5e3985c --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordialog.cpp @@ -0,0 +1,49 @@ +#include "multieditordialog.h" +#include "multieditor.h" +#include +#include + +MultiEditorDialog::MultiEditorDialog(QWidget *parent) : + QDialog(parent) +{ + multiEditor = new MultiEditor(); + + QVBoxLayout* vbox = new QVBoxLayout(); + vbox->addWidget(multiEditor); + setLayout(vbox); + + multiEditor->setReadOnly(false); + + buttonBox = new QDialogButtonBox(Qt::Horizontal); + buttonBox->addButton(QDialogButtonBox::Ok); + buttonBox->addButton(QDialogButtonBox::Cancel); + vbox->addWidget(buttonBox); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); +} + +MultiEditorDialog::~MultiEditorDialog() +{ + delete multiEditor; +} + +void MultiEditorDialog::setValue(const QVariant& value) +{ + multiEditor->setValue(value); +} + +QVariant MultiEditorDialog::getValue() +{ + return multiEditor->getValue(); +} + +void MultiEditorDialog::setDataType(const DataType& dataType) +{ + multiEditor->setDataType(dataType); +} + +void MultiEditorDialog::setReadOnly(bool readOnly) +{ + multiEditor->setReadOnly(readOnly); +} diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordialog.h b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordialog.h new file mode 100644 index 0000000..ffbbd9c --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditordialog.h @@ -0,0 +1,29 @@ +#ifndef MULTIEDITORDIALOG_H +#define MULTIEDITORDIALOG_H + +#include "datagrid/sqlquerymodelcolumn.h" +#include "guiSQLiteStudio_global.h" +#include + +class MultiEditor; +class QDialogButtonBox; + +class GUI_API_EXPORT MultiEditorDialog : public QDialog +{ + Q_OBJECT + public: + explicit MultiEditorDialog(QWidget *parent = 0); + ~MultiEditorDialog(); + + void setValue(const QVariant& value); + QVariant getValue(); + + void setDataType(const DataType& dataType); + void setReadOnly(bool readOnly); + + private: + MultiEditor* multiEditor = nullptr; + QDialogButtonBox* buttonBox = nullptr; +}; + +#endif // MULTIEDITORDIALOG_H diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorhex.cpp b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorhex.cpp new file mode 100644 index 0000000..5a3cd28 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorhex.cpp @@ -0,0 +1,94 @@ +#include "multieditorhex.h" +#include "qhexedit2/qhexedit.h" +#include "common/unused.h" +#include + +MultiEditorHex::MultiEditorHex() +{ + setLayout(new QVBoxLayout()); + hexEdit = new QHexEdit(); + layout()->addWidget(hexEdit); + + //hexEdit->setTabChangesFocus(true); + + connect(hexEdit, SIGNAL(dataChanged()), this, SLOT(modificationChanged())); + setFocusProxy(hexEdit); +} + +MultiEditorHex::~MultiEditorHex() +{ +} + +void MultiEditorHex::setValue(const QVariant& value) +{ + hexEdit->setData(value.toByteArray()); +} + +QVariant MultiEditorHex::getValue() +{ + return hexEdit->data(); +} + +void MultiEditorHex::setReadOnly(bool value) +{ + hexEdit->setReadOnly(value); +} + +QString MultiEditorHex::getTabLabel() +{ + return tr("Hex"); +} + +void MultiEditorHex::focusThisWidget() +{ + hexEdit->setFocus(); +} + +QList MultiEditorHex::getNoScrollWidgets() +{ + return QList(); +} + +void MultiEditorHex::modificationChanged() +{ + emit valueModified(); +} + +MultiEditorWidget*MultiEditorHexPlugin::getInstance() +{ + return new MultiEditorHex(); +} + +bool MultiEditorHexPlugin::validFor(const DataType& dataType) +{ + UNUSED(dataType); + return true; +} + +int MultiEditorHexPlugin::getPriority(const DataType& dataType) +{ + switch (dataType.getType()) + { + case DataType::BLOB: + return 1; + case DataType::BIGINT: + case DataType::DECIMAL: + case DataType::DOUBLE: + case DataType::INTEGER: + case DataType::INT: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::BOOLEAN: + case DataType::NONE: + case DataType::STRING: + case DataType::TEXT: + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::DATE: + case DataType::DATETIME: + case DataType::TIME: + case DataType::unknown: + break; + } + return 100; +} diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorhex.h b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorhex.h new file mode 100644 index 0000000..5fd32a0 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorhex.h @@ -0,0 +1,50 @@ +#ifndef MULTIEDITORHEX_H +#define MULTIEDITORHEX_H + +#include "multieditorwidget.h" +#include "multieditorwidgetplugin.h" +#include "plugins/builtinplugin.h" +#include +#include + +class QHexEdit; +class QBuffer; + +class GUI_API_EXPORT MultiEditorHex : public MultiEditorWidget +{ + Q_OBJECT + public: + explicit MultiEditorHex(); + ~MultiEditorHex(); + + void setValue(const QVariant& value); + QVariant getValue(); + void setReadOnly(bool value); + QString getTabLabel(); + void focusThisWidget(); + + QList getNoScrollWidgets(); + + private: + QHexEdit* hexEdit = nullptr; + + private slots: + void modificationChanged(); +}; + +class GUI_API_EXPORT MultiEditorHexPlugin : public BuiltInPlugin, public MultiEditorWidgetPlugin +{ + Q_OBJECT + + SQLITESTUDIO_PLUGIN_AUTHOR("sqlitestudio.pl") + SQLITESTUDIO_PLUGIN_DESC("Hexadecimal data editor.") + SQLITESTUDIO_PLUGIN_TITLE("Hexadecimal") + SQLITESTUDIO_PLUGIN_VERSION(10000) + + public: + MultiEditorWidget* getInstance(); + bool validFor(const DataType& dataType); + int getPriority(const DataType& dataType); +}; + +#endif // MULTIEDITORHEX_H diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditornumeric.cpp b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditornumeric.cpp new file mode 100644 index 0000000..198f71b --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditornumeric.cpp @@ -0,0 +1,109 @@ +#include "multieditornumeric.h" +#include "common/numericspinbox.h" +#include +#include + +MultiEditorNumeric::MultiEditorNumeric(QWidget* parent) + : MultiEditorWidget(parent) +{ + setLayout(new QVBoxLayout()); + spinBox = new NumericSpinBox(); + layout()->addWidget(spinBox); + + connect(spinBox, SIGNAL(modified()), this, SIGNAL(valueModified())); + + setFocusProxy(spinBox); +} + +void MultiEditorNumeric::setValue(const QVariant& value) +{ + spinBox->setValue(value); +} + +QVariant MultiEditorNumeric::getValue() +{ + return spinBox->getValue(); +} + +void MultiEditorNumeric::setReadOnly(bool value) +{ + spinBox->setReadOnly(value); +} + +QString MultiEditorNumeric::getTabLabel() +{ + return tr("Number"); +} + +void MultiEditorNumeric::focusThisWidget() +{ + spinBox->setFocus(); +} + +QList MultiEditorNumeric::getNoScrollWidgets() +{ + QList list; + list << spinBox; + return list; +} + +MultiEditorWidget*MultiEditorNumericPlugin::getInstance() +{ + return new MultiEditorNumeric(); +} + +bool MultiEditorNumericPlugin::validFor(const DataType& dataType) +{ + switch (dataType.getType()) + { + case DataType::BIGINT: + case DataType::DECIMAL: + case DataType::DOUBLE: + case DataType::INTEGER: + case DataType::INT: + case DataType::NUMERIC: + case DataType::REAL: + return true; + case DataType::BOOLEAN: + case DataType::BLOB: + case DataType::NONE: + case DataType::STRING: + case DataType::TEXT: + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::DATE: + case DataType::DATETIME: + case DataType::TIME: + case DataType::unknown: + break; + } + return false; +} + +int MultiEditorNumericPlugin::getPriority(const DataType& dataType) +{ + switch (dataType.getType()) + { + case DataType::BIGINT: + case DataType::DECIMAL: + case DataType::DOUBLE: + case DataType::INTEGER: + case DataType::INT: + case DataType::NUMERIC: + case DataType::REAL: + return 1; + case DataType::BOOLEAN: + case DataType::BLOB: + case DataType::NONE: + case DataType::STRING: + case DataType::TEXT: + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::DATE: + case DataType::DATETIME: + case DataType::TIME: + case DataType::unknown: + break; + } + return 10; +} diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditornumeric.h b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditornumeric.h new file mode 100644 index 0000000..65d0409 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditornumeric.h @@ -0,0 +1,42 @@ +#ifndef MULTIEDITORNUMERIC_H +#define MULTIEDITORNUMERIC_H + +#include "multieditorwidget.h" +#include "multieditorwidgetplugin.h" +#include "plugins/builtinplugin.h" + +class NumericSpinBox; + +class GUI_API_EXPORT MultiEditorNumeric : public MultiEditorWidget +{ + public: + explicit MultiEditorNumeric(QWidget *parent = 0); + + void setValue(const QVariant& value); + QVariant getValue(); + void setReadOnly(bool value); + QString getTabLabel(); + void focusThisWidget(); + + QList getNoScrollWidgets(); + + private: + NumericSpinBox* spinBox = nullptr; +}; + +class GUI_API_EXPORT MultiEditorNumericPlugin : public BuiltInPlugin, public MultiEditorWidgetPlugin +{ + Q_OBJECT + + SQLITESTUDIO_PLUGIN_AUTHOR("sqlitestudio.pl") + SQLITESTUDIO_PLUGIN_DESC("Numeric data editor.") + SQLITESTUDIO_PLUGIN_TITLE("Numeric types") + SQLITESTUDIO_PLUGIN_VERSION(10000) + + public: + MultiEditorWidget* getInstance(); + bool validFor(const DataType& dataType); + int getPriority(const DataType& dataType); +}; + +#endif // MULTIEDITORNUMERIC_H diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortext.cpp b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortext.cpp new file mode 100644 index 0000000..05db8e0 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortext.cpp @@ -0,0 +1,184 @@ +#include "multieditortext.h" +#include "common/unused.h" +#include +#include +#include +#include +#include + +CFG_KEYS_DEFINE(MultiEditorText) + +MultiEditorText::MultiEditorText(QWidget *parent) : + MultiEditorWidget(parent) +{ + setLayout(new QVBoxLayout()); + textEdit = new QPlainTextEdit(); + layout()->addWidget(textEdit); + initActions(); + setupMenu(); + + setFocusProxy(textEdit); + textEdit->setContextMenuPolicy(Qt::CustomContextMenu); + textEdit->setTabChangesFocus(true); + + connect(textEdit, &QPlainTextEdit::modificationChanged, this, &MultiEditorText::modificationChanged); + connect(textEdit, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showCustomMenu(QPoint))); +} + +void MultiEditorText::setValue(const QVariant& value) +{ + textEdit->setPlainText(value.toString()); +} + +QVariant MultiEditorText::getValue() +{ + return textEdit->toPlainText(); +} + +void MultiEditorText::setReadOnly(bool value) +{ + textEdit->setReadOnly(value); +} + +QString MultiEditorText::getTabLabel() +{ + return tr("Text"); +} + +QToolBar* MultiEditorText::getToolBar(int toolbar) const +{ + UNUSED(toolbar); + return nullptr; +} + +void MultiEditorText::focusThisWidget() +{ + textEdit->setFocus(); +} + +QList MultiEditorText::getNoScrollWidgets() +{ + // We don't return text, we want it to be scrolled. + QList list; + return list; +} + +void MultiEditorText::modificationChanged(bool changed) +{ + if (changed) + emit valueModified(); +} + +void MultiEditorText::deleteSelected() +{ + textEdit->textCursor().removeSelectedText(); +} + +void MultiEditorText::showCustomMenu(const QPoint& point) +{ + contextMenu->popup(textEdit->mapToGlobal(point)); +} + +void MultiEditorText::updateUndoAction(bool enabled) +{ + actionMap[UNDO]->setEnabled(enabled); +} + +void MultiEditorText::updateRedoAction(bool enabled) +{ + actionMap[REDO]->setEnabled(enabled); +} + +void MultiEditorText::updateCopyAction(bool enabled) +{ + actionMap[CUT]->setEnabled(enabled); + actionMap[COPY]->setEnabled(enabled); + actionMap[DELETE]->setEnabled(enabled); +} + +void MultiEditorText::toggleTabFocus() +{ + textEdit->setTabChangesFocus(actionMap[TAB_CHANGES_FOCUS]->isChecked()); +} + +void MultiEditorText::createActions() +{ + createAction(TAB_CHANGES_FOCUS, tr("Tab changes focus"), this, SLOT(toggleTabFocus()), this); + createAction(CUT, ICONS.ACT_CUT, tr("Cut"), textEdit, SLOT(cut()), this); + createAction(COPY, ICONS.ACT_COPY, tr("Copy"), textEdit, SLOT(copy()), this); + createAction(PASTE, ICONS.ACT_PASTE, tr("Paste"), textEdit, SLOT(paste()), this); + createAction(DELETE, ICONS.ACT_DELETE, tr("Delete"), this, SLOT(deleteSelected()), this); + createAction(UNDO, ICONS.ACT_UNDO, tr("Undo"), textEdit, SLOT(undo()), this); + createAction(REDO, ICONS.ACT_REDO, tr("Redo"), textEdit, SLOT(redo()), this); + + actionMap[CUT]->setEnabled(false); + actionMap[COPY]->setEnabled(false); + actionMap[DELETE]->setEnabled(false); + actionMap[UNDO]->setEnabled(false); + actionMap[REDO]->setEnabled(false); + + actionMap[TAB_CHANGES_FOCUS]->setCheckable(true); + actionMap[TAB_CHANGES_FOCUS]->setChecked(true); + + connect(textEdit, &QPlainTextEdit::undoAvailable, this, &MultiEditorText::updateUndoAction); + connect(textEdit, &QPlainTextEdit::redoAvailable, this, &MultiEditorText::updateRedoAction); + connect(textEdit, &QPlainTextEdit::copyAvailable, this, &MultiEditorText::updateCopyAction); +} + +void MultiEditorText::setupDefShortcuts() +{ + BIND_SHORTCUTS(MultiEditorText, Action); +} + +void MultiEditorText::setupMenu() +{ + contextMenu = new QMenu(this); + contextMenu->addAction(actionMap[TAB_CHANGES_FOCUS]); + contextMenu->addSeparator(); + contextMenu->addAction(actionMap[UNDO]); + contextMenu->addAction(actionMap[REDO]); + contextMenu->addSeparator(); + contextMenu->addAction(actionMap[CUT]); + contextMenu->addAction(actionMap[COPY]); + contextMenu->addAction(actionMap[PASTE]); + contextMenu->addAction(actionMap[DELETE]); +} + +MultiEditorWidget* MultiEditorTextPlugin::getInstance() +{ + return new MultiEditorText(); +} + +bool MultiEditorTextPlugin::validFor(const DataType& dataType) +{ + UNUSED(dataType); + return true; +} + +int MultiEditorTextPlugin::getPriority(const DataType& dataType) +{ + switch (dataType.getType()) + { + case DataType::BLOB: + case DataType::BOOLEAN: + case DataType::BIGINT: + case DataType::DECIMAL: + case DataType::DOUBLE: + case DataType::INTEGER: + case DataType::INT: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::DATE: + case DataType::DATETIME: + case DataType::TIME: + return 10; + case DataType::NONE: + case DataType::STRING: + case DataType::TEXT: + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::unknown: + break; + } + return 1; +} diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortext.h b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortext.h new file mode 100644 index 0000000..bd814ce --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortext.h @@ -0,0 +1,87 @@ +#ifndef MULTIEDITORTEXT_H +#define MULTIEDITORTEXT_H + +#include "multieditorwidget.h" +#include "multieditorwidgetplugin.h" +#include "common/extactioncontainer.h" +#include "plugins/builtinplugin.h" + +class QPlainTextEdit; +class QMenu; + +CFG_KEY_LIST(MultiEditorText, QObject::tr("Cell text value editor"), + CFG_KEY_ENTRY(CUT, QKeySequence::Cut, QObject::tr("Cut selected text")) + CFG_KEY_ENTRY(COPY, QKeySequence::Copy, QObject::tr("Copy selected text")) + CFG_KEY_ENTRY(PASTE, QKeySequence::Paste, QObject::tr("Paste from clipboard")) + CFG_KEY_ENTRY(DELETE, QKeySequence::Delete, QObject::tr("Delete selected text")) + CFG_KEY_ENTRY(UNDO, QKeySequence::Undo, QObject::tr("Undo")) + CFG_KEY_ENTRY(REDO, QKeySequence::Redo, QObject::tr("Redo")) +) + +class GUI_API_EXPORT MultiEditorText : public MultiEditorWidget, public ExtActionContainer +{ + Q_OBJECT + Q_ENUMS(Action) + + public: + enum Action + { + TAB_CHANGES_FOCUS, + CUT, + COPY, + PASTE, + DELETE, + UNDO, + REDO + }; + + enum ToolBar + { + }; + + explicit MultiEditorText(QWidget *parent = 0); + + void setValue(const QVariant& value); + QVariant getValue(); + void setReadOnly(bool value); + QString getTabLabel(); + QToolBar* getToolBar(int toolbar) const; + void focusThisWidget(); + QList getNoScrollWidgets(); + + protected: + void createActions(); + void setupDefShortcuts(); + + private: + void setupMenu(); + + QPlainTextEdit* textEdit = nullptr; + QMenu* contextMenu = nullptr; + + private slots: + void modificationChanged(bool changed); + void deleteSelected(); + void showCustomMenu(const QPoint& point); + void updateUndoAction(bool enabled); + void updateRedoAction(bool enabled); + void updateCopyAction(bool enabled); + void toggleTabFocus(); +}; + +class GUI_API_EXPORT MultiEditorTextPlugin : public BuiltInPlugin, public MultiEditorWidgetPlugin +{ + Q_OBJECT + + SQLITESTUDIO_PLUGIN_AUTHOR("sqlitestudio.pl") + SQLITESTUDIO_PLUGIN_DESC("Standard text data editor.") + SQLITESTUDIO_PLUGIN_TITLE("Text") + SQLITESTUDIO_PLUGIN_VERSION(10000) + + public: + MultiEditorWidget* getInstance(); + bool validFor(const DataType& dataType); + int getPriority(const DataType& dataType); +}; + +#endif // MULTIEDITORTEXT_H diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortime.cpp b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortime.cpp new file mode 100644 index 0000000..8b49715 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortime.cpp @@ -0,0 +1,90 @@ +#include "multieditortime.h" +#include + +QStringList MultiEditorTime::formats; + +MultiEditorTime::MultiEditorTime(QWidget *parent) + : MultiEditorDateTime(parent) +{ + showCalendars = false; + updateCalendarDisplay(); + setDisplayFormat(formats.first()); +} + +QString MultiEditorTime::getTabLabel() +{ + return tr("Time"); +} + +void MultiEditorTime::staticInit() +{ + formats << "hh:mm:ss" + << "hh:mm:ss.zzz" + << "hh:mm"; +} + +QStringList MultiEditorTime::getParsingFormats() +{ + return formats; +} + +MultiEditorWidget*MultiEditorTimePlugin::getInstance() +{ + return new MultiEditorTime(); +} + +bool MultiEditorTimePlugin::validFor(const DataType& dataType) +{ + switch (dataType.getType()) + { + case DataType::BLOB: + case DataType::BOOLEAN: + case DataType::BIGINT: + case DataType::DECIMAL: + case DataType::DOUBLE: + case DataType::INTEGER: + case DataType::INT: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::NONE: + case DataType::STRING: + case DataType::TEXT: + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::DATE: + case DataType::DATETIME: + case DataType::unknown: + break; + case DataType::TIME: + return true; + } + return false; +} + +int MultiEditorTimePlugin::getPriority(const DataType& dataType) +{ + switch (dataType.getType()) + { + case DataType::BLOB: + case DataType::BOOLEAN: + case DataType::BIGINT: + case DataType::DECIMAL: + case DataType::DOUBLE: + case DataType::INTEGER: + case DataType::INT: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::NONE: + case DataType::STRING: + case DataType::TEXT: + case DataType::CHAR: + case DataType::VARCHAR: + case DataType::DATE: + case DataType::DATETIME: + case DataType::unknown: + break; + case DataType::TIME: + return 1; + } + return 10; +} diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortime.h b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortime.h new file mode 100644 index 0000000..56bf60e --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditortime.h @@ -0,0 +1,38 @@ +#ifndef MULTIEDITORTIME_H +#define MULTIEDITORTIME_H + +#include "multieditordatetime.h" +#include "guiSQLiteStudio_global.h" + +class GUI_API_EXPORT MultiEditorTime : public MultiEditorDateTime +{ + public: + explicit MultiEditorTime(QWidget *parent = 0); + + QString getTabLabel(); + + static void staticInit(); + + protected: + QStringList getParsingFormats(); + + private: + static QStringList formats; +}; + +class GUI_API_EXPORT MultiEditorTimePlugin : public BuiltInPlugin, public MultiEditorWidgetPlugin +{ + Q_OBJECT + + SQLITESTUDIO_PLUGIN_AUTHOR("sqlitestudio.pl") + SQLITESTUDIO_PLUGIN_DESC("Time data editor.") + SQLITESTUDIO_PLUGIN_TITLE("Time") + SQLITESTUDIO_PLUGIN_VERSION(10000) + + public: + MultiEditorWidget* getInstance(); + bool validFor(const DataType& dataType); + int getPriority(const DataType& dataType); +}; + +#endif // MULTIEDITORTIME_H diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorwidget.cpp b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorwidget.cpp new file mode 100644 index 0000000..caea9a5 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorwidget.cpp @@ -0,0 +1,23 @@ +#include "multieditorwidget.h" + +MultiEditorWidget::MultiEditorWidget(QWidget *parent) : + QWidget(parent) +{ +} + +void MultiEditorWidget::installEventFilter(QObject* filterObj) +{ + QObject::installEventFilter(filterObj); + foreach (QWidget* w, getNoScrollWidgets()) + w->installEventFilter(filterObj); +} + +bool MultiEditorWidget::isUpToDate() const +{ + return upToDate; +} + +void MultiEditorWidget::setUpToDate(bool value) +{ + upToDate = value; +} diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorwidget.h b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorwidget.h new file mode 100644 index 0000000..14bac26 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorwidget.h @@ -0,0 +1,33 @@ +#ifndef MULTIEDITORWIDGET_H +#define MULTIEDITORWIDGET_H + +#include "guiSQLiteStudio_global.h" +#include + +class GUI_API_EXPORT MultiEditorWidget : public QWidget +{ + Q_OBJECT + + public: + explicit MultiEditorWidget(QWidget *parent = 0); + + virtual void setValue(const QVariant& value) = 0; + virtual QVariant getValue() = 0; + virtual void setReadOnly(bool value) = 0; + virtual QList getNoScrollWidgets() = 0; + virtual QString getTabLabel() = 0; + virtual void focusThisWidget() = 0; + + void installEventFilter(QObject* filterObj); + + bool isUpToDate() const; + void setUpToDate(bool value); + + private: + bool upToDate = true; + + signals: + void valueModified(); +}; + +#endif // MULTIEDITORWIDGET_H diff --git a/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorwidgetplugin.h b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorwidgetplugin.h new file mode 100644 index 0000000..011bde5 --- /dev/null +++ b/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditorwidgetplugin.h @@ -0,0 +1,17 @@ +#ifndef MULTIEDITORWIDGETPLUGIN_H +#define MULTIEDITORWIDGETPLUGIN_H + +#include "plugins/plugin.h" +#include "datagrid/sqlquerymodelcolumn.h" + +class MultiEditorWidget; + +class GUI_API_EXPORT MultiEditorWidgetPlugin : public virtual Plugin +{ + public: + virtual MultiEditorWidget* getInstance() = 0; + virtual bool validFor(const DataType& dataType) = 0; + virtual int getPriority(const DataType& dataType) = 0; +}; + +#endif // MULTIEDITORWIDGETPLUGIN_H -- cgit v1.2.3