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