aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/guiSQLiteStudio/multieditor/multieditor.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/multieditor/multieditor.cpp
Imported Upstream version 2.99.6upstream/2.99.6
Diffstat (limited to 'SQLiteStudio3/guiSQLiteStudio/multieditor/multieditor.cpp')
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/multieditor/multieditor.cpp366
1 files changed, 366 insertions, 0 deletions
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 <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QTabWidget>
+#include <QTabBar>
+#include <QLabel>
+#include <QCheckBox>
+#include <QVariant>
+#include <QEvent>
+#include <QGraphicsColorizeEffect>
+#include <QToolButton>
+#include <QDebug>
+#include <QKeyEvent>
+
+static QHash<QString,bool> 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<MultiEditorWidget*>(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<MultiEditorWidget*>(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<MultiEditorWidget*>(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<MultiEditorWidget*> MultiEditor::getEditorTypes(const DataType& dataType)
+{
+ QList<MultiEditorWidget*> editors;
+
+ QString typeStr = dataType.toString().trimmed().toUpper();
+ QHash<QString,QVariant> editorsOrder = CFG_UI.General.DataEditorsOrder.get();
+ if (editorsOrder.contains(typeStr))
+ {
+ MultiEditorWidgetPlugin* plugin = nullptr;
+ for (const QString& editorPluginName : editorsOrder[typeStr].toStringList())
+ {
+ plugin = dynamic_cast<MultiEditorWidgetPlugin*>(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<MultiEditorWidgetPlugin*> plugins = PLUGINS->getLoadedPlugins<MultiEditorWidgetPlugin>();
+
+ typedef QPair<int,MultiEditorWidget*> EditorWithPriority;
+
+ QList<EditorWithPriority> 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<MultiEditorWidget*>(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<MultiEditorWidget*>(tabs->widget(i));
+ editorWidget->setValue(newValue);
+ editorWidget->setUpToDate(true);
+ }
+ invalidatingDisabled = false;
+}
+
+void MultiEditor::updateLabel()
+{
+ if (deleted)
+ stateLabel->setText("<i>"+tr("Deleted", "multieditor")+"<i>");
+ else if (readOnly)
+ stateLabel->setText("<i>"+tr("Read only", "multieditor")+"<i>");
+ else
+ stateLabel->setText("");
+}
+
+QVariant MultiEditor::getValueOmmitNull() const
+{
+ return dynamic_cast<MultiEditorWidget*>(tabs->currentWidget())->getValue();
+}