diff --git a/CMakeLists.txt b/CMakeLists.txt index cbb6231..678ef50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake cmake_policy(SET CMP0072 NEW) # FindOpenGL prefers GLVND by default project(QAD) set(QAD_MAJOR 2) -set(QAD_MINOR 25) +set(QAD_MINOR 26) set(QAD_REVISION 0) set(QAD_SUFFIX ) set(QAD_COMPANY SHS) diff --git a/libs/widgets/plugin/qad_widgets.cpp b/libs/widgets/plugin/qad_widgets.cpp index c0c3ab9..a93d2f5 100644 --- a/libs/widgets/plugin/qad_widgets.cpp +++ b/libs/widgets/plugin/qad_widgets.cpp @@ -17,6 +17,7 @@ #include "scroll_spin_boxplugin.h" #include "shortcutsplugin.h" #include "spinsliderplugin.h" +#include "stateiconplugin.h" QADWidgets::QADWidgets(QObject * parent): QObject(parent) { @@ -37,6 +38,7 @@ QADWidgets::QADWidgets(QObject * parent): QObject(parent) { m_widgets.append(new ImageViewPlugin(this)); m_widgets.append(new ScrollSpinBoxPlugin(this)); m_widgets.append(new RangeSliderPlugin(this)); + m_widgets.append(new StateIconPlugin(this)); } diff --git a/libs/widgets/plugin/stateiconmenuextension.ui b/libs/widgets/plugin/stateiconmenuextension.ui new file mode 100644 index 0000000..4299df2 --- /dev/null +++ b/libs/widgets/plugin/stateiconmenuextension.ui @@ -0,0 +1,191 @@ + + + StateIconMenuExtension + + + + 0 + 0 + 576 + 464 + + + + Select variables + + + + + + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + + + QAbstractItemView::ScrollPerPixel + + + QAbstractItemView::ScrollPerPixel + + + false + + + false + + + false + + + + State + + + + + Text + + + + + Icon + + + + + + + + + + Add + + + + :/icons/list-add.png:/icons/list-add.png + + + + + + + Remove selected + + + + :/icons/edit-delete.png:/icons/edit-delete.png + + + + + + + Qt::Vertical + + + QSizePolicy::Preferred + + + + 5 + 20 + + + + + + + + Clear + + + + :/icons/edit-clear.png:/icons/edit-clear.png + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + + + buttonBox + accepted() + StateIconMenuExtension + accept() + + + 517 + 606 + + + 526 + 629 + + + + + buttonBox + rejected() + StateIconMenuExtension + reject() + + + 470 + 599 + + + 464 + 631 + + + + + buttonClear + clicked() + tree + clear() + + + 590 + 140 + + + 516 + 149 + + + + + diff --git a/libs/widgets/plugin/stateiconplugin.cpp b/libs/widgets/plugin/stateiconplugin.cpp new file mode 100644 index 0000000..07acb19 --- /dev/null +++ b/libs/widgets/plugin/stateiconplugin.cpp @@ -0,0 +1,177 @@ +#include "stateiconplugin.h" + +#include "ui_stateiconmenuextension.h" + +#include +#include +#include +#include +#include +#include +#include + +enum Column { + cState, + cText, + cIcon +}; + + +StateIconMenuExtension::StateIconMenuExtension(StateIcon * widget_, QObject *): QDialog(), ui(new Ui::StateIconMenuExtension) { + ui->setupUi(this); + widget = widget_; + icon_command = QIcon(":/icons/code-function.png"); + action_default = new QAction("Edit states ...", this); + connect(action_default, SIGNAL(triggered(bool)), this, SLOT(action_default_triggered())); +} + + +StateIconMenuExtension::~StateIconMenuExtension() { + delete ui; +} + + +QAction * StateIconMenuExtension::preferredEditAction() const { + return action_default; +} + + +QList StateIconMenuExtension::taskActions() const { + return {action_default}; +} + + +void StateIconMenuExtension::accept() { + widget->clearStates(); + for (int i = 0; i < ui->tree->topLevelItemCount(); ++i) { + QTreeWidgetItem * ti = ui->tree->topLevelItem(i); + widget->addState(ti->text(cState).toInt(), ti->text(cText), ti->text(cIcon)); + } + QDesignerFormWindowInterface * formWindow = QDesignerFormWindowInterface::findFormWindow(widget); + if (formWindow) { + formWindow->cursor()->setProperty("rawStates", widget->saveStates()); + } + QDialog::accept(); +} + + +void StateIconMenuExtension::on_buttonAdd_clicked() { + auto ti = new QTreeWidgetItem({"0"}); + ti->setFlags(ti->flags() | Qt::ItemIsEditable); + ui->tree->addTopLevelItem(ti); + ui->tree->editItem(ti, cState); +} + + +void StateIconMenuExtension::on_buttonDel_clicked() { + qDeleteAll(ui->tree->selectedItems()); +} + + +void StateIconMenuExtension::on_tree_itemClicked(QTreeWidgetItem * item, int column) { + if (!item) return; + Qt::ItemFlags f = item->flags(); + f.setFlag(Qt::ItemIsEditable, column != cIcon); + item->setFlags(f); +} + + +void StateIconMenuExtension::on_tree_itemDoubleClicked(QTreeWidgetItem * item, int column) { + if (!item || column != cIcon) return; + QDesignerFormWindowInterface * formWindow = QDesignerFormWindowInterface::findFormWindow(widget); + if (formWindow) { + QtResourceViewDialog dlg(formWindow->core()); + dlg.selectResource(item->text(cIcon)); + if (dlg.exec() == QDialog::Accepted) { + QString ni = dlg.selectedResource(); + item->setText(cIcon, ni); + item->setIcon(cIcon, QIcon(ni)); + } + } +} + + +void StateIconMenuExtension::action_default_triggered() { + ui->tree->clear(); + auto states = widget->allStates(); + for (auto s: states) { + QTreeWidgetItem * ti = new QTreeWidgetItem(); + ti->setText(cState, QString::number(s)); + ti->setText(cText, widget->stateText(s)); + ti->setText(cIcon, widget->stateIcon(s)); + ti->setIcon(cIcon, QIcon(widget->stateIcon(s))); + ui->tree->addTopLevelItem(ti); + } + exec(); +} + + +QObject * StateIconTaskMenuFactory::createExtension(QObject * object, const QString & iid, QObject * parent) const { + if (iid != Q_TYPEID(QDesignerTaskMenuExtension)) return 0; + if (StateIcon * w = qobject_cast(object)) return new StateIconMenuExtension(w, parent); + return nullptr; +} + + +StateIconPlugin::StateIconPlugin(QObject * parent): QObject(parent) { + m_initialized = false; +} + + +void StateIconPlugin::initialize(QDesignerFormEditorInterface * core) { + if (m_initialized) return; + QExtensionManager * manager = core->extensionManager(); + Q_ASSERT(manager != 0); + manager->registerExtensions(new StateIconTaskMenuFactory(manager), Q_TYPEID(QDesignerTaskMenuExtension)); + m_initialized = true; +} + + +bool StateIconPlugin::isInitialized() const { + return m_initialized; +} + + +QWidget * StateIconPlugin::createWidget(QWidget * parent) { + return new StateIcon(parent); +} + + +QString StateIconPlugin::name() const { + return QLatin1String("StateIcon"); +} + + +QString StateIconPlugin::group() const { + return QLatin1String("Display Widgets"); +} + + +QIcon StateIconPlugin::icon() const { + return QIcon(":/icons/led_on.png"); +} + + +QString StateIconPlugin::toolTip() const { + return QLatin1String("StateIcon"); +} + + +QString StateIconPlugin::whatsThis() const { + return QLatin1String("StateIcon"); +} + + +bool StateIconPlugin::isContainer() const { + return false; +} + + +QString StateIconPlugin::domXml() const { + return QLatin1String("\n\n"); +} + + +QString StateIconPlugin::includeFile() const { + return QLatin1String("stateicon.h"); +} diff --git a/libs/widgets/plugin/stateiconplugin.h b/libs/widgets/plugin/stateiconplugin.h new file mode 100644 index 0000000..685aa44 --- /dev/null +++ b/libs/widgets/plugin/stateiconplugin.h @@ -0,0 +1,90 @@ +#ifndef stateiconplugin_H +#define stateiconplugin_H + +#include +#if QT_VERSION >= 0x050000 +# include +#else +# include +#endif +#include "stateicon.h" + +#include +#include +#include +#include +#include + + +namespace Ui { +class StateIconMenuExtension; +} + +class StateIconMenuExtension + : public QDialog + , public QDesignerTaskMenuExtension { + Q_OBJECT + Q_INTERFACES(QDesignerTaskMenuExtension) + +public: + StateIconMenuExtension(StateIcon * widget, QObject * parent); + ~StateIconMenuExtension(); + + QAction * preferredEditAction() const override; + QList taskActions() const override; + +public slots: + void accept() override; + +private slots: + void on_tree_itemClicked(QTreeWidgetItem * item, int column); + void on_tree_itemDoubleClicked(QTreeWidgetItem * item, int column); + void on_buttonAdd_clicked(); + void on_buttonDel_clicked(); + void action_default_triggered(); + +private: + Ui::StateIconMenuExtension * ui; + StateIcon * widget; + QAction * action_default; + QIcon icon_command; +}; + + +class StateIconTaskMenuFactory: public QExtensionFactory { + Q_OBJECT + +public: + StateIconTaskMenuFactory(QExtensionManager * parent = 0): QExtensionFactory(parent) { ; } + +protected: + QObject * createExtension(QObject * object, const QString & iid, QObject * parent) const; +}; + + +class StateIconPlugin + : public QObject + , public QDesignerCustomWidgetInterface { + Q_OBJECT + Q_INTERFACES(QDesignerCustomWidgetInterface) + +public: + StateIconPlugin(QObject * parent = 0); + + bool isContainer() const; + bool isInitialized() const; + QIcon icon() const; + QString domXml() const; + QString group() const; + QString includeFile() const; + QString name() const; + QString toolTip() const; + QString whatsThis() const; + QWidget * createWidget(QWidget * parent); + void initialize(QDesignerFormEditorInterface * core); + +private: + bool m_initialized; +}; + +#endif diff --git a/libs/widgets/qad_widgets.qrc b/libs/widgets/qad_widgets.qrc index 8224af8..d6c0f73 100644 --- a/libs/widgets/qad_widgets.qrc +++ b/libs/widgets/qad_widgets.qrc @@ -40,5 +40,6 @@ ../../icons/code-word.png ../../icons/f1.png ../../icons/scroll_spin.png +../../icons/led_on.png diff --git a/libs/widgets/stateicon.cpp b/libs/widgets/stateicon.cpp new file mode 100644 index 0000000..81c54ef --- /dev/null +++ b/libs/widgets/stateicon.cpp @@ -0,0 +1,77 @@ +#include "stateicon.h" + +#include "qad_types.h" + +#include +#include +#include + + +StateIcon::StateIcon(QWidget * parent): IconedLabel(parent) {} + + +QString StateIcon::saveStates() const { + return QString::fromLatin1(qSerialize(src_states).toBase64()); +} + + +void StateIcon::loadStates(const QString & ba) { + src_states = qDeserialize>>(QByteArray::fromBase64(ba.toLatin1())); + prepare(); +} + + +void StateIcon::clearStates() { + src_states.clear(); + prepare(); +} + + +void StateIcon::addState(int st, QString text, QIcon icon) { + src_states[st] = QPair(text, ""); + prepared_states[st] = QPair(text, icon); + setState(m_state); +} + + +void StateIcon::addState(int st, QString text, QString icon_path) { + src_states[st] = QPair(text, icon_path); + prepared_states[st] = QPair(text, QIcon(icon_path)); + setState(m_state); +} + + +QList StateIcon::allStates() const { + return src_states.keys(); +} + + +QString StateIcon::stateText(int st) const { + return src_states.value(st).first; +} + + +QString StateIcon::stateIcon(int st) const { + return src_states.value(st).second; +} + + +void StateIcon::prepare() { + prepared_states.clear(); + QMapIterator> it(src_states); + while (it.hasNext()) { + it.next(); + auto & ps(prepared_states[it.key()]); + ps.first = it.value().first; + ps.second = QIcon(it.value().second); + } + setState(m_state); +} + + +void StateIcon::setState(int newState) { + m_state = newState; + auto cv = prepared_states.value(m_state); + setText(cv.first); + setIcon(cv.second); +} diff --git a/libs/widgets/stateicon.h b/libs/widgets/stateicon.h new file mode 100644 index 0000000..db3812b --- /dev/null +++ b/libs/widgets/stateicon.h @@ -0,0 +1,59 @@ +/* + QAD - Qt ADvanced + + Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef stateicon_H +#define stateicon_H + +#include "iconedlabel.h" +#include "qad_widgets_export.h" + +#include + + +class QAD_WIDGETS_EXPORT StateIcon: public IconedLabel { + Q_OBJECT + Q_PROPERTY(QString rawStates READ saveStates WRITE loadStates DESIGNABLE false) + Q_PROPERTY(int state READ state WRITE setState) + +public: + explicit StateIcon(QWidget * parent = nullptr); + + QString saveStates() const; + void loadStates(const QString & ba); + void clearStates(); + void addState(int st, QString text, QIcon icon); + void addState(int st, QString text, QString icon_path); + QList allStates() const; + QString stateText(int st) const; + QString stateIcon(int st) const; + + int state() const { return m_state; } + +private: + void prepare(); + + QMap> src_states; + QMap> prepared_states; + int m_state = 0; + +public slots: + void setState(int newState); +}; + +#endif