HAL
plugin_gui.cpp
Go to the documentation of this file.
1 #include "gui/plugin_gui.h"
2 
7 #include "gui/gui_api/gui_api.h"
16 #include "gui/style/style.h"
19 
23 #include "hal_core/utilities/log.h"
27 
28 #include <QDir>
29 #include <QApplication>
30 #include <QFile>
31 #include <QFont>
32 #include <QFontDatabase>
33 #include <QMetaType>
34 #include <QResource>
35 #include <QSettings>
36 #include <QString>
37 #include <QDebug>
38 #include <QDebug>
39 
40 #include <signal.h>
41 
42 namespace hal
43 {
44  void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
45  {
46  QByteArray localMsg = msg.toLocal8Bit();
47  const char *file = context.file ? context.file : "";
48  const char *function = context.function ? context.function : "";
49  switch (type) {
50  case QtDebugMsg:
51  fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
52  break;
53  case QtInfoMsg:
54  fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
55  break;
56  case QtWarningMsg:
57  fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
58  break;
59  case QtCriticalMsg:
60  fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
61  break;
62  case QtFatalMsg:
63  fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
64  break;
65  }
66 
67  if (localMsg.startsWith("QFSFileEngine::open"))
68  fprintf(stderr, "***break***\n");
69  }
70 
71  extern std::unique_ptr<BasePluginInterface> create_plugin_instance()
72  {
73  return std::make_unique<PluginGui>();
74  }
75 
76  QSettings* mGSettings = nullptr;
77  QSettings* gGuiState = nullptr;
79  std::shared_ptr<Netlist> gNetlistOwner = nullptr;
80  Netlist* gNetlist = nullptr;
86  GuiApi* gGuiApi = nullptr;
88  PythonContext* gPythonContext = nullptr;
89 
90  static void handleProgramArguments(const ProgramArguments& args)
91  {
92  enum OpenArgs { None = 0, OpenProject = 1, DefaultImport = 2, ImportToProject = 3 } openArgs = None;
94  std::filesystem::path fileName;
95  ProjectDirectory projDir;
96  QString gateLibraryPath;
97  if (args.is_option_set("--project-dir"))
98  {
99  openArgs = (OpenArgs) (openArgs|OpenProject);
100  projDir = ProjectDirectory(args.get_parameter("--project-dir"));
101  log_info("gui", "GUI started with project {}.", projDir.string());
102  }
103  if (args.is_option_set("--import-netlist"))
104  {
105  openArgs = (OpenArgs) (openArgs|DefaultImport);
106  fileName = std::filesystem::path(args.get_parameter("--import-netlist"));
107  log_info("gui", "GUI started with file {}.", fileName.string());
108  if (args.is_option_set("--gate-library"))
109  gateLibraryPath = QString::fromStdString(args.get_parameter("--gate-library"));
110  }
111  switch (openArgs)
112  {
113  case None:
114  return;
115  case OpenProject:
117  break;
118  case DefaultImport:
119  projDir = ProjectDirectory(fileName);
120  [[fallthrough]];
121  // continue with Import
122  case ImportToProject:
123  if (!pm->create_project_directory(projDir.string()))
124  {
125  log_error("gui", "Cannot create project directory {}.", projDir.string());
126  return;
127  }
128  else
129  {
130  std::filesystem::path lpath = pm->get_project_directory().get_default_filename(".log");
132  if (!FileManager::get_instance()->deprecatedOpenFile(QString::fromStdString(fileName.string()),gateLibraryPath))
133  log_error("gui", "Failed to open netlist '{}'.", fileName.string());
134  }
135  break;
136  }
137  }
138 
139  static void cleanup()
140  {
141  delete mGSettings;
142  delete gGuiState;
143  delete gFileStatusManager;
144  delete gGraphContextManager;
145  delete gNetlistRelay;
146  delete gPluginRelay;
147  delete gSelectionRelay;
148  }
149 
150  static void mCleanup(int sig)
151  {
152  if (sig == SIGINT)
153  {
154  log_info("gui", "Detected Ctrl+C in terminal");
156  }
157  }
158 
159  static void mCrashHandler(int sig)
160  {
161  log_info("gui", "Emergency dump of executed actions on signal {}", sig);
163  signal(sig,SIG_DFL);
164  return;
165  }
166 
167  bool PluginGui::exec(ProgramArguments& args)
168  {
169  int argc;
170  const char** argv;
171  args.get_original_arguments(&argc, &argv);
172 
173  qInstallMessageHandler(myMessageOutput);
174 
175  QApplication a(argc, const_cast<char**>(argv));
176  //FocusLogger focusLogger(&a);
177 
179 
180  QApplication::setApplicationName("HAL Qt Interface");
181  QApplication::setOrganizationName("Chair for Embedded Security - Ruhr University Bochum");
182  QApplication::setOrganizationDomain("emsec.rub.de");
183 
184 // Non native dialogs do not work on macOS. Therefore do net set AA_DontUseNativeDialogs!
185 #ifdef __linux__
186  a.setAttribute(Qt::AA_DontUseNativeDialogs, true);
187 #endif
188  a.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
189 
190  QResource::registerResource("gui_resources.rcc");
191 
192  QFontDatabase::addApplicationFont(":/fonts/Cabin-Bold");
193  QFontDatabase::addApplicationFont(":/fonts/Cabin-BoldItalic");
194  QFontDatabase::addApplicationFont(":/fonts/Cabin-Italic");
195  QFontDatabase::addApplicationFont(":/fonts/Cabin-Medium");
196  QFontDatabase::addApplicationFont(":/fonts/Cabin-MediumItalic");
197  QFontDatabase::addApplicationFont(":/fonts/Cabin-Regular");
198  QFontDatabase::addApplicationFont(":/fonts/Cabin-SemiBold");
199  QFontDatabase::addApplicationFont(":/fonts/Cabin-SemiBoldItalic");
200  QFontDatabase::addApplicationFont(":/fonts/Hack-Bold");
201  QFontDatabase::addApplicationFont(":/fonts/Hack-BoldItalic");
202  QFontDatabase::addApplicationFont(":/fonts/Hack-Regular");
203  QFontDatabase::addApplicationFont(":/fonts/Hack-RegularItalic");
204  QFontDatabase::addApplicationFont(":/fonts/Hack-RegularOblique");
205  QFontDatabase::addApplicationFont(":/fonts/iosevka-bold");
206  QFontDatabase::addApplicationFont(":/fonts/iosevka-bolditalic");
207  QFontDatabase::addApplicationFont(":/fonts/iosevka-italic");
208  QFontDatabase::addApplicationFont(":/fonts/iosevka-oblique");
209  QFontDatabase::addApplicationFont(":/fonts/iosevka-regular");
210  QFontDatabase::addApplicationFont(":/fonts/Droid Sans Mono/DroidSansMono");
211  QFontDatabase::addApplicationFont(":/fonts/Montserrat/Montserrat-Black");
212  QFontDatabase::addApplicationFont(":/fonts/Source Code Pro/SourceCodePro-Black");
213 
214 // gate_library_manager::load_all();
215 
216  //TEMPORARY CODE TO CHANGE BETWEEN THE 2 STYLESHEETS WITH SETTINGS (NOT FINAL)
217  //this settingsobject is currently neccessary to read from the settings from here, because the mGSettings are not yet initialized(?)
218  QString styleSheetToOpen;
219 
220  MainWindow::sSettingStyle = new SettingsItemDropdown(
221  "Theme",
222  "main_style/theme",
223  MainWindow::StyleSheetOption::Dark,
224  "Appearance:Style",
225  "Specifies which theme should be used. Light style is designed to print screenshots and not recommended for regular use."
226  );
229 
230  switch(theme)
231  {
232  case MainWindow::StyleSheetOption::Dark : styleSheetToOpen = ":/style/dark"; break;
233  case MainWindow::StyleSheetOption::Light : styleSheetToOpen = ":/style/light"; break;
234 
235  default: styleSheetToOpen = ":/style/dark";
236  }
237 
238  QFile stylesheet(styleSheetToOpen);
239  stylesheet.open(QFile::ReadOnly);
240  a.setStyleSheet(QString(stylesheet.readAll()));
241  stylesheet.close();
242  //##############END OF TEMPORARY TESTING TO SWITCH BETWEEN STYLESHEETS
243 
245 
246  qRegisterMetaType<u32>("u32");
247  qRegisterMetaType<spdlog::level::level_enum>("spdlog::level::level_enum");
248 
251  gNetlistRelay = new NetlistRelay();
252  gPluginRelay = new PluginRelay();
253  gSelectionRelay = new SelectionRelay();
254  gFileStatusManager = new FileStatusManager();
255  gGraphContextManager = new GraphContextManager();
256 
257  gGuiApi = new GuiApi();
258 
259  const int handleSignals[] = { SIGTERM, SIGSEGV, SIGILL, SIGABRT, SIGFPE, 0 };
260  for (int isignal=0; handleSignals[isignal]; isignal++)
261  signal(handleSignals[isignal], mCrashHandler);
262  signal(SIGINT, mCleanup);
263 
264  MainWindow w;
265  handleProgramArguments(args);
266  w.show();
267  auto ret = a.exec();
268  return ret;
269  }
270 
271  std::string PluginGui::get_name() const
272  {
273  return std::string("hal_gui");
274  }
275 
276  std::string PluginGui::get_version() const
277  {
278  return std::string("2.0");
279  }
280 
281  std::string PluginGui::get_description() const
282  {
283  return std::string("GUI control for HAL app (can't be unloaded)");
284  }
285 
286  void PluginGui::initialize_logging()
287  {
288  const char* gui_info_channel[] = {"user", "gui", "python", "UserStudy", nullptr };
289  for (int i=0; gui_info_channel[i]; i++)
291  }
292 
293  ProgramOptions CliExtensionsGui::get_cli_options() const
294  {
295  ProgramOptions mDescription;
296 
297  mDescription.add({"--gui", "-g"}, "start graphical user interface");
298 
299  return mDescription;
300  }
301 
302  void PluginGui::set_layout_locker(bool enable)
303  {
304  if (enable)
305  mLayoutLockerList.append(new LayoutLocker);
306  else
307  {
308  if (mLayoutLockerList.isEmpty()) return;
309  LayoutLocker* ll = mLayoutLockerList.takeLast();
310  delete ll;
311  }
312  }
313 } // namespace hal
then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file
Manages all ContentWidgets.
void openProject(QString projPath)
static FileManager * get_instance()
Holds information about the state (e.g. saved/unsaved) of all laded files (i.e. .hal/....
User interface to manage all GraphContexts.
Interface to interact with the gui itself.
Definition: gui_api.h:247
std::shared_ptr< spdlog::logger > add_channel(const std::string &channel_name, const std::vector< std::shared_ptr< log_sink >> &sinks, const std::string &level="info")
Definition: log.cpp:100
static std::shared_ptr< log_sink > create_gui_sink()
Definition: log.cpp:274
static std::shared_ptr< log_sink > create_file_sink(const std::filesystem::path &file_name="", const bool truncate=false)
Definition: log.cpp:247
static std::shared_ptr< log_sink > create_stdout_sink(const bool colored=true)
Definition: log.cpp:216
static LogManager * get_instance(const std::filesystem::path &file_name="")
Definition: log.cpp:61
void set_file_name(const std::filesystem::path &file_name)
Definition: log.cpp:291
static SettingsItemDropdown * sSettingStyle
Definition: main_window.h:302
Connects the hal-core events to the gui.
Definition: netlist_relay.h:55
Forwards plugin related events from the core to the gui.
Definition: plugin_relay.h:40
bool add(const std::string &flag, const std::string &description, const std::initializer_list< std::string > &parameters={})
std::filesystem::path get_default_filename(const std::string &extension=std::string()) const
static ProjectManager * instance()
bool create_project_directory(const std::string &path)
const ProjectDirectory & get_project_directory() const
Stores and manages the gui's selection state.
virtual QVariant value() const override
static UserActionManager * instance()
#define log_error(channel,...)
Definition: log.h:78
#define log_info(channel,...)
Definition: log.h:70
void debugUpdate()
Definition: style.cpp:28
std::filesystem::path get_user_config_directory()
Definition: utils.cpp:171
PythonContext * gPythonContext
Definition: plugin_gui.cpp:88
QSettings * gGuiState
Definition: plugin_gui.cpp:77
ContentManager * gContentManager
Definition: plugin_gui.cpp:78
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
Definition: plugin_gui.cpp:44
PluginRelay * gPluginRelay
Definition: plugin_gui.cpp:82
FileStatusManager * gFileStatusManager
Definition: plugin_gui.cpp:84
GraphContextManager * gGraphContextManager
Definition: plugin_gui.cpp:85
SelectionRelay * gSelectionRelay
Definition: plugin_gui.cpp:83
CommentManager * gCommentManager
Definition: plugin_gui.cpp:87
QSettings * mGSettings
Definition: plugin_gui.cpp:76
std::unique_ptr< BasePluginInterface > create_plugin_instance()
Definition: plugin_gui.cpp:71
Netlist * gNetlist
Definition: plugin_gui.cpp:80
NetlistRelay * gNetlistRelay
Definition: plugin_gui.cpp:81
GuiApi * gGuiApi
Definition: plugin_gui.cpp:86
std::shared_ptr< Netlist > gNetlistOwner
Definition: plugin_gui.cpp:79
PinType type
const char * constData() const const
bool startsWith(const QByteArray &ba) const const
void setApplicationName(const QString &application)
void exit(int returnCode)
void setOrganizationDomain(const QString &orgDomain)
void setOrganizationName(const QString &orgName)
int addApplicationFont(const QString &fileName)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool registerResource(const QString &rccFileName, const QString &mapRoot)
QString fromStdString(const std::string &str)
QByteArray toLocal8Bit() const const
AA_DontUseNativeDialogs
int toInt(bool *ok) const const