42 #include <QApplication>
43 #include <QCloseEvent>
44 #include <QDesktopWidget>
46 #include <QFileDialog>
47 #include <QInputDialog>
48 #include <QMessageBox>
49 #include <QPushButton>
52 #include <QStringList>
53 #include <QtConcurrent>
70 mLayout->setContentsMargins(0, 0, 0, 0);
71 mLayout->setSpacing(0);
74 mMenuBar->setNativeMenuBar(
true);
76 mLayout->addWidget(mMenuBar);
79 mToolBarLayout->setContentsMargins(0, 0, 0, 0);
80 mToolBarLayout->setSpacing(0);
81 mLayout->addLayout(mToolBarLayout);
84 mLeftToolBar->setObjectName(
"Toolbar");
85 mLeftToolBar->setMovable(
false);
86 mLeftToolBar->setFloatable(
false);
87 mLeftToolBar->setIconSize(
QSize(18, 18));
89 mToolBarLayout->addWidget(mLeftToolBar);
92 mRightToolBar->setObjectName(
"Toolbar");
93 mRightToolBar->setMovable(
false);
94 mRightToolBar->setFloatable(
false);
95 mRightToolBar->setIconSize(
QSize(18, 18));
98 mToolBarLayout->addWidget(mRightToolBar);
101 mLayout->addWidget(mStackedWidget);
104 mStackedWidget->addWidget(mSettings);
108 mStackedWidget->addWidget(mPluginManager);
111 mStackedWidget->addWidget(mLayoutArea);
134 mStackedWidget->addWidget(mWelcomeScreen);
136 mStackedWidget->addWidget(mGateLibraryManager);
138 mStackedWidget->setCurrentWidget(mWelcomeScreen);
142 mActionImportNetlist =
new Action(
this);
143 mActionExportProject =
new Action(
this);
144 mActionImportProject =
new Action(
this);
145 mActionGateLibraryManager =
new Action(
this);
146 mActionAbout =
new Action(
this);
148 mActionStartRecording =
new Action(
this);
149 mActionStopRecording =
new Action(
this);
150 mActionPlayMacro =
new Action(
this);
151 mActionUndo =
new Action(
this);
153 mActionSettings =
new Action(
this);
154 mActionPluginManager =
new Action(
this);
155 mActionQuit =
new Action(
this);
189 mMenuFile =
new QMenu(mMenuBar);
190 mMenuEdit =
new QMenu(mMenuBar);
191 mMenuMacro =
new QMenu(mMenuBar);
192 mMenuUtilities =
new QMenu(mMenuBar);
193 mMenuPlugins =
new QMenu(mMenuBar);
194 mMenuHelp =
new QMenu(mMenuBar);
196 mMenuBar->addAction(mMenuFile->menuAction());
197 mMenuBar->addAction(mMenuEdit->menuAction());
198 mMenuBar->addAction(mMenuMacro->menuAction());
199 mMenuBar->addAction(mMenuUtilities->menuAction());
200 mMenuBar->addAction(mMenuPlugins->menuAction());
201 mMenuBar->addAction(mMenuHelp->menuAction());
202 mMenuFile->addAction(mFileActions->create());
203 mMenuFile->addAction(mFileActions->open());
204 mMenuFile->addAction(mFileActions->close());
205 mMenuFile->addAction(mFileActions->save());
206 mMenuFile->addAction(mFileActions->saveAs());
208 QMenu* menuImport =
new QMenu(
"Import …",
this);
209 menuImport->
addAction(mActionImportNetlist);
210 menuImport->
addAction(mActionImportProject);
212 QMenu* menuExport =
new QMenu(
"Export …",
this);
213 bool hasExporter =
false;
216 if (it.second.empty())
continue;
226 for (std::string ex : it.second)
231 action->setData(extensions);
235 if (hasExporter) mMenuFile->addSeparator();
237 menuExport->
addAction(mActionExportProject);
239 mMenuFile->addMenu(menuImport);
240 mMenuFile->addMenu(menuExport);
241 mMenuFile->addSeparator();
242 mMenuFile->addAction(mActionQuit);
248 "eXpert Settings:Debug",
249 "Specifies whether each netlist event gets dumped to event log. Might generate a lot of output thus slowing down hal system."
254 mMenuEdit->addAction(mActionUndo);
255 mMenuEdit->addSeparator();
256 mMenuEdit->addAction(mActionSettings);
257 mMenuMacro->addAction(mActionStartRecording);
258 mMenuMacro->addAction(mActionStopRecording);
259 mMenuMacro->addSeparator();
260 mMenuMacro->addAction(mActionPlayMacro);
261 mMenuPlugins->setDisabled(
true);
262 mMenuUtilities->addAction(mActionPluginManager);
263 mMenuUtilities->addAction(mActionGateLibraryManager);
264 mMenuHelp->addAction(mActionAbout);
265 mLeftToolBar->addAction(mFileActions->create());
266 mLeftToolBar->addAction(mFileActions->open());
267 mLeftToolBar->addAction(mFileActions->save());
268 mLeftToolBar->addAction(mFileActions->saveAs());
269 mLeftToolBar->addAction(mActionUndo);
270 mRightToolBar->addAction(mActionPluginManager);
271 mRightToolBar->addAction(mActionGateLibraryManager);
272 mRightToolBar->addAction(mActionSettings);
274 mActionStartRecording->setText(
"Start recording");
275 mActionStopRecording->setText(
"Stop recording");
276 mActionPlayMacro->setText(
"Play macro");
278 mActionStartRecording->setEnabled(
true);
279 mActionStopRecording->setEnabled(
false);
280 mActionPlayMacro->setEnabled(
true);
282 setWindowTitle(
"HAL");
283 mActionImportNetlist->setText(
"Import Netlist");
284 mActionImportProject->setText(
"Import Project");
285 mActionExportProject->setText(
"Export Project");
286 mActionGateLibraryManager->setText(
"Gate Library Manager");
287 mActionUndo->setText(
"Undo");
288 mActionAbout->setText(
"About");
289 mActionSettings->setText(
"Settings");
290 mActionPluginManager->setText(
"Plugin Manager");
291 mActionQuit->setText(
"Quit");
292 mMenuFile->setTitle(
"File");
293 mMenuEdit->setTitle(
"Edit");
294 mMenuMacro->setTitle(
"Macro");
295 mMenuUtilities->setTitle(
"Utilities");
296 mMenuPlugins->setTitle(
"Plugins");
297 mMenuHelp->setTitle(
"Help");
304 mSettingUndoLast =
new SettingsItemKeybind(
"Undo Last Action",
"keybinds/action_undo",
QKeySequence(
"Ctrl+Z"),
"Keybindings:Global",
"Keybind for having last user interaction undone.");
306 QShortcut* shortCutUndoLast =
new QShortcut(mSettingUndoLast->value().toString(),
this);
318 connect(mActionExportProject, &
Action::triggered,
this, &MainWindow::handleExportProjectTriggered);
319 connect(mActionImportProject, &
Action::triggered,
this, &MainWindow::handleImportProjectTriggered);
335 void MainWindow::reloadStylsheet(
int istyle)
341 case StyleSheetOption::Dark:
342 styleSheetToOpen =
":/style/dark";
344 case StyleSheetOption::Light:
345 styleSheetToOpen =
":/style/light";
350 QFile stylesheet(styleSheetToOpen);
362 return mHalIconStyle;
367 return mOpenFileIconPath;
372 return mOpenFileIconStyle;
377 return mQuitIconPath;
382 return mQuitIconStyle;
387 return mSettingsIconPath;
392 return mSettingsIconStyle;
397 return mPluginsIconPath;
402 return mPluginsIconStyle;
407 return mUndoIconPath;
412 return mUndoIconStyle;
417 return mNeGateIconPath;
421 return mNeGateIconStyle;
426 return mDisabledIconStyle;
429 void MainWindow::setHalIconPath(
const QString& path)
434 void MainWindow::setHalIconStyle(
const QString& style)
436 mHalIconStyle = style;
439 void MainWindow::setOpenFileIconPath(
const QString& path)
441 mOpenFileIconPath = path;
444 void MainWindow::setOpenFileIconStyle(
const QString& style)
446 mOpenFileIconStyle = style;
449 void MainWindow::setQuitIconPath(
const QString& path)
451 mQuitIconPath = path;
454 void MainWindow::setQuitIconStyle(
const QString& style)
456 mQuitIconStyle = style;
459 void MainWindow::setSettingsIconPath(
const QString& path)
461 mSettingsIconPath = path;
464 void MainWindow::setSettingsIconStyle(
const QString& style)
466 mSettingsIconStyle = style;
469 void MainWindow::setPluginsIconPath(
const QString& path)
471 mPluginsIconPath = path;
474 void MainWindow::setPluginsIconStyle(
const QString& style)
476 mPluginsIconStyle = style;
479 void MainWindow::setUndoIconPath(
const QString& path)
481 mUndoIconPath = path;
484 void MainWindow::setUndoIconStyle(
const QString& style)
486 mUndoIconStyle = style;
489 void MainWindow::setNeGateIconPath(
const QString& path)
491 mNeGateIconPath = path;
493 void MainWindow::setNeGateIconStyle(
const QString& style)
495 mNeGateIconStyle = style;
498 void MainWindow::setDisabledIconStyle(
const QString& style)
500 mDisabledIconStyle = style;
505 mLayoutArea->addContent(widget, index, anchor);
516 mLayoutArea->clear();
519 void MainWindow::handleEventLogEnabled(
bool enable)
526 void MainWindow::onActionCloseDocumentTriggered()
531 void MainWindow::openSettings()
535 if(!mGateLibraryManager->callUnsavedChangesWindow())
return;
537 if (mStackedWidget->currentWidget() == mSettings)
540 mSettings->activate();
541 mStackedWidget->setCurrentWidget(mSettings);
544 void MainWindow::closeSettings()
546 if (!mSettings->handleAboutToClose())
548 if (FileManager::get_instance()->fileOpen())
549 mStackedWidget->setCurrentWidget(mLayoutArea);
551 mStackedWidget->setCurrentWidget(mWelcomeScreen);
554 void MainWindow::closeGateLibraryManager()
556 bool isFileOpen = FileManager::get_instance()->fileOpen();
558 mStackedWidget->setCurrentWidget(mLayoutArea);
560 mStackedWidget->setCurrentWidget(mWelcomeScreen);
561 mFileActions->setup();
564 void MainWindow::openPluginManager()
568 if(!mGateLibraryManager->callUnsavedChangesWindow())
return;
571 mPluginManager->repolish();
572 if (mStackedWidget->currentWidget() == mPluginManager)
575 if (mStackedWidget->currentWidget() == mSettings)
577 if (!mSettings->handleAboutToClose())
580 mStackedWidget->setCurrentWidget(mPluginManager);
581 mFileActions->setup(
nullptr, mPluginManager);
584 void MainWindow::closePluginManager()
586 if (FileManager::get_instance()->fileOpen())
587 mStackedWidget->setCurrentWidget(mLayoutArea);
589 mStackedWidget->setCurrentWidget(mWelcomeScreen);
591 mMenuPlugins->clear();
592 if (FileManager::get_instance()->fileOpen())
593 mPluginManager->addPluginActions(mMenuPlugins);
595 mMenuPlugins->setDisabled(
true);
596 mFileActions->setup();
599 void MainWindow::handleActionNew()
604 msgBox.
setText(
"Error: New Project");
617 void MainWindow::handleActionOpenProject()
622 msgBox.
setText(
"Error: Open Project");
634 for (
int inx = 0; inx < projects.
size(); ++inx)
638 QMessageBox::warning(
this,
"Bad project directory",
"HAL project directories must not have suffix (." +
648 void MainWindow::handleActionImportNetlist()
653 msgBox.
setText(
"Error: Import Netlist");
662 QString title =
"Import Netlist";
687 void MainWindow::handleProjectOpened(
const QString& projDir,
const QString& fileName)
690 mActionExportProject->setEnabled(
true);
691 mActionImportProject->setDisabled(
true);
692 handleFileOpened(fileName);
695 void MainWindow::handleFileOpened(
const QString& fileName)
698 if (mStackedWidget->currentWidget() == mWelcomeScreen)
700 mStackedWidget->setCurrentWidget(mLayoutArea);
701 mWelcomeScreen->close();
705 mMenuPlugins->clear();
706 mPluginManager->addPluginActions(mMenuPlugins);
709 void MainWindow::handleActionExport()
721 void MainWindow::handleActionGatelibraryManager()
727 newBtn->
setToolTip(
"Create new gate library");
729 openBtn->
setToolTip(
"Open existing gate library");
734 optBox.
setText(
"Gate Library Manager");
736 auto btn = optBox.
exec();
740 mGateLibraryManager->handleCreateAction();
741 mStackedWidget->setCurrentWidget(mGateLibraryManager);
742 mFileActions->setup(mGateLibraryManager);
750 if(!mGateLibraryManager->callUnsavedChangesWindow())
return;
752 if(mGateLibraryManager->initialize())
754 mStackedWidget->setCurrentWidget(mGateLibraryManager);
755 mFileActions->setup(mGateLibraryManager);
759 void MainWindow::handleImportProjectTriggered()
764 if (ipd.importProject())
767 ipd.extractedProjectAbsolutePath());
772 "Import Project Failed",
773 "Failed to extract a HAL project from selected archive file.\n"
774 "You might want to uncompress the archive manually and try to fetchGateLibrary the project.");
778 void MainWindow::handleExportProjectTriggered()
780 ExportProjectDialog epd(
this);
787 void MainWindow::handleSaveAsTriggered()
789 QString filename = saveHandler();
794 void MainWindow::handleSaveTriggered()
799 saveHandler(projectDir);
807 QString saveProjectDir(projectDir);
811 if (saveProjectDir.isEmpty())
813 QString title =
"Save Project";
814 QString filter =
"HAL Directory Folder (*)";
818 if (saveProjectDir.isEmpty())
return QString();
822 if (!finfo.suffix().isEmpty())
824 QMessageBox::warning(
this,
"Save Error",
"selected project directory name must not have suffix ." + finfo.suffix());
850 FileManager* fm = FileManager::get_instance();
851 fm->watchFile(qNetlistPath);
852 fm->emitProjectSaved(saveProjectDir, qNetlistPath);
857 void MainWindow::handleActionStartRecording()
859 mActionStartRecording->setEnabled(
false);
860 mActionStopRecording->setEnabled(
true);
861 mActionPlayMacro->setEnabled(
false);
862 UserActionManager::instance()->setStartRecording();
865 void MainWindow::handleActionStopRecording()
869 bool trySaveMacro =
true;
870 while (trySaveMacro) {
885 trySaveMacro =
false;
889 mActionStartRecording->setEnabled(
true);
890 mActionStopRecording->setEnabled(
false);
891 mActionPlayMacro->setEnabled(
true);
894 void MainWindow::handleActionPlayMacro()
898 UserActionManager::instance()->playMacro(macroFile);
901 void MainWindow::handleActionAbout()
907 void MainWindow::handleActionUndo()
909 UserActionManager::instance()->undoLastAction();
912 void MainWindow::enableUndo(
bool enable)
914 QString iconStyle =
enable ? mUndoIconStyle : mDisabledIconStyle;
915 mActionUndo->setEnabled(
enable);
919 void MainWindow::handleActionCloseFile()
921 if (FileManager::get_instance()->fileOpen())
925 void MainWindow::onActionQuitTriggered()
934 if (tryToCloseFile())
947 bool MainWindow::tryToCloseFile()
952 msgBox.setStyleSheet(
"QLabel{min-width: 600px;}");
955 msgBox.setDefaultButton(cancelButton);
956 msgBox.setInformativeText(
"Are you sure you want to close the application ?");
958 msgBox.setText(
"There are unsaved modifications.");
959 QString detailed_text =
"The following modifications have not been saved yet:\n";
961 detailed_text.
append(
" -> modified Gate Library\n");
963 detailed_text.
append(
" -> " + s +
"\n");
965 msgBox.setDetailedText(detailed_text);
967 for (
const auto& button : msgBox.buttons())
979 if (msgBox.clickedButton() == cancelButton)
985 for (GuiExtensionInterface* geif : GuiPluginManager::getGuiExtensions().values())
986 geif->netlist_about_to_close(
gNetlist);
988 mActionExportProject->setDisabled(
true);
989 mActionImportProject->setEnabled(
true);
1002 FileManager::get_instance()->closeFile();
1003 setWindowTitle(
"HAL");
1006 mStackedWidget->setCurrentWidget(mWelcomeScreen);
1010 mMenuPlugins->clear();
1011 mMenuPlugins->setDisabled(
true);
1017 void MainWindow::restoreState()
1019 QPoint pos = SettingsManager::instance()->mainWindowPosition();
1021 QSize size = SettingsManager::instance()->mainWindowSize();
1024 mLayoutArea->initSplitterSize(size);
1027 void MainWindow::saveState()
1029 SettingsManager::instance()->mainWindowSaveGeometry(pos(), size());
A dialog that displays the Qt version and our open source license.
Provides an interface for triggerable functionality that can be inserted into widgets and also connec...
Manages the layout of all ContentWidgets.
Manages all ContentWidgets.
void setWindowTitle(const QString &filename)
Abstract class for Widgets within HAL's ContentArea.
static FileManager * get_instance()
void projectOpened(QString projectDir, QString fileName)
void fileOpened(const QString &fileName)
QList< QString > getUnsavedChangeDescriptors() const
bool modifiedFilesExisting() const
bool isGatelibModified() const
SupportedFileFormats listFacFeature(FacExtensionInterface::Feature ft) const
void loadFeature(FacExtensionInterface::Feature ft, const QString &extension=QString())
The top-level widget that displays all settings.
void closeGateLibraryManager()
void handleActionImportNetlist()
void handleActionGatelibraryManager()
void closePluginManager()
void reloadStylsheet(int istyle)
void handleActionStopRecording()
void handleActionStartRecording()
void enableUndo(bool enable=true)
void handleProjectOpened(const QString &projDir, const QString &fileName)
void handleActionPlayMacro()
void onActionQuitTriggered()
void handleFileOpened(const QString &fileName)
void handleActionExport()
static SettingsItemDropdown * sSettingStyle
GuiPluginTable * mGuiPluginTable
std::filesystem::path get_default_filename(const std::string &extension=std::string()) const
bool create_project_directory(const std::string &path)
bool serialize_project(Netlist *netlist, bool shadow=false)
ProjectStatus get_project_status() const
const ProjectDirectory & get_project_directory() const
A SettingsItem representing a Checkbox.
virtual QVariant value() const override
A SettingsItem that represents a dropdown menu.
void intChanged(int value)
A SettingsItem to modify keybinds.
void keySequenceChanged(QKeySequence value)
Handles and manages user actions related proccesses.
void canUndoLastAction(bool yesWeCan)
static UserActionManager * instance()
QMessageBox::StandardButton setStopRecording(const QString ¯oFilename)
#define log_warning(channel,...)
void enable_event_log(bool enable)
QIcon getStyledSvgIcon(const QString &from_to_colors_enabled, const QString &svg_path, QString from_to_colors_disabled=QString())
const std::unordered_map< std::string, std::vector< std::string > > & get_writer_extensions()
Retrieve the extensions for which extensions have been registered.
const char * MSG_PROJECT_ALREADY_OPEN
PythonContext * gPythonContext
ContentManager * gContentManager
PluginRelay * gPluginRelay
FileStatusManager * gFileStatusManager
void runMain(const QString fileName, const QList< QString > plugins)
GraphContextManager * gGraphContextManager
SelectionRelay * gSelectionRelay
CommentManager * gCommentManager
NetlistRelay * gNetlistRelay
This file contains various functions to create and load netlists.
QVariant data() const const
void triggered(bool checked)
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)
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
QStringList selectedFiles() const const
QString suffix() const const
void append(const T &value)
const T & at(int i) const const
virtual int exec() override
void setInformativeText(const QString &text)
void setWindowTitle(const QString &title)
void setText(const QString &text)
QMessageBox::StandardButton warning(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
QString cap(int nth) const const
int indexIn(const QString &str, int offset, QRegExp::CaretMode caretMode) const const
bool contains(const QString &key) const const
void setValue(const QString &key, const QVariant &value)
QVariant value(const QString &key, const QVariant &defaultValue) const const
void setKey(const QKeySequence &key)
QString & append(QChar ch)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString fromStdString(const std::string &str)
bool isEmpty() const const
bool isNull() const const
QString & remove(int position, int n)
std::string toStdString() const const
bool isNull() const const
bool toBool() const const
QString toString() const const
QStringList toStringList() const const