1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3 
4 #include "core/Cutter.h" // only needed for ut64
5 #include "dialogs/NewFileDialog.h"
6 #include "dialogs/WelcomeDialog.h"
7 #include "common/Configuration.h"
8 #include "common/InitialOptions.h"
9 #include "common/IOModesController.h"
10 #include "common/CutterLayout.h"
11 #include "MemoryDockWidget.h"
12 
13 #include <memory>
14 
15 #include <QMainWindow>
16 #include <QList>
17 
18 class CutterCore;
19 class Omnibar;
20 class ProgressIndicator;
21 class PreviewWidget;
22 class Highlighter;
23 class AsciiHighlighter;
24 class VisualNavbar;
25 class FunctionsWidget;
26 class ImportsWidget;
27 class ExportsWidget;
28 class SymbolsWidget;
29 class RelocsWidget;
30 class CommentsWidget;
31 class StringsWidget;
32 class FlagsWidget;
33 class Dashboard;
34 class QLineEdit;
35 class SdbWidget;
36 class QAction;
37 class SectionsWidget;
38 class SegmentsWidget;
39 class ConsoleWidget;
40 class EntrypointWidget;
41 class DisassemblerGraphView;
42 class ClassesWidget;
43 class ResourcesWidget;
44 class VTablesWidget;
45 class TypesWidget;
46 class HeadersWidget;
47 class ZignaturesWidget;
48 class SearchWidget;
49 class QDockWidget;
50 class DisassemblyWidget;
51 class GraphWidget;
52 class HexdumpWidget;
53 class DecompilerWidget;
54 class OverviewWidget;
55 class R2GraphWidget;
56 class CallGraphWidget;
57 
58 namespace Ui {
59 class MainWindow;
60 }
61 
62 class MainWindow : public QMainWindow
63 {
64     Q_OBJECT
65 
66 public:
67     bool responsive;
68 
69     explicit MainWindow(QWidget *parent = nullptr);
70     ~MainWindow() override;
71 
72     void openNewFile(InitialOptions &options, bool skipOptionsDialog = false);
73     void displayNewFileDialog();
74     void displayWelcomeDialog();
75     void closeNewFileDialog();
76     void openProject(const QString &project_name);
77 
78     /**
79      * @param quit whether to show destructive button in dialog
80      * @return if quit is true, false if the application should not close
81      */
82     bool saveProject(bool quit = false);
83 
84     /**
85      * @param quit whether to show destructive button in dialog
86      * @return false if the application should not close
87      */
88     bool saveProjectAs(bool quit = false);
89 
90     void closeEvent(QCloseEvent *event) override;
91     void paintEvent(QPaintEvent *event) override;
92     void readSettings();
93     void saveSettings();
94     void setFilename(const QString &fn);
95     void refreshOmniBar(const QStringList &flags);
96 
97     void addWidget(CutterDockWidget *widget);
98     void addMemoryDockWidget(MemoryDockWidget *widget);
99     void removeWidget(CutterDockWidget *widget);
100     void addExtraWidget(CutterDockWidget *extraDock);
101     MemoryDockWidget *addNewMemoryWidget(MemoryWidgetType type, RVA address, bool synchronized = true);
102 
103     CUTTER_DEPRECATED("Action will be ignored. Use addPluginDockWidget(CutterDockWidget*) instead.")
addPluginDockWidget(CutterDockWidget * dockWidget,QAction *)104     void addPluginDockWidget(CutterDockWidget *dockWidget, QAction *) { addPluginDockWidget(dockWidget); }
105     void addPluginDockWidget(CutterDockWidget *dockWidget);
106     enum class MenuType { File, Edit, View, Windows, Debug, Help, Plugins };
107     /**
108      * @brief Getter for MainWindow's different menus
109      * @param type The type which represents the desired menu
110      * @return The requested menu or nullptr if "type" is invalid
111      */
112     QMenu *getMenuByType(MenuType type);
113     void addMenuFileAction(QAction *action);
114 
getFilename()115     QString getFilename() const
116     {
117         return filename;
118     }
119     void messageBoxWarning(QString title, QString message);
120 
121     QString getUniqueObjectName(const QString &widgetType) const;
122     void showMemoryWidget();
123     void showMemoryWidget(MemoryWidgetType type);
124     enum class AddressTypeHint { Function, Data, Unknown };
125     QMenu *createShowInMenu(QWidget *parent, RVA address, AddressTypeHint addressType = AddressTypeHint::Unknown);
126     void setCurrentMemoryWidget(MemoryDockWidget* memoryWidget);
127     MemoryDockWidget* getLastMemoryWidget();
128 
129     /* Context menu plugins */
130     enum class ContextMenuType { Disassembly, Addressable };
131     /**
132      * @brief Fetches the pointer to a context menu extension of type
133      * @param type - the type of the context menu
134      * @return plugins submenu of the selected context menu
135      */
136     QMenu *getContextMenuExtensions(ContextMenuType type);
137 
138 public slots:
139     void finalizeOpen();
140 
141     void refreshAll();
142     void seekToFunctionLastInstruction();
143     void seekToFunctionStart();
144     void setTabLocation();
145 
146     void on_actionTabs_triggered();
147 
148     void on_actionAnalyze_triggered();
149 
150     void lockDocks(bool lock);
151 
152     void on_actionRun_Script_triggered();
153 
154     void toggleResponsive(bool maybe);
155 
156     void openNewFileFailed();
157 
158     void toggleOverview(bool visibility, GraphWidget *targetGraph);
159 private slots:
160     void on_actionAbout_triggered();
161     void on_actionIssue_triggered();
162     void documentationClicked();
163     void addExtraGraph();
164     void addExtraHexdump();
165     void addExtraDisassembly();
166     void addExtraDecompiler();
167 
168     void on_actionRefresh_Panels_triggered();
169 
170     void on_actionDisasAdd_comment_triggered();
171 
172     void on_actionDefault_triggered();
173 
174     void on_actionNew_triggered();
175 
176     void on_actionSave_triggered();
177     void on_actionSaveAs_triggered();
178 
179     void on_actionBackward_triggered();
180     void on_actionForward_triggered();
181 
182     void on_actionMap_triggered();
183 
184     void on_actionTabs_on_Top_triggered();
185 
186     void on_actionReset_settings_triggered();
187 
188     void on_actionQuit_triggered();
189 
190     void on_actionRefresh_contents_triggered();
191 
192     void on_actionPreferences_triggered();
193 
194     void on_actionImportPDB_triggered();
195 
196     void on_actionExport_as_code_triggered();
197 
198     void on_actionGrouped_dock_dragging_triggered(bool checked);
199 
200     void projectSaved(bool successfully, const QString &name);
201 
202     void updateTasksIndicator();
203 
204     void mousePressEvent(QMouseEvent *event) override;
205     bool eventFilter(QObject *object, QEvent *event) override;
206     bool event(QEvent *event) override;
207     void toggleDebugView();
208     void chooseThemeIcons();
209 
210     void onZoomIn();
211     void onZoomOut();
212     void onZoomReset();
213 
214     void setAvailableIOModeOptions();
215 private:
216     CutterCore *core;
217 
218     bool tabsOnTop;
219     ut64 hexdumpTopOffset;
220     ut64 hexdumpBottomOffset;
221     QString filename;
222     std::unique_ptr<Ui::MainWindow> ui;
223     Highlighter *highlighter;
224     VisualNavbar *visualNavbar;
225     Omnibar *omnibar;
226     ProgressIndicator *tasksProgressIndicator;
227     QByteArray emptyState;
228     IOModesController ioModesController;
229 
230     Configuration *configuration;
231 
232     QList<CutterDockWidget *> dockWidgets;
233     QList<CutterDockWidget *> pluginDocks;
234     OverviewWidget     *overviewDock = nullptr;
235     QAction *actionOverview = nullptr;
236     EntrypointWidget   *entrypointDock = nullptr;
237     FunctionsWidget    *functionsDock = nullptr;
238     ImportsWidget      *importsDock = nullptr;
239     ExportsWidget      *exportsDock = nullptr;
240     HeadersWidget      *headersDock = nullptr;
241     TypesWidget        *typesDock = nullptr;
242     SearchWidget       *searchDock = nullptr;
243     SymbolsWidget      *symbolsDock = nullptr;
244     RelocsWidget       *relocsDock = nullptr;
245     CommentsWidget     *commentsDock = nullptr;
246     StringsWidget      *stringsDock = nullptr;
247     FlagsWidget        *flagsDock = nullptr;
248     Dashboard          *dashboardDock = nullptr;
249     SdbWidget          *sdbDock = nullptr;
250     SectionsWidget     *sectionsDock = nullptr;
251     SegmentsWidget     *segmentsDock = nullptr;
252     ZignaturesWidget   *zignaturesDock = nullptr;
253     ConsoleWidget      *consoleDock = nullptr;
254     ClassesWidget      *classesDock = nullptr;
255     ResourcesWidget    *resourcesDock = nullptr;
256     VTablesWidget      *vTablesDock = nullptr;
257     CutterDockWidget   *stackDock = nullptr;
258     CutterDockWidget   *threadsDock = nullptr;
259     CutterDockWidget   *processesDock = nullptr;
260     CutterDockWidget   *registersDock = nullptr;
261     CutterDockWidget   *backtraceDock = nullptr;
262     CutterDockWidget   *memoryMapDock = nullptr;
263     NewFileDialog      *newFileDialog = nullptr;
264     CutterDockWidget   *breakpointDock = nullptr;
265     CutterDockWidget   *registerRefsDock = nullptr;
266     R2GraphWidget      *r2GraphDock = nullptr;
267     CallGraphWidget    *callGraphDock = nullptr;
268     CallGraphWidget    *globalCallGraphDock = nullptr;
269 
270     QMenu *disassemblyContextMenuExtensions = nullptr;
271     QMenu *addressableContextMenuExtensions = nullptr;
272 
273     QMap<QString, Cutter::CutterLayout> layouts;
274 
275     void initUI();
276     void initToolBar();
277     void initDocks();
278     void initBackForwardMenu();
279     void displayInitialOptionsDialog(const InitialOptions &options = InitialOptions(), bool skipOptionsDialog = false);
280 
281     Cutter::CutterLayout getViewLayout();
282     Cutter::CutterLayout getViewLayout(const QString &name);
283 
284     void setViewLayout(const Cutter::CutterLayout &layout);
285     void loadLayouts(QSettings &settings);
286     void saveLayouts(QSettings &settings);
287 
288 
289     void updateMemberPointers();
290     void restoreDocks();
291     void showZenDocks();
292     void showDebugDocks();
293     /**
294      * @brief Try to guess which is the "main" section of layout and dock there.
295      * @param widget that needs to be docked
296      */
297     void dockOnMainArea(QDockWidget *widget);
298     void enableDebugWidgetsMenu(bool enable);
299     /**
300      * @brief Fill menu with seek history entries.
301      * @param menu
302      * @param redo set to false for undo history, true for redo.
303      */
304     void updateHistoryMenu(QMenu *menu, bool redo = false);
305     void updateLayoutsMenu();
306     void saveNamedLayout();
307     void manageLayouts();
308 
309     void setOverviewData();
310     bool isOverviewActive();
311     /**
312      * @brief Check if a widget is one of debug specific dock widgets.
313      * @param dock
314      * @return true for debug specific widgets, false for all other including common dock widgets.
315      */
316     bool isDebugWidget(QDockWidget *dock) const;
317     bool isExtraMemoryWidget(QDockWidget *dock) const;
318 
319     MemoryWidgetType getMemoryWidgetTypeToRestore();
320 
321     /**
322      * @brief Map from a widget type (e.g. DisassemblyWidget::getWidgetType()) to the respective contructor of the widget
323      */
324     QMap<QString, std::function<CutterDockWidget*(MainWindow*)>> widgetTypeToConstructorMap;
325 
326     MemoryDockWidget* lastSyncMemoryWidget = nullptr;
327     MemoryDockWidget* lastMemoryWidget = nullptr;
328     int functionDockWidthToRestore = 0;
329 };
330 
331 #endif // MAINWINDOW_H
332