diff --git a/CodeGenerator/codegenerator.cpp b/CodeGenerator/codegenerator.cpp index f6e8976..351375d 100644 --- a/CodeGenerator/codegenerator.cpp +++ b/CodeGenerator/codegenerator.cpp @@ -44,6 +44,19 @@ GeneratedFunction* GeneratedCodeStorage::addFunction(const QString& name) return function; } +GeneratedFunction* GeneratedCodeStorage::addFunction(GeneratedFunction* function) +{ + function->setParent(this); + m_functions.append(function); + return function; +} + +void GeneratedCodeStorage::removeFunction(GeneratedFunction* function) +{ + function->deleteLater(); + m_functions.removeOne(function); +} + QObject* Serializer::load(const QDomElement& element, QObject* parent) { QString className = element.attribute("class"); @@ -81,7 +94,13 @@ QObject* Serializer::load(const QDomElement& element, QObject* parent) if (!propertyElement.isNull()) { // Deserialize the element - if (property.userType() == qMetaTypeId()) + if (property.isEnumType()) + { + QMetaEnum metaEnum = property.enumerator(); + Q_ASSERT(metaEnum.isValid()); + property.write(deserializedObject, metaEnum.keyToValue(propertyElement.text().toLatin1().data())); + } + else if (property.userType() == qMetaTypeId()) { QObjectList objectList; QDomNodeList children = propertyElement.childNodes(); @@ -135,7 +154,13 @@ void Serializer::store(QObject* object, QDomElement& element) propertyElement.setAttribute("name", property.name()); QVariant value = property.read(object); - if (value.canConvert()) + if (property.isEnumType()) + { + QMetaEnum metaEnum = property.enumerator(); + Q_ASSERT(metaEnum.isValid()); + propertyElement.appendChild(propertyElement.ownerDocument().createTextNode(metaEnum.valueToKey(value.toInt()))); + } + else if (value.canConvert()) { QObjectList objectList = value.value(); for (QObject* currentObject : objectList) @@ -154,6 +179,15 @@ void Serializer::store(QObject* object, QDomElement& element) } } +QObject* Serializer::clone(QObject* object, QObject* parent) +{ + QDomDocument document; + QDomElement rootElement = document.createElement("root"); + document.appendChild(rootElement); + Serializer::store(object, rootElement); + return Serializer::load(rootElement, parent); +} + CodeGenerator::CodeGenerator(QObject* parent) : BaseClass(parent) { @@ -231,4 +265,509 @@ void GeneratedFunction::setFunctionDescription(const QString& functionDescriptio m_functionDescription = functionDescription; } +GeneratedFunction* GeneratedFunction::clone(QObject* parent) +{ + return qobject_cast(Serializer::clone(this, parent)); +} + +bool GeneratedFunction::hasField(GeneratedBase::FieldType fieldType) const +{ + switch (fieldType) + { + case FieldType::Name: + case FieldType::ItemType: + case FieldType::DataType: + case FieldType::Description: + return true; + + case FieldType::Value: + return false; + + default: + break; + } + + return false; +} + +QVariant GeneratedFunction::readField(GeneratedBase::FieldType fieldType) const +{ + switch (fieldType) + { + case FieldType::Name: + return m_functionName; + case FieldType::ItemType: + return int(m_functionType); + case FieldType::DataType: + return int(m_returnType); + case FieldType::Description: + return m_functionDescription; + + case FieldType::Value: + default: + break; + } + + return QVariant(); +} + +void GeneratedFunction::writeField(GeneratedBase::FieldType fieldType, QVariant value) +{ + switch (fieldType) + { + case FieldType::Name: + m_functionName = value.toString(); + break; + case FieldType::ItemType: + m_functionType = static_cast(value.toInt()); + break; + case FieldType::DataType: + m_returnType = static_cast(value.toInt()); + break; + case FieldType::Description: + m_functionDescription = value.toString(); + break; + + case FieldType::Value: + default: + break; + } +} + +void GeneratedFunction::fillComboBox(QComboBox* comboBox, GeneratedBase::FieldType fieldType) +{ + switch (fieldType) + { + case FieldType::ItemType: + Serializer::fillComboBox(comboBox, m_functionType); + break; + case FieldType::DataType: + Serializer::fillComboBox(comboBox, m_returnType); + break; + + default: + break; + } +} + +bool GeneratedFunction::canHaveSubitems() const +{ + return true; +} + +GeneratedFunction::DataType GeneratedFunction::getReturnType() const +{ + return m_returnType; +} + +void GeneratedFunction::setReturnType(DataType returnType) +{ + m_returnType = returnType; +} + +GeneratedAction::GeneratedAction(QObject* parent) : + BaseClass(parent), + m_actionType(CreateObject) +{ + +} + +bool GeneratedAction::hasField(FieldType fieldType) const +{ + switch (fieldType) + { + case FieldType::Name: + return m_actionType == CreateObject; + case FieldType::ItemType: + return true; + case FieldType::DataType: + return hasField(FieldType::Name) && !m_variableName.isEmpty(); + case FieldType::Description: + return m_actionType == Code; + + default: + break; + } + + return false; +} + +QVariant GeneratedAction::readField(GeneratedBase::FieldType fieldType) const +{ + switch (fieldType) + { + case FieldType::Name: + return m_variableName; + case FieldType::ItemType: + return int(m_actionType); + case FieldType::DataType: + return int(m_variableType); + case FieldType::Description: + return m_code; + + default: + break; + } + + return QVariant(); +} + +void GeneratedAction::writeField(GeneratedBase::FieldType fieldType, QVariant value) +{ + switch (fieldType) + { + case FieldType::Name: + m_variableName = value.toString(); + break; + case FieldType::ItemType: + m_actionType = static_cast(value.toInt()); + break; + case FieldType::DataType: + m_variableType = static_cast(value.toInt()); + break; + case FieldType::Description: + m_code = value.toString(); + break; + + default: + break; + } +} + +void GeneratedAction::fillComboBox(QComboBox* comboBox, FieldType fieldType) +{ + switch (fieldType) + { + case FieldType::ItemType: + Serializer::fillComboBox(comboBox, m_actionType); + break; + case FieldType::DataType: + Serializer::fillComboBox(comboBox, m_variableType); + break; + + default: + break; + } +} + +bool GeneratedAction::canHaveSubitems() const +{ + switch (m_actionType) + { + case Parameters: + case CreateObject: + return true; + + default: + break; + } + + return false; +} + +GeneratedAction::ActionType GeneratedAction::getActionType() const +{ + return m_actionType; +} + +void GeneratedAction::setActionType(ActionType actionType) +{ + m_actionType = actionType; + + if (!canHaveSubitems()) + { + clearItems(); + } +} + +QString GeneratedAction::getVariableName() const +{ + return m_variableName; +} + +void GeneratedAction::setVariableName(const QString& variableName) +{ + m_variableName = variableName; +} + +GeneratedAction::DataType GeneratedAction::getVariableType() const +{ + return m_variableType; +} + +void GeneratedAction::setVariableType(DataType variableType) +{ + m_variableType = variableType; +} + +QString GeneratedAction::getCode() const +{ + return m_code; +} + +void GeneratedAction::setCode(const QString& code) +{ + m_code = code; +} + +QObjectList GeneratedBase::getItems() const +{ + return m_items; +} + +void GeneratedBase::setItems(const QObjectList& items) +{ + m_items = items; +} + +void GeneratedBase::addItem(QObject* object) +{ + object->setParent(this); + m_items.append(object); +} + +void GeneratedBase::removeItem(QObject* object) +{ + object->deleteLater(); + m_items.removeAll(object); +} + +void GeneratedBase::clearItems() +{ + qDeleteAll(m_items); + m_items.clear(); +} + +GeneratedPDFObject::GeneratedPDFObject(QObject* parent) : + BaseClass(parent) +{ + +} + +bool GeneratedPDFObject::hasField(GeneratedBase::FieldType fieldType) const +{ + switch (fieldType) + { + case FieldType::Name: + return m_objectType == DictionaryItemSimple || m_objectType == DictionaryItemComplex; + case FieldType::ItemType: + return true; + case FieldType::Value: + return m_objectType == Object || m_objectType == ArraySimple || m_objectType == DictionaryItemSimple; + + default: + break; + } + + return false; +} + +QVariant GeneratedPDFObject::readField(GeneratedBase::FieldType fieldType) const +{ + switch (fieldType) + { + case FieldType::Name: + return m_dictionaryItemName; + case FieldType::ItemType: + return int(m_objectType); + case FieldType::Value: + return m_value; + + default: + break; + } + + return QVariant(); +} + +void GeneratedPDFObject::writeField(GeneratedBase::FieldType fieldType, QVariant value) +{ + switch (fieldType) + { + case FieldType::Name: + m_dictionaryItemName = value.toString(); + break; + case FieldType::ItemType: + m_objectType = static_cast(value.toInt()); + break; + case FieldType::Value: + m_value = value.toString(); + break; + + default: + break; + } +} + +void GeneratedPDFObject::fillComboBox(QComboBox* comboBox, GeneratedBase::FieldType fieldType) +{ + switch (fieldType) + { + case FieldType::ItemType: + Serializer::fillComboBox(comboBox, m_objectType); + break; + + default: + break; + } +} + +bool GeneratedPDFObject::canHaveSubitems() const +{ + switch (m_objectType) + { + case ArrayComplex: + case Dictionary: + case DictionaryItemComplex: + return true; + + default: + break; + } + + return false; +} + +QString GeneratedPDFObject::getValue() const +{ + return m_value; +} + +void GeneratedPDFObject::setValue(const QString& value) +{ + m_value = value; +} + +GeneratedPDFObject::ObjectType GeneratedPDFObject::getObjectType() const +{ + return m_objectType; +} + +void GeneratedPDFObject::setObjectType(ObjectType objectType) +{ + m_objectType = objectType; + + if (!canHaveSubitems()) + { + clearItems(); + } +} + +QString GeneratedPDFObject::getDictionaryItemName() const +{ + return m_dictionaryItemName; +} + +void GeneratedPDFObject::setDictionaryItemName(const QString& dictionaryItemName) +{ + m_dictionaryItemName = dictionaryItemName; +} + +GeneratedParameter::GeneratedParameter(QObject* parent) : + BaseClass(parent) +{ + +} + +bool GeneratedParameter::hasField(GeneratedBase::FieldType fieldType) const +{ + switch (fieldType) + { + case FieldType::Name: + case FieldType::DataType: + case FieldType::Description: + return true; + + default: + break; + } + + return false; +} + +QVariant GeneratedParameter::readField(GeneratedBase::FieldType fieldType) const +{ + switch (fieldType) + { + case FieldType::Name: + return m_parameterName; + case FieldType::DataType: + return m_parameterDataType; + case FieldType::Description: + return m_parameterDescription; + + default: + break; + } + + return QVariant(); +} + +void GeneratedParameter::writeField(GeneratedBase::FieldType fieldType, QVariant value) +{ + switch (fieldType) + { + case FieldType::Name: + m_parameterName = value.toString(); + break; + case FieldType::DataType: + m_parameterDataType = static_cast(value.toInt()); + break; + case FieldType::Description: + m_parameterDescription = value.toString(); + break; + + default: + break; + } +} + +void GeneratedParameter::fillComboBox(QComboBox* comboBox, GeneratedBase::FieldType fieldType) +{ + switch (fieldType) + { + case FieldType::DataType: + Serializer::fillComboBox(comboBox, m_parameterDataType); + break; + + default: + break; + } +} + +bool GeneratedParameter::canHaveSubitems() const +{ + return false; +} + +QString GeneratedParameter::getParameterName() const +{ + return m_parameterName; +} + +void GeneratedParameter::setParameterName(const QString& parameterName) +{ + m_parameterName = parameterName; +} + +GeneratedParameter::DataType GeneratedParameter::getParameterDataType() const +{ + return m_parameterDataType; +} + +void GeneratedParameter::setParameterDataType(const DataType& parameterDataType) +{ + m_parameterDataType = parameterDataType; +} + +QString GeneratedParameter::getParameterDescription() const +{ + return m_parameterDescription; +} + +void GeneratedParameter::setParameterDescription(const QString& parameterDescription) +{ + m_parameterDescription = parameterDescription; +} + } diff --git a/CodeGenerator/codegenerator.h b/CodeGenerator/codegenerator.h index 26dd907..e0e6602 100644 --- a/CodeGenerator/codegenerator.h +++ b/CodeGenerator/codegenerator.h @@ -24,6 +24,7 @@ #include #include #include +#include namespace codegen { @@ -33,6 +34,7 @@ class Serializer public: static QObject* load(const QDomElement& element, QObject* parent); static void store(QObject* object, QDomElement& element); + static QObject* clone(QObject* object, QObject* parent); template static inline QString convertEnumToString(T enumValue) @@ -55,6 +57,23 @@ public: value = T(); } } + + template + static inline void fillComboBox(QComboBox* comboBox, T value) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + Q_ASSERT(metaEnum.isValid()); + + const int keyCount = metaEnum.keyCount(); + comboBox->setUpdatesEnabled(false); + comboBox->clear(); + for (int i = 0; i < keyCount; ++i) + { + comboBox->addItem(metaEnum.key(i), metaEnum.value(i)); + } + comboBox->setCurrentIndex(comboBox->findData(int(value))); + comboBox->setUpdatesEnabled(true); + } }; class GeneratedFunction; @@ -75,18 +94,200 @@ public: void setFunctions(const QObjectList& functions); GeneratedFunction* addFunction(const QString& name); + GeneratedFunction* addFunction(GeneratedFunction* function); + void removeFunction(GeneratedFunction* function); private: QObjectList m_functions; }; -class GeneratedFunction : public QObject +class GeneratedBase : public QObject { Q_OBJECT private: using BaseClass = QObject; +public: + using BaseClass::BaseClass; + + enum class FieldType + { + Name, + ItemType, + DataType, + Value, + Description + }; + + enum DataType + { + _void, + _PDFNull, + _bool, + _PDFInteger, + _PDFReal, + _PDFObjectReference, + _QString, + _QPointF, + _QRectF, + _QVariant + }; + Q_ENUM(DataType) + + Q_PROPERTY(QObjectList items READ getItems WRITE setItems) + + virtual bool hasField(FieldType fieldType) const = 0; + virtual QVariant readField(FieldType fieldType) const = 0; + virtual void writeField(FieldType fieldType, QVariant value) = 0; + virtual void fillComboBox(QComboBox* comboBox, FieldType fieldType) = 0; + virtual bool canHaveSubitems() const = 0; + + QObjectList getItems() const; + void setItems(const QObjectList& items); + void addItem(QObject* object); + void removeItem(QObject* object); + void clearItems(); + +private: + QObjectList m_items; +}; + +class GeneratedParameter : public GeneratedBase +{ + Q_OBJECT + +private: + using BaseClass = GeneratedBase; + +public: + Q_INVOKABLE GeneratedParameter(QObject* parent); + Q_PROPERTY(QString parameterName READ getParameterName WRITE setParameterName) + Q_PROPERTY(DataType parameterType READ getParameterDataType WRITE setParameterDataType) + Q_PROPERTY(QString parameterDescription READ getParameterDescription WRITE setParameterDescription) + + virtual bool hasField(FieldType fieldType) const override; + virtual QVariant readField(FieldType fieldType) const override; + virtual void writeField(FieldType fieldType, QVariant value) override; + virtual void fillComboBox(QComboBox* comboBox, FieldType fieldType) override; + virtual bool canHaveSubitems() const override; + + QString getParameterName() const; + void setParameterName(const QString& parameterName); + + DataType getParameterDataType() const; + void setParameterDataType(const DataType& parameterDataType); + + QString getParameterDescription() const; + void setParameterDescription(const QString& parameterDescription); + +private: + QString m_parameterName; + DataType m_parameterDataType = _void; + QString m_parameterDescription; +}; + +class GeneratedPDFObject : public GeneratedBase +{ + Q_OBJECT + +private: + using BaseClass = GeneratedBase; + +public: + + enum ObjectType + { + Object, + ArraySimple, + ArrayComplex, + Dictionary, + DictionaryItemSimple, + DictionaryItemComplex + }; + Q_ENUM(ObjectType) + + Q_INVOKABLE GeneratedPDFObject(QObject* parent); + Q_PROPERTY(QString dictionaryItemName READ getDictionaryItemName WRITE setDictionaryItemName) + Q_PROPERTY(ObjectType objectType READ getObjectType WRITE setObjectType) + Q_PROPERTY(QString value READ getValue WRITE setValue) + + virtual bool hasField(FieldType fieldType) const override; + virtual QVariant readField(FieldType fieldType) const override; + virtual void writeField(FieldType fieldType, QVariant value) override; + virtual void fillComboBox(QComboBox* comboBox, FieldType fieldType) override; + virtual bool canHaveSubitems() const override; + + QString getValue() const; + void setValue(const QString& value); + + ObjectType getObjectType() const; + void setObjectType(ObjectType objectType); + + QString getDictionaryItemName() const; + void setDictionaryItemName(const QString& dictionaryItemName); + +private: + QString m_dictionaryItemName; + ObjectType m_objectType = Object; + QString m_value; +}; + +class GeneratedAction : public GeneratedBase +{ + Q_OBJECT + +private: + using BaseClass = GeneratedBase; + +public: + + enum ActionType + { + Parameters, + CreateObject, + Code + }; + Q_ENUM(ActionType) + + Q_INVOKABLE GeneratedAction(QObject* parent); + Q_PROPERTY(ActionType actionType READ getActionType WRITE setActionType) + Q_PROPERTY(QString variableName READ getVariableName WRITE setVariableName) + Q_PROPERTY(DataType variableType READ getVariableType WRITE setVariableType) + Q_PROPERTY(QString code READ getCode WRITE setCode) + + virtual bool hasField(FieldType fieldType) const override; + virtual QVariant readField(FieldType fieldType) const override; + virtual void writeField(FieldType fieldType, QVariant value) override; + virtual void fillComboBox(QComboBox* comboBox, FieldType fieldType) override; + virtual bool canHaveSubitems() const override; + + ActionType getActionType() const; + void setActionType(ActionType actionType); + + QString getVariableName() const; + void setVariableName(const QString& variableName); + + DataType getVariableType() const; + void setVariableType(DataType variableType); + + QString getCode() const; + void setCode(const QString& code); + +private: + ActionType m_actionType; + QString m_variableName; + DataType m_variableType = _void; + QString m_code; +}; + +class GeneratedFunction : public GeneratedBase +{ + Q_OBJECT + +private: + using BaseClass = GeneratedBase; + public: enum FunctionType @@ -99,9 +300,16 @@ public: Q_INVOKABLE GeneratedFunction(QObject* parent); - Q_PROPERTY(QString functionType READ getFunctionTypeString WRITE setFunctionTypeString) + Q_PROPERTY(FunctionType functionType READ getFunctionType WRITE setFunctionType) Q_PROPERTY(QString functionName READ getFunctionName WRITE setFunctionName) Q_PROPERTY(QString functionDescription READ getFunctionDescription WRITE setFunctionDescription) + Q_PROPERTY(DataType returnType READ getReturnType WRITE setReturnType) + + virtual bool hasField(FieldType fieldType) const override; + virtual QVariant readField(FieldType fieldType) const override; + virtual void writeField(FieldType fieldType, QVariant value) override; + virtual void fillComboBox(QComboBox* comboBox, FieldType fieldType) override; + virtual bool canHaveSubitems() const override; QString getFunctionTypeString() const; void setFunctionTypeString(const QString& string); @@ -115,10 +323,17 @@ public: QString getFunctionDescription() const; void setFunctionDescription(const QString& functionDescription); + DataType getReturnType() const; + void setReturnType(DataType returnType); + + /// Create a clone of this function + GeneratedFunction* clone(QObject* parent); + private: FunctionType m_functionType = FunctionType::Annotations; QString m_functionName; QString m_functionDescription; + DataType m_returnType = _void; }; class CodeGenerator : public QObject @@ -133,7 +348,10 @@ public: void initialize(); + QObjectList getFunctions() const { return m_storage->getFunctions(); } GeneratedFunction* addFunction(const QString& name) { return m_storage->addFunction(name); } + GeneratedFunction* addFunction(GeneratedFunction* function) { return m_storage->addFunction(function); } + void removeFunction(GeneratedFunction* function) { m_storage->removeFunction(function); } void load(const QDomDocument& document); void store(QDomDocument& document); diff --git a/CodeGenerator/generatormainwindow.cpp b/CodeGenerator/generatormainwindow.cpp index f3c6672..ec25bbd 100644 --- a/CodeGenerator/generatormainwindow.cpp +++ b/CodeGenerator/generatormainwindow.cpp @@ -25,11 +25,14 @@ #include #include #include +#include GeneratorMainWindow::GeneratorMainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::GeneratorMainWindow), - m_generator(new codegen::CodeGenerator(this)) + m_generator(new codegen::CodeGenerator(this)), + m_currentFunction(nullptr), + m_isLoadingData(false) { ui->setupUi(this); @@ -41,10 +44,10 @@ GeneratorMainWindow::GeneratorMainWindow(QWidget *parent) : { load(m_defaultFileName); } + connect(ui->generatedFunctionsTreeWidget, &QTreeWidget::currentItemChanged, this, &GeneratorMainWindow::onCurrentItemChanged); - // Temporary - to delete: - m_generator->addFunction("createAnnotationWatermark"); - m_generator->addFunction("createAnnotationFreeText"); + setWindowState(Qt::WindowMaximized); + updateFunctionListUI(); } GeneratorMainWindow::~GeneratorMainWindow() @@ -73,6 +76,84 @@ void GeneratorMainWindow::saveSettings() settings.setValue("fileName", m_defaultFileName); } +void GeneratorMainWindow::updateFunctionListUI() +{ + BoolGuard guard(m_isLoadingData); + + ui->generatedFunctionsTreeWidget->setUpdatesEnabled(false); + ui->generatedFunctionsTreeWidget->clear(); + m_mapFunctionToWidgetItem.clear(); + + // First, create roots + std::map mapFunctionTypeToRoot; + for (QObject* functionObject : m_generator->getFunctions()) + { + codegen::GeneratedFunction* function = qobject_cast(functionObject); + Q_ASSERT(function); + + if (!mapFunctionTypeToRoot.count(function->getFunctionType())) + { + QTreeWidgetItem* subroot = new QTreeWidgetItem(ui->generatedFunctionsTreeWidget, QStringList(function->getFunctionTypeString())); + subroot->setFlags(Qt::ItemIsEnabled); + mapFunctionTypeToRoot[function->getFunctionType()] = subroot; + } + } + ui->generatedFunctionsTreeWidget->sortByColumn(0, Qt::AscendingOrder); + + for (QObject* functionObject : m_generator->getFunctions()) + { + codegen::GeneratedFunction* function = qobject_cast(functionObject); + Q_ASSERT(function); + + QTreeWidgetItem* functionItem = new QTreeWidgetItem(mapFunctionTypeToRoot[function->getFunctionType()], QStringList(function->getFunctionName())); + functionItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + functionItem->setData(0, Qt::UserRole, QVariant::fromValue(function)); + m_mapFunctionToWidgetItem[function] = functionItem; + } + + ui->generatedFunctionsTreeWidget->expandAll(); + ui->generatedFunctionsTreeWidget->setUpdatesEnabled(true); + + // Select current function + auto it = m_mapFunctionToWidgetItem.find(m_currentFunction); + if (it != m_mapFunctionToWidgetItem.cend()) + { + ui->generatedFunctionsTreeWidget->setCurrentItem(it->second, 0, QItemSelectionModel::SelectCurrent); + } + + m_isLoadingData = false; +} + +void GeneratorMainWindow::setCurrentFunction(codegen::GeneratedFunction* currentFunction) +{ + BoolGuard guard(m_isLoadingData); + + if (m_currentFunction != currentFunction) + { + m_currentFunction = currentFunction; + + // Select current function + auto it = m_mapFunctionToWidgetItem.find(m_currentFunction); + if (it != m_mapFunctionToWidgetItem.cend()) + { + ui->generatedFunctionsTreeWidget->setCurrentItem(it->second, 0, QItemSelectionModel::SelectCurrent); + } + } +} + +void GeneratorMainWindow::onCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous) +{ + Q_UNUSED(previous); + + if (m_isLoadingData) + { + return; + } + + codegen::GeneratedFunction* function = current->data(0, Qt::UserRole).value(); + setCurrentFunction(function); +} + void GeneratorMainWindow::loadSettings() { QSettings settings("MelkaJ"); @@ -132,3 +213,35 @@ void GeneratorMainWindow::on_actionSave_triggered() on_actionSaveAs_triggered(); } } + +void GeneratorMainWindow::on_newFunctionButton_clicked() +{ + QString functionName = QInputDialog::getText(this, tr("Create function"), tr("Enter function name")); + if (!functionName.isEmpty()) + { + codegen::GeneratedFunction* generatedFunction = m_generator->addFunction(functionName); + updateFunctionListUI(); + setCurrentFunction(generatedFunction); + } +} + +void GeneratorMainWindow::on_cloneFunctionButton_clicked() +{ + if (m_currentFunction) + { + codegen::GeneratedFunction* generatedFunction = m_generator->addFunction(m_currentFunction->clone(nullptr)); + updateFunctionListUI(); + setCurrentFunction(generatedFunction); + } +} + +void GeneratorMainWindow::on_removeFunctionButton_clicked() +{ + if (m_currentFunction) + { + codegen::GeneratedFunction* functionToDelete = m_currentFunction; + setCurrentFunction(nullptr); + m_generator->removeFunction(functionToDelete); + updateFunctionListUI(); + } +} diff --git a/CodeGenerator/generatormainwindow.h b/CodeGenerator/generatormainwindow.h index 6ac705d..1484f5a 100644 --- a/CodeGenerator/generatormainwindow.h +++ b/CodeGenerator/generatormainwindow.h @@ -20,9 +20,12 @@ #include +class QTreeWidgetItem; + namespace codegen { class CodeGenerator; +class GeneratedFunction; } namespace Ui @@ -30,6 +33,26 @@ namespace Ui class GeneratorMainWindow; } +class BoolGuard +{ +public: + explicit inline BoolGuard(bool& value) : + m_oldValue(value), + m_value(&value) + { + *m_value = true; + } + + inline ~BoolGuard() + { + *m_value = m_oldValue; + } + +private: + bool m_oldValue; + bool* m_value; +}; + class GeneratorMainWindow : public QMainWindow { Q_OBJECT @@ -44,16 +67,25 @@ public: private slots: void on_actionLoad_triggered(); void on_actionSaveAs_triggered(); - void on_actionSave_triggered(); + void on_newFunctionButton_clicked(); + void on_cloneFunctionButton_clicked(); + void on_removeFunctionButton_clicked(); private: void loadSettings(); void saveSettings(); + void updateFunctionListUI(); + void setCurrentFunction(codegen::GeneratedFunction* currentFunction); + void onCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous); + Ui::GeneratorMainWindow* ui; codegen::CodeGenerator* m_generator; + codegen::GeneratedFunction* m_currentFunction; QString m_defaultFileName; + std::map m_mapFunctionToWidgetItem; + bool m_isLoadingData; }; #endif // GENERATORMAINWINDOW_H diff --git a/CodeGenerator/generatormainwindow.ui b/CodeGenerator/generatormainwindow.ui index d902060..5fbaf35 100644 --- a/CodeGenerator/generatormainwindow.ui +++ b/CodeGenerator/generatormainwindow.ui @@ -19,6 +19,12 @@ + + true + + + false + 1 @@ -26,37 +32,6 @@ - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Up - - - - - - - Down - - - - - @@ -104,10 +79,72 @@ Parameters + + + + + Data type + + + + + + + + + + + + + + + + false + + + + + + + Value + + + + + + + Item type + + + + + + + Name + + + + + + + Text description + + + + + + + - + + + + 1 + + + @@ -125,30 +162,37 @@ - + - PushButton + Delete - + - PushButton + Up - + - PushButton + Down - + - PushButton + New Child + + + + + + + New Sibling