HAL
gatelibrary_manager.cpp
Go to the documentation of this file.
2 
10 
11 #include <QGridLayout>
12 #include <QVBoxLayout>
13 #include <QHBoxLayout>
14 #include <QGraphicsView>
15 #include <QTabWidget>
16 #include <QTableView>
17 
18 #include <QDebug>
19 #include <QDir>
20 #include <QFileDialog>
21 #include <QHeaderView>
22 #include <QLabel>
23 #include <QPushButton>
24 #include <QTableWidget>
25 #include <QSplitter>
26 #include <QDialogButtonBox>
27 #include <gui/gui_globals.h>
28 
29 namespace hal
30 {
32  : QFrame(parent), mFrameWidth(0), mLayout(new QGridLayout()), mGateLibrary(nullptr)
33  {
34  mSplitter = new QSplitter(this);
35  QWidget* rightWindow = new QWidget(mSplitter);
36  QGridLayout* rlay = new QGridLayout(rightWindow);
38 
39  mTableModel = new GatelibraryTableModel(this);
40  mContentWidget = new GatelibraryContentWidget(mTableModel,mSplitter);
41 
42  //pages for the tab widget
43  mGeneralTab = new GateLibraryTabGeneral(this);
44  mPinTab = new GateLibraryTabPin(false,this);
45  mBooleanFunctionTab = new GateLibraryTabTruthTable(this);
46 
47  //buttons
48  mOkBtn = bbox->button(QDialogButtonBox::Ok);
49  mCancelBtn = bbox->button(QDialogButtonBox::Cancel);
50  mCancelBtn->setEnabled(true);
51 
52  //adding pages to the tab widget
53  mTabWidget = new QTabWidget(this);
54  mTabWidget->addTab(mGeneralTab, "Gate Type");
55  mTabWidget->addTab(mPinTab, "Pins");
56  mTabWidget->addTab(mBooleanFunctionTab, "Truth Table"); // TODO : implement truth table
57 
58  mGraphicsView = new GatelibraryGraphicsView(this);
59  QGraphicsScene* sc = new QGraphicsScene(mGraphicsView);
60  sc->setSceneRect(0,0,300,1200);
61  mGraphicsView->setScene(sc);
62 
63  rlay->addWidget(mTabWidget,0,0);
64  rlay->addWidget(mGraphicsView,0,1);
65  rlay->addWidget(bbox,1,0,1,2);
66 
67  // Add widgets to the layout
68  mSplitter->addWidget(mContentWidget);
69  mSplitter->addWidget(rightWindow);
70 
71  mLayout->addWidget(mSplitter);
72 
76  connect(mContentWidget->mAddAction, &QAction::triggered, this, &GateLibraryManager::handleAddWizard);
80 
81  setLayout(mLayout);
82  repolish(); // CALL FROM PARENT
83  }
84 
86  {
87  QStyle* s = style();
88 
89  s->unpolish(this);
90  s->polish(this);
91  }
92 
94  {
95  mCreationMode = true; //needed for callUnsavedChangesWindow
96  mContentWidget->mCreationMode = mCreationMode;
97  std::filesystem::path path;
98  QFile gldpath(":/path/gate_library_definitions");
99  if (gldpath.open(QIODevice::ReadOnly))
100  {
101  path = QString::fromUtf8(gldpath.readAll()).toStdString();
102  QStringList allNames = QDir(QString::fromStdString(path.string())).entryList();
103  if(allNames.contains("unnamed_gate_library.hgl"))
104  {
105  u32 cnt = 1;
106  while(allNames.contains(QString("unnamed_gate_library(%1).hgl").arg(cnt)))
107  cnt++;
108  path += std::filesystem::path(QString("/unnamed_gate_library(%1).hgl").arg(cnt).toStdString());
109  }
110  else path += "/unnamed_gate_library.hgl";
111  }
112 
114  {
115  if(!callUnsavedChangesWindow()) return;
116  else window()->setWindowTitle(QString("GateLibrary %1").arg(QDir::home().relativeFilePath(QString::fromStdString(path.string()))));
117  }
118  mGateLibrary = new GateLibrary(path, path.string());
119  initialize(mGateLibrary);
120  mCreationMode = false;
121  }
122 
124  {
125  mContentWidget->handleSaveAction();
126  }
127 
129  {
130  mContentWidget->handleSaveAsAction();
131  }
132 
133  bool GateLibraryManager::initialize(GateLibrary* gateLibrary, bool readOnly)
134  {
135  if(!gateLibrary)
136  {
138  // readonly flag makes sure mGateLibrary does not get modified, const attribute not needed
139  mGateLibrary = const_cast<GateLibrary*>(gNetlist->get_gate_library());
140  mReadOnly = true;
141  }
142  else
143  {
144  QString title = "Load gate library";
145  QString text = "HAL Gate Library (*.hgl *.lib)";
146  QString path = QDir::currentPath();
147  QFile gldpath(":/path/gate_library_definitions");
148  if (gldpath.open(QIODevice::ReadOnly))
149  path = QString::fromUtf8(gldpath.readAll());
150 
151  //TODO fileDialog throws bad window error
152  QString fileName = QFileDialog::getOpenFileName(nullptr, title, path, text, nullptr);
153  if (fileName == nullptr)
154  return false;
155 
158 
159  auto gateLibrary = gate_library_manager::load(std::filesystem::path(fileName.toStdString()));
160 
161  if(gateLibrary)
162  mGateLibrary = gateLibrary;
163  else
164  {
165  //extract gatelibrary name from path
166  mGateLibrary = new GateLibrary(std::filesystem::path(fileName.toStdString()), QFileInfo(fileName).baseName().toStdString());
167  }
168 
169  mReadOnly = false;
170  }
171 
172  }
173  else
174  {
175  mReadOnly = readOnly;
176  mGateLibrary = gateLibrary;
177  mProjectName = window()->windowTitle();
178  }
179  QDir dir(QDir::home());
180  if(!gFileStatusManager->isGatelibModified()) window()->setWindowTitle(QString("GateLibrary %1").arg(QDir::home().relativeFilePath(QString::fromStdString(mGateLibrary->get_path().string()))));
181  mPath = mGateLibrary->get_path().generic_string();
182 
183  mDemoNetlist = netlist_factory::create_netlist(mGateLibrary);
184  mGraphicsView->showGate(nullptr);
185  updateTabs(nullptr);
186  mTableModel->loadFile(mGateLibrary);
187  mContentWidget->activate(mReadOnly);
188 
189  mContentWidget->toggleSelection(false);
190  return true;
191  }
192 
194  {
195  if(mReadOnly)
196  return;
197  GateType* gtEditable = mTableModel->getGateTypeAtIndex(index.row());
198  mWizard = new GateLibraryWizard(mGateLibrary, gtEditable);
199  connect(mWizard, &GateLibraryWizard::triggerUnsavedChanges, mContentWidget, &GatelibraryContentWidget::handleUnsavedChanges);
200 
201  mWizard->exec();
202  initialize(mGateLibrary);
203 
204  for (int r=0; r<mTableModel->rowCount(); r++) {
205  if(mTableModel->getGateTypeAtIndex(r) == gtEditable)
206  mContentWidget->mTableView->selectRow(r);
207  }
208  mContentWidget->setGateLibrary(mGateLibrary);
209  mContentWidget->setGateLibraryPath(mPath);
210  }
211 
213  {
214  mWizard = new GateLibraryWizard(mGateLibrary);
215  connect(mWizard, &GateLibraryWizard::triggerUnsavedChanges, mContentWidget, &GatelibraryContentWidget::handleUnsavedChanges);
216 
217  mWizard->exec();
218  initialize(mGateLibrary);
219 
220  for (int r=0; r<mTableModel->rowCount(); r++) {
221  if(mTableModel->getGateTypeAtIndex(r) == mWizard->getRecentCreatedGate())
222  mContentWidget->mTableView->selectRow(r);
223  }
224  mContentWidget->setGateLibrary(mGateLibrary);
225  mContentWidget->setGateLibraryPath(mPath);
226  }
227 
229  {
230  GateType* gate = mTableModel->getGateTypeAtIndex(index.row());
231  mGateLibrary->remove_gate_type(gate->get_name());
232  initialize(mGateLibrary);
234  //qInfo() << "handleDeleteType " << QString::fromStdString(gate->get_name()) << ":" << gate->get_id();
235  }
236 
238  {
239  QSet<u32>* occupiedIds = new QSet<u32>;
240  u32 freeId = 1;
241  for (auto gt : mGateLibrary->get_gate_types()) {
242  occupiedIds->insert(gt.second->get_id());
243  }
244  while(occupiedIds->contains(freeId))
245  {
246  freeId++;
247  }
248  return freeId;
249  }
250 
252  {
253  Q_UNUSED(prevIndex);
254  GateType* gateType;
255  //get selected gate
256  gateType = mTableModel->getGateTypeAtIndex(index.row());
257  //qInfo() << "selected " << QString::fromStdString(gateType->get_name());
258 
259  if(!mReadOnly) mContentWidget->toggleSelection(true);
260  //update tabs
261  updateTabs(gateType);
262  if (mDemoNetlist)
263  {
264  Gate* g = mDemoNetlist->get_gate_by_id(1);
265  if (g) mDemoNetlist->delete_gate(g);
266  g = mDemoNetlist.get()->create_gate(1,gateType,"Instance of");
267  mGraphicsView->showGate(g);
268  }
269  }
270 
272  {
274  {
275  if(!mReadOnly) window()->setWindowTitle("HAL");
276  else window()->setWindowTitle(mProjectName);
277  Q_EMIT close();
278  }
279  else
280  {
282  }
283  }
284 
286  {
288  mContentWidget->handleSaveAction();
289  Q_EMIT close();
290  }
291 
292  GateType* GateLibraryManager::getSelectedGate()
293  {
294  PinProxyModel* proxyModel = mContentWidget->mPinProxyModel;
295  QModelIndex index = mContentWidget->mTableView->currentIndex();
296  QModelIndex sourceIndex = proxyModel->mapToSource(index);
297 
298  return mTableModel->getGateTypeAtIndex(sourceIndex.row());
299  }
300 
302  {
303  mGeneralTab->update(gateType);
304  mBooleanFunctionTab->update(gateType);
305  mPinTab->update(gateType);
306  }
307 
309  {
310  return mReadOnly;
311  }
312 
314  {
315  QMessageBox* msgBox = new QMessageBox(this);
316  msgBox->setWindowTitle("Unsaved changes");
317  msgBox->setInformativeText("The current gate library has been modified. Do you want to save your changes or discard them?");
319 
320  int r = msgBox->exec();
321  switch(r)
322  {
323  case QMessageBox::Save:
324  mContentWidget->handleSaveAsAction();
325  Q_EMIT close();
326  break;
328  if(!mCreationMode)
329  {
330  gate_library_manager::remove(std::filesystem::path(mGateLibrary->get_path()));
331  mDemoNetlist.reset(); //delete unique pointer
333  if(!mReadOnly) window()->setWindowTitle("HAL");
334  else window()->setWindowTitle(mProjectName);
335  Q_EMIT close();
336  }
337  else
338  {
339  gate_library_manager::remove(std::filesystem::path(mGateLibrary->get_path()));
340  mDemoNetlist.reset(); //delete unique pointer
342  }
343  break;
344  case QMessageBox::Cancel:
345  msgBox->reject();
346  return false;
347  }
348  return true;
349  }
350 
352  {
353  QFrame::resizeEvent(evt);
354  if (evt->size().width() != mFrameWidth)
355  {
356  mFrameWidth = evt->size().width();
357  QList<int> splitSizes;
358  // divide available size in percent
359  splitSizes << mFrameWidth * 27 / 100 << mFrameWidth * 73 / 100;
360  mSplitter->setSizes(splitSizes);
361  }
362  }
363 }
Definition: gate.h:58
std::filesystem::path get_path() const
void remove_gate_type(const std::string &name)
std::unordered_map< std::string, GateType * > get_gate_types(const std::function< bool(const GateType *)> &filter=nullptr) const
bool initialize(GateLibrary *gateLibrary=nullptr, bool readOnly=false)
void updateTabs(GateType *gateType)
void handleEditWizard(const QModelIndex &index)
void handleDeleteType(QModelIndex index)
void handleSelectionChanged(const QModelIndex &index, const QModelIndex &prevIndex)
GateLibraryManager(MainWindow *parent)
void resizeEvent(QResizeEvent *evt) override
void update(GateType *gt) override
void update(GateType *gate) override
const std::string & get_name() const
Definition: gate_type.cpp:64
void setGateLibraryPath(std::filesystem::path p)
void triggerEditType(QModelIndex index)
void triggerCurrentSelectionChanged(QModelIndex index, QModelIndex prevIndex)
void triggerDoubleClicked(QModelIndex index)
void triggerDeleteType(QModelIndex index)
A model to display loaded gatelibraries.
void loadFile(const GateLibrary *g)
GateType * getGateTypeAtIndex(int index)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void loadFeature(FacExtensionInterface::Feature ft, const QString &extension=QString())
The top level widget.
Definition: main_window.h:65
const GateLibrary * get_gate_library() const
Definition: netlist.cpp:132
A proxy model to filter the ContextTableModel by a given string.
GuiPluginTable * mGuiPluginTable
Definition: plugin_relay.h:68
void remove(std::filesystem::path file_path)
GateLibrary * load(std::filesystem::path file_path, bool reload)
std::unique_ptr< Netlist > create_netlist(const GateLibrary *gate_library)
Create a new empty netlist using the specified gate library.
PluginRelay * gPluginRelay
Definition: plugin_gui.cpp:82
FileStatusManager * gFileStatusManager
Definition: plugin_gui.cpp:84
Netlist * gNetlist
Definition: plugin_gui.cpp:80
quint32 u32
This file contains various functions to create and load netlists.
void clicked(bool checked)
QModelIndex currentIndex() const const
void triggered(bool checked)
virtual int exec()
virtual void reject()
QPushButton * button(QDialogButtonBox::StandardButton which) const const
QString currentPath()
QStringList entryList(QDir::Filters filters, QDir::SortFlags sort) const const
QDir home()
virtual bool open(QIODevice::OpenMode mode) override
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
void setSceneRect(const QRectF &rect)
void setScene(QGraphicsScene *scene)
void addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment)
QByteArray readAll()
virtual int exec() override
void setInformativeText(const QString &text)
void setWindowTitle(const QString &title)
void setStandardButtons(QMessageBox::StandardButtons buttons)
int row() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
const QSize & size() const const
bool contains(const T &value) const const
QSet::iterator insert(const T &value)
int width() const const
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const const override
void addWidget(QWidget *widget)
void setSizes(const QList< int > &list)
QString fromStdString(const std::string &str)
QString fromUtf8(const char *str, int size)
std::string toStdString() const const
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
virtual void polish(QWidget *widget)
virtual void unpolish(QWidget *widget)
Horizontal
void selectRow(int row)
int addTab(QWidget *page, const QString &label)
QWidget(QWidget *parent, Qt::WindowFlags f)
void setEnabled(bool)
virtual void resizeEvent(QResizeEvent *event)
void setLayout(QLayout *layout)
QStyle * style() const const
QWidget * window() const const
void setWindowTitle(const QString &)