diff --git a/plugins/gui/include/gui/gatelibrary_management/gatelibrary_pages/bool_wizardpage.h b/plugins/gui/include/gui/gatelibrary_management/gatelibrary_pages/bool_wizardpage.h index 86df50bd549..2578e294629 100644 --- a/plugins/gui/include/gui/gatelibrary_management/gatelibrary_pages/bool_wizardpage.h +++ b/plugins/gui/include/gui/gatelibrary_management/gatelibrary_pages/bool_wizardpage.h @@ -33,15 +33,44 @@ #include #include #include +#include namespace hal { class GateLibraryWizard; + + class BoolWizardPage; + + class BooleanFunctionEdit : public QLineEdit + { + Q_OBJECT + public: + + // Would like to define the state as enum, however, + // something seems to go wrong when QSS style converts it to string + // enum State {Empty, Valid, Invalid}; + // Q_ENUM(State) + Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged); + + private: + QString mState; + std::set mLegalVariables; + + Q_SIGNALS: + void stateChanged(QString s); + private Q_SLOTS: + void handleEditingFinished(); + public: + BooleanFunctionEdit(std::set& legalVar, QWidget* parent = nullptr); + QString state() const { return mState; } + void setState(const QString& s); + }; + class BoolWizardPage:public QWizardPage { + friend BooleanFunctionEdit; public: BoolWizardPage(QWidget* parent = nullptr); void initializePage() override; - bool validatePage() override; void setData(GateType* gate); private: diff --git a/plugins/gui/include/gui/pin_model/pin_item.h b/plugins/gui/include/gui/pin_model/pin_item.h index a8527f66e07..16987b45270 100644 --- a/plugins/gui/include/gui/pin_model/pin_item.h +++ b/plugins/gui/include/gui/pin_model/pin_item.h @@ -66,8 +66,10 @@ namespace hal u32 getId() const; QString getName() const; - QString getType() const; - QString getDirection() const; + PinType getPinType() const; + PinDirection getDirection() const; + QString getPinTypeAsText() const; + QString getDirectionAsText() const; TreeItemType getItemType() const; diff --git a/plugins/gui/include/gui/pin_model/pin_model.h b/plugins/gui/include/gui/pin_model/pin_model.h index 9908427203f..839521fb8d0 100644 --- a/plugins/gui/include/gui/pin_model/pin_model.h +++ b/plugins/gui/include/gui/pin_model/pin_model.h @@ -82,14 +82,14 @@ namespace hal * @param index index of the PinItem * @param direction new direction */ - void handleEditDirection(QModelIndex index, const QString& direction); + void handleEditDirection(QModelIndex index, const QString& directionString); /** * should be called when the items type is changed via the delegate * @param index index of the PinItem * @param type new type */ - void handleEditType(QModelIndex index, const QString& type); + void handleEditType(QModelIndex index, const QString& typeString); void handleDeleteItem(QModelIndex index); diff --git a/plugins/gui/resources/stylesheet/dark.qss b/plugins/gui/resources/stylesheet/dark.qss index 6d1de741c1f..7a2193d5cb9 100755 --- a/plugins/gui/resources/stylesheet/dark.qss +++ b/plugins/gui/resources/stylesheet/dark.qss @@ -1477,6 +1477,27 @@ hal--GatelibraryManagementDialog QHeaderView::section background: rgb(35, 35, 35); } +hal--BooleanFunctionEdit +{ + background : black; + color : #E0F0FF; + font-family : "Iosevka"; + font-size : 15px; + font-style : "Heavy"; + font-weight : 700; +} + +hal--BooleanFunctionEdit[state="Empty"] +{ + background : #171e22; + color : #909090; +} + +hal--BooleanFunctionEdit[state="Invalid"] +{ + background: red; +} + hal--GuiPluginManager { qproperty-loadIconPath : ":/icons/insert-plugin"; diff --git a/plugins/gui/src/gatelibrary_management/gatelibrary_pages/bool_wizardpage.cpp b/plugins/gui/src/gatelibrary_management/gatelibrary_pages/bool_wizardpage.cpp index bd4e5b796be..60832a17fe7 100644 --- a/plugins/gui/src/gatelibrary_management/gatelibrary_pages/bool_wizardpage.cpp +++ b/plugins/gui/src/gatelibrary_management/gatelibrary_pages/bool_wizardpage.cpp @@ -4,6 +4,56 @@ namespace hal { + BooleanFunctionEdit::BooleanFunctionEdit(std::set &legalVar, QWidget *parent) + : QLineEdit(parent), mState("Valid"), mLegalVariables(legalVar) + { + connect(this, &QLineEdit::editingFinished, this, &BooleanFunctionEdit::handleEditingFinished); + setState("Empty"); + } + + void BooleanFunctionEdit::setState(const QString &s) + { + if (s == mState) return; + mState = s; + Q_EMIT stateChanged(s); + QStyle* sty = style(); + + sty->unpolish(this); + sty->polish(this); + } + + void BooleanFunctionEdit::handleEditingFinished() + { + if (text().isEmpty()) + { + setState("Empty"); + return; + } + + QString nextState = "Valid"; // think positive + + auto bfres = BooleanFunction::from_string(text().toStdString()); + if(bfres.is_error()) + nextState = "Invalid"; + else + { + BooleanFunction bf = bfres.get(); + std::set var_names = bf.get_variable_names(); + + for(std::string vname : var_names) + { + if (mLegalVariables.find(vname) == mLegalVariables.end()) + { + nextState = "Invalid"; + break; + } + } + } + if (mState != nextState) + setState(nextState); + } + +//-------------------------------------------- BoolWizardPage::BoolWizardPage(QWidget* parent) : QWizardPage(parent) { setTitle("Step 4: Boolean functions"); @@ -15,6 +65,11 @@ namespace hal mWizard = static_cast(wizard()); QList pinGroups = mWizard->getPingroups(); + QList inputPins = mWizard->mPinModel->getInputPins(); + std::set input_pins; + for (PinItem* pi : inputPins) + input_pins.insert(pi->getName().toStdString()); + if(mGate != nullptr){ auto boolFunctions = mGate->get_boolean_functions(); auto list = QList>(); @@ -22,7 +77,7 @@ namespace hal for(std::pair, BooleanFunction> bf : boolFunctions){ QLabel* label = new QLabel(QString::fromStdString(bf.first)); - QLineEdit* lineEdit = new QLineEdit(this); + BooleanFunctionEdit* lineEdit = new BooleanFunctionEdit(input_pins, this); mLayout->addWidget(label, boolFuncCnt, 0); mLayout->addWidget(lineEdit, boolFuncCnt, 1); lineEdit->setText(QString::fromStdString(bf.second.to_string())); @@ -34,20 +89,19 @@ namespace hal { int rowCount = 0; for(PinItem* pinGroup : pinGroups){ - if(pinGroup->getItemType() != PinItem::TreeItemType::GroupCreator && pinGroup->getDirection() == "output"){ + if(pinGroup->getItemType() != PinItem::TreeItemType::GroupCreator && pinGroup->getDirection() == PinDirection::output){ for(auto item : pinGroup->getChildren()) { PinItem* pin = static_cast(item); if(pin->getItemType() != PinItem::TreeItemType::PinCreator){ QLabel* label = new QLabel(pin->getName()); QString name = label->text(); - QLineEdit* lineEdit = new QLineEdit(this); + BooleanFunctionEdit* lineEdit = new BooleanFunctionEdit(input_pins, this); mLayout->addWidget(label, rowCount, 0); mLayout->addWidget(lineEdit, rowCount, 1); rowCount++; } } - } } } @@ -60,23 +114,4 @@ namespace hal mGate = gate; } - bool BoolWizardPage::validatePage(){ - - int rowCount = 0; - QList inputPins = mWizard->mPinModel->getInputPins(); - QList outputPins = mWizard->mPinModel->getOutputPins(); - while(mLayout->itemAtPosition(rowCount, 1) != nullptr){ - QLabel* label = static_cast(mLayout->itemAtPosition(rowCount, 1)->widget()); - auto bfres = BooleanFunction::from_string(label->text().toStdString()); - if(bfres.is_error()) return false; - BooleanFunction bf = bfres.get(); - std::set names = bf.get_variable_names(); - for(auto item : inputPins) - { - if(names.find(item->getName().toStdString()) == names.end()) return false; - } - rowCount++; - } - return true; - } } diff --git a/plugins/gui/src/gatelibrary_management/gatelibrary_pages/ram_port_wizardpage.cpp b/plugins/gui/src/gatelibrary_management/gatelibrary_pages/ram_port_wizardpage.cpp index 8f9864829e2..a1ba813ad87 100644 --- a/plugins/gui/src/gatelibrary_management/gatelibrary_pages/ram_port_wizardpage.cpp +++ b/plugins/gui/src/gatelibrary_management/gatelibrary_pages/ram_port_wizardpage.cpp @@ -51,8 +51,8 @@ void RAMPortWizardPage::initializePage(){ //create empty lines for ram_port for each data/address pair //assumption at this point: #data fields = #address fields for (int i=0; igetType(); - if(type == "data") + PinType type = pinGroups[i]->getPinType(); + if(type == PinType::data) { ramPortCnt++; mLayout->addWidget(new GateLibraryLabel(false, QString("RAM Port %1").arg(ramPortCnt), this), 6*(ramPortCnt-1), 0); diff --git a/plugins/gui/src/pin_model/pin_delegate.cpp b/plugins/gui/src/pin_model/pin_delegate.cpp index c7025ea2e6a..908dcf06591 100644 --- a/plugins/gui/src/pin_model/pin_delegate.cpp +++ b/plugins/gui/src/pin_model/pin_delegate.cpp @@ -102,7 +102,7 @@ namespace hal if(itemType != PinItem::TreeItemType::Pin && itemType != PinItem::TreeItemType::InvalidPin) break; auto comboBox = static_cast(editor); - comboBox->setCurrentText(pinItem->getDirection()); + comboBox->setCurrentText(pinItem->getDirectionAsText()); break; } case 2: { @@ -110,7 +110,7 @@ namespace hal if(itemType == PinItem::TreeItemType::PinCreator || itemType == PinItem::TreeItemType::GroupCreator) break; auto comboBox = static_cast(editor); - comboBox->setCurrentText(pinItem->getType()); + comboBox->setCurrentText(pinItem->getPinTypeAsText()); break; } } diff --git a/plugins/gui/src/pin_model/pin_item.cpp b/plugins/gui/src/pin_model/pin_item.cpp index ab2b55a2d05..2397626293d 100644 --- a/plugins/gui/src/pin_model/pin_item.cpp +++ b/plugins/gui/src/pin_model/pin_item.cpp @@ -83,12 +83,22 @@ namespace hal return mName; } - QString PinItem::getType() const + PinType PinItem::getPinType() const + { + return mType; + } + + QString PinItem::getPinTypeAsText() const { return QString::fromStdString(enum_to_string(mType)); } - QString PinItem::getDirection() const + PinDirection PinItem::getDirection() const + { + return mDirection; + } + + QString PinItem::getDirectionAsText() const { return QString::fromStdString(enum_to_string(mDirection)); } diff --git a/plugins/gui/src/pin_model/pin_model.cpp b/plugins/gui/src/pin_model/pin_model.cpp index 7cd75d2cbc7..329fe4ab35c 100644 --- a/plugins/gui/src/pin_model/pin_model.cpp +++ b/plugins/gui/src/pin_model/pin_model.cpp @@ -91,21 +91,25 @@ namespace hal for(auto group : tempGroupList){ auto groupItem = new PinItem(PinItem::TreeItemType::PinGroup); //get all infos for that group - QString groupDirection = group->getDirection(); - QString groupType = group->getType(); + PinDirection groupDirection = group->getDirection(); + PinType groupType = group->getPinType(); //create group item - groupItem->setData(QList() << group->getId() << group->getName() << groupDirection << groupType); + groupItem->setName(group->getName()); + groupItem->setDirection(groupDirection); + groupItem->setType(groupType); for (auto item : group->getChildren()) { auto pinItem = new PinItem(PinItem::TreeItemType::Pin); PinItem* pin = static_cast(item); //get all infos for that pin - QString pinDirection = pin->getDirection(); - QString pinType = pin->getType(); + PinDirection pinDirection = pin->getDirection(); + PinType pinType = pin->getPinType(); - pinItem->setData(QList() << pin->getId() << pin->getName() << pinDirection << pinType); + pinItem->setName(pin->getName()); + pinItem->setDirection(pinDirection); + pinItem->setType(pinType); groupItem->appendChild(pinItem); @@ -197,7 +201,7 @@ namespace hal newPinGroup->setId(pinItem->getId()); newPinGroup->setName(pinItem->getName()); newPinGroup->setDirection(pinItem->getDirection()); - newPinGroup->setType(pinItem->getType()); + newPinGroup->setType(pinItem->getPinType()); endInsertRows(); //add pin to group @@ -211,8 +215,8 @@ namespace hal if(!renamePin(pinItem, input)) break; PinItem* parentGroup = static_cast(pinItem->getParent()); - PinDirection pdir = enum_from_string(parentGroup->getDirection().toStdString()); - PinType ptype = enum_from_string(parentGroup->getType().toStdString()); + PinDirection pdir = parentGroup->getDirection(); + PinType ptype = parentGroup->getPinType(); pinItem->setFields(input, getNextId(PinItem::TreeItemType::Pin), pdir, ptype); if(pdir != PinDirection::none) pinItem->setItemType(PinItem::TreeItemType::Pin); else pinItem->setItemType(PinItem::TreeItemType::InvalidPin); @@ -240,13 +244,15 @@ namespace hal Q_EMIT dataChanged(index, index); } - void PinModel::handleEditDirection(QModelIndex index, const QString& direction) + void PinModel::handleEditDirection(QModelIndex index, const QString& directionString) { if(!index.isValid()) return; //TODO handle direction edited from PinDelegate auto pinItem = static_cast(index.internalPointer()); auto itemType = pinItem->getItemType(); + PinDirection pinDirection = enum_from_string(directionString.toStdString()); + switch(itemType){ case PinItem::TreeItemType::PinGroup: /*{ @@ -263,12 +269,12 @@ namespace hal break; }*/ case PinItem::TreeItemType::InvalidPinGroup:{ - pinItem->setDirection(direction); + pinItem->setDirection(directionString); for(auto child : pinItem->getChildren()) //set same direction for all pins of the pingroup { PinItem* pin = static_cast(child); if(pin->getItemType() == PinItem::TreeItemType::Pin || pin->getItemType() == PinItem::TreeItemType::InvalidPin){ - pin->setDirection(direction); + pin->setDirection(directionString); handleInvalidPinUpdate(pin); } } @@ -291,19 +297,19 @@ namespace hal PinItem* parentGroup = static_cast(pinItem->getParent()); warning.setWindowTitle("New pin creation"); warning.setText(QString("You are about to create an %1 pin in an %2 pin group") - .arg(direction) - .arg(parentGroup->getDirection())); - if(direction != parentGroup->getDirection()) + .arg(directionString) + .arg(parentGroup->getDirectionAsText())); + if(pinDirection != parentGroup->getDirection()) { warning.exec(); if(warning.clickedButton() == acceptBtn){ - pinItem->setDirection(direction); + pinItem->setDirection(pinDirection); handleInvalidPinUpdate(pinItem); } } else { - pinItem->setDirection(direction); + pinItem->setDirection(pinDirection); handleInvalidPinUpdate(pinItem); } @@ -313,30 +319,32 @@ namespace hal Q_EMIT dataChanged(index, index); } - void PinModel::handleEditType(QModelIndex index, const QString& type) + void PinModel::handleEditType(QModelIndex index, const QString& typeString) { if(!index.isValid()) return; auto pinItem = static_cast(index.internalPointer()); auto itemType = pinItem->getItemType(); + PinType pinType = enum_from_string(typeString.toStdString()); + switch (itemType) { case PinItem::TreeItemType::InvalidPin:{ - pinItem->setType(type); + pinItem->setType(pinType); handleInvalidPinUpdate(pinItem); break; } case PinItem::TreeItemType::Pin: { - pinItem->setType(type); + pinItem->setType(pinType); break; } case PinItem::TreeItemType::InvalidPinGroup:{ - pinItem->setType(type); + pinItem->setType(pinType); for(auto child : pinItem->getChildren()) //set same type for all pins of the pingroup { PinItem* pin = static_cast(child); if(pin->getItemType() == PinItem::TreeItemType::Pin || pin->getItemType() == PinItem::TreeItemType::InvalidPin){ - pin->setType(type); + pin->setType(pinType); handleInvalidPinUpdate(pin); } } @@ -344,7 +352,7 @@ namespace hal break; } case PinItem::TreeItemType::PinGroup: { - pinItem->setType(type); + pinItem->setType(pinType); //PinModel::PINGROUP* pinGroup = static_cast(pinItem); /*for(auto child : pinItem->getChildren()) //set same type for all pins of the pingroup @@ -359,7 +367,7 @@ namespace hal if(group->getName() == pinItem->getName()){ for(auto item : group->getChildren()){ PinItem* pin = static_cast(item); - pin->setType(type); + pin->setType(pinType); } break; } @@ -466,7 +474,7 @@ namespace hal void PinModel::handleInvalidPinUpdate(PinItem* pinItem) { if(!isNameAvailable(pinItem->getName(), pinItem) - || enum_from_string(pinItem->getDirection().toStdString()) == PinDirection::none) + || pinItem->getDirection() == PinDirection::none) return; // Pin is not valid //pin is valid @@ -626,7 +634,11 @@ namespace hal { QList retval; for (BaseTreeItem* bti : mRootItem->getChildren()) - retval.append(static_cast(bti)); + { + PinItem* grp = static_cast(bti); + if (grp->getItemType() != PinItem::TreeItemType::PinGroup) continue; + retval.append(grp); + } return retval; } @@ -720,9 +732,11 @@ namespace hal QList inputPins; for(BaseTreeItem* pinGroup : mRootItem->getChildren()) { + if (static_cast(pinGroup)->getItemType() != PinItem::TreeItemType::PinGroup) continue; for(BaseTreeItem* item : pinGroup->getChildren()){ PinItem* pin = static_cast(item); - if(pin->getDirection() == "input" || pin->getDirection() == "inout") inputPins.append(pin); + if (pin->getItemType() != PinItem::TreeItemType::Pin) continue; + if (pin->getDirection() == PinDirection::input || pin->getDirection() == PinDirection::inout) inputPins.append(pin); } } return inputPins; @@ -733,9 +747,11 @@ namespace hal QList outputPins; for(BaseTreeItem* pinGroup : mRootItem->getChildren()) { + if (static_cast(pinGroup)->getItemType() != PinItem::TreeItemType::PinGroup) continue; for(BaseTreeItem* item : pinGroup->getChildren()){ PinItem* pin = static_cast(item); - if(pin->getDirection() == "output" || pin->getDirection() == "inout") outputPins.append(pin); + if (pin->getItemType() != PinItem::TreeItemType::Pin) continue; + if (pin->getDirection() == PinDirection::output || pin->getDirection() == PinDirection::inout) outputPins.append(pin); } } return outputPins;