HAL
bool_wizardpage.cpp
Go to the documentation of this file.
4 
5 namespace hal
6 {
7  const char* BooleanFunctionEdit::STATE_EMPTY = "Empty";
8  const char* BooleanFunctionEdit::STATE_VALID = "Valid";
9  const char* BooleanFunctionEdit::STATE_INVALID = "Invalid";
10 
11  BooleanFunctionEdit::BooleanFunctionEdit(std::set<std::string> &legalVar, QWidget *parent)
12  : QLineEdit(parent), mState(STATE_VALID), mLegalVariables(legalVar)
13  {
14  connect(this, &QLineEdit::textChanged, this, &BooleanFunctionEdit::handleEditingFinished);
15  connect(this, &BooleanFunctionEdit::legalVariablesChanged, this, &BooleanFunctionEdit::handleEditingFinished);
16 
17  setState(STATE_EMPTY); // do an active transition to enforce style
18  }
19 
21  {
22  if (s == mState) return;
23  mState = s;
25  QStyle* sty = style();
26 
27  sty->unpolish(this);
28  sty->polish(this);
29  }
30 
31  void BooleanFunctionEdit::setLegalVariables(std::set<std::string> &legalVar)
32  {
33  mLegalVariables = legalVar;
34  Q_EMIT legalVariablesChanged(legalVar);
35  }
36 
37  void BooleanFunctionEdit::handleEditingFinished()
38  {
39  if (text().isEmpty())
40  {
41  setState(STATE_EMPTY);
42  return;
43  }
44 
45  QString nextState = STATE_VALID; // think positive
46 
47  auto bfres = BooleanFunction::from_string(text().toStdString());
48  if(bfres.is_error())
49  nextState = STATE_INVALID;
50  else
51  {
52  BooleanFunction bf = bfres.get();
53  std::set<std::string> var_names = bf.get_variable_names();
54  std::set<std::string> leg = mLegalVariables;
55  for(std::string vname : var_names)
56  {
57  if (mLegalVariables.find(vname) == mLegalVariables.end())
58  {
59  nextState = STATE_INVALID;
60  break;
61  }
62  }
63  }
64  if (mState != nextState)
65  setState(nextState);
66 
67  }
68 //--------------------------------------------
70  : QWizardPage(parent)
71  {
72  setTitle("Boolean functions");
73  setSubTitle("Enter the boolean functions");
74  mLayout = new QGridLayout(this);
75  }
76 
78  mWizard = static_cast<GateLibraryWizard*>(wizard());
79  QList<PinItem*> pinGroups = mWizard->getPingroups();
80 
81  QList<PinItem*> inputPins = mWizard->mPinModel->getInputPins();
82  QList<PinItem*> outputPins = mWizard->mPinModel->getOutputPins();
83  std::set<std::string> legVars;
84  for (PinItem* pi : inputPins)
85  legVars.insert(pi->getName().toStdString());
86 
87  if (!mEditFunctions.isEmpty())
88  {
89  for (BooleanFunctionEdit* bfe : mEditFunctions)
90  delete bfe;
91  mEditFunctions.clear();
92  }
93 
94  if(mGate != nullptr){
95  std::unordered_map<std::string, BooleanFunction> boolFunctions = mGate->get_boolean_functions();
97  int boolFuncCnt = 0;
98 
99  for(PinItem* pi : outputPins)
100  {
101  QLabel* label = new QLabel(pi->getName());
102  BooleanFunctionEdit* lineEdit;
103  if(mWizard->generalInfoPage->getProperties().contains(GateTypeProperty::ff)
104  || mWizard->generalInfoPage->getProperties().contains(GateTypeProperty::latch))
105  {
106  legVars.insert(mWizard->statePage->mStateIdentifier->text().toStdString());
107  legVars.insert(mWizard->statePage->mNegStateIdentifier->text().toStdString());
108  }
109  lineEdit = new BooleanFunctionEdit(legVars, this);
110  mLayout->addWidget(label, boolFuncCnt, 0);
111  mLayout->addWidget(lineEdit, boolFuncCnt, 1);
112 
113  if(auto bf = boolFunctions.find(pi->getName().toStdString()); bf != boolFunctions.end())
114  {
115  lineEdit->setText(QString::fromStdString(bf->second.to_string()));
116  }
117  connect(lineEdit, &BooleanFunctionEdit::stateChanged,this,&BoolWizardPage::handleStateChanged);
118  connect(lineEdit, &BooleanFunctionEdit::textChanged, this, &BoolWizardPage::handleTextChanged);
119  mEditFunctions.append(lineEdit);
120  mOutputPins.append(label->text());
121  boolFuncCnt++;
122  }
123  }
124  else{
125  if(!pinGroups.empty())
126  {
127  int rowCount = 0;
128  for(PinItem* pinGroup : pinGroups){
129  if(pinGroup->getItemType() != PinItem::TreeItemType::GroupCreator && pinGroup->getDirection() == PinDirection::output){
130  for(auto item : pinGroup->getChildren())
131  {
132  PinItem* pin = static_cast<PinItem*>(item);
134  QLabel* label = new QLabel(pin->getName());
135  QString name = label->text();
136  BooleanFunctionEdit* lineEdit;
137 
138  if(mWizard->generalInfoPage->getProperties().contains(GateTypeProperty::ff) ||
139  mWizard->generalInfoPage->getProperties().contains(GateTypeProperty::latch))
140  {
141  legVars.insert(mWizard->statePage->mStateIdentifier->text().toStdString());
142  legVars.insert(mWizard->statePage->mNegStateIdentifier->text().toStdString());
143  }
144  lineEdit = new BooleanFunctionEdit(legVars, this);
145 
146  mLayout->addWidget(label, rowCount, 0);
147  mLayout->addWidget(lineEdit, rowCount, 1);
148  connect(lineEdit,&BooleanFunctionEdit::stateChanged,this,&BoolWizardPage::handleStateChanged);
149  connect(lineEdit, &BooleanFunctionEdit::textChanged, this, &BoolWizardPage::handleTextChanged);
150  mEditFunctions.append(lineEdit);
151  mOutputPins.append(label->text());
152  rowCount++;
153  }
154  }
155  }
156  }
157  }
158  }
159 
160  setLayout(mLayout);
162  mWizard->mEditMode = true;
163  }
164 
166  {
167  mGate = gate;
168  }
169 
170  void BoolWizardPage::handleStateChanged(const QString& stat)
171  {
172  Q_UNUSED(stat);
174  if(mWizard->mEditMode) Q_EMIT hasChanged();
175  }
176 
177  void BoolWizardPage::handleTextChanged(const QString& txt)
178  {
179  Q_UNUSED(txt);
180 
181  //explicitly needed here because isComplete() is called
182  //before mWasEdited is changed in the wizard
183  //
184 
185  if(mWizard->mEditMode)
186  {
187  mWizard->mWasEdited = true;
188  Q_EMIT hasChanged();
189  }
191  }
192 
194  {
195  for(BooleanFunctionEdit* lineEdit : mEditFunctions)
196  {
197  if(!lineEdit->isValid())
198  {
199  return false;
200  }
201  }
202  if(isFinalPage() && !mWizard->mWasEdited) return false;
203  mWizard->mEditMode = false;
204  return true;
205  }
206 
207  std::unordered_map<std::string, BooleanFunction> BoolWizardPage::getBoolFunctions(){
208  std::unordered_map<std::string, BooleanFunction> retval;
209  for(int i = 0; i<mEditFunctions.length(); i++)
210  {
211  auto bfres = BooleanFunction::from_string(mEditFunctions[i]->text().toStdString());
212  if(bfres.is_error())
213  continue;
214  else
215  retval.insert({mOutputPins[i].toStdString(), bfres.get()});
216  }
217  return retval;
218  }
219 
220 }
BoolWizardPage(QWidget *parent=nullptr)
std::unordered_map< std::string, BooleanFunction > getBoolFunctions()
void setData(GateType *gate)
void initializePage() override
bool isComplete() const override
void setState(const QString &s)
void setLegalVariables(std::set< std::string > &legalVar)
void legalVariablesChanged(std::set< std::string > legalVar)
BooleanFunctionEdit(std::set< std::string > &legalVar, QWidget *parent=nullptr)
void stateChanged(QString s)
static Result< BooleanFunction > from_string(const std::string &expression)
QList< PinItem * > getPingroups()
const std::unordered_map< std::string, BooleanFunction > & get_boolean_functions() const
Definition: gate_type.cpp:746
QList< GateTypeProperty > getProperties() const
An item in the PinModel.
Definition: pin_item.h:48
QString getName() const
Definition: pin_item.cpp:81
TreeItemType getItemType() const
Definition: pin_item.cpp:132
QList< PinItem * > getInputPins()
Definition: pin_model.cpp:729
QList< PinItem * > getOutputPins()
Definition: pin_model.cpp:744
std::string name
void addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment)
void insert(const QString &newText)
void textChanged(const QString &text)
void append(const T &value)
bool empty() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString fromStdString(const std::string &str)
virtual void polish(QWidget *widget)
virtual void unpolish(QWidget *widget)
void setLayout(QLayout *layout)
QStyle * style() const const
void completeChanged()
bool isFinalPage() const const
void setSubTitle(const QString &subTitle)
void setTitle(const QString &title)
QWizard * wizard() const const