From 1e6782de4827c02ff698a1e8d178737f80985019 Mon Sep 17 00:00:00 2001 From: Premade <128969155+PremadeS@users.noreply.github.com> Date: Thu, 21 May 2026 14:26:49 +0500 Subject: [PATCH] Refactor code to match new style (#3612) * Refactor code to match coding style * NULL to nullptr * clang format 16 * Remove unused header * Fix ordering of headers * QtResImporter: Don't ignore return value of file.open() * Add missing memory header * GraphGridLayout: Remove * GraphGridLayout: no views::reverse * Fix typos * Console widget cmd fix --- src/CMakeLists.txt | 9 +- src/CutterApplication.cpp | 218 ++-- src/CutterApplication.h | 13 +- src/Main.cpp | 14 +- src/bindings/bindings.h | 6 +- src/common/AddressableItemModel.cpp | 4 +- src/common/AddressableItemModel.h | 24 +- src/common/AnalysisTask.cpp | 37 +- src/common/AnalysisTask.h | 15 +- src/common/AsyncTask.cpp | 19 +- src/common/AsyncTask.h | 30 +- src/common/BasicBlockHighlighter.cpp | 15 +- src/common/BasicBlockHighlighter.h | 18 +- src/common/BasicInstructionHighlighter.cpp | 25 +- src/common/BasicInstructionHighlighter.h | 37 +- src/common/BinaryTrees.h | 67 +- src/common/BugReporting.cpp | 7 +- src/common/BugReporting.h | 6 +- src/common/CachedFontMetrics.h | 63 +- src/common/ColorThemeWorker.cpp | 45 +- src/common/ColorThemeWorker.h | 44 +- src/common/Colors.cpp | 100 +- src/common/Colors.h | 38 +- src/common/CommandTask.cpp | 3 +- src/common/CommandTask.h | 9 +- src/common/Configuration.cpp | 123 ++- src/common/Configuration.h | 25 +- src/common/CutterLayout.cpp | 2 +- src/common/CutterLayout.h | 7 +- src/common/CutterSearchable.cpp | 18 +- src/common/CutterSearchable.h | 8 +- src/common/CutterSeekable.cpp | 9 +- src/common/CutterSeekable.h | 17 +- src/common/Decompiler.cpp | 8 +- src/common/Decompiler.h | 12 +- src/common/DecompilerHighlighter.cpp | 16 +- src/common/DecompilerHighlighter.h | 12 +- src/common/DirectionalComboBox.h | 4 +- src/common/DisassemblyHelper.cpp | 55 +- src/common/DisassemblyHelper.h | 11 +- src/common/DisassemblyPreview.cpp | 36 +- src/common/DisassemblyPreview.h | 9 +- src/common/FunctionsTask.h | 6 +- src/common/Helpers.cpp | 90 +- src/common/Helpers.h | 32 +- src/common/HighDpiPixmap.cpp | 8 +- src/common/HighDpiPixmap.h | 4 + src/common/Highlighter.cpp | 64 -- src/common/Highlighter.h | 46 - src/common/IOModesController.cpp | 26 +- src/common/IOModesController.h | 7 +- src/common/InitialOptions.h | 8 +- src/common/{JsonModel.cpp => Json.cpp} | 6 +- src/common/Json.h | 27 +- src/common/JsonModel.h | 14 - src/common/LinkedListPool.h | 15 +- src/common/MdHighlighter.cpp | 12 +- src/common/MdHighlighter.h | 8 +- src/common/Metrics.h | 1 - src/common/PythonAPI.cpp | 2 +- src/common/PythonManager.cpp | 14 +- src/common/QtResImporter.cpp | 18 +- src/common/RefreshDeferrer.cpp | 2 +- src/common/RefreshDeferrer.h | 2 +- src/common/ResourcePaths.cpp | 16 +- src/common/ResourcePaths.h | 2 +- src/common/RichTextPainter.cpp | 57 +- src/common/RichTextPainter.h | 84 +- src/common/RizinTask.cpp | 13 +- src/common/RizinTask.h | 11 +- src/common/RunScriptTask.cpp | 3 +- src/common/RunScriptTask.h | 12 +- src/common/SelectionHighlight.cpp | 22 +- src/common/SelectionHighlight.h | 29 +- src/common/SettingsUpgrade.cpp | 304 +++--- src/common/SettingsUpgrade.h | 12 +- src/common/StringsTask.h | 12 +- src/common/SvgIconEngine.cpp | 16 +- src/common/SvgIconEngine.h | 4 +- src/common/SyntaxHighlighter.cpp | 4 +- src/common/SyntaxHighlighter.h | 9 +- src/common/TempConfig.cpp | 23 +- src/common/TempConfig.h | 4 +- src/common/UpdateWorker.cpp | 38 +- src/common/UpdateWorker.h | 11 +- src/core/Basefind.cpp | 20 +- src/core/Basefind.h | 23 +- src/core/Cutter.cpp | 954 +++++++++--------- src/core/Cutter.h | 214 ++-- src/core/CutterCommon.h | 18 +- src/core/CutterDescriptions.h | 43 +- src/core/CutterJson.cpp | 2 +- src/core/CutterJson.h | 39 +- src/core/MainWindow.cpp | 460 +++++---- src/core/MainWindow.h | 104 +- src/core/MainWindow.ui | 125 +-- src/core/RizinCpp.h | 54 +- src/dialogs/AboutDialog.cpp | 64 +- src/dialogs/AboutDialog.h | 22 +- src/dialogs/AboutDialog.ui | 20 +- src/dialogs/ArenaInfoDialog.cpp | 20 +- src/dialogs/ArenaInfoDialog.h | 4 +- src/dialogs/AsyncTaskDialog.cpp | 16 +- src/dialogs/AsyncTaskDialog.h | 12 +- src/dialogs/AttachProcDialog.cpp | 70 +- src/dialogs/AttachProcDialog.h | 19 +- src/dialogs/BreakpointsDialog.cpp | 14 +- src/dialogs/BreakpointsDialog.h | 9 +- src/dialogs/CommentsDialog.cpp | 17 +- src/dialogs/CommentsDialog.h | 14 +- src/dialogs/EditFunctionDialog.cpp | 10 +- src/dialogs/EditFunctionDialog.h | 8 +- src/dialogs/EditInstructionDialog.cpp | 16 +- src/dialogs/EditInstructionDialog.h | 12 +- src/dialogs/EditMethodDialog.cpp | 35 +- src/dialogs/EditMethodDialog.h | 16 +- src/dialogs/EditRegProfileDialog.cpp | 52 +- src/dialogs/EditRegProfileDialog.h | 11 +- src/dialogs/EditStringDialog.cpp | 23 +- src/dialogs/EditStringDialog.h | 10 +- src/dialogs/EditStringDialog.ui | 32 +- src/dialogs/EditVariablesDialog.cpp | 42 +- src/dialogs/EditVariablesDialog.h | 12 +- src/dialogs/EditVariablesDialog.ui | 8 +- src/dialogs/FlagDialog.cpp | 23 +- src/dialogs/FlagDialog.h | 11 +- src/dialogs/GlibcHeapBinsDialog.cpp | 48 +- src/dialogs/GlibcHeapBinsDialog.h | 17 +- src/dialogs/GlibcHeapInfoDialog.cpp | 27 +- src/dialogs/GlibcHeapInfoDialog.h | 10 +- src/dialogs/GlobalVariableDialog.cpp | 15 +- src/dialogs/GlobalVariableDialog.h | 9 +- src/dialogs/HexdumpRangeDialog.cpp | 29 +- src/dialogs/HexdumpRangeDialog.h | 21 +- src/dialogs/InitialOptionsDialog.cpp | 131 ++- src/dialogs/InitialOptionsDialog.h | 23 +- src/dialogs/InitialOptionsDialog.ui | 18 +- src/dialogs/LayoutManager.cpp | 11 +- src/dialogs/LayoutManager.h | 12 +- src/dialogs/MapFileDialog.cpp | 19 +- src/dialogs/MapFileDialog.h | 12 +- src/dialogs/MarkDialog.cpp | 20 +- src/dialogs/MarkDialog.h | 14 +- src/dialogs/MultitypeFileSaveDialog.cpp | 28 +- src/dialogs/MultitypeFileSaveDialog.h | 6 +- src/dialogs/NativeDebugDialog.cpp | 13 +- src/dialogs/NativeDebugDialog.h | 5 +- src/dialogs/NewFileDialog.cpp | 154 +-- src/dialogs/NewFileDialog.h | 40 +- src/dialogs/NewFileDialog.ui | 58 +- src/dialogs/ProfileDirectivesDialog.cpp | 9 +- src/dialogs/ProfileDirectivesDialog.h | 3 +- src/dialogs/RegisterProfileDialog.cpp | 53 +- src/dialogs/RegisterProfileDialog.h | 5 +- src/dialogs/RemoteDebugDialog.cpp | 52 +- src/dialogs/RemoteDebugDialog.h | 7 +- src/dialogs/RizinPluginsDialog.cpp | 50 +- src/dialogs/RizinPluginsDialog.h | 10 +- src/dialogs/RizinPluginsDialog.ui | 30 +- src/dialogs/RizinTaskDialog.cpp | 14 +- src/dialogs/RizinTaskDialog.h | 23 +- src/dialogs/SetToDataDialog.cpp | 21 +- src/dialogs/SetToDataDialog.h | 14 +- src/dialogs/TypesInteractionDialog.cpp | 45 +- src/dialogs/TypesInteractionDialog.h | 10 +- src/dialogs/TypesVariablesDialog.cpp | 38 +- src/dialogs/TypesVariablesDialog.h | 21 +- src/dialogs/VersionInfoDialog.cpp | 174 ++-- src/dialogs/VersionInfoDialog.h | 17 +- src/dialogs/WelcomeDialog.cpp | 71 +- src/dialogs/WelcomeDialog.h | 43 +- src/dialogs/WelcomeDialog.ui | 48 +- src/dialogs/WriteCommandsDialogs.cpp | 27 +- src/dialogs/WriteCommandsDialogs.h | 31 +- src/dialogs/XrefsDialog.cpp | 78 +- src/dialogs/XrefsDialog.h | 29 +- src/dialogs/XrefsDialog.ui | 4 +- .../preferences/AnalysisOptionsWidget.cpp | 21 +- .../preferences/AnalysisOptionsWidget.h | 7 +- .../preferences/AppearanceOptionsWidget.cpp | 124 ++- .../preferences/AppearanceOptionsWidget.h | 25 +- src/dialogs/preferences/AsmOptionsWidget.cpp | 84 +- src/dialogs/preferences/AsmOptionsWidget.h | 39 +- .../preferences/ColorThemeEditDialog.cpp | 32 +- .../preferences/ColorThemeEditDialog.h | 7 +- .../preferences/DebugOptionsWidget.cpp | 32 +- src/dialogs/preferences/DebugOptionsWidget.h | 11 +- .../preferences/GraphOptionsWidget.cpp | 53 +- src/dialogs/preferences/GraphOptionsWidget.h | 15 +- .../preferences/InitializationFileEditor.cpp | 36 +- .../preferences/InitializationFileEditor.h | 7 +- .../preferences/InitializationFileEditor.ui | 6 +- .../preferences/InterfaceOptionsWidget.cpp | 6 +- .../preferences/InterfaceOptionsWidget.h | 1 + .../preferences/PluginsOptionsWidget.cpp | 7 +- .../preferences/PluginsOptionsWidget.h | 4 +- .../preferences/PreferenceCategory.cpp | 10 +- src/dialogs/preferences/PreferenceCategory.h | 8 +- src/dialogs/preferences/PreferencesDialog.cpp | 24 +- src/dialogs/preferences/PreferencesDialog.h | 8 +- .../preferences/ShortcutOptionsWidget.cpp | 14 +- .../preferences/ShortcutOptionsWidget.h | 4 + .../preferences/SymbolsOptionsWidget.cpp | 22 +- .../preferences/SymbolsOptionsWidget.h | 9 +- src/menus/AddressableItemContextMenu.cpp | 25 +- src/menus/AddressableItemContextMenu.h | 12 +- src/menus/DecompilerContextMenu.cpp | 128 +-- src/menus/DecompilerContextMenu.h | 20 +- src/menus/DisassemblyContextMenu.cpp | 302 +++--- src/menus/DisassemblyContextMenu.h | 93 +- src/menus/FlirtContextMenu.cpp | 19 +- src/menus/FlirtContextMenu.h | 12 +- src/plugins/CutterPlugin.h | 3 + src/plugins/PluginManager.cpp | 23 +- src/plugins/PluginManager.h | 11 +- src/plugins/sample-cpp/CutterSamplePlugin.cpp | 14 +- src/plugins/sample-cpp/CutterSamplePlugin.h | 4 +- src/shortcuts/DefaultShortcuts.h | 10 +- src/shortcuts/ShortcutManager.cpp | 24 +- src/shortcuts/ShortcutManager.h | 14 +- src/tools/basefind/BaseFindDialog.cpp | 35 +- src/tools/basefind/BaseFindDialog.h | 9 +- src/tools/basefind/BaseFindResultsDialog.cpp | 32 +- src/tools/basefind/BaseFindResultsDialog.h | 22 +- src/tools/basefind/BaseFindSearchDialog.cpp | 25 +- src/tools/basefind/BaseFindSearchDialog.h | 9 +- src/translations | 2 +- src/widgets/AbstractFilterView.cpp | 5 +- src/widgets/AbstractFilterView.h | 9 +- src/widgets/AddressRangeScrollBar.cpp | 35 +- src/widgets/AddressRangeScrollBar.h | 11 +- src/widgets/AddressableDockWidget.cpp | 14 +- src/widgets/AddressableDockWidget.h | 4 +- src/widgets/AddressableItemList.h | 27 +- src/widgets/BacktraceWidget.cpp | 8 +- src/widgets/BacktraceWidget.h | 15 +- src/widgets/BoolToggleDelegate.cpp | 19 +- src/widgets/BoolToggleDelegate.h | 14 +- src/widgets/BreakpointWidget.cpp | 37 +- src/widgets/BreakpointWidget.h | 16 +- src/widgets/CallGraph.cpp | 20 +- src/widgets/CallGraph.h | 3 +- src/widgets/ClassesWidget.cpp | 227 +++-- src/widgets/ClassesWidget.h | 46 +- src/widgets/ColorPicker.cpp | 47 +- src/widgets/ColorPicker.h | 12 +- src/widgets/ColorThemeComboBox.cpp | 9 +- src/widgets/ColorThemeListView.cpp | 119 +-- src/widgets/ColorThemeListView.h | 18 +- src/widgets/ComboQuickFilterView.cpp | 1 + src/widgets/ComboQuickFilterView.h | 7 + src/widgets/CommentsWidget.cpp | 41 +- src/widgets/CommentsWidget.h | 17 +- src/widgets/ConsoleWidget.cpp | 130 +-- src/widgets/ConsoleWidget.h | 21 +- src/widgets/CutterDockWidget.cpp | 12 +- src/widgets/CutterDockWidget.h | 11 +- src/widgets/CutterGraphView.cpp | 64 +- src/widgets/CutterGraphView.h | 25 +- src/widgets/CutterTreeView.cpp | 1 + src/widgets/CutterTreeView.h | 6 +- src/widgets/Dashboard.cpp | 91 +- src/widgets/Dashboard.h | 35 +- src/widgets/DebugActions.cpp | 103 +- src/widgets/DebugActions.h | 10 +- src/widgets/DecompilerWidget.cpp | 128 ++- src/widgets/DecompilerWidget.h | 18 +- src/widgets/DisassemblerGraphView.cpp | 334 +++--- src/widgets/DisassemblerGraphView.h | 37 +- src/widgets/DisassemblyWidget.cpp | 184 ++-- src/widgets/DisassemblyWidget.h | 14 +- src/widgets/EntrypointWidget.cpp | 25 +- src/widgets/EntrypointWidget.h | 10 +- src/widgets/ExportsWidget.cpp | 42 +- src/widgets/ExportsWidget.h | 14 +- src/widgets/FlagsWidget.cpp | 119 ++- src/widgets/FlagsWidget.h | 33 +- src/widgets/FlirtWidget.cpp | 48 +- src/widgets/FlirtWidget.h | 20 +- src/widgets/FunctionsWidget.cpp | 232 +++-- src/widgets/FunctionsWidget.h | 33 +- src/widgets/GlibcHeapWidget.cpp | 56 +- src/widgets/GlibcHeapWidget.h | 21 +- src/widgets/GlobalsWidget.cpp | 28 +- src/widgets/GlobalsWidget.h | 22 +- src/widgets/GraphGridLayout.cpp | 293 +++--- src/widgets/GraphGridLayout.h | 15 +- src/widgets/GraphHorizontalAdapter.cpp | 4 +- src/widgets/GraphHorizontalAdapter.h | 3 +- src/widgets/GraphLayout.h | 8 +- src/widgets/GraphView.cpp | 137 +-- src/widgets/GraphView.h | 57 +- src/widgets/GraphWidget.cpp | 16 +- src/widgets/GraphWidget.h | 4 + src/widgets/GraphvizLayout.cpp | 30 +- src/widgets/GraphvizLayout.h | 7 +- src/widgets/HeadersWidget.cpp | 26 +- src/widgets/HeadersWidget.h | 18 +- src/widgets/HeapBinsGraphView.cpp | 51 +- src/widgets/HeapBinsGraphView.h | 7 +- src/widgets/HeapDockWidget.cpp | 9 +- src/widgets/HeapDockWidget.h | 12 +- src/widgets/HexWidget.cpp | 441 ++++---- src/widgets/HexWidget.h | 235 +++-- src/widgets/HexdumpWidget.cpp | 135 +-- src/widgets/HexdumpWidget.h | 47 +- src/widgets/HexdumpWidget.ui | 60 +- src/widgets/ImportsWidget.cpp | 30 +- src/widgets/ImportsWidget.h | 25 +- src/widgets/ItemCountLineEdit.cpp | 60 +- src/widgets/ItemCountLineEdit.h | 6 +- src/widgets/ListDockWidget.cpp | 7 +- src/widgets/ListDockWidget.h | 17 +- src/widgets/MemoryDockWidget.cpp | 10 +- src/widgets/MemoryDockWidget.h | 18 +- src/widgets/MemoryMapWidget.cpp | 31 +- src/widgets/MemoryMapWidget.h | 22 +- src/widgets/Omnibar.cpp | 135 +-- src/widgets/Omnibar.h | 28 +- src/widgets/OverviewView.cpp | 34 +- src/widgets/OverviewView.h | 10 +- src/widgets/OverviewWidget.cpp | 64 +- src/widgets/OverviewWidget.h | 3 + src/widgets/ProcessesWidget.cpp | 48 +- src/widgets/ProcessesWidget.h | 21 +- src/{common => widgets}/ProgressIndicator.cpp | 29 +- src/{common => widgets}/ProgressIndicator.h | 4 +- src/widgets/QuickFilterView.cpp | 3 +- src/widgets/QuickFilterView.h | 3 + src/widgets/RegisterRefsWidget.cpp | 70 +- src/widgets/RegisterRefsWidget.h | 29 +- src/widgets/RegistersWidget.cpp | 18 +- src/widgets/RegistersWidget.h | 24 +- src/widgets/RelocsWidget.cpp | 20 +- src/widgets/RelocsWidget.h | 22 +- src/widgets/ResourcesWidget.cpp | 23 +- src/widgets/ResourcesWidget.h | 11 +- src/widgets/RizinGraphWidget.cpp | 19 +- src/widgets/RizinGraphWidget.h | 10 +- src/widgets/SdbWidget.cpp | 33 +- src/widgets/SdbWidget.h | 13 +- src/widgets/SearchBarWidget.cpp | 87 +- src/widgets/SearchBarWidget.h | 15 +- src/widgets/SearchWidget.cpp | 98 +- src/widgets/SearchWidget.h | 24 +- src/widgets/SearchableDockWidget.cpp | 9 +- src/widgets/SearchableDockWidget.h | 4 +- src/widgets/SearchableTextEdit.cpp | 79 +- src/widgets/SearchableTextEdit.h | 6 +- src/widgets/SectionsWidget.cpp | 154 ++- src/widgets/SectionsWidget.h | 54 +- src/widgets/SegmentsWidget.cpp | 44 +- src/widgets/SegmentsWidget.h | 19 +- src/widgets/SimpleTextGraphView.cpp | 58 +- src/widgets/SimpleTextGraphView.h | 18 +- src/widgets/StackWidget.cpp | 40 +- src/widgets/StackWidget.h | 30 +- src/widgets/StringsWidget.cpp | 61 +- src/widgets/StringsWidget.h | 25 +- src/widgets/StringsWidget.ui | 4 +- src/widgets/SymbolsWidget.cpp | 16 +- src/widgets/SymbolsWidget.h | 22 +- src/widgets/ThreadsWidget.cpp | 39 +- src/widgets/ThreadsWidget.h | 20 +- src/widgets/TypesWidget.cpp | 146 +-- src/widgets/TypesWidget.h | 26 +- src/widgets/TypesWidget.ui | 8 +- src/widgets/VTablesWidget.cpp | 72 +- src/widgets/VTablesWidget.h | 27 +- src/widgets/VisualNavbar.cpp | 157 +-- src/widgets/VisualNavbar.h | 24 +- 371 files changed, 8027 insertions(+), 6727 deletions(-) delete mode 100644 src/common/Highlighter.cpp delete mode 100644 src/common/Highlighter.h rename src/common/{JsonModel.cpp => Json.cpp} (93%) delete mode 100644 src/common/JsonModel.h rename src/{common => widgets}/ProgressIndicator.cpp (68%) rename src/{common => widgets}/ProgressIndicator.h (92%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8c4b3acb..2fb6788b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,7 +24,6 @@ set(SOURCES dialogs/XrefsDialog.cpp core/MainWindow.cpp common/Helpers.cpp - common/Highlighter.cpp common/MdHighlighter.cpp common/DirectionalComboBox.cpp dialogs/preferences/AsmOptionsWidget.cpp @@ -75,7 +74,6 @@ set(SOURCES widgets/CutterDockWidget.cpp widgets/GraphWidget.cpp widgets/OverviewWidget.cpp - common/JsonModel.cpp dialogs/VersionInfoDialog.cpp widgets/FlirtWidget.cpp common/AsyncTask.cpp @@ -87,7 +85,7 @@ set(SOURCES widgets/BacktraceWidget.cpp dialogs/MapFileDialog.cpp common/CommandTask.cpp - common/ProgressIndicator.cpp + widgets/ProgressIndicator.cpp common/RizinTask.cpp dialogs/RizinTaskDialog.cpp widgets/DebugActions.cpp @@ -172,6 +170,7 @@ set(SOURCES widgets/ItemCountLineEdit.cpp widgets/AbstractFilterView.cpp dialogs/preferences/InterfaceOptionsWidget.cpp + common/Json.cpp ) set(HEADER_FILES core/Cutter.h @@ -197,7 +196,6 @@ set(HEADER_FILES dialogs/XrefsDialog.h common/Helpers.h core/MainWindow.h - common/Highlighter.h common/MdHighlighter.h common/DirectionalComboBox.h dialogs/InitialOptionsDialog.h @@ -247,7 +245,6 @@ set(HEADER_FILES widgets/CutterDockWidget.h widgets/GraphWidget.h widgets/OverviewWidget.h - common/JsonModel.h dialogs/VersionInfoDialog.h widgets/FlirtWidget.h common/AsyncTask.h @@ -261,7 +258,7 @@ set(HEADER_FILES common/StringsTask.h common/FunctionsTask.h common/CommandTask.h - common/ProgressIndicator.h + widgets/ProgressIndicator.h plugins/CutterPlugin.h common/RizinTask.h dialogs/RizinTaskDialog.h diff --git a/src/CutterApplication.cpp b/src/CutterApplication.cpp index 49c4c9f2..2060e790 100644 --- a/src/CutterApplication.cpp +++ b/src/CutterApplication.cpp @@ -1,24 +1,26 @@ -#include "common/PythonManager.h" #include "CutterApplication.h" -#include "plugins/PluginManager.h" + #include "CutterConfig.h" -#include "common/Decompiler.h" +#include "common/Decompiler.h" // IWYU pragma: keep +#include "common/PythonManager.h" // IWYU pragma: keep #include "common/ResourcePaths.h" +#include "core/Cutter.h" +#include "plugins/PluginManager.h" #include -#include +#include +#include #include +#include +#include +#include #include #include -#include -#include -#include -#include #include -#include +#include +#include +#include #include -#include -#include #ifdef Q_OS_WIN # include #endif // Q_OS_WIN @@ -88,8 +90,8 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc } // Check rizin version - QString rzversion = rz_core_version(); - QString localVersion = CUTTER_COMPILE_TIME_RZ_VERSION; + const QString rzversion = rz_core_version(); + const QString localVersion = CUTTER_COMPILE_TIME_RZ_VERSION; qDebug() << rzversion << localVersion; if (rzversion != localVersion) { QMessageBox msg; @@ -147,7 +149,7 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc } mainWindow->displayNewFileDialog(); } else { // filename specified as positional argument - bool askOptions = (clOptions.analysisLevel != AutomaticAnalysisLevel::Ask) + const bool askOptions = (clOptions.analysisLevel != AutomaticAnalysisLevel::Ask) || !clOptions.fileOpenOptions.projectFile.isEmpty(); mainWindow->openNewFile(clOptions.fileOpenOptions, askOptions); } @@ -213,16 +215,16 @@ void CutterApplication::launchNewInstance(const QStringList &args) bool CutterApplication::event(QEvent *e) { if (e->type() == QEvent::FileOpen) { - QFileOpenEvent *openEvent = static_cast(e); + const auto *openEvent = static_cast(e); if (openEvent) { - if (m_FileAlreadyDropped) { + if (fileAlreadyDropped) { // We already dropped a file in macOS, let's spawn another instance // (Like the File -> Open) - QString fileName = openEvent->file(); + const QString fileName = openEvent->file(); launchNewInstance({ fileName }); } else { - QString fileName = openEvent->file(); - m_FileAlreadyDropped = true; + const QString fileName = openEvent->file(); + fileAlreadyDropped = true; mainWindow->closeNewFileDialog(); InitialOptions options; options.filename = fileName; @@ -246,9 +248,9 @@ bool CutterApplication::loadTranslations() QApplication::setLayoutDirection(locale.textDirection()); QLocale::setDefault(locale); - QTranslator *trCutter = new QTranslator; - QTranslator *trQtBase = new QTranslator; - QTranslator *trQt = new QTranslator; + auto *trCutter = new QTranslator; + auto *trQtBase = new QTranslator; + auto *trQt = new QTranslator; const QStringList &cutterTrPaths = Cutter::getTranslationsDirectories(); @@ -361,11 +363,11 @@ QStringList CutterApplication::getArgs() const } if (options.binLoadAddr != RVA_INVALID) { args.push_back("-B"); - args.push_back(RzAddressString(options.binLoadAddr)); + args.push_back(rzAddressString(options.binLoadAddr)); } if (options.mapAddr != RVA_INVALID) { args.push_back("-m"); - args.push_back(RzAddressString(options.mapAddr)); + args.push_back(rzAddressString(options.mapAddr)); } if (!options.filename.isEmpty()) { args.push_back(options.filename); @@ -377,104 +379,104 @@ bool CutterApplication::parseCommandLineOptions() { // Keep this function in sync with documentation - QCommandLineParser cmd_parser; - cmd_parser.setApplicationDescription( + QCommandLineParser cmdParser; + cmdParser.setApplicationDescription( QObject::tr("A Qt and C++ GUI for rizin reverse engineering framework")); - cmd_parser.addHelpOption(); - cmd_parser.addVersionOption(); - cmd_parser.addPositionalArgument("filename", QObject::tr("Filename to open.")); + cmdParser.addHelpOption(); + cmdParser.addVersionOption(); + cmdParser.addPositionalArgument("filename", QObject::tr("Filename to open.")); - QCommandLineOption analOption( + const QCommandLineOption analOption( { "A", "analysis" }, QObject::tr("Automatically open file and optionally start analysis. " "Needs filename to be specified. May be a value between 0 and 2:" " 0 = no analysis, 1 = aaa, 2 = aaaa (experimental)"), QObject::tr("level")); - cmd_parser.addOption(analOption); + cmdParser.addOption(analOption); - QCommandLineOption archOption({ "a", "arch" }, QObject::tr("Sets a specific architecture name"), - QObject::tr("arch")); - cmd_parser.addOption(archOption); + const QCommandLineOption archOption( + { "a", "arch" }, QObject::tr("Sets a specific architecture name"), QObject::tr("arch")); + cmdParser.addOption(archOption); - QCommandLineOption bitsOption({ "b", "bits" }, QObject::tr("Sets a specific architecture bits"), - QObject::tr("bits")); - cmd_parser.addOption(bitsOption); + const QCommandLineOption bitsOption( + { "b", "bits" }, QObject::tr("Sets a specific architecture bits"), QObject::tr("bits")); + cmdParser.addOption(bitsOption); - QCommandLineOption cpuOption({ "c", "cpu" }, QObject::tr("Sets a specific CPU"), - QObject::tr("cpu")); - cmd_parser.addOption(cpuOption); + const QCommandLineOption cpuOption({ "c", "cpu" }, QObject::tr("Sets a specific CPU"), + QObject::tr("cpu")); + cmdParser.addOption(cpuOption); - QCommandLineOption osOption({ "o", "os" }, QObject::tr("Sets a specific operating system"), - QObject::tr("os")); - cmd_parser.addOption(osOption); + const QCommandLineOption osOption( + { "o", "os" }, QObject::tr("Sets a specific operating system"), QObject::tr("os")); + cmdParser.addOption(osOption); - QCommandLineOption endianOption({ "e", "endian" }, - QObject::tr("Sets the endianness (big or little)"), - QObject::tr("big|little")); - cmd_parser.addOption(endianOption); + const QCommandLineOption endianOption({ "e", "endian" }, + QObject::tr("Sets the endianness (big or little)"), + QObject::tr("big|little")); + cmdParser.addOption(endianOption); - QCommandLineOption formatOption({ "F", "format" }, - QObject::tr("Force using a specific file format (bin plugin)"), - QObject::tr("name")); - cmd_parser.addOption(formatOption); + const QCommandLineOption formatOption( + { "F", "format" }, QObject::tr("Force using a specific file format (bin plugin)"), + QObject::tr("name")); + cmdParser.addOption(formatOption); - QCommandLineOption baddrOption({ "B", "base" }, - QObject::tr("Load binary at a specific base address"), - QObject::tr("base address")); - cmd_parser.addOption(baddrOption); + const QCommandLineOption baddrOption({ "B", "base" }, + QObject::tr("Load binary at a specific base address"), + QObject::tr("base address")); + cmdParser.addOption(baddrOption); - QCommandLineOption maddrOption({ "m", "map" }, - QObject::tr("Map the binary at a specific address"), - QObject::tr("map address")); - cmd_parser.addOption(maddrOption); + const QCommandLineOption maddrOption({ "m", "map" }, + QObject::tr("Map the binary at a specific address"), + QObject::tr("map address")); + cmdParser.addOption(maddrOption); - QCommandLineOption scriptOption("i", QObject::tr("Run script file"), QObject::tr("file")); - cmd_parser.addOption(scriptOption); + const QCommandLineOption scriptOption("i", QObject::tr("Run script file"), QObject::tr("file")); + cmdParser.addOption(scriptOption); - QCommandLineOption projectOption({ "p", "project" }, QObject::tr("Load project file"), - QObject::tr("project file")); - cmd_parser.addOption(projectOption); + const QCommandLineOption projectOption({ "p", "project" }, QObject::tr("Load project file"), + QObject::tr("project file")); + cmdParser.addOption(projectOption); - QCommandLineOption writeModeOption({ "w", "writemode" }, - QObject::tr("Open file in write mode")); - cmd_parser.addOption(writeModeOption); + const QCommandLineOption writeModeOption({ "w", "writemode" }, + QObject::tr("Open file in write mode")); + cmdParser.addOption(writeModeOption); - QCommandLineOption phyModeOption({ "P", "phymode" }, - QObject::tr("Disables virtual addressing")); - cmd_parser.addOption(phyModeOption); + const QCommandLineOption phyModeOption({ "P", "phymode" }, + QObject::tr("Disables virtual addressing")); + cmdParser.addOption(phyModeOption); - QCommandLineOption pythonHomeOption( + const QCommandLineOption pythonHomeOption( "pythonhome", QObject::tr("PYTHONHOME to use for embedded python interpreter"), "PYTHONHOME"); - cmd_parser.addOption(pythonHomeOption); + cmdParser.addOption(pythonHomeOption); - QCommandLineOption disableRedirectOption( + const QCommandLineOption disableRedirectOption( "no-output-redirect", QObject::tr("Disable output redirection." " Some of the output in console widget will not be visible." " Use this option when debuging a crash or freeze and output " " redirection is causing some messages to be lost.")); - cmd_parser.addOption(disableRedirectOption); + cmdParser.addOption(disableRedirectOption); - QCommandLineOption disablePlugins("no-plugins", QObject::tr("Do not load plugins")); - cmd_parser.addOption(disablePlugins); + const QCommandLineOption disablePlugins("no-plugins", QObject::tr("Do not load plugins")); + cmdParser.addOption(disablePlugins); - QCommandLineOption disableCutterPlugins("no-cutter-plugins", - QObject::tr("Do not load Cutter plugins")); - cmd_parser.addOption(disableCutterPlugins); + const QCommandLineOption disableCutterPlugins("no-cutter-plugins", + QObject::tr("Do not load Cutter plugins")); + cmdParser.addOption(disableCutterPlugins); - QCommandLineOption disableRizinPlugins("no-rizin-plugins", - QObject::tr("Do not load rizin plugins")); - cmd_parser.addOption(disableRizinPlugins); + const QCommandLineOption disableRizinPlugins("no-rizin-plugins", + QObject::tr("Do not load rizin plugins")); + cmdParser.addOption(disableRizinPlugins); - cmd_parser.process(*this); + cmdParser.process(*this); CutterCommandLineOptions opts; - opts.args = cmd_parser.positionalArguments(); + opts.args = cmdParser.positionalArguments(); - if (cmd_parser.isSet(analOption)) { + if (cmdParser.isSet(analOption)) { bool analysisLevelSpecified = false; - int analysisLevel = cmd_parser.value(analOption).toInt(&analysisLevelSpecified); + const int analysisLevel = cmdParser.value(analOption).toInt(&analysisLevelSpecified); if (!analysisLevelSpecified || analysisLevel < 0 || analysisLevel > 2) { fprintf(stderr, "%s\n", @@ -506,17 +508,17 @@ bool CutterApplication::parseCommandLineOptions() if (!opts.args.isEmpty()) { opts.fileOpenOptions.filename = opts.args[0]; - opts.fileOpenOptions.forceBinPlugin = cmd_parser.value(formatOption); - if (cmd_parser.isSet(baddrOption)) { + opts.fileOpenOptions.forceBinPlugin = cmdParser.value(formatOption); + if (cmdParser.isSet(baddrOption)) { bool ok = false; - RVA baddr = cmd_parser.value(baddrOption).toULongLong(&ok, 0); + const RVA baddr = cmdParser.value(baddrOption).toULongLong(&ok, 0); if (ok) { opts.fileOpenOptions.binLoadAddr = baddr; } } - if (cmd_parser.isSet(maddrOption)) { + if (cmdParser.isSet(maddrOption)) { bool ok = false; - RVA maddr = cmd_parser.value(maddrOption).toULongLong(&ok, 0); + const RVA maddr = cmdParser.value(maddrOption).toULongLong(&ok, 0); if (ok) { opts.fileOpenOptions.mapAddr = maddr; } @@ -539,19 +541,19 @@ bool CutterApplication::parseCommandLineOptions() }; break; } - opts.fileOpenOptions.script = cmd_parser.value(scriptOption); - opts.fileOpenOptions.arch = cmd_parser.value(archOption); - opts.fileOpenOptions.cpu = cmd_parser.value(cpuOption); - opts.fileOpenOptions.os = cmd_parser.value(osOption); - if (cmd_parser.isSet(bitsOption)) { + opts.fileOpenOptions.script = cmdParser.value(scriptOption); + opts.fileOpenOptions.arch = cmdParser.value(archOption); + opts.fileOpenOptions.cpu = cmdParser.value(cpuOption); + opts.fileOpenOptions.os = cmdParser.value(osOption); + if (cmdParser.isSet(bitsOption)) { bool ok = false; - int bits = cmd_parser.value(bitsOption).toInt(&ok, 10); + const int bits = cmdParser.value(bitsOption).toInt(&ok, 10); if (ok && bits > 0) { opts.fileOpenOptions.bits = bits; } } - if (cmd_parser.isSet(endianOption)) { - QString endian = cmd_parser.value(endianOption).toLower(); + if (cmdParser.isSet(endianOption)) { + const QString endian = cmdParser.value(endianOption).toLower(); opts.fileOpenOptions.endian = InitialOptions::Endianness::Auto; if (endian == "little") { opts.fileOpenOptions.endian = InitialOptions::Endianness::Little; @@ -568,27 +570,27 @@ bool CutterApplication::parseCommandLineOptions() opts.fileOpenOptions.endian = InitialOptions::Endianness::Auto; } - opts.fileOpenOptions.writeEnabled = cmd_parser.isSet(writeModeOption); - opts.fileOpenOptions.useVA = !cmd_parser.isSet(phyModeOption); + opts.fileOpenOptions.writeEnabled = cmdParser.isSet(writeModeOption); + opts.fileOpenOptions.useVA = !cmdParser.isSet(phyModeOption); } - opts.fileOpenOptions.projectFile = cmd_parser.value(projectOption); + opts.fileOpenOptions.projectFile = cmdParser.value(projectOption); - if (cmd_parser.isSet(pythonHomeOption)) { - opts.pythonHome = cmd_parser.value(pythonHomeOption); + if (cmdParser.isSet(pythonHomeOption)) { + opts.pythonHome = cmdParser.value(pythonHomeOption); } - opts.outputRedirectionEnabled = !cmd_parser.isSet(disableRedirectOption); - if (cmd_parser.isSet(disablePlugins)) { + opts.outputRedirectionEnabled = !cmdParser.isSet(disableRedirectOption); + if (cmdParser.isSet(disablePlugins)) { opts.enableCutterPlugins = false; opts.enableRizinPlugins = false; } - if (cmd_parser.isSet(disableCutterPlugins)) { + if (cmdParser.isSet(disableCutterPlugins)) { opts.enableCutterPlugins = false; } - if (cmd_parser.isSet(disableRizinPlugins)) { + if (cmdParser.isSet(disableRizinPlugins)) { opts.enableRizinPlugins = false; } diff --git a/src/CutterApplication.h b/src/CutterApplication.h index e4ed041c..473184da 100644 --- a/src/CutterApplication.h +++ b/src/CutterApplication.h @@ -1,14 +1,14 @@ #ifndef CUTTERAPPLICATION_H #define CUTTERAPPLICATION_H -#include +#include "core/MainWindow.h" + #include +#include #include #include -#include "core/MainWindow.h" - -enum class AutomaticAnalysisLevel { Ask, None, AAA, AAAA }; +enum class AutomaticAnalysisLevel : ut8 { Ask, None, AAA, AAAA }; struct CutterCommandLineOptions { @@ -21,6 +21,9 @@ struct CutterCommandLineOptions bool enableRizinPlugins = true; }; +/** + * @brief Main application class for Cutter + */ class CutterApplication : public QApplication { Q_OBJECT @@ -53,7 +56,7 @@ private: bool parseCommandLineOptions(); private: - bool m_FileAlreadyDropped; + bool fileAlreadyDropped; CutterCore core; MainWindow *mainWindow; CutterCommandLineOptions clOptions; diff --git a/src/Main.cpp b/src/Main.cpp index 2c4a62ff..5d42b8a5 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -1,13 +1,11 @@ - #include "CutterApplication.h" -#include "core/MainWindow.h" -#include "common/UpdateWorker.h" #include "CutterConfig.h" #include "common/SettingsUpgrade.h" +#include "common/UpdateWorker.h" +#include "core/MainWindow.h" // IWYU pragma: keep -#include #include -#include +#include /** * @brief Attempt to connect to a parent console and configure outputs. @@ -85,13 +83,13 @@ int main(int argc, char *argv[]) # endif #endif - CutterApplication a(argc, argv); + const CutterApplication a(argc, argv); Cutter::migrateThemes(); if (Config()->getAutoUpdateEnabled()) { #if CUTTER_UPDATE_WORKER_AVAILABLE - UpdateWorker *updateWorker = new UpdateWorker; + auto *updateWorker = new UpdateWorker; QObject::connect(updateWorker, &UpdateWorker::checkComplete, [=](const QVersionNumber &version, const QString &error) { if (error.isEmpty() @@ -104,7 +102,7 @@ int main(int argc, char *argv[]) #endif } - int ret = a.exec(); + const int ret = a.exec(); return ret; } diff --git a/src/bindings/bindings.h b/src/bindings/bindings.h index b05aa384..3bbed883 100644 --- a/src/bindings/bindings.h +++ b/src/bindings/bindings.h @@ -4,11 +4,11 @@ #define QT_ANNOTATE_ACCESS_SPECIFIER(a) __attribute__((annotate(#a))) -#include "../core/Cutter.h" #include "../common/Configuration.h" +#include "../core/Cutter.h" #include "../core/MainWindow.h" -#include "../widgets/CutterDockWidget.h" -#include "../plugins/CutterPlugin.h" #include "../menus/AddressableItemContextMenu.h" +#include "../plugins/CutterPlugin.h" +#include "../widgets/CutterDockWidget.h" #endif // CUTTER_BINDINGS_H diff --git a/src/common/AddressableItemModel.cpp b/src/common/AddressableItemModel.cpp index 120b4f38..f7a94a8e 100644 --- a/src/common/AddressableItemModel.cpp +++ b/src/common/AddressableItemModel.cpp @@ -1,14 +1,12 @@ -#include #include "AddressableItemModel.h" #include AddressableFilterProxyModel::AddressableFilterProxyModel(AddressableItemModelI *sourceModel, QObject *parent) - : AddressableItemModel(parent) + : AddressableItemModel(parent), addressableSourceModel(sourceModel) { setSourceModel(sourceModel); - addressableSourceModel = sourceModel; } RVA AddressableFilterProxyModel::address(const QModelIndex &index) const diff --git a/src/common/AddressableItemModel.h b/src/common/AddressableItemModel.h index 37c02975..5a16d451 100644 --- a/src/common/AddressableItemModel.h +++ b/src/common/AddressableItemModel.h @@ -1,13 +1,14 @@ - #ifndef ADDRESSABLEITEMMODEL_H #define ADDRESSABLEITEMMODEL_H -#include -#include -#include - #include "core/CutterCommon.h" +#include +#include + +/** + * @brief An interface for QAbstractItemModel containing an address field for each index + */ class CUTTER_EXPORT AddressableItemModelI { public: @@ -17,14 +18,13 @@ public: * @param index item intex * @return Item name or empty QString if item doesn't have short descriptive name. */ - virtual QString name(const QModelIndex &index) const - { - Q_UNUSED(index) - return QString(); - } + virtual QString name(const QModelIndex & /*index*/) const { return QString(); } virtual QAbstractItemModel *asItemModel() = 0; }; +/** + * @brief A wrapper class for QAbstractItemModel containing an address field for each index + */ template class CUTTER_EXPORT AddressableItemModel : public ParentModel, public AddressableItemModelI { @@ -37,6 +37,10 @@ public: QAbstractItemModel *asItemModel() { return this; } }; +/** + * @brief A wrapper class for QSortFilterProxyModel with @ref AddressableItemModelI as source + * model + */ class CUTTER_EXPORT AddressableFilterProxyModel : public AddressableItemModel { using ParentClass = AddressableItemModel; diff --git a/src/common/AnalysisTask.cpp b/src/common/AnalysisTask.cpp index 93a961a5..32f389bc 100644 --- a/src/common/AnalysisTask.cpp +++ b/src/common/AnalysisTask.cpp @@ -1,10 +1,12 @@ -#include "core/Cutter.h" #include "common/AnalysisTask.h" + +#include "core/Cutter.h" #include "core/MainWindow.h" #include "dialogs/InitialOptionsDialog.h" -#include -#include + #include +#include +#include AnalysisTask::AnalysisTask() : AsyncTask() {} @@ -16,12 +18,9 @@ void AnalysisTask::interrupt() rz_cons_singleton()->context->breaked = true; } -QString AnalysisTask::getTitle() +QString AnalysisTask::getTitle() const { - // If no file is loaded we consider it's Initial Analysis - RzCoreLocked core(Core()); - RzList *descs = rz_id_storage_list(core->io->files); - if (rz_list_empty(descs)) { + if (Core()->isFileLoaded()) { return tr("Initial Analysis"); } return tr("Analyzing Program"); @@ -34,17 +33,18 @@ void AnalysisTask::runTask() perms |= RZ_PERM_W; emit Core()->ioModeChanged(); } + // Need to lock Core here, so avoid the use of Core()-> functions as much as possible + RzCoreLocked core(Core()); - // Demangle (must be before file Core()->loadFile) - Core()->setConfig("bin.demangle", options.demangle); + // recursive mutex Demangle (must be before file Core()->loadFile) + rz_config_set_b(core->config, "bin.demangle", options.demangle); // Do not reload the file if already loaded - RzCoreLocked core(Core()); - RzList *descs = rz_id_storage_list(core->io->files); + const RzList *descs = rz_id_storage_list(core->io->files); if (rz_list_empty(descs) && options.filename.length()) { log(tr("Loading the file...")); openFailed = false; - bool fileLoaded = + const bool fileLoaded = Core()->loadFile(options.filename, options.binLoadAddr, options.mapAddr, perms, options.useVA, options.loadBinInfo, options.forceBinPlugin); if (!fileLoaded) { @@ -64,17 +64,17 @@ void AnalysisTask::runTask() } if (!options.os.isNull()) { - RzCoreLocked core(Core()); rz_config_set(core->config, "asm.os", options.os.toUtf8().constData()); } if (!options.pdbFile.isNull()) { log(tr("Loading PDB file...")); - Core()->loadPDB(options.pdbFile); + rz_core_bin_pdb_load(core, options.pdbFile.toUtf8().constData()); } if (Core()->getConfigb("bin.dbginfo.debuginfod")) { - Core()->applyDwarf(); + log(tr("Applying Dwarf...")); + rz_core_bin_apply_dwarf(core, rz_bin_cur(core->bin)); } if (isInterrupted()) { @@ -87,7 +87,8 @@ void AnalysisTask::runTask() } if (options.endian != InitialOptions::Endianness::Auto) { - Core()->setEndianness(options.endian == InitialOptions::Endianness::Big); + rz_config_set_b(core->config, "cfg.bigendian", + options.endian == InitialOptions::Endianness::Big); } rz_flag_space_set(core->flags, "*"); @@ -103,7 +104,7 @@ void AnalysisTask::runTask() if (!options.analysisCmd.empty()) { log(tr("Executing analysis...")); - for (const CommandDescription &cmd : options.analysisCmd) { + for (const CommandDescription &cmd : std::as_const(options.analysisCmd)) { if (isInterrupted()) { return; } diff --git a/src/common/AnalysisTask.h b/src/common/AnalysisTask.h index 6b992fd9..b802aac9 100644 --- a/src/common/AnalysisTask.h +++ b/src/common/AnalysisTask.h @@ -1,14 +1,17 @@ -#ifndef ANALTHREAD_H -#define ANALTHREAD_H +#ifndef ANALYSISTASK_H +#define ANALYSISTASK_H #include "common/AsyncTask.h" -#include "core/Cutter.h" #include "common/InitialOptions.h" +// #include "core/Cutter.h" class CutterCore; class MainWindow; class InitialOptionsDialog; +/** + * @brief Background task for initial binary analysis and file loading + */ class AnalysisTask : public AsyncTask { Q_OBJECT @@ -17,13 +20,13 @@ public: explicit AnalysisTask(); ~AnalysisTask(); - QString getTitle() override; + QString getTitle() const override; void setOptions(const InitialOptions &options) { this->options = options; } void interrupt() override; - bool getOpenFileFailed() { return openFailed; } + bool getOpenFileFailed() const { return openFailed; } protected: void runTask() override; @@ -37,4 +40,4 @@ private: bool openFailed = false; }; -#endif // ANALTHREAD_H +#endif // ANALYSISTASK_H diff --git a/src/common/AsyncTask.cpp b/src/common/AsyncTask.cpp index 7e9ddf91..75aca65c 100644 --- a/src/common/AsyncTask.cpp +++ b/src/common/AsyncTask.cpp @@ -1,10 +1,9 @@ #include "AsyncTask.h" -AsyncTask::AsyncTask() : QObject(nullptr), QRunnable() +AsyncTask::AsyncTask() : QObject(nullptr), QRunnable(), running(false) { setAutoDelete(false); - running = false; } AsyncTask::~AsyncTask() @@ -20,7 +19,7 @@ void AsyncTask::wait() bool AsyncTask::wait(int timeout) { - bool r = runningMutex.tryLock(timeout); + const bool r = runningMutex.tryLock(timeout); if (r) { runningMutex.unlock(); } @@ -62,24 +61,24 @@ void AsyncTask::log(QString s) emit logChanged(logBuffer); } -AsyncTaskManager::AsyncTaskManager(QObject *parent) : QObject(parent) +AsyncTaskManager::AsyncTaskManager(QObject *parent) + : QObject(parent), threadPool(new QThreadPool(this)) { - threadPool = new QThreadPool(this); } AsyncTaskManager::~AsyncTaskManager() {} -void AsyncTaskManager::start(AsyncTask::Ptr task) +void AsyncTaskManager::start(const AsyncTask::Ptr &task) { tasks.append(task); task->prepareRun(); - QWeakPointer weakPtr = task; - connect(task.data(), &AsyncTask::finished, this, [this, weakPtr]() { - tasks.removeOne(weakPtr); + const std::weak_ptr weakPtr = task; + connect(task.get(), &AsyncTask::finished, this, [this, weakPtr]() { + tasks.removeOne(weakPtr.lock()); emit tasksChanged(); }); - threadPool->start(task.data()); + threadPool->start(task.get()); emit tasksChanged(); } diff --git a/src/common/AsyncTask.h b/src/common/AsyncTask.h index cda92edc..47919baa 100644 --- a/src/common/AsyncTask.h +++ b/src/common/AsyncTask.h @@ -1,18 +1,22 @@ - #ifndef ASYNCTASK_H #define ASYNCTASK_H #include "core/CutterCommon.h" +#include +#include +#include #include #include -#include -#include -#include -#include + +#include class AsyncTaskManager; +/** + * @brief Wrapper class for QRunnable that provides timing and logging, intended to be used + * with @ref AsyncTaskManager + */ class CUTTER_EXPORT AsyncTask : public QObject, public QRunnable { Q_OBJECT @@ -20,7 +24,7 @@ class CUTTER_EXPORT AsyncTask : public QObject, public QRunnable friend class AsyncTaskManager; public: - using Ptr = QSharedPointer; + using Ptr = std::shared_ptr; AsyncTask(); ~AsyncTask(); @@ -30,14 +34,14 @@ public: void wait(); bool wait(int timeout); virtual void interrupt(); - bool isInterrupted() { return interrupted; } - bool isRunning() { return running; } + bool isInterrupted() const { return interrupted; } + bool isRunning() const { return running; } const QString &getLog() { return logBuffer; } const QElapsedTimer &getTimer() { return timer; } qint64 getElapsedTime() { return timer.isValid() ? timer.elapsed() : 0; } - virtual QString getTitle() { return QString(); } + virtual QString getTitle() const { return QString(); } protected: virtual void runTask() = 0; @@ -59,6 +63,10 @@ private: void prepareRun(); }; +/** + * @brief Wrapper class for QThreadPool, used for starting @ref AsyncTask objects on separate + * threads + */ class AsyncTaskManager : public QObject { Q_OBJECT @@ -71,11 +79,11 @@ public: explicit AsyncTaskManager(QObject *parent = nullptr); ~AsyncTaskManager(); - void start(AsyncTask::Ptr task); + void start(const AsyncTask::Ptr &task); bool getTasksRunning(); signals: void tasksChanged(); }; -#endif // ASYNCTASK_H \ No newline at end of file +#endif // ASYNCTASK_H diff --git a/src/common/BasicBlockHighlighter.cpp b/src/common/BasicBlockHighlighter.cpp index d8270d44..998b9b4f 100644 --- a/src/common/BasicBlockHighlighter.cpp +++ b/src/common/BasicBlockHighlighter.cpp @@ -2,9 +2,6 @@ BasicBlockHighlighter::BasicBlockHighlighter() {} -/** - * @brief Highlight the basic block at address - */ void BasicBlockHighlighter::highlight(RVA address, const QColor &color) { BasicBlock block; @@ -13,22 +10,14 @@ void BasicBlockHighlighter::highlight(RVA address, const QColor &color) bbMap[address] = block; } -/** - * @brief Clear the basic block highlighting - */ void BasicBlockHighlighter::clear(RVA address) { bbMap.erase(address); } -/** - * @brief Return a highlighted basic block - * - * If there is nothing to highlight at specified address, returns nullptr - */ -BasicBlockHighlighter::BasicBlock *BasicBlockHighlighter::getBasicBlock(RVA address) +const BasicBlockHighlighter::BasicBlock *BasicBlockHighlighter::getBasicBlock(RVA address) const { - auto it = bbMap.find(address); + const auto it = bbMap.find(address); if (it != bbMap.end()) { return &it->second; } diff --git a/src/common/BasicBlockHighlighter.h b/src/common/BasicBlockHighlighter.h index 2e0825e3..70e4b9e9 100644 --- a/src/common/BasicBlockHighlighter.h +++ b/src/common/BasicBlockHighlighter.h @@ -4,8 +4,12 @@ class BasicBlockHighlighter; #include "Cutter.h" + #include +/** + * @brief Contains a highlight map for basic blocks + */ class BasicBlockHighlighter { public: @@ -17,9 +21,21 @@ public: BasicBlockHighlighter(); + /** + * @brief Highlight the basic block at address + */ void highlight(RVA address, const QColor &color); + + /** + * @brief Clear the basic block highlighting + */ void clear(RVA address); - BasicBlock *getBasicBlock(RVA address); + + /** + * @brief Return a highlighted basic block + * If there is nothing to highlight at specified address, returns nullptr + */ + const BasicBlock *getBasicBlock(RVA address) const; private: std::map bbMap; diff --git a/src/common/BasicInstructionHighlighter.cpp b/src/common/BasicInstructionHighlighter.cpp index 152a87b8..23a99c7e 100644 --- a/src/common/BasicInstructionHighlighter.cpp +++ b/src/common/BasicInstructionHighlighter.cpp @@ -1,12 +1,10 @@ #include "BasicInstructionHighlighter.h" + #include -/** - * @brief Clear the basic instruction highlighting - */ void BasicInstructionHighlighter::clear(RVA address, RVA size) { - BasicInstructionIt it = biMap.lower_bound(address); + auto it = biMap.lower_bound(address); if (it != biMap.begin()) { --it; } @@ -34,40 +32,33 @@ void BasicInstructionHighlighter::clear(RVA address, RVA size) } } - for (RVA addr : addrs) { + for (const RVA addr : addrs) { const BasicInstruction &bi = biMap[addr]; if (std::max(bi.address, address) < std::min(bi.address + bi.size, address + size)) { biMap.erase(addr); } } - for (BasicInstruction newInstr : newInstructions) { + for (const auto &newInstr : newInstructions) { biMap[newInstr.address] = newInstr; } } -/** - * @brief Highlight the basic instruction at address - */ void BasicInstructionHighlighter::highlight(RVA address, RVA size, QColor color) { clear(address, size); biMap[address] = { address, size, color }; } -/** - * @brief Return a highlighted basic instruction - * - * If there is nothing to highlight at specified address, returns nullptr - */ -BasicInstruction *BasicInstructionHighlighter::getBasicInstruction(RVA address) +const BasicInstructionHighlighter::BasicInstruction * +BasicInstructionHighlighter::getBasicInstruction(RVA address) const { - BasicInstructionIt it = biMap.upper_bound(address); + auto it = biMap.upper_bound(address); if (it == biMap.begin()) { return nullptr; } - BasicInstruction *bi = &(--it)->second; + const BasicInstruction *bi = &(--it)->second; if (bi->address <= address && address < bi->address + bi->size) { return bi; } diff --git a/src/common/BasicInstructionHighlighter.h b/src/common/BasicInstructionHighlighter.h index 5037e180..ea222016 100644 --- a/src/common/BasicInstructionHighlighter.h +++ b/src/common/BasicInstructionHighlighter.h @@ -2,24 +2,41 @@ #define BASICINSTRUCTIONHIGHLIGHTER_H #include "CutterCommon.h" -#include + #include -struct BasicInstruction -{ - RVA address; - RVA size; - QColor color; -}; - -typedef std::map::iterator BasicInstructionIt; +#include +/** + * @brief Contains a highlight map for basic instructions + */ class BasicInstructionHighlighter { public: + struct BasicInstruction + { + RVA address; + RVA size; + QColor color; + }; + + typedef std::map::iterator BasicInstructionIt; + + /** + * @brief Clear the basic instruction highlighting + */ void clear(RVA address, RVA size); + + /** + * @brief Highlight the basic instruction at address + */ void highlight(RVA address, RVA size, QColor color); - BasicInstruction *getBasicInstruction(RVA address); + + /** + * @brief Return a highlighted basic instruction + * If there is nothing to highlight at specified address, returns nullptr + */ + const BasicInstruction *getBasicInstruction(RVA address) const; private: std::map biMap; diff --git a/src/common/BinaryTrees.h b/src/common/BinaryTrees.h index 2cea5986..d677d959 100644 --- a/src/common/BinaryTrees.h +++ b/src/common/BinaryTrees.h @@ -1,15 +1,16 @@ #ifndef BINARY_TREES_H #define BINARY_TREES_H -/** \file BinaryTrees.h - * \brief Utilities to simplify creation of specialized augmented binary trees. +/** + * @file BinaryTrees.h + * @brief Utilities to simplify creation of specialized augmented binary trees. */ -#include -#include +#include #include #include -#include +#include +#include /** * Not really a segment tree for storing segments as referred in academic literature. Can be @@ -19,8 +20,8 @@ * Child classes are expected to implement updateFromChildren(NodeType&parent, NodeType& left, * NodeType& right) method which calculates inner node values from children nodes. * - * \tparam NodeTypeT type of each tree element - * \tparam FinalType final child class used for curiously recurring template pattern + * @tparam NodeTypeT type of each tree element + * @tparam FinalType final child class used for curiously recurring template pattern */ template class SegmentTreeBase @@ -86,7 +87,7 @@ protected: }; /** - * \brief Tree for point modification and range queries. + * @brief Tree for point modification and range queries. */ template class PointSetSegmentTree : public SegmentTreeBase @@ -221,17 +222,17 @@ public: }; /** - * \brief Tree that supports lazily applying an operation to range. + * @brief Tree that supports lazily applying an operation to range. * * Each inner node has a promise value describing an operation that needs to be applied to * corresponding subtree. * * Child classes are expected to implement to pushDown(size_t nodePosition) method. Which applies - * the applies the operation stored in \a promise for nodePosition to the direct children nodes. + * the applies the operation stored in @a promise for nodePosition to the direct children nodes. * - * \tparam NodeType type of tree nodes - * \tparam PromiseType type describing operation that needs to be applied to subtree - * \tparam FinalType child class type for CRTP. See SegmentTreeBase + * @tparam NodeType type of tree nodes + * @tparam PromiseType type describing operation that needs to be applied to subtree + * @tparam FinalType child class type for CRTP. See SegmentTreeBase */ template class LazySegmentTreeBase : public SegmentTreeBase @@ -244,9 +245,9 @@ public: * @param neutralPromise Promise value that doesn't modify tree nodes. */ LazySegmentTreeBase(size_t size, const PromiseType &neutralPromise) - : BaseType(size), neutralPromiseElement(neutralPromise), promise(size, neutralPromise) + : BaseType(size), h(0), neutralPromiseElement(neutralPromise), promise(size, neutralPromise) { - h = 0; + size_t v = size; while (v) { v >>= 1; @@ -339,8 +340,8 @@ public: void pushDown(size_t parent) { if (promise[parent]) { - size_t left = (parent << 1); - size_t right = (parent << 1) | 1; + const size_t left = (parent << 1); + const size_t right = (parent << 1) | 1; nodes[left] = nodes[right] = nodes[parent]; if (left < size) { promise[left] = promise[parent]; @@ -428,46 +429,46 @@ class MinMaxAccumulateTree : public LazySegmentTreeBase::max(), std::numeric_limits::min() }; } - static MinMax Combine(const MinMax &a, const MinMax &b) + static MinMax combine(const MinMax &a, const MinMax &b) { return { std::min(a.first, b.first), std::max(a.second, b.second) }; } - void UpdateNode(NodePosition nodePos, ValueType value) + void updateNode(NodePosition nodePos, ValueType value) { - this->nodes[nodePos] = Combine(this->nodes[nodePos], value); + this->nodes[nodePos] = combine(this->nodes[nodePos], value); if (!this->isLeave(nodePos)) { - this->promise[nodePos] = Combine(this->promise[nodePos], value); + this->promise[nodePos] = combine(this->promise[nodePos], value); } } public: - MinMaxAccumulateTree(size_t size, ValueType initialValue = LIMITS()) - : BaseType(size, initialValue, LIMITS()) + MinMaxAccumulateTree(size_t size, ValueType initialValue = limits()) + : BaseType(size, initialValue, limits()) { } void updateFromChildren(NodeType &parent, const NodeType &left, const NodeType &right) { - parent = Combine(left, right); + parent = combine(left, right); } void pushDown(NodePosition parent) { - size_t left = (parent << 1); - size_t right = (parent << 1) | 1; - this->UpdateNode(left, this->promise[parent]); - this->UpdateNode(right, this->promise[parent]); + const size_t left = (parent << 1); + const size_t right = (parent << 1) | 1; + this->updateNode(left, this->promise[parent]); + this->updateNode(right, this->promise[parent]); this->promise[parent] = this->neutralPromiseElement; } /** - * @brief Update min and max values in the range [\a left, \a right) with number \a value. + * @brief Update min and max values in the range [@a left, @a right) with number @a value. * @param left inclusive range left side * @param right exclusive right side of range * @param value number to be used for updating minimum and maximum @@ -478,15 +479,15 @@ public: right = this->leaveIndexToPosition(right); this->pushDownFromRoot(left); this->pushDownFromRoot(right - 1); - MinMax pairValue { value, value }; + const MinMax pairValue { value, value }; for (size_t l = left, r = right; l < r; l >>= 1, r >>= 1) { if (l & 1) { - UpdateNode(l, pairValue); + updateNode(l, pairValue); l += 1; } if (r & 1) { r -= 1; - UpdateNode(r, pairValue); + updateNode(r, pairValue); } } this->updateUntilRoot(left); diff --git a/src/common/BugReporting.cpp b/src/common/BugReporting.cpp index 13463d00..aaa219cc 100644 --- a/src/common/BugReporting.cpp +++ b/src/common/BugReporting.cpp @@ -1,10 +1,11 @@ #include "BugReporting.h" #include "Cutter.h" -#include -#include #include "CutterConfig.h" + #include +#include +#include void openIssue() { @@ -12,7 +13,7 @@ void openIssue() RzBinFile *bf = rz_bin_cur(core->bin); RzBinObject *bobj = rz_bin_cur_object(core->bin); const RzBinInfo *info = bobj ? rz_bin_object_get_info(bobj) : nullptr; - RzBinPlugin *plugin = rz_bin_file_cur_plugin(bf); + const RzBinPlugin *plugin = rz_bin_file_cur_plugin(bf); QString url, osInfo, format, arch, type; // Pull in info needed for git issue diff --git a/src/common/BugReporting.h b/src/common/BugReporting.h index 85c11eb8..5e5f9376 100644 --- a/src/common/BugReporting.h +++ b/src/common/BugReporting.h @@ -1,5 +1,5 @@ -#ifndef CRASHREPORTING_H -#define CRASHREPORTING_H +#ifndef BUGREPORTING_H +#define BUGREPORTING_H /** * @brief Opens issue on Cutter's github page @@ -7,4 +7,4 @@ */ void openIssue(); -#endif // CRASHREPORTING_H +#endif // BUGREPORTING_H diff --git a/src/common/CachedFontMetrics.h b/src/common/CachedFontMetrics.h index 405c625d..fe2f2271 100644 --- a/src/common/CachedFontMetrics.h +++ b/src/common/CachedFontMetrics.h @@ -3,34 +3,42 @@ #include "common/Metrics.h" -#include #include #include +#include +/** + * @brief A cache class for font measurements + * + * Stores calculated widths in an array so when asking for a character's width + * second time, it is returned instantly without any calculation + * + * @tparam T The type used for dimensions, such as int or qreal + */ template class CachedFontMetrics { public: - explicit CachedFontMetrics(const QFont &font) : mFontMetrics(font) + explicit CachedFontMetrics(const QFont &font) + : fontMetrics(font), charWidths {}, fontHeight(fontMetrics.height()) { - memset(mWidths, 0, sizeof(mWidths)); - mHeight = mFontMetrics.height(); } T width(const QChar &ch) { - // return mFontMetrics.width(ch); auto unicode = ch.unicode(); - if (unicode >= 0xD800) { - if (unicode >= 0xE000) + if (unicode >= 0xD800) [[unlikely]] { + if (unicode >= 0xE000) { unicode -= 0xE000 - 0xD800; - else + } else { // is lonely surrogate return fetchWidth(ch); + } } - if (!mWidths[unicode]) - return mWidths[unicode] = fetchWidth(ch); - return mWidths[unicode]; + if (!charWidths[unicode]) [[unlikely]] { + return charWidths[unicode] = fetchWidth(ch); + } + return charWidths[unicode]; } T width(const QString &text) @@ -38,17 +46,18 @@ public: T result = 0; QChar temp; for (const QChar &ch : text) { - if (ch.isHighSurrogate()) + if (ch.isHighSurrogate()) [[unlikely]] { temp = ch; - else if (ch.isLowSurrogate()) + } else if (ch.isLowSurrogate()) [[unlikely]] { result += fetchWidth(QString(temp) + ch); - else + } else [[likely]] { result += width(ch); + } } return result; } - T height() { return mHeight; } + T height() { return fontHeight; } T position(const QString &text, T offset) { @@ -56,15 +65,15 @@ public: QChar temp; for (int i = 0; i < text.length(); i++) { - QChar ch = text[i]; + const QChar ch = text[i]; - if (ch.isHighSurrogate()) + if (ch.isHighSurrogate()) [[unlikely]] { temp = ch; - else if (ch.isLowSurrogate()) + } else if (ch.isLowSurrogate()) [[unlikely]] { curWidth += fetchWidth(QString(temp) + ch); - else + } else [[likely]] { curWidth += width(ch); - + } if (curWidth >= offset) { return i; } @@ -74,25 +83,25 @@ public: } private: - typename Metrics::FontMetrics mFontMetrics; - T mWidths[0x10000 - 0xE000 + 0xD800]; - T mHeight; + typename Metrics::FontMetrics fontMetrics; + T charWidths[0x10000 - 0xE000 + 0xD800]; + T fontHeight; T fetchWidth(QChar c) { #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - return mFontMetrics.width(c); + return fontMetrics.width(c); #else - return mFontMetrics.horizontalAdvance(c); + return fontMetrics.horizontalAdvance(c); #endif } T fetchWidth(const QString &s) { #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - return mFontMetrics.width(s); + return fontMetrics.width(s); #else - return mFontMetrics.horizontalAdvance(s); + return fontMetrics.horizontalAdvance(s); #endif } }; diff --git a/src/common/ColorThemeWorker.cpp b/src/common/ColorThemeWorker.cpp index 23ccd37a..828ea5bf 100644 --- a/src/common/ColorThemeWorker.cpp +++ b/src/common/ColorThemeWorker.cpp @@ -1,14 +1,15 @@ #include "ColorThemeWorker.h" +#include "common/Configuration.h" + +#include #include #include -#include #include -#include #include -#include +#include -#include "common/Configuration.h" +#include const QStringList ColorThemeWorker::cutterSpecificOptions = { "wordHighlight", @@ -55,9 +56,9 @@ ColorThemeWorker::ColorThemeWorker(QObject *parent) : QObject(parent) QDir().mkpath(customRzThemesLocationPath); } - RzPath *sys_path = rz_path_new(); - const char *theme_dir = rz_path_system(sys_path, RZ_THEMES); - QDir currDir { theme_dir }; + RzPath *sysPath = rz_path_new(); + const char *themeDir = rz_path_system(sysPath, RZ_THEMES); + const QDir currDir { themeDir }; if (currDir.exists()) { standardRzThemesLocationPath = currDir.absolutePath(); } else { @@ -66,7 +67,7 @@ ColorThemeWorker::ColorThemeWorker(QObject *parent) : QObject(parent) "Most likely, Rizin is not properly installed.") .arg(currDir.path())); } - rz_path_free(sys_path); + rz_path_free(sysPath); } QColor ColorThemeWorker::mergeColors(const QColor &upper, const QColor &lower) const @@ -128,14 +129,14 @@ bool ColorThemeWorker::isCustomTheme(const QString &themeName) const bool ColorThemeWorker::isThemeExist(const QString &name) const { - QStringList themes = Core()->getColorThemes(); + const QStringList themes = Core()->getColorThemes(); return themes.contains(name); } ColorThemeWorker::Theme ColorThemeWorker::getTheme(const QString &themeName) const { Theme theme; - QString curr = Config()->getColorTheme(); + const QString curr = Config()->getColorTheme(); if (themeName != curr) { RzCoreLocked core(Core()); @@ -206,13 +207,13 @@ QString ColorThemeWorker::deleteTheme(const QString &themeName) const QString ColorThemeWorker::importTheme(const QString &file) const { - QFileInfo src(file); + const QFileInfo src(file); if (!src.exists()) { return tr("File %1 does not exist.").arg(file); } bool ok; - bool isTheme = isFileTheme(file, &ok); + const bool isTheme = isFileTheme(file, &ok); if (!ok) { return tr("File %1 could not be opened. " "Please make sure you have access to it and try again.") @@ -221,7 +222,7 @@ QString ColorThemeWorker::importTheme(const QString &file) const return tr("File %1 is not a Cutter color theme").arg(file); } - QString name = src.fileName(); + const QString name = src.fileName(); if (isThemeExist(name)) { return tr("A color theme named %1 already exists.").arg(name); } @@ -246,8 +247,8 @@ QString ColorThemeWorker::renameTheme(const QString &themeName, const QString &n return tr("You can not rename standard Rizin themes."); } - QDir dir = customRzThemesLocationPath; - bool ok = QFile::rename(dir.filePath(themeName), dir.filePath(newName)); + const QDir dir = customRzThemesLocationPath; + const bool ok = QFile::rename(dir.filePath(themeName), dir.filePath(newName)); if (!ok) { return tr("Something went wrong during renaming. " "Please make sure you have access to the directory \"%1\".") @@ -265,13 +266,13 @@ bool ColorThemeWorker::isFileTheme(const QString &filePath, bool *ok) const } const QString colors = "black|red|white|green|magenta|yellow|cyan|blue|gray|none"; - QString options = + const QString options = (Core()->getThemeKeys() << cutterSpecificOptions).join('|').replace(".", "\\."); - QString pattern = + const QString pattern = QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*").arg(options, colors); // The below construct mimics the behaviour of QRegexP::exactMatch(), which was here before - QRegularExpression regexp("\\A(?:" + pattern + ")\\z"); + const QRegularExpression regexp("\\A(?:" + pattern + ")\\z"); for (auto &line : QString(f.readAll()).split('\n', CUTTER_QT_SKIP_EMPTY_PARTS)) { line.replace("#~", "ec "); @@ -287,11 +288,11 @@ bool ColorThemeWorker::isFileTheme(const QString &filePath, bool *ok) const QStringList ColorThemeWorker::customThemes() const { - QStringList themes = Core()->getColorThemes(); + const QStringList themes = Core()->getColorThemes(); QStringList ret; - for (int i = 0; i < themes.size(); i++) { - if (isCustomTheme(themes[i])) { - ret.push_back(themes[i]); + for (const auto &theme : themes) { + if (isCustomTheme(theme)) { + ret.push_back(theme); } } return ret; diff --git a/src/common/ColorThemeWorker.h b/src/common/ColorThemeWorker.h index 3942a428..1aac5dc2 100644 --- a/src/common/ColorThemeWorker.h +++ b/src/common/ColorThemeWorker.h @@ -1,18 +1,19 @@ #ifndef COLORTHEMEWORKER_H #define COLORTHEMEWORKER_H -#include -#include -#include #include "Cutter.h" + +#include +#include #include #include +#include #define ThemeWorker() (ColorThemeWorker::instance()) /** - * @brief The ColorThemeWorker class is a singletone that provides API for working with - * color themes. + * @brief The ColorThemeWorker class is a singleton that provides API for working with + * color themes */ class ColorThemeWorker : public QObject { @@ -40,20 +41,16 @@ public: /** * @brief Copies @a srcThemeName with name @a copyThemeName. - * @param srcThemeName - * Name of theme to be copied. - * @param copyThemeName - * Name of copy. + * @param srcThemeName Name of theme to be copied. + * @param copyThemeName Name of copy. * @return "" on success or error message. */ QString copy(const QString &srcThemeName, const QString ©ThemeName) const; /** * @brief Saves @a theme as @a themeName theme. - * @param theme - * Theme to be saved. - * @param themeName - * Name of theme to save. + * @param theme Theme to be saved. + * @param themeName Name of theme to save. * @return "" on success or error message. */ QString save(const Theme &theme, const QString &themeName) const; @@ -61,8 +58,7 @@ public: /** * @brief Returns whether or not @a themeName theme is custom (created by user or imported) or * not. - * @param themeName - * Name of theme to check. + * @param themeName Name of theme to check. */ bool isCustomTheme(const QString &themeName) const; @@ -74,15 +70,13 @@ public: /** * @brief Returns theme as QHash where key is option name and value is QColor. - * @param themeName - * Theme to get. + * @param themeName Theme to get. */ Theme getTheme(const QString &themeName) const; /** * @brief Deletes theme named @a themeName. - * @param themeName - * Name of theme to be removed. + * @param themeName Name of theme to be removed. * @return "" on success or error message. */ QString deleteTheme(const QString &themeName) const; @@ -101,11 +95,9 @@ public: /** * @brief Returns whether or not file at @a filePath is a color theme. - * @param filePath - * Path to file to check. - * @param ok - * Output parameter. Indicates wheter or not check was successful. - * @return true if given file is color theme and ok == true, otherwise returns false. + * @param filePath Path to file to check. + * @param ok Output parameter. Indicates wheter or not check was successful. + * @return true if given file is a valid color theme and ok == true, otherwise returns false. */ bool isFileTheme(const QString &filePath, bool *ok) const; @@ -114,8 +106,8 @@ public: */ QStringList customThemes() const; - QString getStandardThemesPath() { return standardRzThemesLocationPath; } - QString getCustomThemesPath() { return customRzThemesLocationPath; } + QString getStandardThemesPath() const { return standardRzThemesLocationPath; } + QString getCustomThemesPath() const { return customRzThemesLocationPath; } const QStringList &getRizinSpecificOptions(); diff --git a/src/common/Colors.cpp b/src/common/Colors.cpp index fff7cded..4be56dd2 100644 --- a/src/common/Colors.cpp +++ b/src/common/Colors.cpp @@ -1,106 +1,26 @@ #include "Colors.h" + #include "common/Configuration.h" -Colors::Colors() {} +#include -void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 type_num) +void Colors::colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 typeNum) { - RichTextPainter::CustomRichText_t assembly; + RichTextPainter::CustomRichText assembly; assembly.highlight = false; assembly.flags = RichTextPainter::FlagColor; // TODO cut opcode and use op["ptr"] to colorate registers and immediate values - assembly.text = opcode; + assembly.text = std::move(opcode); - QString colorName = Colors::getColor(type_num); + const QString colorName = Core()->getColorNameFromOp(typeNum); assembly.textColor = ConfigColor(colorName); list.push_back(assembly); } -// Temporary solution -// Copied from RZ_API const char* r_print_color_op_type(RPrint *p, ut64 analysis_type) { -QString Colors::getColor(ut64 type) -{ - switch (type & RZ_ANALYSIS_OP_TYPE_MASK) { - case RZ_ANALYSIS_OP_TYPE_NOP: - return "nop"; - case RZ_ANALYSIS_OP_TYPE_ADD: - case RZ_ANALYSIS_OP_TYPE_SUB: - case RZ_ANALYSIS_OP_TYPE_MUL: - case RZ_ANALYSIS_OP_TYPE_DIV: - case RZ_ANALYSIS_OP_TYPE_MOD: - case RZ_ANALYSIS_OP_TYPE_LENGTH: - return "math"; - case RZ_ANALYSIS_OP_TYPE_AND: - case RZ_ANALYSIS_OP_TYPE_OR: - case RZ_ANALYSIS_OP_TYPE_XOR: - case RZ_ANALYSIS_OP_TYPE_NOT: - case RZ_ANALYSIS_OP_TYPE_SHL: - case RZ_ANALYSIS_OP_TYPE_SAL: - case RZ_ANALYSIS_OP_TYPE_SAR: - case RZ_ANALYSIS_OP_TYPE_SHR: - case RZ_ANALYSIS_OP_TYPE_ROL: - case RZ_ANALYSIS_OP_TYPE_ROR: - case RZ_ANALYSIS_OP_TYPE_CPL: - return "bin"; - case RZ_ANALYSIS_OP_TYPE_IO: - return "swi"; - case RZ_ANALYSIS_OP_TYPE_JMP: - case RZ_ANALYSIS_OP_TYPE_UJMP: - case RZ_ANALYSIS_OP_TYPE_IJMP: - case RZ_ANALYSIS_OP_TYPE_RJMP: - case RZ_ANALYSIS_OP_TYPE_IRJMP: - case RZ_ANALYSIS_OP_TYPE_MJMP: - return "jmp"; - case RZ_ANALYSIS_OP_TYPE_CJMP: - case RZ_ANALYSIS_OP_TYPE_UCJMP: - case RZ_ANALYSIS_OP_TYPE_SWITCH: - return "cjmp"; - case RZ_ANALYSIS_OP_TYPE_CMP: - case RZ_ANALYSIS_OP_TYPE_ACMP: - return "cmp"; - case RZ_ANALYSIS_OP_TYPE_UCALL: - case RZ_ANALYSIS_OP_TYPE_ICALL: - case RZ_ANALYSIS_OP_TYPE_RCALL: - case RZ_ANALYSIS_OP_TYPE_IRCALL: - case RZ_ANALYSIS_OP_TYPE_UCCALL: - case RZ_ANALYSIS_OP_TYPE_CALL: - case RZ_ANALYSIS_OP_TYPE_CCALL: - return "call"; - case RZ_ANALYSIS_OP_TYPE_NEW: - case RZ_ANALYSIS_OP_TYPE_SWI: - return "swi"; - case RZ_ANALYSIS_OP_TYPE_ILL: - case RZ_ANALYSIS_OP_TYPE_TRAP: - return "trap"; - case RZ_ANALYSIS_OP_TYPE_CRET: - case RZ_ANALYSIS_OP_TYPE_RET: - return "ret"; - case RZ_ANALYSIS_OP_TYPE_CAST: - case RZ_ANALYSIS_OP_TYPE_MOV: - case RZ_ANALYSIS_OP_TYPE_LEA: - case RZ_ANALYSIS_OP_TYPE_CMOV: // TODO: add cmov cathegory? - return "mov"; - case RZ_ANALYSIS_OP_TYPE_PUSH: - case RZ_ANALYSIS_OP_TYPE_UPUSH: - case RZ_ANALYSIS_OP_TYPE_LOAD: - return "push"; - case RZ_ANALYSIS_OP_TYPE_POP: - case RZ_ANALYSIS_OP_TYPE_STORE: - return "pop"; - case RZ_ANALYSIS_OP_TYPE_CRYPTO: - return "crypto"; - case RZ_ANALYSIS_OP_TYPE_NULL: - return "other"; - case RZ_ANALYSIS_OP_TYPE_UNK: - default: - return "invalid"; - } -} - QColor Colors::overlayColor(const QColor &base, const QColor &overlay) { - int alpha = overlay.alpha(); + const int alpha = overlay.alpha(); if (alpha == 255) { return overlay; } @@ -108,9 +28,9 @@ QColor Colors::overlayColor(const QColor &base, const QColor &overlay) return base; } - int r = (overlay.red() * alpha + base.red() * (255 - alpha)) / 255; - int g = (overlay.green() * alpha + base.green() * (255 - alpha)) / 255; - int b = (overlay.blue() * alpha + base.blue() * (255 - alpha)) / 255; + const int r = (overlay.red() * alpha + base.red() * (255 - alpha)) / 255; + const int g = (overlay.green() * alpha + base.green() * (255 - alpha)) / 255; + const int b = (overlay.blue() * alpha + base.blue() * (255 - alpha)) / 255; return QColor(r, g, b); } diff --git a/src/common/Colors.h b/src/common/Colors.h index b6a1a8ad..2b710b6b 100644 --- a/src/common/Colors.h +++ b/src/common/Colors.h @@ -1,23 +1,29 @@ #ifndef COLORS_H #define COLORS_H -#include "core/Cutter.h" #include "common/RichTextPainter.h" -#include +#include "core/Cutter.h" -class Colors -{ -public: - Colors(); - static void colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 type_num); - static QString getColor(ut64 type); - /** - * @brief Blends an overlay color onto an existing base color - * @param base The original color (assumes base color is solid) - * @param overlay The overlay color with alpha transparency - * @return The resulting blended color - */ - static QColor overlayColor(const QColor &base, const QColor &overlay); -}; +/** + * @brief Utilities for handling color logic and syntax highlighting for assembly + */ +namespace Colors { + +/** + * @brief Colorize asssembly text + * @param list RichTextPainter::List to add the opcode to + * @param opcode Opcode to colorize + * @param typeNum Type of opcode + */ +void colorizeAssembly(RichTextPainter::List &list, QString opcode, ut64 typeNum); + +/** + * @brief Blends an overlay color onto an existing base color + * @param base The original color (assumes base color is solid) + * @param overlay The overlay color with alpha transparency + * @return The resulting blended color + */ +QColor overlayColor(const QColor &base, const QColor &overlay); +} #endif // COLORS_H diff --git a/src/common/CommandTask.cpp b/src/common/CommandTask.cpp index 0366aaf2..b6860139 100644 --- a/src/common/CommandTask.cpp +++ b/src/common/CommandTask.cpp @@ -1,5 +1,6 @@ - #include "CommandTask.h" + +#include "Cutter.h" #include "TempConfig.h" CommandTask::CommandTask(const QString &cmd, ColorMode colorMode) : cmd(cmd), colorMode(colorMode) diff --git a/src/common/CommandTask.h b/src/common/CommandTask.h index 15136699..6d2cceab 100644 --- a/src/common/CommandTask.h +++ b/src/common/CommandTask.h @@ -1,16 +1,17 @@ - #ifndef COMMANDTASK_H #define COMMANDTASK_H #include "common/AsyncTask.h" -#include "core/Cutter.h" +/** + * @brief Background task for running a command in rizin + */ class CUTTER_EXPORT CommandTask : public AsyncTask { Q_OBJECT public: - enum ColorMode { + enum ColorMode : ut8 { DISABLED = COLOR_MODE_DISABLED, MODE_16 = COLOR_MODE_16, MODE_256 = COLOR_MODE_256, @@ -19,7 +20,7 @@ public: CommandTask(const QString &cmd, ColorMode colorMode = ColorMode::DISABLED); - QString getTitle() override { return tr("Running Command"); } + QString getTitle() const override { return tr("Running Command"); } signals: void finished(const QString &result); diff --git a/src/common/Configuration.cpp b/src/common/Configuration.cpp index 031c66fc..f1e98fa8 100644 --- a/src/common/Configuration.cpp +++ b/src/common/Configuration.cpp @@ -1,21 +1,24 @@ #include "Configuration.h" -#include -#include -#include -#include -#include + #include +#include +#include +#include #include +#include +#include + +#include #ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING +# include # include # include -# include #endif #include "common/ColorThemeWorker.h" -#include "common/SyntaxHighlighter.h" #include "common/ResourcePaths.h" +#include "common/SyntaxHighlighter.h" /* Map with names of themes associated with its color palette * (Dark or Light), so for dark interface themes will be shown only Dark color themes @@ -37,8 +40,8 @@ const QHash Configuration::relevantThemes = { { "cutter", LightFlag }, { "matrix", LightFlag }, { "white", LightFlag }, }; -static const QString DEFAULT_LIGHT_COLOR_THEME = "cutter"; -static const QString DEFAULT_DARK_COLOR_THEME = "ayu"; +static const QString defaultLightColorTheme = "cutter"; +static const QString defaultDarkColorTheme = "ayu"; const QHash> Configuration::cutterOptionColors = { { "gui.cflow", @@ -114,7 +117,7 @@ const QHash> Configuration::cutterOptionColor { LightFlag, QColor(0xb3, 0x77, 0xd6, 0x50) } } } }; -Configuration *Configuration::mPtr = nullptr; +Configuration *Configuration::ptr = nullptr; /** * @brief All asm.* options saved as settings. Values are the default values. @@ -157,7 +160,7 @@ static const QHash asmOptions = { { "asm.esil", false }, Configuration::Configuration() : QObject(), nativePalette(qApp->palette()) { - mPtr = this; + ptr = this; if (!s.isWritable()) { QMessageBox::critical( nullptr, tr("Critical Error!"), @@ -171,9 +174,10 @@ Configuration::Configuration() : QObject(), nativePalette(qApp->palette()) Configuration *Configuration::instance() { - if (!mPtr) - mPtr = new Configuration(); - return mPtr; + if (!ptr) { + ptr = new Configuration(); + } + return ptr; } void Configuration::loadInitial() @@ -189,7 +193,7 @@ void Configuration::loadInitial() QString Configuration::getRecentFolder() { - QString recentFolder = s.value("dir.recentFolder", QDir::homePath()).toString(); + const QString recentFolder = s.value("dir.recentFolder", QDir::homePath()).toString(); return QDir::toNativeSeparators(recentFolder); } @@ -279,7 +283,7 @@ bool Configuration::setLocaleByName(const QString &language) bool Configuration::windowColorIsDark() { - ColorFlags currentThemeColorFlags = getCurrentTheme()->flag; + const ColorFlags currentThemeColorFlags = getCurrentTheme()->flag; if (currentThemeColorFlags == ColorFlags::LightFlag) { return false; } else if (currentThemeColorFlags == ColorFlags::DarkFlag) { @@ -301,15 +305,13 @@ void Configuration::loadNativeStylesheet() QFile f(":native/native.qss"); if (!f.exists()) { qWarning() << "Can't find Native theme stylesheet."; - } else { - f.open(QFile::ReadOnly | QFile::Text); + } else if (f.open(QFile::ReadOnly | QFile::Text)) { QTextStream ts(&f); - QString stylesheet = ts.readAll(); + QString stylesheet = ts.readAll(); // NOLINT #ifdef Q_OS_MACOS QFile mf(nativeWindowIsDark() ? ":native/native-macos-dark.qss" : ":native/native-macos-light.qss"); - if (mf.exists()) { - mf.open(QFile::ReadOnly | QFile::Text); + if (mf.exists() && mf.open(QFile::ReadOnly | QFile::Text)) { QTextStream mts(&mf); stylesheet += "\n" + mts.readAll(); } @@ -336,10 +338,9 @@ void Configuration::loadLightStylesheet() QFile f(":lightstyle/light.qss"); if (!f.exists()) { qWarning() << "Can't find Light theme stylesheet."; - } else { - f.open(QFile::ReadOnly | QFile::Text); + } else if (f.open(QFile::ReadOnly | QFile::Text)) { QTextStream ts(&f); - QString stylesheet = ts.readAll(); + const QString stylesheet = ts.readAll(); QPalette p = qApp->palette(); p.setColor(QPalette::Text, Qt::black); @@ -355,10 +356,9 @@ void Configuration::loadDarkStylesheet() QFile f(":qdarkstyle/style.qss"); if (!f.exists()) { qWarning() << "Can't find Dark theme stylesheet."; - } else { - f.open(QFile::ReadOnly | QFile::Text); + } else if (f.open(QFile::ReadOnly | QFile::Text)) { QTextStream ts(&f); - QString stylesheet = ts.readAll(); + QString stylesheet = ts.readAll(); // NOLINT #ifdef Q_OS_MACX // see https://github.com/ColinDuquesnoy/QDarkStyleSheet/issues/22#issuecomment-96179529 stylesheet += "QDockWidget::title" @@ -381,10 +381,9 @@ void Configuration::loadMidnightStylesheet() QFile f(":midnight/style.css"); if (!f.exists()) { qWarning() << "Can't find Midnight theme stylesheet."; - } else { - f.open(QFile::ReadOnly | QFile::Text); + } else if (f.open(QFile::ReadOnly | QFile::Text)) { QTextStream ts(&f); - QString stylesheet = ts.readAll(); + const QString stylesheet = ts.readAll(); QPalette p = qApp->palette(); p.setColor(QPalette::Text, Qt::white); @@ -396,7 +395,7 @@ void Configuration::loadMidnightStylesheet() const QFont Configuration::getBaseFont() const { - QFont font = s.value("font", QFont("Inconsolata", 11)).value(); + const auto font = s.value("font", QFont("Inconsolata", 11)).value(); return font; } @@ -420,7 +419,7 @@ void Configuration::refreshFont() qreal Configuration::getZoomFactor() const { - qreal fontZoom = s.value("zoomFactor", 1.0).value(); + const auto fontZoom = s.value("zoomFactor", 1.0).value(); return qMax(fontZoom, 0.1); } @@ -442,7 +441,7 @@ void Configuration::setInterfaceTheme(int theme) } s.setValue("ColorPalette", theme); - CutterInterfaceTheme interfaceTheme = cutterInterfaceThemesList()[theme]; + const CutterInterfaceTheme interfaceTheme = cutterInterfaceThemesList()[theme]; if (interfaceTheme.name == "Native") { loadNativeStylesheet(); @@ -517,11 +516,6 @@ QString Configuration::getLogoFile() : QString(":/img/cutter_plain.svg"); } -/** - * @brief Configuration::setColor sets the local Cutter configuration color - * @param name Color Name - * @param color The color you want to set - */ void Configuration::setColor(const QString &name, const QColor &color) { s.setValue("colors." + name, color); @@ -553,7 +547,7 @@ void Configuration::setColorTheme(const QString &theme) s.setValue("theme", theme); } - ColorThemeWorker::Theme colorTheme = ThemeWorker().getTheme(theme); + const ColorThemeWorker::Theme colorTheme = ThemeWorker().getTheme(theme); for (auto it = colorTheme.constBegin(); it != colorTheme.constEnd(); it++) { setColor(it.key(), it.value()); } @@ -563,12 +557,12 @@ void Configuration::setColorTheme(const QString &theme) void Configuration::adjustColorThemeDarkness() { - bool windowIsDark = windowColorIsDark(); - int windowDarkness = windowIsDark ? DarkFlag : LightFlag; - int currentColorThemeDarkness = colorThemeDarkness(getColorTheme()); + const bool windowIsDark = windowColorIsDark(); + const int windowDarkness = windowIsDark ? DarkFlag : LightFlag; + const int currentColorThemeDarkness = colorThemeDarkness(getColorTheme()); if ((currentColorThemeDarkness & windowDarkness) == 0) { - setColorTheme(windowIsDark ? DEFAULT_DARK_COLOR_THEME : DEFAULT_LIGHT_COLOR_THEME); + setColorTheme(windowIsDark ? defaultDarkColorTheme : defaultLightColorTheme); } } @@ -608,8 +602,18 @@ const QList &Configuration::cutterInterfaceThemesList() QVariant Configuration::getConfigVar(const QString &key) { - QHash::const_iterator it = asmOptions.find(key); + const QHash::const_iterator it = asmOptions.find(key); if (it != asmOptions.end()) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + switch (it.value().typeId()) { + case QMetaType::Type::Bool: + return Core()->getConfigb(key); + case QMetaType::Type::Int: + return Core()->getConfigi(key); + default: + return Core()->getConfig(key); + } +#else switch (it.value().type()) { case QVariant::Type::Bool: return Core()->getConfigb(key); @@ -618,6 +622,7 @@ QVariant Configuration::getConfigVar(const QString &key) default: return Core()->getConfig(key); } +#endif } return QVariant(); } @@ -637,12 +642,6 @@ QString Configuration::getConfigString(const QString &key) return getConfigVar(key).toString(); } -/** - * @brief Configuration::setConfig - * Set Rizin configuration value (e.g. "asm.lines") - * @param key - * @param value - */ void Configuration::setConfig(const QString &key, const QVariant &value) { if (asmOptions.contains(key)) { @@ -652,17 +651,13 @@ void Configuration::setConfig(const QString &key, const QVariant &value) Core()->setConfig(key, value); } -/** - * @brief this function will gather and return available translation for Cutter - * @return a list of locales and their names - */ std::vector Configuration::getAvailableTranslations() { const auto &trDirs = Cutter::getTranslationsDirectories(); QSet fileNamesSet; for (const auto &trDir : trDirs) { - QDir dir(trDir); + const QDir dir(trDir); if (!dir.exists()) { continue; } @@ -678,20 +673,20 @@ std::vector Configuration::getAvailableTranslations() QString currLanguageName; std::vector result; QHash langCount; - for (const auto &translationFile : fileNames) { + for (const auto &translationFile : std::as_const(fileNames)) { auto name = QFileInfo(translationFile).baseName(); auto parts = name.split("_"); if (parts.length() < 2) { continue; } - auto langCode = parts[1]; + const auto &langCode = parts[1]; ++langCount[langCode]; } for (auto &i : fileNames) { auto name = QFileInfo(i).baseName(); - QString localeName = name.mid(sizeof("cutter_") - 1); - QLocale locale(localeName); + const QString localeName = name.mid(sizeof("cutter_") - 1); + const QLocale locale(localeName); if (locale.language() == QLocale::C) { continue; } @@ -704,7 +699,7 @@ std::vector Configuration::getAvailableTranslations() if (langCount[langCode] <= 1 && locale.language() != QLocale::Chinese) { // Always distinguish Chinese Traditional, // Chinese simplified - QLocale localSimple(locale.language()); + const QLocale localSimple(locale.language()); auto simpleName = localSimple.nativeLanguageName(); if (!simpleName.isEmpty()) { currLanguageName = simpleName; @@ -848,10 +843,10 @@ QList Configuration::getRecentFiles() const const QStringList list = s.value("recentFileList").toStringList(); for (const QString &file : list) { - int sep = file.indexOf("://"); + const int sep = file.indexOf("://"); if (sep != -1) { - QString ioMode = file.left(sep + 3); - QString path = file.mid(sep + 3); + const QString ioMode = file.left(sep + 3); + const QString path = file.mid(sep + 3); recentFiles.append({ ioMode, path }); } else { recentFiles.append({ "file://", file }); @@ -892,7 +887,7 @@ void Configuration::setRecentProjects(const QList &list) void Configuration::addRecentProject(QString file) { - RecentFileEntry project = { "", file }; + const RecentFileEntry project = { "", std::move(file) }; QList files = getRecentProjects(); files.removeAll(project); files.prepend(project); diff --git a/src/common/Configuration.h b/src/common/Configuration.h index d8280fca..31139b55 100644 --- a/src/common/Configuration.h +++ b/src/common/Configuration.h @@ -1,8 +1,9 @@ #ifndef CONFIGURATION_H #define CONFIGURATION_H -#include #include +#include + #include #define Config() (Configuration::instance()) @@ -18,7 +19,7 @@ class Theme; class QSyntaxHighlighter; class QTextDocument; -enum ColorFlags { +enum ColorFlags : ut8 { LightFlag = 1, DarkFlag = 2, DualColor = LightFlag | DarkFlag, @@ -41,13 +42,16 @@ struct RecentFileEntry } }; +/** + * @brief Singleton class to save and load all of the configuration values + */ class CUTTER_EXPORT Configuration : public QObject { Q_OBJECT private: QPalette nativePalette; QSettings s; - static Configuration *mPtr; + static Configuration *ptr; #ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING KSyntaxHighlighting::Repository *kSyntaxHighlightingRepository; @@ -91,6 +95,10 @@ public: QString name; QLocale locale; }; + /** + * @brief this function will gather and return available translation for Cutter + * @return a list of locales and their names + */ std::vector getAvailableTranslations(); // Fonts @@ -147,6 +155,11 @@ public: void adjustColorThemeDarkness(); int colorThemeDarkness(const QString &colorTheme) const; + /** + * @brief Configuration::setColor sets the local Cutter configuration color + * @param name Color Name + * @param color The color you want to set + */ void setColor(const QString &name, const QColor &color); const QColor getColor(const QString &name) const; @@ -232,12 +245,16 @@ public: void setPreviewValue(bool checked); bool getPreviewValue() const; + // Tooltip + /** * @brief Show tooltips for known values of registers, variables, and memory when debugging */ void setShowVarTooltips(bool enabled); bool getShowVarTooltips() const; + // Recent Items + /** * @brief Recently opened binaries, as shown in NewFileDialog. */ @@ -274,7 +291,7 @@ public: */ void removeRecentRegProfile(const QString &profile); - // Functions Widget Layout + // Interface /** * @brief Get the layout of the Functions widget. diff --git a/src/common/CutterLayout.cpp b/src/common/CutterLayout.cpp index 4dc145b6..66dd39ed 100644 --- a/src/common/CutterLayout.cpp +++ b/src/common/CutterLayout.cpp @@ -4,5 +4,5 @@ using namespace Cutter; bool Cutter::isBuiltinLayoutName(const QString &name) { - return name == LAYOUT_DEFAULT || name == LAYOUT_DEBUG; + return name == layoutDefault || name == layoutDebug; } diff --git a/src/common/CutterLayout.h b/src/common/CutterLayout.h index 2870c007..465bf888 100644 --- a/src/common/CutterLayout.h +++ b/src/common/CutterLayout.h @@ -6,6 +6,9 @@ #include #include +/** + * @namespace Utilities related to cutter layout + */ namespace Cutter { struct CutterLayout @@ -15,8 +18,8 @@ struct CutterLayout QMap viewProperties; }; -const QString LAYOUT_DEFAULT = "Default"; -const QString LAYOUT_DEBUG = "Debug"; +const QString layoutDefault = "Default"; +const QString layoutDebug = "Debug"; bool isBuiltinLayoutName(const QString &name); diff --git a/src/common/CutterSearchable.cpp b/src/common/CutterSearchable.cpp index f90a8a87..73f73efa 100644 --- a/src/common/CutterSearchable.cpp +++ b/src/common/CutterSearchable.cpp @@ -1,14 +1,15 @@ #include "CutterSearchable.h" + #include "SearchBarWidget.h" #include "shortcuts/ShortcutManager.h" -#include #include +#include #include void CutterSearchableHelper::setupConnections(QWidget *parent, SearchBarWidget *searchBar) { - CutterSearchable *searchable = dynamic_cast(parent); + auto *searchable = dynamic_cast(parent); if (!searchBar || !parent || !searchable) { return; } @@ -49,8 +50,8 @@ void CutterSearchableHelper::setupConnections(QWidget *parent, SearchBarWidget * searchBar->showSearchBar(); QWidget *searchArea = searchable->searchableArea(); - int hPadding = searchable->searchHPadding(); - int vPadding = searchable->searchVPadding(); + const int hPadding = searchable->searchHPadding(); + const int vPadding = searchable->searchVPadding(); positionSearchBar(parent, searchBar, searchArea, hPadding, vPadding); } @@ -66,13 +67,14 @@ void CutterSearchableHelper::positionSearchBar(QWidget *parent, SearchBarWidget int searchBarWidth = 0; if (auto *scrollArea = qobject_cast(searchArea)) { - QScrollBar *scrollBar = scrollArea->verticalScrollBar(); + const QScrollBar *scrollBar = scrollArea->verticalScrollBar(); searchBarWidth = (scrollBar && scrollBar->isVisible()) ? scrollBar->width() : 0; } - QPoint areaPos = searchArea->mapTo(parent, QPoint(0, 0)); - int x = areaPos.x() + searchArea->width() - searchBarWidth - searchBar->width() - hPadding; - int y = areaPos.y() + vPadding; + const QPoint areaPos = searchArea->mapTo(parent, QPoint(0, 0)); + const int x = + areaPos.x() + searchArea->width() - searchBarWidth - searchBar->width() - hPadding; + const int y = areaPos.y() + vPadding; searchBar->move(x, y); } diff --git a/src/common/CutterSearchable.h b/src/common/CutterSearchable.h index 73082f7b..0411bb5b 100644 --- a/src/common/CutterSearchable.h +++ b/src/common/CutterSearchable.h @@ -1,11 +1,13 @@ #ifndef CUTTERSEARCHABLE_H #define CUTTERSEARCHABLE_H +#include "CutterCommon.h" + class QString; class SearchBarWidget; class QWidget; -enum SearchOption { +enum SearchOption : ut8 { CaseSensitive = 1, WholeWords = 1 << 1, RegExp = 1 << 2, @@ -15,10 +17,10 @@ enum SearchOption { /** * @brief Interface for any widget that needs a search bar */ -class CutterSearchable +class CutterSearchableI { public: - virtual ~CutterSearchable() = default; + virtual ~CutterSearchableI() = default; /** * @brief Widget which the search bar will be shown relative to diff --git a/src/common/CutterSeekable.cpp b/src/common/CutterSeekable.cpp index 654b7e0b..bbe87c64 100644 --- a/src/common/CutterSeekable.cpp +++ b/src/common/CutterSeekable.cpp @@ -1,6 +1,7 @@ -#include "core/MainWindow.h" #include "CutterSeekable.h" +#include "core/MainWindow.h" + #include CutterSeekable::CutterSeekable(QObject *parent) : QObject(parent) @@ -44,7 +45,7 @@ void CutterSeekable::seekPrev() } } -RVA CutterSeekable::getOffset() +RVA CutterSeekable::getOffset() const { return (synchronized) ? Core()->getOffset() : widgetOffset; } @@ -54,7 +55,7 @@ void CutterSeekable::toggleSynchronization() setSynchronization(!synchronized); } -bool CutterSeekable::isSynchronized() +bool CutterSeekable::isSynchronized() const { return synchronized; } @@ -65,7 +66,7 @@ void CutterSeekable::seekToReference(RVA offset) return; } - QList refs = Core()->getXRefs(offset, false, false); + const QList refs = Core()->getXRefs(offset, false, false); if (refs.length()) { if (refs.length() > 1) { diff --git a/src/common/CutterSeekable.h b/src/common/CutterSeekable.h index 85af3de7..84e19cf9 100644 --- a/src/common/CutterSeekable.h +++ b/src/common/CutterSeekable.h @@ -4,6 +4,9 @@ class MainWindow; +/** + * @brief Class to synchronize seeks with other widgets + */ class CUTTER_EXPORT CutterSeekable : public QObject { Q_OBJECT @@ -39,19 +42,19 @@ public: * If it's not synchronized, it will return the seekable current seek. * @return the seekable current offset. */ - RVA getOffset(); + RVA getOffset() const; /** * @brief isSynchronized tells whether the seekable * is synchronized with Core or not. - * @return boolean + * @return true if synchronized, false otherwise */ - bool isSynchronized(); + bool isSynchronized() const; /** * @brief seekToReference will seek to the function or the object which is referenced in a given * offset - * @param offset - an address that contains a reference to jump to + * @param offset An address that contains a reference to jump to */ void seekToReference(RVA offset); @@ -62,15 +65,11 @@ public slots: void seekPrev(); /** - * @brief toggleSyncWithCore toggles - * Core seek synchronization. + * @brief toggleSyncWithCore toggles Core seek synchronization. */ void toggleSynchronization(); private slots: - /** - * @brief onCoreSeekChanged - */ void onCoreSeekChanged(RVA addr, CutterCore::SeekHistoryType type); private: diff --git a/src/common/Decompiler.cpp b/src/common/Decompiler.cpp index 2089a408..7e244bd2 100644 --- a/src/common/Decompiler.cpp +++ b/src/common/Decompiler.cpp @@ -1,17 +1,17 @@ - #include "Decompiler.h" + #include "Cutter.h" -#include #include +#include Decompiler::Decompiler(const QString &id, const QString &name, QObject *parent) : QObject(parent), id(id), name(name) { } -RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage) +RzAnnotatedCode *Decompiler::makeWarning(const QString &warningMessage) { - std::string temporary = warningMessage.toStdString(); + const std::string temporary = warningMessage.toStdString(); return rz_annotated_code_new(strdup(temporary.c_str())); } diff --git a/src/common/Decompiler.h b/src/common/Decompiler.h index 5cff67a8..e576998a 100644 --- a/src/common/Decompiler.h +++ b/src/common/Decompiler.h @@ -2,14 +2,14 @@ #define DECOMPILER_H #include "CutterCommon.h" -#include "RizinTask.h" + +#include +#include + #include -#include -#include - /** - * Implements a decompiler that can be registered using CutterCore::registerDecompiler() + * @brief Implements a decompiler that can be registered using CutterCore::registerDecompiler() */ class CUTTER_EXPORT Decompiler : public QObject { @@ -23,7 +23,7 @@ public: Decompiler(const QString &id, const QString &name, QObject *parent = nullptr); virtual ~Decompiler() = default; - static RzAnnotatedCode *makeWarning(QString warningMessage); + static RzAnnotatedCode *makeWarning(const QString &warningMessage); QString getId() const { return id; } QString getName() const { return name; } diff --git a/src/common/DecompilerHighlighter.cpp b/src/common/DecompilerHighlighter.cpp index af7cb48f..12a09348 100644 --- a/src/common/DecompilerHighlighter.cpp +++ b/src/common/DecompilerHighlighter.cpp @@ -1,5 +1,5 @@ - #include "DecompilerHighlighter.h" + #include "common/Configuration.h" #include @@ -20,7 +20,7 @@ void DecompilerHighlighter::setAnnotations(RzAnnotatedCode *code) void DecompilerHighlighter::setupTheme() { - struct + const struct { RSyntaxHighlightType type; QString name; @@ -46,19 +46,17 @@ void DecompilerHighlighter::highlightBlock(const QString &) return; } auto block = currentBlock(); - size_t start = block.position(); - size_t end = block.position() + block.length(); + const size_t start = block.position(); + const size_t end = block.position() + block.length(); auto annotations = fromOwned(rz_annotated_code_annotations_range(code, start, end)); - void **iter; - rz_pvector_foreach(annotations.get(), iter) - { - RzCodeAnnotation *annotation = static_cast(*iter); + for (const auto *annotation : CutterPVector(annotations.get())) { + if (annotation->type != RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT) { continue; } auto type = annotation->syntax_highlight.type; - if (size_t(type) >= HIGHLIGHT_COUNT) { + if (size_t(type) >= highlightCount) { continue; } auto annotationStart = annotation->start; diff --git a/src/common/DecompilerHighlighter.h b/src/common/DecompilerHighlighter.h index 21ac364e..f346c597 100644 --- a/src/common/DecompilerHighlighter.h +++ b/src/common/DecompilerHighlighter.h @@ -2,14 +2,16 @@ #define DECOMPILER_HIGHLIGHTER_H #include "CutterCommon.h" -#include + #include -#include #include +#include + #include +#include /** - * \brief SyntaxHighlighter based on annotations from decompiled code. + * @brief SyntaxHighlighter based on annotations from decompiled code. * Can be only used in combination with DecompilerWidget. */ class CUTTER_EXPORT DecompilerHighlighter : public QSyntaxHighlighter @@ -36,8 +38,8 @@ protected: private: void setupTheme(); - static const int HIGHLIGHT_COUNT = RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE + 1; - std::array format; + static const int highlightCount = RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE + 1; + std::array format; RzAnnotatedCode *code = nullptr; }; diff --git a/src/common/DirectionalComboBox.h b/src/common/DirectionalComboBox.h index 59a442af..6144bc4e 100644 --- a/src/common/DirectionalComboBox.h +++ b/src/common/DirectionalComboBox.h @@ -3,8 +3,8 @@ #include /** * @brief Custom QComboBox created to prevent the menu popup from opening up at different - * offsets for different items, which may result in list items being rendered outside - * of the screen/containing widget. + * offsets for different items, which may result in list items being rendered outside + * of the screen/containing widget. */ class DirectionalComboBox : public QComboBox { diff --git a/src/common/DisassemblyHelper.cpp b/src/common/DisassemblyHelper.cpp index cb9d0c3c..952a5714 100644 --- a/src/common/DisassemblyHelper.cpp +++ b/src/common/DisassemblyHelper.cpp @@ -1,18 +1,19 @@ #include "DisassemblyHelper.h" + #include "Cutter.h" #include "rz_types_base.h" -typedef struct mmio_lookup_context +typedef struct MmioLookupContext { QString selected; - RVA mmio_address; + RVA mmioAddress; } mmio_lookup_context_t; -static bool lookup_mmio_addr_cb(void *user, const ut64 key, const void *value) +static bool lookupMmioAddrCb(void *user, const ut64 key, const void *value) { - mmio_lookup_context_t *ctx = (mmio_lookup_context_t *)user; - if (ctx->selected == (const char *)value) { - ctx->mmio_address = key; + auto *ctx = static_cast(user); + if (ctx->selected == static_cast(value)) { + ctx->mmioAddress = key; return false; } return true; @@ -35,8 +36,8 @@ DisassemblyTextBlockUserData *DisassemblyHelper::getUserData(const QTextBlock &b RVA DisassemblyHelper::getXRefFromWord(RVA offset, const QString &selectedWord) { - RVA selectedOffset = Core()->num(selectedWord); - auto xrefsTo = Core()->getXRefs(offset, true, false); + const RVA selectedOffset = Core()->num(selectedWord); + const auto xrefsTo = Core()->getXRefs(offset, true, false); for (const auto &xref : xrefsTo) { if (xref.from == selectedOffset) { return xref.from; @@ -50,7 +51,7 @@ bool DisassemblyHelper::isXRefFromComment(RVA offset, const QString &line) return Core()->getXRefCommentAt(offset).simplified().contains(line.simplified()); } -RVA DisassemblyHelper::readDisassemblyOffset(QTextCursor tc) +RVA DisassemblyHelper::readDisassemblyOffset(const QTextCursor &tc) { auto userData = DisassemblyHelper::getUserData(tc.block()); if (!userData) { @@ -60,7 +61,7 @@ RVA DisassemblyHelper::readDisassemblyOffset(QTextCursor tc) return userData->line.offset; } -RVA DisassemblyHelper::readDisassemblyArrow(QTextCursor tc) +RVA DisassemblyHelper::readDisassemblyArrow(const QTextCursor &tc) { auto userData = getUserData(tc.block()); if (!userData) { @@ -74,8 +75,8 @@ DisassemblyHelper::BracketResult DisassemblyHelper::findBracketRange(const QStri int posInLine) { BracketResult res; - int openBracket = line.lastIndexOf('[', posInLine); - int closeBracket = line.indexOf(']', posInLine); + const int openBracket = line.lastIndexOf('[', posInLine); + const int closeBracket = line.indexOf(']', posInLine); if (openBracket != -1 && closeBracket != -1) { bool isInside = true; @@ -106,12 +107,12 @@ DisassemblyHelper::BracketResult DisassemblyHelper::findBracketRange(const QStri DisassemblyHelper::TargetContext DisassemblyHelper::getContextFromCursor(QTextCursor tc) { - int originalPos = tc.position(); + const int originalPos = tc.position(); tc.select(QTextCursor::WordUnderCursor); QString word = tc.selectedText(); - QString line = tc.block().text(); - int lineStart = tc.block().position(); - int posInLine = originalPos - lineStart; + const QString line = tc.block().text(); + const int lineStart = tc.block().position(); + const int posInLine = originalPos - lineStart; auto bracketRes = findBracketRange(line, posInLine); if (bracketRes.found) { @@ -135,7 +136,7 @@ DisassemblyHelper::TargetAction DisassemblyHelper::resolveTarget(const TargetCon // Xref comments need special handling to show preview for each caller offset if (filter & TargetFilter::XRefComments) { - bool showXRefComments = Core()->getConfigb("asm.xrefs"); + const bool showXRefComments = Core()->getConfigb("asm.xrefs"); if (showXRefComments && isXRefFromComment(ctx.offset, ctx.line)) { res.value = getXRefFromWord(ctx.offset, ctx.word); res.type = TargetType::XRefComment; @@ -162,8 +163,8 @@ DisassemblyHelper::TargetAction DisassemblyHelper::resolveTarget(const TargetCon } if (filter & TargetFilter::VariableXrefs) { - XrefDescription xref = Core()->getFirstXRefForVariable(ctx.word, ctx.offset); - if (!xref.from_str.isEmpty() || !xref.to_str.isEmpty()) { + const XrefDescription xref = Core()->getFirstXRefForVariable(ctx.word, ctx.offset); + if (!xref.fromStr.isEmpty() || !xref.toStr.isEmpty()) { res.value = xref.from; res.type = TargetType::VariableXRef; return res; @@ -196,16 +197,16 @@ DisassemblyHelper::TargetAction DisassemblyHelper::resolveTarget(const TargetCon } if (filter & TargetFilter::MMIO) { - mmio_lookup_context_t mmio_ctx; - mmio_ctx.selected = ctx.word; - mmio_ctx.mmio_address = RVA_INVALID; + mmio_lookup_context_t mmioCtx; + mmioCtx.selected = ctx.word; + mmioCtx.mmioAddress = RVA_INVALID; auto core = Core()->lock(); - RzPlatformTarget *arch_target = rz_analysis_get_arch_target(core->analysis); - if (arch_target && arch_target->profile) { - ht_up_foreach(arch_target->profile->registers_mmio, lookup_mmio_addr_cb, &mmio_ctx); + const RzPlatformTarget *archTarget = rz_analysis_get_arch_target(core->analysis); + if (archTarget && archTarget->profile) { + ht_up_foreach(archTarget->profile->registers_mmio, lookupMmioAddrCb, &mmioCtx); } - if (mmio_ctx.mmio_address != RVA_INVALID) { - res.value = mmio_ctx.mmio_address; + if (mmioCtx.mmioAddress != RVA_INVALID) { + res.value = mmioCtx.mmioAddress; res.type = TargetType::MMIO; return res; } diff --git a/src/common/DisassemblyHelper.h b/src/common/DisassemblyHelper.h index 70b4cc5d..9742f78a 100644 --- a/src/common/DisassemblyHelper.h +++ b/src/common/DisassemblyHelper.h @@ -1,9 +1,10 @@ #ifndef DISASSEMBLYHELPER_H #define DISASSEMBLYHELPER_H -#include #include "core/CutterDescriptions.h" +#include + /** * @brief Metadata container attached to each QTextBlock in the disassembly view * @@ -25,7 +26,7 @@ namespace DisassemblyHelper { /** * @brief Identifies what kind of item was clicked or hovered */ -enum class TargetType { +enum class TargetType : ut8 { VariableXRef, VariableValue, TypeName, @@ -60,7 +61,7 @@ struct TargetAction /** * @brief Filter to control how deep the search goes */ -enum TargetFilter { +enum TargetFilter : ut8 { XRefComments = 1 << 0, VariableXrefs = 1 << 1, VariableValues = 1 << 2, @@ -116,13 +117,13 @@ bool isXRefFromComment(RVA offset, const QString &line); * @brief Reads the offset for the cursor position * @return The disassembly offset of the hovered asm text */ -RVA readDisassemblyOffset(QTextCursor tc); +RVA readDisassemblyOffset(const QTextCursor &tc); /*! * @brief Reads the arrow offset for the cursor position * @return Offset the arrow points to */ -RVA readDisassemblyArrow(QTextCursor tc); +RVA readDisassemblyArrow(const QTextCursor &tc); /** * @brief Gets the text and address at the current cursor position diff --git a/src/common/DisassemblyPreview.cpp b/src/common/DisassemblyPreview.cpp index 454933f7..02557c6b 100644 --- a/src/common/DisassemblyPreview.cpp +++ b/src/common/DisassemblyPreview.cpp @@ -1,12 +1,12 @@ #include "DisassemblyPreview.h" + #include "Configuration.h" #include "rz_types_base.h" -#include "widgets/GraphView.h" #include -#include -#include #include +#include +#include namespace DH = DisassemblyHelper; @@ -15,15 +15,14 @@ QString DisassemblyPreview::getToolTipStyleSheet() return QString { "QToolTip { border-width: 1px; max-width: %1px;" "opacity: 230; background-color: %2;" "color: %3; border-color: %3;}" } - .arg(400) - .arg(Config()->getColor("gui.tooltip.background").name()) - .arg(Config()->getColor("gui.tooltip.foreground").name()); + .arg(QString::number(400), Config()->getColor("gui.tooltip.background").name(), + Config()->getColor("gui.tooltip.foreground").name()); } bool DisassemblyPreview::showDisasPreview(QWidget *parent, const QPoint &pointOfEvent, const RVA offsetFrom) { - QList refs = Core()->getXRefs(offsetFrom, false, false); + const QList refs = Core()->getXRefs(offsetFrom, false, false); if (refs.length()) { if (refs.length() > 1) { qWarning() << QObject::tr( @@ -31,7 +30,7 @@ bool DisassemblyPreview::showDisasPreview(QWidget *parent, const QPoint &pointOf .arg(refs.length()); } - RVA offsetTo = refs.at(0).to; // This is the offset we want to preview + const RVA offsetTo = refs.at(0).to; // This is the offset we want to preview /* * Only if the offset we point *to* is different from the one the cursor is currently * on *and* the former is a valid offset, we are allowed to get a preview of offsetTo @@ -46,16 +45,15 @@ bool DisassemblyPreview::showDisasPreview(QWidget *parent, const QPoint &pointOf bool DisassemblyPreview::showDisasPreviewAt(QWidget *parent, const QPoint &pointOfEvent, const RVA offset) { - QStringList disasmPreview = Core()->getDisassemblyPreview(offset, 10); + const QStringList disasmPreview = Core()->getDisassemblyPreview(offset, 10); if (!disasmPreview.isEmpty()) { const QFont &fnt = Config()->getFont(); - QString tooltip = QString("
Disassembly Preview:
" - "%3
") - .arg(fnt.family().toHtmlEscaped()) - .arg(qMax(8, fnt.pointSize() - 1)) - .arg(disasmPreview.join("
")); + const QString tooltip = QString("
Disassembly Preview:
%3
") + .arg(fnt.family()) + .arg(qMax(8, fnt.pointSize() - 1)) + .arg(disasmPreview.join("
")); QToolTip::showText(pointOfEvent, tooltip, parent, QRect {}, 3500); return true; @@ -83,7 +81,7 @@ bool DisassemblyPreview::showDebugValueTooltip(QWidget *parent, const QPoint &po break; } case DH::TargetType::MMIO: { - int len = 8; // TODO: Determine proper len of mmio address for the cpu + const int len = 8; // TODO: Determine proper len of mmio address for the cpu auto core = Core()->lock(); if (char *r = rz_core_print_hexdump_or_hexdiff_str(core, RZ_OUTPUT_MODE_STANDARD, ta.value, len, false)) { @@ -93,7 +91,7 @@ bool DisassemblyPreview::showDebugValueTooltip(QWidget *parent, const QPoint &po break; } case DH::TargetType::Memory: { - ut64 addr = Core()->math(ctx.word.mid(1, ctx.word.length() - 2)); + const ut64 addr = Core()->math(ctx.word.mid(1, ctx.word.length() - 2)); msg = QString("%1 = 0x%2 -> 0x%3").arg(ctx.word).arg(addr, 0, 16).arg(ta.value, 0, 16); break; } @@ -113,7 +111,7 @@ bool DisassemblyPreview::showDebugValueTooltip(QWidget *parent, const QPoint &po bool DisassemblyPreview::showTooltip(QWidget *parent, const QPoint &globalPos, const DH::TargetContext &ctx, bool hasPreview) { - bool isWordEmpty = ctx.word.isEmpty(); + const bool isWordEmpty = ctx.word.isEmpty(); if (hasPreview) { auto ta = DH::resolveTarget(ctx, DH::XRefComments | DH::Arrows); diff --git a/src/common/DisassemblyPreview.h b/src/common/DisassemblyPreview.h index a416bdc2..7990a46a 100644 --- a/src/common/DisassemblyPreview.h +++ b/src/common/DisassemblyPreview.h @@ -1,16 +1,15 @@ #ifndef DISASSEMBLYPREVIEW_H #define DISASSEMBLYPREVIEW_H -#include -#include "core/CutterDescriptions.h" #include "DisassemblyHelper.h" +#include "core/CutterDescriptions.h" + +#include class QWidget; /** - * @brief Namespace to define relevant functions - * - * @ingroup DisassemblyPreview + * @namespace Namespace containing functions for showing tooltips in disassembly */ namespace DisassemblyPreview { /*! diff --git a/src/common/FunctionsTask.h b/src/common/FunctionsTask.h index 7de50877..9b361486 100644 --- a/src/common/FunctionsTask.h +++ b/src/common/FunctionsTask.h @@ -1,16 +1,18 @@ - #ifndef FUNCTIONSTASK_H #define FUNCTIONSTASK_H #include "common/AsyncTask.h" #include "core/Cutter.h" +/** + * @brief Async task for fetching functions through rizin + */ class FunctionsTask : public AsyncTask { Q_OBJECT public: - QString getTitle() override { return tr("Fetching Functions"); } + QString getTitle() const override { return tr("Fetching Functions"); } signals: void fetchFinished(const QList &strings); diff --git a/src/common/Helpers.cpp b/src/common/Helpers.cpp index 32b36a21..d50bd5b4 100644 --- a/src/common/Helpers.cpp +++ b/src/common/Helpers.cpp @@ -1,30 +1,25 @@ #include "common/Helpers.h" + #include "Configuration.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include -static QAbstractItemView::ScrollMode scrollMode() -{ - const bool use_scrollperpixel = true; - return use_scrollperpixel ? QAbstractItemView::ScrollPerPixel - : QAbstractItemView::ScrollPerItem; -} +#include namespace qhelpers { -QString formatBytecount(const uint64_t bytecount) +QString formatByteCount(ut64 bytecount) { if (bytecount == 0) { return "0"; @@ -54,7 +49,7 @@ void adjustColumns(QTreeView *tv, int startIndex, int endIndex, int padding) for (int i = startIndex; i < endIndex; ++i) { tv->resizeColumnToContents(i); if (padding > 0) { - int width = tv->columnWidth(i); + const int width = tv->columnWidth(i); tv->setColumnWidth(i, width + padding); } } @@ -80,29 +75,28 @@ void adjustColumn(QTreeView *tv, int columnIndex, int width) QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2, const QString &str3, const QString &str4, const QString &str5) { - QTreeWidgetItem *tempItem = new QTreeWidgetItem(); + auto *tempItem = new QTreeWidgetItem(); // Fill dummy hidden column tempItem->setText(0, "0"); tempItem->setText(1, str); - if (!str2.isNull()) + if (!str2.isNull()) { tempItem->setText(2, str2); - if (!str3.isNull()) + } + if (!str3.isNull()) { tempItem->setText(3, str3); - if (!str4.isNull()) + } + if (!str4.isNull()) { tempItem->setText(4, str4); - if (!str5.isNull()) + } + if (!str5.isNull()) { tempItem->setText(5, str5); + } tw->insertTopLevelItem(0, tempItem); return tempItem; } -/** - * @brief Select first item of a QAbstractItemView if not empty - * @param itemView - * @return true if first item was selected - */ bool selectFirstItem(QAbstractItemView *itemView) { if (!itemView) { @@ -121,12 +115,12 @@ bool selectFirstItem(QAbstractItemView *itemView) void setVerticalScrollMode(QAbstractItemView *tw) { - tw->setVerticalScrollMode(scrollMode()); + tw->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); } void setCheckedWithoutSignals(QAbstractButton *button, bool checked) { - bool blocked = button->signalsBlocked(); + const bool blocked = button->signalsBlocked(); button->blockSignals(true); button->setChecked(checked); button->blockSignals(blocked); @@ -164,14 +158,14 @@ SizePolicyMinMax forceHeight(QWidget *widget, int height) return r; } -void SizePolicyMinMax::restoreWidth(QWidget *widget) +void SizePolicyMinMax::restoreWidth(QWidget *widget) const { widget->setSizePolicy(sizePolicy.horizontalPolicy(), widget->sizePolicy().verticalPolicy()); widget->setMinimumWidth(min); widget->setMaximumWidth(max); } -void SizePolicyMinMax::restoreHeight(QWidget *widget) +void SizePolicyMinMax::restoreHeight(QWidget *widget) const { widget->setSizePolicy(widget->sizePolicy().horizontalPolicy(), sizePolicy.verticalPolicy()); widget->setMinimumHeight(min); @@ -180,7 +174,7 @@ void SizePolicyMinMax::restoreHeight(QWidget *widget) int getMaxFullyDisplayedLines(QTextEdit *textEdit) { - QFontMetrics fontMetrics(textEdit->document()->defaultFont()); + const QFontMetrics fontMetrics(textEdit->document()->defaultFont()); return (textEdit->height() - (textEdit->contentsMargins().top() + textEdit->contentsMargins().bottom() + (int)(textEdit->document()->documentMargin() * 2))) @@ -189,7 +183,7 @@ int getMaxFullyDisplayedLines(QTextEdit *textEdit) int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit) { - QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont()); + const QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont()); return (plainTextEdit->height() - (plainTextEdit->contentsMargins().top() + plainTextEdit->contentsMargins().bottom() + (int)(plainTextEdit->document()->documentMargin() * 2))) @@ -201,19 +195,19 @@ QByteArray applyColorToSvg(const QByteArray &data, QColor color) static const QRegularExpression styleRegExp( "(?:style=\".*fill:(.*?);.*?\")|(?:fill=\"(.*?)\")"); - QString replaceStr = QString("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0')); - int replaceStrLen = replaceStr.length(); + const QString replaceStr = QString("#%1").arg(color.rgb() & 0xffffff, 6, 16, QLatin1Char('0')); + const int replaceStrLen = replaceStr.length(); QString xml = QString::fromUtf8(data); int offset = 0; while (true) { - QRegularExpressionMatch match = styleRegExp.match(xml, offset); + const QRegularExpressionMatch match = styleRegExp.match(xml, offset); if (!match.hasMatch()) { break; } - int captureIndex = match.captured(1).isNull() ? 2 : 1; + const int captureIndex = match.captured(1).isNull() ? 2 : 1; xml.replace(match.capturedStart(captureIndex), match.capturedLength(captureIndex), replaceStr); offset = match.capturedStart(captureIndex) + replaceStrLen; @@ -225,21 +219,15 @@ QByteArray applyColorToSvg(const QByteArray &data, QColor color) QByteArray applyColorToSvg(const QString &filename, QColor color) { QFile file(filename); - file.open(QIODevice::ReadOnly); + if (!file.open(QIODevice::ReadOnly)) { + return QByteArray(); + } return applyColorToSvg(file.readAll(), color); } -/** - * @brief finds the theme-specific icon path and calls `setter` functor providing a pointer of an - * object which has to be used and loaded icon - * @param supportedIconsNames list of - * @param setter functor which has to be called - * for example we need to set an action icon, the functor can be just [](void* o, const QIcon - * &icon) { static_cast(o)->setIcon(icon); } - */ -void setThemeIcons(QList> supportedIconsNames, - std::function setter) +void setThemeIcons(const QList> &supportedIconsNames, + const std::function &setter) { if (supportedIconsNames.isEmpty() || !setter) { return; @@ -280,7 +268,7 @@ qreal devicePixelRatio(const QPaintDevice *p) #endif } -void selectIndexByData(QComboBox *widget, QVariant data, int defaultIndex) +void selectIndexByData(QComboBox *widget, const QVariant &data, int defaultIndex) { for (int i = 0; i < widget->count(); i++) { if (widget->itemData(i) == data) { diff --git a/src/common/Helpers.h b/src/common/Helpers.h index cbda9dbb..2a1c8c7e 100644 --- a/src/common/Helpers.h +++ b/src/common/Helpers.h @@ -3,9 +3,10 @@ #include "core/CutterCommon.h" -#include #include #include +#include + #include class QIcon; @@ -32,8 +33,11 @@ class QMouseEvent; # define CUTTER_QT_SKIP_EMPTY_PARTS Qt::SkipEmptyParts #endif +/** + * @namespace Helpers for QT related objects + */ namespace qhelpers { -CUTTER_EXPORT QString formatBytecount(const uint64_t bytecount); +CUTTER_EXPORT QString formatByteCount(ut64 bytecount); CUTTER_EXPORT void adjustColumns(QTreeView *tv, int columnCount, int padding); CUTTER_EXPORT void adjustColumns(QTreeView *tw, int startIndex, int endIndex, int padding); CUTTER_EXPORT void adjustColumns(QTreeWidget *tw, int padding); @@ -49,6 +53,11 @@ CUTTER_EXPORT void adjustColumns(QTreeWidget *tw, int padding); */ CUTTER_EXPORT void adjustColumn(QTreeView *tv, int columnIndex, int width = -1); +/** + * @brief Select first item of a QAbstractItemView if not empty + * @param itemView + * @return true if first item was selected + */ CUTTER_EXPORT bool selectFirstItem(QAbstractItemView *itemView); CUTTER_EXPORT QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2 = QString(), @@ -66,8 +75,8 @@ struct CUTTER_EXPORT SizePolicyMinMax int min; int max; - void restoreWidth(QWidget *widget); - void restoreHeight(QWidget *widget); + void restoreWidth(QWidget *widget) const; + void restoreHeight(QWidget *widget) const; }; CUTTER_EXPORT SizePolicyMinMax forceWidth(QWidget *widget, int width); @@ -79,8 +88,16 @@ CUTTER_EXPORT int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit); CUTTER_EXPORT QByteArray applyColorToSvg(const QByteArray &data, QColor color); CUTTER_EXPORT QByteArray applyColorToSvg(const QString &filename, QColor color); -CUTTER_EXPORT void setThemeIcons(QList> supportedIconsNames, - std::function setter); +/** + * @brief Finds the theme-specific icon path and calls `setter` functor providing a pointer of an + * object which has to be used and loaded icon + * @param supportedIconsNames list of + * @param setter functor which has to be called + * for example we need to set an action icon, the functor can be just [](void* o, const QIcon + * &icon) { static_cast(o)->setIcon(icon); } + */ +CUTTER_EXPORT void setThemeIcons(const QList> &supportedIconsNames, + const std::function &setter); CUTTER_EXPORT void prependQAction(QAction *action, QMenu *menu); CUTTER_EXPORT qreal devicePixelRatio(const QPaintDevice *p); @@ -90,7 +107,8 @@ CUTTER_EXPORT qreal devicePixelRatio(const QPaintDevice *p); * @param data - value to search in combobox item data * @param defaultIndex - item to select in case no match */ -CUTTER_EXPORT void selectIndexByData(QComboBox *comboBox, QVariant data, int defaultIndex = -1); +CUTTER_EXPORT void selectIndexByData(QComboBox *comboBox, const QVariant &data, + int defaultIndex = -1); /** * @brief Emit data change signal in a model's column (DisplayRole) * @param model - model containing data with changes diff --git a/src/common/HighDpiPixmap.cpp b/src/common/HighDpiPixmap.cpp index c21cd2dd..6ecf530f 100644 --- a/src/common/HighDpiPixmap.cpp +++ b/src/common/HighDpiPixmap.cpp @@ -3,7 +3,7 @@ #include #include -static qreal GetDevicePixelRatio(qreal devicePixelRatio) +static qreal getDevicePixelRatio(qreal devicePixelRatio) { if (devicePixelRatio > 0) { return devicePixelRatio; @@ -16,8 +16,8 @@ static qreal GetDevicePixelRatio(qreal devicePixelRatio) } HighDpiPixmap::HighDpiPixmap(int width, int height, qreal devicePixelRatio) - : QPixmap(int(width * GetDevicePixelRatio(devicePixelRatio)), - int(height * GetDevicePixelRatio(devicePixelRatio))) + : QPixmap(int(width * getDevicePixelRatio(devicePixelRatio)), + int(height * getDevicePixelRatio(devicePixelRatio))) { - setDevicePixelRatio(GetDevicePixelRatio(devicePixelRatio)); + setDevicePixelRatio(getDevicePixelRatio(devicePixelRatio)); } diff --git a/src/common/HighDpiPixmap.h b/src/common/HighDpiPixmap.h index b46593a9..614e954b 100644 --- a/src/common/HighDpiPixmap.h +++ b/src/common/HighDpiPixmap.h @@ -2,6 +2,10 @@ #define HIGHDPIPIXMAP_H #include + +/** + * @brief A QPixmap wrapper that automatically scales for high density displays + */ class HighDpiPixmap : public QPixmap { public: diff --git a/src/common/Highlighter.cpp b/src/common/Highlighter.cpp deleted file mode 100644 index 03a9e3bf..00000000 --- a/src/common/Highlighter.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "Highlighter.h" -#include "core/MainWindow.h" - -#include - -Highlighter::Highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) -{ - HighlightingRule rule; - - core = Core(); - - regFormat.setForeground(QColor(236, 100, 75)); - - for (const QString &pattern : this->core->regs) { - rule.pattern.setPattern("\\b" + pattern + "\\b"); - rule.pattern.setPatternOptions(QRegularExpression::CaseInsensitiveOption); - rule.format = regFormat; - highlightingRules.append(rule); - } - - singleLineCommentFormat.setFontWeight(QFont::Bold); - singleLineCommentFormat.setForeground(QColor(63, 195, 128)); - rule.pattern.setPattern(";[^\n]*"); - rule.format = singleLineCommentFormat; - highlightingRules.append(rule); - - commentStartRegularExpression.setPattern("/\\*"); - commentEndRegularExpression.setPattern("\\*/"); -} - -void Highlighter::highlightBlock(const QString &text) -{ - for (const HighlightingRule &rule : highlightingRules) { - QRegularExpression expression(rule.pattern); - int index = expression.match(text).capturedStart(); - while (index >= 0) { - int length = expression.match(text).capturedLength(); - setFormat(index, length, rule.format); - index = expression.match(text.mid(index + length)).capturedStart(); - } - } - setCurrentBlockState(0); - - int startIndex = 0; - if (previousBlockState() != 1) - startIndex = QRegularExpression(commentStartRegularExpression).match(text).capturedStart(); - - while (startIndex >= 0) { - QRegularExpressionMatch commentEndMatch = - QRegularExpression(commentEndRegularExpression).match(text.mid(startIndex)); - int endIndex = commentEndMatch.capturedStart(); - int commentLength; - if (endIndex == -1) { - setCurrentBlockState(1); - commentLength = text.length() - startIndex; - } else { - commentLength = endIndex - startIndex + commentEndMatch.capturedLength(); - } - setFormat(startIndex, commentLength, multiLineCommentFormat); - startIndex = QRegularExpression(commentStartRegularExpression) - .match(text.mid(startIndex + commentLength)) - .capturedStart(); - } -} diff --git a/src/common/Highlighter.h b/src/common/Highlighter.h deleted file mode 100644 index bdf85dcd..00000000 --- a/src/common/Highlighter.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef HIGHLIGHTER_H -#define HIGHLIGHTER_H - -#include "core/Cutter.h" - -#include -#include -#include -#include - -class QTextDocument; -class MainWindow; - -class Highlighter : public QSyntaxHighlighter -{ - Q_OBJECT - -public: - Highlighter(QTextDocument *parent = nullptr); - -protected: - void highlightBlock(const QString &text); - -private: - CutterCore *core; - - struct HighlightingRule - { - QRegularExpression pattern; - QTextCharFormat format; - }; - QVector highlightingRules; - - QRegularExpression commentStartRegularExpression; - QRegularExpression commentEndRegularExpression; - - QTextCharFormat keywordFormat; - QTextCharFormat regFormat; - QTextCharFormat classFormat; - QTextCharFormat singleLineCommentFormat; - QTextCharFormat multiLineCommentFormat; - QTextCharFormat quotationFormat; - QTextCharFormat functionFormat; -}; - -#endif // HIGHLIGHTER_H diff --git a/src/common/IOModesController.cpp b/src/common/IOModesController.cpp index 4072d6e7..36546299 100644 --- a/src/common/IOModesController.cpp +++ b/src/common/IOModesController.cpp @@ -1,11 +1,12 @@ #include "IOModesController.h" + #include "Cutter.h" #include -#include -#include -#include #include +#include +#include +#include #include IOModesController::IOModesController(QWidget *parentWindow) @@ -64,9 +65,9 @@ bool IOModesController::prepareForWriting() "For safety, please consider using Cache mode and then commit the changes manually " "via File -> Commit modifications to disk.")); msgBox.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole); - QAbstractButton *reopenButton = + const QAbstractButton *reopenButton = msgBox.addButton(QObject::tr("Reopen in Write mode"), QMessageBox::YesRole); - QAbstractButton *iocacheButton = + const QAbstractButton *iocacheButton = msgBox.addButton(QObject::tr("Enable Cache mode"), QMessageBox::YesRole); msgBox.exec(); @@ -81,22 +82,11 @@ bool IOModesController::prepareForWriting() return true; } -bool IOModesController::allChangesComitted() -{ - RzCoreLocked core(Core()); - for (auto c : CutterPVector(&core->io->cache)) { - if (!c->written) { - return false; - } - } - return true; -} - bool IOModesController::askCommitUnsavedChanges() { // Check if there are uncommitted changes - if (!allChangesComitted()) { - QMessageBox::StandardButton ret = QMessageBox::question( + if (!Core()->hasUncommitedChanges()) { + const QMessageBox::StandardButton ret = QMessageBox::question( parentWindow, QObject::tr("Uncommitted changes"), QObject::tr("It seems that you have changes or patches that are not committed to " "the file.\n" diff --git a/src/common/IOModesController.h b/src/common/IOModesController.h index 4a0a5890..32499a69 100644 --- a/src/common/IOModesController.h +++ b/src/common/IOModesController.h @@ -2,8 +2,14 @@ #define IOMODESCONTROLLER_H #include "core/Cutter.h" + #include +/** + * @brief Manages switching between Read-Only, Cache, and Write modes + * + * Handles the logic required when changing how Cutter interacts with the underlying file on disk + */ class IOModesController : public QObject { @@ -13,7 +19,6 @@ public: enum class Mode { READ_ONLY, CACHE, WRITE }; bool prepareForWriting(); bool canWrite(); - bool allChangesComitted(); Mode getIOMode(); void setIOMode(Mode mode); diff --git a/src/common/InitialOptions.h b/src/common/InitialOptions.h index 04e2b44d..a3b62197 100644 --- a/src/common/InitialOptions.h +++ b/src/common/InitialOptions.h @@ -1,8 +1,7 @@ - #ifndef CUTTER_INITIALOPTIONS_H #define CUTTER_INITIALOPTIONS_H -#include "core/Cutter.h" +#include "core/Cutter.h" // IWYU pragma: keep /** * @brief The CommandDescription struct is a pair of a Rizin command and its description @@ -15,9 +14,12 @@ struct CommandDescription QString translatedDescription() const; }; +/** + * @brief Struct to hold the options set when opening a file/project + */ struct InitialOptions { - enum class Endianness { Auto, Little, Big }; + enum class Endianness : ut8 { Auto, Little, Big }; QString filename; QString projectFile; diff --git a/src/common/JsonModel.cpp b/src/common/Json.cpp similarity index 93% rename from src/common/JsonModel.cpp rename to src/common/Json.cpp index 4bc01cb4..6b6e8ee8 100644 --- a/src/common/JsonModel.cpp +++ b/src/common/Json.cpp @@ -1,4 +1,8 @@ -#include "JsonModel.h" +#include "Json.h" + +#include "CutterJson.h" + +#include QTreeWidgetItem *Cutter::jsonTreeWidgetItem(const QString &key, const CutterJson &json) { diff --git a/src/common/Json.h b/src/common/Json.h index a8ce6288..f9099cd2 100644 --- a/src/common/Json.h +++ b/src/common/Json.h @@ -1,19 +1,32 @@ +#ifndef JSON_H +#define JSON_H -#ifndef CUTTER_JSON_H -#define CUTTER_JSON_H - -#include "core/Cutter.h" +#include "CutterCommon.h" #include +#include -static inline RVA JsonValueGetRVA(const QJsonValue &value, RVA defaultValue = RVA_INVALID) +class QTreeWidgetItem; +class CutterJson; + +/** + * @file Json.h + * @brief Helpers for Json objects + */ +namespace Cutter { + +inline RVA jsonValueToRVA(const QJsonValue &value, RVA defaultValue = RVA_INVALID) { bool ok; - RVA ret = value.toVariant().toULongLong(&ok); + const RVA ret = value.toVariant().toULongLong(&ok); if (!ok) { return defaultValue; } return ret; } -#endif // CUTTER_JSON_H +QTreeWidgetItem *jsonTreeWidgetItem(const QString &key, const CutterJson &json); + +} + +#endif // JSON_H diff --git a/src/common/JsonModel.h b/src/common/JsonModel.h deleted file mode 100644 index 5af02ab6..00000000 --- a/src/common/JsonModel.h +++ /dev/null @@ -1,14 +0,0 @@ - -#ifndef JSONMODEL_H -#define JSONMODEL_H - -#include -#include "CutterJson.h" - -namespace Cutter { - -QTreeWidgetItem *jsonTreeWidgetItem(const QString &key, const CutterJson &json); - -}; - -#endif // JSONMODEL_H diff --git a/src/common/LinkedListPool.h b/src/common/LinkedListPool.h index 53cd6dd7..22e3ff22 100644 --- a/src/common/LinkedListPool.h +++ b/src/common/LinkedListPool.h @@ -1,9 +1,8 @@ #ifndef LINKED_LIST_POOL_H #define LINKED_LIST_POOL_H -#include -#include #include +#include /** * @brief Pool of singly linked lists. @@ -92,7 +91,7 @@ public: }; /** - * @brief Create a linked list pool with capacity for \a initialCapacity list items. + * @brief Create a linked list pool with capacity for @a initialCapacity list items. * @param initialCapacity number of elements to preallocate. */ LinkedListPool(size_t initialCapacity) : data(1) @@ -110,7 +109,7 @@ public: */ List makeList(const T &value) { - size_t position = data.size(); + const size_t position = data.size(); data.push_back(Item { 0, value }); return { position, position }; } @@ -122,8 +121,8 @@ public: * items. Modifying them will affect both lists. * * @param list The list that needs to be split. - * @param head Iterator to the first item in new list. Needs to be within \a list . - * @return Returns suffix of \a list. + * @param head Iterator to the first item in new list. Needs to be within @a list . + * @return Returns suffix of @a list. */ List splitTail(const List &list, const ListIterator &head) { @@ -135,8 +134,8 @@ public: * * @param list The list that needs to be split. * @param end Iterator to the first item that should not be included in returned list. Needs to - * be within \a list . - * @return Returns prefix of \a list. + * be within @a list . + * @return Returns prefix of @a list. */ List splitHead(const List &list, const ListIterator &end) { diff --git a/src/common/MdHighlighter.cpp b/src/common/MdHighlighter.cpp index c399da80..1e402369 100644 --- a/src/common/MdHighlighter.cpp +++ b/src/common/MdHighlighter.cpp @@ -1,7 +1,7 @@ -#include - #include "common/MdHighlighter.h" +#include + MdHighlighter::MdHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) { HighlightingRule rule; @@ -16,7 +16,7 @@ MdHighlighter::MdHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) << "\\_([^\\\\]+)\\_" << "\\_\\_([^\\\\]+)\\_\\_"; - for (const QString &pattern : keywordPatterns) { + for (const QString &pattern : std::as_const(keywordPatterns)) { rule.pattern.setPattern(pattern); rule.format = keywordFormat; highlightingRules.append(rule); @@ -31,11 +31,11 @@ MdHighlighter::MdHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) void MdHighlighter::highlightBlock(const QString &text) { - for (const HighlightingRule &rule : highlightingRules) { - QRegularExpression expression(rule.pattern); + for (const HighlightingRule &rule : std::as_const(highlightingRules)) { + const QRegularExpression expression(rule.pattern); int index = expression.match(text).capturedStart(); while (index >= 0) { - int length = expression.match(text).capturedLength(); + const int length = expression.match(text).capturedLength(); setFormat(index, length, rule.format); index = expression.match(text.mid(index + length)).capturedStart(); } diff --git a/src/common/MdHighlighter.h b/src/common/MdHighlighter.h index 951ffd55..31e29897 100644 --- a/src/common/MdHighlighter.h +++ b/src/common/MdHighlighter.h @@ -1,14 +1,16 @@ #ifndef MDHIGHLIGHTER_H #define MDHIGHLIGHTER_H -#include - #include -#include #include +#include +#include class QTextDocument; +/** + * @brief Wrapper of QSyntaxHighlighter for Markdown + */ class MdHighlighter : public QSyntaxHighlighter { Q_OBJECT diff --git a/src/common/Metrics.h b/src/common/Metrics.h index 0c2afbc1..b52a826e 100644 --- a/src/common/Metrics.h +++ b/src/common/Metrics.h @@ -1,4 +1,3 @@ - #ifndef METRICS_H #define METRICS_H diff --git a/src/common/PythonAPI.cpp b/src/common/PythonAPI.cpp index a09160f3..58eb22ef 100644 --- a/src/common/PythonAPI.cpp +++ b/src/common/PythonAPI.cpp @@ -1,7 +1,7 @@ #include "PythonAPI.h" -#include "core/Cutter.h" #include "CutterConfig.h" +#include "core/Cutter.h" #include diff --git a/src/common/PythonManager.cpp b/src/common/PythonManager.cpp index dca8fcba..e6b0e9e8 100644 --- a/src/common/PythonManager.cpp +++ b/src/common/PythonManager.cpp @@ -1,18 +1,20 @@ -#include - +// clang-format off #include "PythonAPI.h" #include "PythonManager.h" +// clang-format on + #include "Cutter.h" -#include -#include -#include #include +#include #include +#include + +#include #ifdef CUTTER_ENABLE_PYTHON_BINDINGS -# include # include +# include # ifdef HAVE_PYSIDECLEANUP // This header is introduced in PySide 6 # include diff --git a/src/common/QtResImporter.cpp b/src/common/QtResImporter.cpp index 04e97d34..98b107e4 100644 --- a/src/common/QtResImporter.cpp +++ b/src/common/QtResImporter.cpp @@ -1,8 +1,10 @@ +// clang-format off #include "PythonAPI.h" #include "QtResImporter.h" +// clang-format on -#include #include +#include bool QtResExists(const char *name, QFile &file) { @@ -19,7 +21,10 @@ PyObject *QtResGetCode(const char *name) return nullptr; } - moduleFile.open(QIODevice::ReadOnly); + if (!moduleFile.open(QIODevice::ReadOnly)) { + return nullptr; + } + QByteArray data = moduleFile.readAll(); moduleFile.close(); @@ -50,8 +55,9 @@ PyObject *qtres_exists(PyObject *self, PyObject *args) Q_UNUSED(self) char *name; QFile resFile; - if (!PyArg_ParseTuple(args, "s", &name)) + if (!PyArg_ParseTuple(args, "s", &name)) { return NULL; + } return PyBool_FromLong(QtResExists(name, resFile)); } @@ -59,11 +65,13 @@ PyObject *qtres_get_code(PyObject *self, PyObject *args) { Q_UNUSED(self) char *name; - if (!PyArg_ParseTuple(args, "s", &name)) + if (!PyArg_ParseTuple(args, "s", &name)) { return NULL; + } PyObject *ret = QtResGetCode(name); - if (ret) + if (ret) { return ret; + } Py_RETURN_NONE; } diff --git a/src/common/RefreshDeferrer.cpp b/src/common/RefreshDeferrer.cpp index aab920ae..33fa7730 100644 --- a/src/common/RefreshDeferrer.cpp +++ b/src/common/RefreshDeferrer.cpp @@ -1,5 +1,5 @@ - #include "RefreshDeferrer.h" + #include "widgets/CutterDockWidget.h" RefreshDeferrer::RefreshDeferrer(RefreshDeferrerAccumulator *acc, QObject *parent) diff --git a/src/common/RefreshDeferrer.h b/src/common/RefreshDeferrer.h index 0a008973..e07ae752 100644 --- a/src/common/RefreshDeferrer.h +++ b/src/common/RefreshDeferrer.h @@ -58,7 +58,7 @@ private: public: /** - * \param Determines whether, if nullptr is passed, the current value should be replaced or + * @param Determines whether, if nullptr is passed, the current value should be replaced or * kept. */ explicit ReplacingRefreshDeferrerAccumulator(bool replaceIfNull = true) diff --git a/src/common/ResourcePaths.cpp b/src/common/ResourcePaths.cpp index db36c1c9..d80d251d 100644 --- a/src/common/ResourcePaths.cpp +++ b/src/common/ResourcePaths.cpp @@ -1,10 +1,10 @@ #include "common/ResourcePaths.h" -#include -#include -#include #include #include +#include +#include +#include #include #ifdef APPIMAGE @@ -30,7 +30,7 @@ static QString substitutePath(QString path) /** * @brief Substitute or filter paths returned by standardLocations based on Cutter package kind. * @param paths list of paths to process - * @return + * @return List of substituted path strings */ static QStringList substitutePaths(const QStringList &paths) { @@ -50,8 +50,8 @@ QStringList Cutter::locateAll(QStandardPaths::StandardLocation type, const QStri // This function is reimplemented here instead of forwarded to Qt becauase existence check needs // to be done after substitutions QStringList result; - for (auto path : standardLocations(type)) { - QString filePath = path + QLatin1Char('/') + fileName; + for (const auto &path : standardLocations(type)) { + const QString filePath = path + QLatin1Char('/') + fileName; bool exists = false; if (options & QStandardPaths::LocateDirectory) { exists = QDir(filePath).exists(); @@ -79,6 +79,10 @@ QStringList Cutter::getTranslationsDirectories() { auto result = locateAll(QStandardPaths::AppDataLocation, "translations", QStandardPaths::LocateDirectory); +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + result << QLibraryInfo::path(QLibraryInfo::TranslationsPath); +#else result << QLibraryInfo::location(QLibraryInfo::TranslationsPath); +#endif return result; } diff --git a/src/common/ResourcePaths.h b/src/common/ResourcePaths.h index f3622ff1..35f1c642 100644 --- a/src/common/ResourcePaths.h +++ b/src/common/ResourcePaths.h @@ -4,7 +4,7 @@ #include /** - * \file ResourcePaths.h + * @file ResourcePaths.h * Set of functions for obtaining various paths. Some of the functions are wrappers around * QStandardPaths functions having the same name but with modifications specific to way * Cutter is packaged. diff --git a/src/common/RichTextPainter.cpp b/src/common/RichTextPainter.cpp index 83ad353f..3c20c6b8 100644 --- a/src/common/RichTextPainter.cpp +++ b/src/common/RichTextPainter.cpp @@ -1,7 +1,9 @@ /* x64dbg RichTextPainter */ #include "RichTextPainter.h" + #include "CachedFontMetrics.h" #include "common/Configuration.h" + #include #include #include @@ -15,13 +17,15 @@ void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xin QPen pen; QPen highlightPen; QBrush brush(Qt::cyan); - for (const CustomRichText_t &curRichText : richText) { + for (const CustomRichText &curRichText : richText) { T textWidth = fontMetrics->width(curRichText.text); T backgroundWidth = textWidth; - if (backgroundWidth + xinc > w) + if (backgroundWidth + xinc > w) { backgroundWidth = w - xinc; - if (backgroundWidth <= 0) // stop drawing when going outside the specified width + } + if (backgroundWidth <= 0) { // stop drawing when going outside the specified width break; + } switch (curRichText.flags) { case FlagNone: // defaults pen.setColor(ConfigColor("btext").name()); @@ -46,7 +50,7 @@ void RichTextPainter::paintRichText(QPainter *painter, T x, T y, T w, T h, T xin painter->setPen(pen); break; } - int flags = 0; + int flags = 0; // NOLINT #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) flags = Qt::TextBypassShaping; #endif @@ -69,18 +73,9 @@ template void RichTextPainter::paintRichText(QPainter *painter, qreal x, qreal h, qreal xinc, const List &richText, CachedFontMetrics *fontMetrics); -/** - * @brief RichTextPainter::htmlRichText Convert rich text in x64dbg to HTML, for use by other - * applications - * @param richText The rich text to be converted to HTML format - * @param textHtml The HTML source. Any previous content will be preserved and new content will be - * appended at the end. - * @param textPlain The plain text. Any previous content will be preserved and new content will be - * appended at the end. - */ void RichTextPainter::htmlRichText(const List &richText, QString &textHtml, QString &textPlain) { - for (const CustomRichText_t &curRichText : richText) { + for (const CustomRichText &curRichText : richText) { if (curRichText.text == " ") { // blank textHtml += " "; textPlain += " "; @@ -95,29 +90,33 @@ void RichTextPainter::htmlRichText(const List &richText, QString &textHtml, QStr break; case FlagBackground: // background only if (curRichText.textBackground - != Qt::transparent) // QColor::name() returns "#000000" for transparent color. - // That's not desired. Leave it blank. + != Qt::transparent) { // QColor::name() returns "#000000" for transparent color. + // That's not desired. Leave it blank. textHtml += QString("") .arg(curRichText.textBackground.name()); - else + } else { textHtml += QString(""); + } break; case FlagAll: // color+background if (curRichText.textBackground - != Qt::transparent) // QColor::name() returns "#000000" for transparent color. - // That's not desired. Leave it blank. + != Qt::transparent) { // QColor::name() returns "#000000" for transparent color. + // That's not desired. Leave it blank. textHtml += QString("") .arg(curRichText.textColor.name(), curRichText.textBackground.name()); - else + } else { textHtml += QString("").arg(curRichText.textColor.name()); + } break; } - if (curRichText.highlight) // Underline highlighted token + if (curRichText.highlight) { // Underline highlighted token textHtml += ""; + } textHtml += curRichText.text.toHtmlEscaped(); - if (curRichText.highlight) + if (curRichText.highlight) { textHtml += ""; + } textHtml += ""; // Close the tag textPlain += curRichText.text; } @@ -129,16 +128,16 @@ RichTextPainter::List RichTextPainter::fromTextDocument(const QTextDocument &doc for (QTextBlock block = doc.begin(); block != doc.end(); block = block.next()) { for (QTextBlock::iterator it = block.begin(); it != block.end(); ++it) { - QTextFragment fragment = it.fragment(); - QTextCharFormat format = fragment.charFormat(); + const QTextFragment fragment = it.fragment(); + const QTextCharFormat format = fragment.charFormat(); - CustomRichText_t text; + CustomRichText text; text.text = fragment.text(); text.textColor = format.foreground().color(); text.textBackground = format.background().color(); - bool hasForeground = format.hasProperty(QTextFormat::ForegroundBrush); - bool hasBackground = format.hasProperty(QTextFormat::BackgroundBrush); + const bool hasForeground = format.hasProperty(QTextFormat::ForegroundBrush); + const bool hasBackground = format.hasProperty(QTextFormat::BackgroundBrush); if (hasForeground && !hasBackground) { text.flags = FlagColor; @@ -166,14 +165,14 @@ RichTextPainter::List RichTextPainter::cropped(const RichTextPainter::List &rich int cols = 0; bool cropped = false; for (const auto &text : richText) { - int textLength = text.text.size(); + const int textLength = text.text.size(); if (cols + textLength <= maxCols) { r.push_back(text); cols += textLength; } else if (cols == maxCols) { break; } else { - CustomRichText_t croppedText = text; + CustomRichText croppedText = text; croppedText.text.truncate(maxCols - cols); r.push_back(croppedText); cropped = true; diff --git a/src/common/RichTextPainter.h b/src/common/RichTextPainter.h index b0f0f180..63dd4a47 100644 --- a/src/common/RichTextPainter.h +++ b/src/common/RichTextPainter.h @@ -2,11 +2,12 @@ #ifndef RICHTEXTPAINTER_H #define RICHTEXTPAINTER_H -#include "common/Metrics.h" +#include "CutterDescriptions.h" // IWYU pragma: keep +#include #include #include -#include + #include class QFontMetricsF; @@ -14,36 +15,57 @@ template class CachedFontMetrics; class QPainter; -class RichTextPainter +/** + * @namespace For efficient painting of text + */ +namespace RichTextPainter { + +// structures +enum CustomRichTextFlags : ut8 { FlagNone, FlagColor, FlagBackground, FlagAll }; + +struct CustomRichText { -public: - // structures - enum CustomRichTextFlags { FlagNone, FlagColor, FlagBackground, FlagAll }; - - struct CustomRichText_t - { - QString text; - QColor textColor; - QColor textBackground; - CustomRichTextFlags flags; - bool highlight = false; - QColor highlightColor; - int highlightWidth = 2; - bool highlightConnectPrev = false; - }; - - typedef std::vector List; - - // functions - template - static void paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc, const List &richText, - CachedFontMetrics *fontMetrics); - static void htmlRichText(const List &richText, QString &textHtml, QString &textPlain); - - static List fromTextDocument(const QTextDocument &doc); - - static List cropped(const List &richText, int maxCols, const QString &indicator = nullptr, - bool *croppedOut = nullptr); + QString text; + QColor textColor; + QColor textBackground; + CustomRichTextFlags flags; + bool highlight = false; + QColor highlightColor; + int highlightWidth = 2; + bool highlightConnectPrev = false; }; +typedef std::vector List; + +// functions +template +void paintRichText(QPainter *painter, T x, T y, T w, T h, T xinc, const List &richText, + CachedFontMetrics *fontMetrics); + +/** + * @brief RichTextPainter::htmlRichText Convert rich text in x64dbg to HTML, for use by other + * applications + * @param richText The rich text to be converted to HTML format + * @param[out] textHtml The HTML source. Any previous content will be preserved and new content will + * be appended at the end. + * @param[out] textPlain The plain text. Any previous content will be preserved and new content will + * be appended at the end. + */ +void htmlRichText(const List &richText, QString &textHtml, QString &textPlain); + +List fromTextDocument(const QTextDocument &doc); + +/** + * @brief Crops a list of rich text elements to a maximum column width. + * + * @param richText The input list of rich text segments. + * @param maxCols The maximum character width allowed. + * @param indicator String to append if text is cropped (e.g., "..."). + * @param[out] croppedOut Set to true if the text was actually truncated. + * @return A new list containing the cropped segments. + */ +List cropped(const List &richText, int maxCols, const QString &indicator = nullptr, + bool *croppedOut = nullptr); +} + #endif // RICHTEXTPAINTER_H diff --git a/src/common/RizinTask.cpp b/src/common/RizinTask.cpp index 1482ffb3..a606e855 100644 --- a/src/common/RizinTask.cpp +++ b/src/common/RizinTask.cpp @@ -1,6 +1,7 @@ - #include "RizinTask.h" + #include +#include RizinTask::~RizinTask() { @@ -11,17 +12,17 @@ RizinTask::~RizinTask() void RizinTask::startTask() { - rz_core_task_enqueue(&Core()->core_->tasks, task); + rz_core_task_enqueue(&Core()->rzCore->tasks, task); } void RizinTask::breakTask() { - rz_core_task_break(&Core()->core_->tasks, task->id); + rz_core_task_break(&Core()->rzCore->tasks, task->id); } void RizinTask::joinTask() { - rz_core_task_join(&Core()->core_->tasks, nullptr, task->id); + rz_core_task_join(&Core()->rzCore->tasks, nullptr, task->id); } void RizinTask::taskFinished() @@ -74,7 +75,7 @@ const char *RizinCmdTask::getResultRaw() // RizinFunctionTask RizinFunctionTask::RizinFunctionTask(std::function fcn, bool transient) - : fcn(fcn), res(nullptr) + : fcn(std::move(fcn)), res(nullptr) { auto core = Core()->lock(); task = rz_core_function_task_new( @@ -85,7 +86,7 @@ RizinFunctionTask::RizinFunctionTask(std::function fcn, bool t void *RizinFunctionTask::runner(RzCore *core, void *user) { - RizinFunctionTask *task = reinterpret_cast(user); + auto *task = reinterpret_cast(user); task->res = task->fcn(core); task->taskFinished(); return nullptr; diff --git a/src/common/RizinTask.h b/src/common/RizinTask.h index e0972bc4..0b5a0f8c 100644 --- a/src/common/RizinTask.h +++ b/src/common/RizinTask.h @@ -1,9 +1,13 @@ - #ifndef RZTASK_H #define RZTASK_H #include "core/Cutter.h" +#include + +/** + * @brief Base class for managing background tasks via the Rizin core task API + */ class CUTTER_EXPORT RizinTask : public QObject { Q_OBJECT @@ -15,7 +19,7 @@ protected: void taskFinished(); public: - using Ptr = QSharedPointer; + using Ptr = std::shared_ptr; virtual ~RizinTask(); @@ -27,6 +31,9 @@ signals: void finished(); }; +/** + * @brief AsyncTask for executing individual Rizin commands and fetching their output + */ class CUTTER_EXPORT RizinCmdTask : public RizinTask { Q_OBJECT diff --git a/src/common/RunScriptTask.cpp b/src/common/RunScriptTask.cpp index ca830b1a..c473faef 100644 --- a/src/common/RunScriptTask.cpp +++ b/src/common/RunScriptTask.cpp @@ -1,5 +1,6 @@ -#include "core/Cutter.h" #include "common/RunScriptTask.h" + +#include "core/Cutter.h" #include "core/MainWindow.h" RunScriptTask::RunScriptTask() : AsyncTask() {} diff --git a/src/common/RunScriptTask.h b/src/common/RunScriptTask.h index 03c135bd..184d51f8 100644 --- a/src/common/RunScriptTask.h +++ b/src/common/RunScriptTask.h @@ -1,9 +1,11 @@ -#ifndef RUNSCRIPTTHREAD_H -#define RUNSCRIPTTHREAD_H +#ifndef RUNSCRIPTTASK_H +#define RUNSCRIPTTASK_H #include "common/AsyncTask.h" -#include "core/Cutter.h" +/** + * @brief Async task for running rizin scripts + */ class RunScriptTask : public AsyncTask { Q_OBJECT @@ -12,7 +14,7 @@ public: explicit RunScriptTask(); ~RunScriptTask(); - QString getTitle() override { return tr("Run Script"); } + QString getTitle() const override { return tr("Run Script"); } void setFileName(const QString &fileName) { this->fileName = fileName; } @@ -25,4 +27,4 @@ private: QString fileName; }; -#endif // RUNSCRIPTTHREAD_H +#endif // RUNSCRIPTTASK_H diff --git a/src/common/SelectionHighlight.cpp b/src/common/SelectionHighlight.cpp index fe389c27..ebfe622f 100644 --- a/src/common/SelectionHighlight.cpp +++ b/src/common/SelectionHighlight.cpp @@ -1,22 +1,22 @@ - #include "SelectionHighlight.h" -#include "Configuration.h" -#include "Colors.h" -#include -#include +#include "Colors.h" +#include "Configuration.h" + #include -#include +#include #include #include +#include +#include QList createSameWordsSelections(QPlainTextEdit *textEdit, const QString &word) { QList selections; QTextEdit::ExtraSelection highlightSelection; - QTextDocument *document = textEdit->document(); - QColor highlightWordColor = ConfigColor("wordHighlight"); + const QTextDocument *document = textEdit->document(); + const QColor highlightWordColor = ConfigColor("wordHighlight"); if (word.isEmpty()) { return QList(); @@ -85,18 +85,18 @@ QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor QTextEdit::ExtraSelection createLineHighlightSelection(const QTextCursor &cursor) { - QColor highlightColor = ConfigColor("lineHighlight"); + const QColor highlightColor = ConfigColor("lineHighlight"); return createLineHighlight(cursor, highlightColor); } QTextEdit::ExtraSelection createLineHighlightPC(const QTextCursor &cursor) { - QColor highlightColor = ConfigColor("highlightPC"); + const QColor highlightColor = ConfigColor("highlightPC"); return createLineHighlight(cursor, highlightColor); } QTextEdit::ExtraSelection createLineHighlightBP(const QTextCursor &cursor) { - QColor highlightColor = ConfigColor("gui.breakpoint_background"); + const QColor highlightColor = ConfigColor("gui.breakpoint_background"); return createLineHighlight(cursor, highlightColor); } diff --git a/src/common/SelectionHighlight.h b/src/common/SelectionHighlight.h index e85e3f10..f65128da 100644 --- a/src/common/SelectionHighlight.h +++ b/src/common/SelectionHighlight.h @@ -7,40 +7,43 @@ class QPlainTextEdit; class QString; /** - * @brief createSameWordsSelections se - * @param textEdit - * @param word - * @return + * @brief Create selections for any occurences of the given word + * @param textEdit TextEdit object to make selections in + * @param word Word to make selections of + * @return List of ExtraSelection with highlighted words */ QList createSameWordsSelections(QPlainTextEdit *textEdit, const QString &word); /** - * @brief createLineHighlight - * @param cursor - a Cursor object represents the line to be highlighted - * @param highlightColor - the color to be used for highlighting. The color is decided by the callee + * @brief Highlight the currently selected line with given color + * @param cursor A Cursor object represents the line to be highlighted + * @param highlightColor The color to be used for highlighting. The color is decided by the callee * for different usages (BP, PC, Current line, ...) * @return ExtraSelection with highlighted line */ QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor); /** - * @brief This function responsible to highlight the currently selected line - * @param cursor - a Cursor object represents the line to be highlighted + * @brief This function is responsible for highlighting the currently selected line + * + * Similar to @ref createLineHighlight() but uses "lineHighlght" value from config + * + * @param cursor A Cursor object represents the line to be highlighted * @return ExtraSelection with highlighted line */ QTextEdit::ExtraSelection createLineHighlightSelection(const QTextCursor &cursor); /** - * @brief This function responsible to highlight the program counter line - * @param cursor - a Cursor object represents the line to be highlighted + * @brief This function is responsible for highlighting the program counter line + * @param cursor A Cursor object represents the line to be highlighted * @return ExtraSelection with highlighted line */ QTextEdit::ExtraSelection createLineHighlightPC(const QTextCursor &cursor); /** - * @brief This function responsible to highlight a line with breakpoint - * @param cursor - a Cursor object represents the line to be highlighted + * @brief This function is responsible for highlighting a line that contains a breakpoint + * @param cursor A Cursor object represents the line to be highlighted * @return ExtraSelection with highlighted line */ QTextEdit::ExtraSelection createLineHighlightBP(const QTextCursor &cursor); diff --git a/src/common/SettingsUpgrade.cpp b/src/common/SettingsUpgrade.cpp index 7e931e5d..d290bb43 100644 --- a/src/common/SettingsUpgrade.cpp +++ b/src/common/SettingsUpgrade.cpp @@ -1,22 +1,44 @@ #include "SettingsUpgrade.h" -#include -#include #include "Configuration.h" #include "common/ColorThemeWorker.h" +#include +#include + +#define CUTTER_SETTINGS_VERSION_CURRENT 7 +#define CUTTER_SETTINGS_VERSION_KEY "version" + +#define THEME_VERSION_CURRENT 2 +#define THEME_VERSION_KEY "theme_version" + +/* + * How Settings migrations work: + * + * Every time settings are changed in a way that needs migration, + * CUTTER_SETTINGS_VERSION_CURRENT is raised by 1 and a function migrateSettingsToX + * is implemented and added to initializeSettings(). + * This function takes care of migrating from EXACTLY version X-1 to X. + */ + +namespace { + +const char preRizinOrg[] = "RadareOrg"; +const char preRizinApp[] = "Cutter"; +const int lastR2CutterSettingVersion = 6; + /** * @brief Migrate Settings used before Cutter 1.8 * * @return whether any settings have been migrated */ -static bool migrateSettingsPre18(QSettings &newSettings) +bool migrateSettingsPre18(QSettings &newSettings) { if (newSettings.value("settings_migrated", false).toBool()) { return false; } QSettings oldSettings(QSettings::NativeFormat, QSettings::Scope::UserScope, "Cutter", "Cutter"); - QStringList allKeys = oldSettings.allKeys(); + const QStringList allKeys = oldSettings.allKeys(); if (allKeys.isEmpty()) { return false; } @@ -31,32 +53,20 @@ static bool migrateSettingsPre18(QSettings &newSettings) return true; } -#define CUTTER_SETTINGS_VERSION_CURRENT 7 -#define CUTTER_SETTINGS_VERSION_KEY "version" - -/* - * How Settings migrations work: - * - * Every time settings are changed in a way that needs migration, - * CUTTER_SETTINGS_VERSION_CURRENT is raised by 1 and a function migrateSettingsToX - * is implemented and added to initializeSettings(). - * This function takes care of migrating from EXACTLY version X-1 to X. - */ - -static void migrateSettingsTo1(QSettings &settings) +void migrateSettingsTo1(QSettings &settings) { settings.remove("settings_migrated"); // now handled by version settings.remove("updated_custom_themes"); // now handled by theme_version } -static void migrateSettingsTo2(QSettings &settings) +void migrateSettingsTo2(QSettings &settings) { QStringList docks = settings.value("docks").toStringList(); // get current list of docks // replace occurences of "PseudocodeWidget" with "DecompilerWidget" settings.setValue("docks", docks.replaceInStrings("PseudocodeWidget", "DecompilerWidget")); } -static void migrateSettingsTo3(QSettings &settings) +void migrateSettingsTo3(QSettings &settings) { auto defaultGeometry = settings.value("geometry").toByteArray(); auto defaultState = settings.value("state").toByteArray(); @@ -69,7 +79,7 @@ static void migrateSettingsTo3(QSettings &settings) #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) QSet unsyncDocks = unsyncList.toSet(); #else - QSet unsyncDocks(unsyncList.begin(), unsyncList.end()); + const QSet unsyncDocks(unsyncList.begin(), unsyncList.end()); #endif QVariantMap viewProperties; @@ -108,7 +118,7 @@ static void migrateSettingsTo3(QSettings &settings) settings.remove("unsync"); } -static void renameAsmOption(QSettings &settings, const QString &oldName, const QString &newName) +void renameAsmOption(QSettings &settings, const QString &oldName, const QString &newName) { if (settings.contains(oldName)) { auto value = settings.value(oldName); @@ -117,23 +127,23 @@ static void renameAsmOption(QSettings &settings, const QString &oldName, const Q } } -static void migrateSettingsTo4(QSettings &settings) +void migrateSettingsTo4(QSettings &settings) { renameAsmOption(settings, "asm.var.subonly", "asm.sub.varonly"); renameAsmOption(settings, "asm.bytespace", "asm.bytes.space"); } -static void migrateSettingsTo5(QSettings &settings) +void migrateSettingsTo5(QSettings &settings) { renameAsmOption(settings, "asm.var.sub", "asm.sub.var"); } -static void migrateSettingsTo6(QSettings &settings) +void migrateSettingsTo6(QSettings &settings) { settings.remove("dir.projects"); } -static void migrateSettingsTo7(QSettings &settings) +void migrateSettingsTo7(QSettings &settings) { auto list = settings.value("recentFileList").toStringList(); for (auto &file : list) { @@ -142,12 +152,120 @@ static void migrateSettingsTo7(QSettings &settings) settings.setValue("recentFileList", list); } +void removeObsoleteOptionsFromCustomThemes() +{ + const QStringList options = Core()->getThemeKeys() << ColorThemeWorker::cutterSpecificOptions; + const QStringList themes = Core()->getColorThemes(); + for (const auto &themeName : themes) { + if (!ThemeWorker().isCustomTheme(themeName)) { + continue; + } + const ColorThemeWorker::Theme sch = ThemeWorker().getTheme(themeName); + ColorThemeWorker::Theme updatedTheme; + for (auto it = sch.constBegin(); it != sch.constEnd(); ++it) { + if (options.contains(it.key())) { + updatedTheme.insert(it.key(), it.value()); + } + } + ThemeWorker().save(updatedTheme, themeName); + } +} + +void syncCustomThemes() +{ + const QStringList options = Core()->getThemeKeys() << ColorThemeWorker::cutterSpecificOptions; + const QStringList themes = Core()->getColorThemes(); + const ColorThemeWorker::Theme lightTheme = + ThemeWorker().getTheme("cutter"); // default light theme + const ColorThemeWorker::Theme darkTheme = ThemeWorker().getTheme("ayu"); // default dark theme + + // note that there was no entry for angui.navbar.str (as it was a typo) so the + // default color for it will most likely be black instead of the color defined + // in config, unless changed by the user + QHash renames = { + { "angui.navbar.str", "gui.navbar.str" }, + { "gui.navbar.empty", "gui.navbar.unexplored" }, + }; + const QStringList forceDefaultKeys = { "gui.navbar.signature", "gui.navbar.data" }; + + for (const auto &themeName : themes) { + if (!ThemeWorker().isCustomTheme(themeName)) { + continue; + } + + const ColorThemeWorker::Theme originalTheme = ThemeWorker().getTheme(themeName); + ColorThemeWorker::Theme updatedTheme; + + for (auto it = renames.begin(); it != renames.end(); ++it) { + if (originalTheme.contains(it.key())) { + updatedTheme.insert(it.value(), originalTheme.value(it.key())); + } + } + + const QColor bg = originalTheme.value("gui.background", QColor(Qt::white)); + const QStringList renameValues = renames.values(); + for (const auto &option : options) { + if (renameValues.contains(option)) { + continue; + } + if (originalTheme.contains(option) && !forceDefaultKeys.contains(option)) { + updatedTheme.insert(option, originalTheme.value(option)); + } else { + const QColor color = + bg.lightness() > 128 ? lightTheme.value(option) : darkTheme.value(option); + updatedTheme.insert(option, color); + } + } + + ThemeWorker().save(updatedTheme, themeName); + if (Config()->getColorTheme() == themeName) { + Config()->setColorTheme(themeName); + } + } +} + +void importOldSettings() +{ + // QSettings + QSettings::setDefaultFormat(QSettings::IniFormat); + const QSettings r2CutterSettings(QSettings::IniFormat, QSettings::Scope::UserScope, preRizinOrg, + preRizinApp); + QSettings newSettings; + for (const auto &key : r2CutterSettings.allKeys()) { + newSettings.setValue(key, r2CutterSettings.value(key)); + } + + // Color Themes + char *szThemes = rz_str_home(".local/share/radare2/cons"); + const QString r2ThemesPath = szThemes; + rz_mem_free(szThemes); + const QDir r2ThemesDir(r2ThemesPath); + if (QFileInfo(r2ThemesPath).isDir()) { + const QDir rzThemesDir(ThemeWorker().getCustomThemesPath()); + if (!rzThemesDir.exists()) { + QDir().mkpath(rzThemesDir.absolutePath()); + } + for (const auto &f : r2ThemesDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files)) { + auto dst = rzThemesDir.absoluteFilePath(f.fileName()); + if (QDir(dst).exists()) { + qInfo() << "Theme" << dst << "already exists. Not overwriting with" + << f.absoluteFilePath(); + continue; + } + qInfo() << "Copying Theme" << f.absoluteFilePath() << "to" << dst; + QFile::copy(f.absoluteFilePath(), dst); + } + } +} + +} // End Anonymous namespace + void Cutter::initializeSettings() { QSettings::setDefaultFormat(QSettings::IniFormat); QSettings settings; - int settingsVersion = settings.value(CUTTER_SETTINGS_VERSION_KEY, 0).toInt(); + const int settingsVersion = settings.value(CUTTER_SETTINGS_VERSION_KEY, 0).toInt(); if (settingsVersion == 0) { migrateSettingsPre18(settings); } @@ -189,84 +307,10 @@ void Cutter::initializeSettings() settings.setValue(CUTTER_SETTINGS_VERSION_KEY, CUTTER_SETTINGS_VERSION_CURRENT); } -#define THEME_VERSION_CURRENT 2 -#define THEME_VERSION_KEY "theme_version" - -static void removeObsoleteOptionsFromCustomThemes() -{ - const QStringList options = Core()->getThemeKeys() << ColorThemeWorker::cutterSpecificOptions; - QStringList themes = Core()->getColorThemes(); - for (const auto &themeName : themes) { - if (!ThemeWorker().isCustomTheme(themeName)) { - continue; - } - ColorThemeWorker::Theme sch = ThemeWorker().getTheme(themeName); - ColorThemeWorker::Theme updatedTheme; - for (auto it = sch.constBegin(); it != sch.constEnd(); ++it) { - if (options.contains(it.key())) { - updatedTheme.insert(it.key(), it.value()); - } - } - ThemeWorker().save(updatedTheme, themeName); - } -} - -static void syncCustomThemes() -{ - const QStringList options = Core()->getThemeKeys() << ColorThemeWorker::cutterSpecificOptions; - QStringList themes = Core()->getColorThemes(); - ColorThemeWorker::Theme lightTheme = ThemeWorker().getTheme("cutter"); // default light theme - ColorThemeWorker::Theme darkTheme = ThemeWorker().getTheme("ayu"); // default dark theme - - // note that there was no entry for angui.navbar.str (as it is a typo) so the - // default color for it will most likely be black instead of the color defined - // in config, unless changed by the user - QHash renames = { - { "angui.navbar.str", "gui.navbar.str" }, - { "gui.navbar.empty", "gui.navbar.unexplored" }, - }; - const QStringList forceDefaultKeys = { "gui.navbar.signature", "gui.navbar.data" }; - - for (const auto &themeName : themes) { - if (!ThemeWorker().isCustomTheme(themeName)) { - continue; - } - - ColorThemeWorker::Theme originalTheme = ThemeWorker().getTheme(themeName); - ColorThemeWorker::Theme updatedTheme; - - for (auto it = renames.begin(); it != renames.end(); ++it) { - if (originalTheme.contains(it.key())) { - updatedTheme.insert(it.value(), originalTheme.value(it.key())); - } - } - - QColor bg = originalTheme.value("gui.background", QColor(Qt::white)); - const QStringList renameValues = renames.values(); - for (const auto &option : options) { - if (renameValues.contains(option)) { - continue; - } - if (originalTheme.contains(option) && !forceDefaultKeys.contains(option)) { - updatedTheme.insert(option, originalTheme.value(option)); - } else { - QColor color = - bg.lightness() > 128 ? lightTheme.value(option) : darkTheme.value(option); - updatedTheme.insert(option, color); - } - } - - ThemeWorker().save(updatedTheme, themeName); - if (Config()->getColorTheme() == themeName) { - Config()->setColorTheme(themeName); - } - } -} - void Cutter::migrateThemes() { QSettings settings; - int themeVersion = settings.value(THEME_VERSION_KEY, 0).toInt(); + const int themeVersion = settings.value(THEME_VERSION_KEY, 0).toInt(); if (themeVersion >= THEME_VERSION_CURRENT) { qWarning() << "Themes have a higher version than current! Skipping migration."; return; @@ -288,73 +332,35 @@ void Cutter::migrateThemes() settings.setValue(THEME_VERSION_KEY, THEME_VERSION_CURRENT); } -static const char PRE_RIZIN_ORG[] = "RadareOrg"; -static const char PRE_RIZIN_APP[] = "Cutter"; -const int LAST_R2_CUTTER_SETTING_VERSION = 6; - bool Cutter::shouldOfferSettingImport() { QSettings::setDefaultFormat(QSettings::IniFormat); - QSettings settings; + const QSettings settings; if (settings.contains("firstExecution")) { return false; } - QSettings r2CutterSettings(QSettings::IniFormat, QSettings::Scope::UserScope, PRE_RIZIN_ORG, - PRE_RIZIN_APP); - QString f = r2CutterSettings.fileName(); + const QSettings r2CutterSettings(QSettings::IniFormat, QSettings::Scope::UserScope, preRizinOrg, + preRizinApp); + const QString f = r2CutterSettings.fileName(); if (r2CutterSettings.value("firstExecution", true) != QVariant(false)) { return false; // no Cutter <= 1.12 settings to import } - int version = r2CutterSettings.value("version", -1).toInt(); - if (version < 1 || version > LAST_R2_CUTTER_SETTING_VERSION) { + const int version = r2CutterSettings.value("version", -1).toInt(); + if (version < 1 || version > lastR2CutterSettingVersion) { return false; // version too new maybe it's from r2Cutter fork instead of pre-rizin Cutter. } return true; } -static void importOldSettings() -{ - // QSettings - QSettings::setDefaultFormat(QSettings::IniFormat); - QSettings r2CutterSettings(QSettings::IniFormat, QSettings::Scope::UserScope, PRE_RIZIN_ORG, - PRE_RIZIN_APP); - QSettings newSettings; - for (auto key : r2CutterSettings.allKeys()) { - newSettings.setValue(key, r2CutterSettings.value(key)); - } - - // Color Themes - char *szThemes = rz_str_home(".local/share/radare2/cons"); - QString r2ThemesPath = szThemes; - rz_mem_free(szThemes); - QDir r2ThemesDir(r2ThemesPath); - if (QFileInfo(r2ThemesPath).isDir()) { - QDir rzThemesDir(ThemeWorker().getCustomThemesPath()); - if (!rzThemesDir.exists()) { - QDir().mkpath(rzThemesDir.absolutePath()); - } - for (auto f : r2ThemesDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files)) { - auto dst = rzThemesDir.absoluteFilePath(f.fileName()); - if (QDir(dst).exists()) { - qInfo() << "Theme" << dst << "already exists. Not overwriting with" - << f.absoluteFilePath(); - continue; - } - qInfo() << "Copying Theme" << f.absoluteFilePath() << "to" << dst; - QFile::copy(f.absoluteFilePath(), dst); - } - } -} - void Cutter::showSettingImportDialog(int &argc, char **argv) { // Creating temporary QApplication because this happens before anything else in Cutter is // initialized - QApplication temporaryApp(argc, argv); - QSettings r2CutterSettings(QSettings::IniFormat, QSettings::Scope::UserScope, PRE_RIZIN_ORG, - PRE_RIZIN_APP); - QString oldFile = r2CutterSettings.fileName(); + const QApplication temporaryApp(argc, argv); + const QSettings r2CutterSettings(QSettings::IniFormat, QSettings::Scope::UserScope, preRizinOrg, + preRizinApp); + const QString oldFile = r2CutterSettings.fileName(); // Can't use message translations because settings have not been imported auto result = QMessageBox::question(nullptr, "Setting import", diff --git a/src/common/SettingsUpgrade.h b/src/common/SettingsUpgrade.h index 80541673..3c06fa02 100644 --- a/src/common/SettingsUpgrade.h +++ b/src/common/SettingsUpgrade.h @@ -1,9 +1,15 @@ -#ifndef COMMON_SETTINGS_UPGRADE_H -#define COMMON_SETTINGS_UPGRADE_H +#ifndef SETTINGS_UPGRADE_H +#define SETTINGS_UPGRADE_H #include + #include +/** + * @file SettingsUpgrade.h + * @brief Logic for migrating and importing Cutter settings from older versions + */ + namespace Cutter { void initializeSettings(); /** @@ -21,4 +27,4 @@ void showSettingImportDialog(int &argc, char **argv); void migrateThemes(); } -#endif // COMMON_SETTINGS_UPGRADE_H +#endif // SETTINGS_UPGRADE_H diff --git a/src/common/StringsTask.h b/src/common/StringsTask.h index ff046206..e1d6d447 100644 --- a/src/common/StringsTask.h +++ b/src/common/StringsTask.h @@ -1,16 +1,18 @@ - -#ifndef STRINGSASYNCTASK_H -#define STRINGSASYNCTASK_H +#ifndef STRINGSTASK_H +#define STRINGSTASK_H #include "common/AsyncTask.h" #include "core/Cutter.h" +/** + * @brief AsyncTask for querying all strings in binary + */ class StringsTask : public AsyncTask { Q_OBJECT public: - QString getTitle() override { return tr("Searching for Strings"); } + QString getTitle() const override { return tr("Searching for Strings"); } signals: void stringSearchFinished(const QList &strings); @@ -23,4 +25,4 @@ protected: } }; -#endif // STRINGSASYNCTASK_H +#endif // STRINGSTASK_H diff --git a/src/common/SvgIconEngine.cpp b/src/common/SvgIconEngine.cpp index c11e94e9..8ca2bad5 100644 --- a/src/common/SvgIconEngine.cpp +++ b/src/common/SvgIconEngine.cpp @@ -1,17 +1,17 @@ - #include "SvgIconEngine.h" -#include -#include -#include - #include "Helpers.h" +#include +#include +#include + SvgIconEngine::SvgIconEngine(const QString &filename) { QFile file(filename); - file.open(QFile::ReadOnly); - this->svgData = file.readAll(); + if (file.open(QFile::ReadOnly)) { + this->svgData = file.readAll(); + } } SvgIconEngine::SvgIconEngine(const QString &filename, const QColor &tintColor) @@ -44,7 +44,7 @@ QPixmap SvgIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State QPixmap pix = QPixmap::fromImage(img, Qt::NoFormatConversion); { QPainter painter(&pix); - QRect r(QPoint(0, 0), size); + const QRect r(QPoint(0, 0), size); this->paint(&painter, r, mode, state); } return pix; diff --git a/src/common/SvgIconEngine.h b/src/common/SvgIconEngine.h index b8280866..e64c430a 100644 --- a/src/common/SvgIconEngine.h +++ b/src/common/SvgIconEngine.h @@ -1,10 +1,12 @@ - #ifndef SVGICONENGINE_H #define SVGICONENGINE_H #include #include +/** + * @brief QIconEngine wrapper for rendering Svg's + */ class SvgIconEngine : public QIconEngine { private: diff --git a/src/common/SyntaxHighlighter.cpp b/src/common/SyntaxHighlighter.cpp index b15afc63..10dc782f 100644 --- a/src/common/SyntaxHighlighter.cpp +++ b/src/common/SyntaxHighlighter.cpp @@ -66,7 +66,7 @@ FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent) QTextCharFormat keywordFormat; keywordFormat.setForeground(QColor(80, 200, 215)); - for (const auto &pattern : keywordPatterns) { + for (const auto &pattern : std::as_const(keywordPatterns)) { rule.pattern.setPattern(pattern); rule.format = keywordFormat; highlightingRules.append(rule); @@ -99,7 +99,7 @@ FallbackSyntaxHighlighter::FallbackSyntaxHighlighter(QTextDocument *parent) void FallbackSyntaxHighlighter::highlightBlock(const QString &text) { - for (const auto &it : highlightingRules) { + for (const auto &it : std::as_const(highlightingRules)) { auto matchIterator = it.pattern.globalMatch(text); while (matchIterator.hasNext()) { const auto match = matchIterator.next(); diff --git a/src/common/SyntaxHighlighter.h b/src/common/SyntaxHighlighter.h index 7846c227..6690721d 100644 --- a/src/common/SyntaxHighlighter.h +++ b/src/common/SyntaxHighlighter.h @@ -2,11 +2,12 @@ #define SYNTAXHIGHLIGHTER_H #include "CutterCommon.h" -#include -#include -#include + #include +#include #include +#include +#include #ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING @@ -26,7 +27,7 @@ private slots: #endif /** - * SyntaxHighlighter to be used when KSyntaxHighlighting is not available + * @brief SyntaxHighlighter to be used when KSyntaxHighlighting is not available */ class CUTTER_EXPORT FallbackSyntaxHighlighter : public QSyntaxHighlighter { diff --git a/src/common/TempConfig.cpp b/src/common/TempConfig.cpp index fb19e32f..542065f3 100644 --- a/src/common/TempConfig.cpp +++ b/src/common/TempConfig.cpp @@ -1,12 +1,28 @@ - -#include +#include "TempConfig.h" #include "core/Cutter.h" -#include "TempConfig.h" + +#include TempConfig::~TempConfig() { for (auto i = resetValues.constBegin(); i != resetValues.constEnd(); ++i) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + switch (i.value().typeId()) { + case QMetaType::Type::QString: + Core()->setConfig(i.key(), i.value().toString()); + break; + case QMetaType::Type::Int: + Core()->setConfig(i.key(), i.value().toInt()); + break; + case QMetaType::Type::Bool: + Core()->setConfig(i.key(), i.value().toBool()); + break; + default: + assert(false); + break; + } +#else switch (i.value().type()) { case QVariant::String: Core()->setConfig(i.key(), i.value().toString()); @@ -21,6 +37,7 @@ TempConfig::~TempConfig() assert(false); break; } +#endif } } diff --git a/src/common/TempConfig.h b/src/common/TempConfig.h index a3c2239d..c9e58af4 100644 --- a/src/common/TempConfig.h +++ b/src/common/TempConfig.h @@ -15,13 +15,13 @@ * calls can be chained. If a command or Rizin method accepts arguments directly it is preferred to * use those instead of temporary modifying global configuration. * - * \code + * @code * { * TempConfig tempConfig; * tempConfig.set("asm.arch", "x86").set("asm.comments", false); * // config automatically restored at the end of scope * } - * \endcode + * @endcode */ class CUTTER_EXPORT TempConfig { diff --git a/src/common/UpdateWorker.cpp b/src/common/UpdateWorker.cpp index 065e19c2..4dadeec4 100644 --- a/src/common/UpdateWorker.cpp +++ b/src/common/UpdateWorker.cpp @@ -1,25 +1,25 @@ #include "UpdateWorker.h" #if CUTTER_UPDATE_WORKER_AVAILABLE -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +# include "CutterConfig.h" +# include "common/Configuration.h" +# include +# include +# include +# include +# include +# include +# include +# include +# include # include # include -# include -# include -# include "common/Configuration.h" -# include "CutterConfig.h" +# include +# include +# include +# include +# include #endif #if CUTTER_UPDATE_WORKER_AVAILABLE @@ -39,7 +39,7 @@ UpdateWorker::UpdateWorker(QObject *parent) : QObject(parent), pending(false) void UpdateWorker::checkCurrentVersion(time_t timeoutMs) { - QUrl url("https://api.github.com/repos/rizinorg/cutter/releases/latest"); + const QUrl url("https://api.github.com/repos/rizinorg/cutter/releases/latest"); QNetworkRequest request; request.setUrl(url); @@ -70,7 +70,7 @@ void UpdateWorker::showUpdateDialog(bool showDontCheckForUpdatesButton) mb.setStandardButtons(QMessageBox::Ok); } mb.setDefaultButton(QMessageBox::Ok); - int ret = mb.exec(); + const int ret = mb.exec(); if (ret == QMessageBox::Reset) { Config()->setAutoUpdateEnabled(false); } @@ -90,7 +90,7 @@ void UpdateWorker::serveVersionCheckReply() .toString(); versionReplyStr.remove('v'); } - QVersionNumber versionReply = QVersionNumber::fromString(versionReplyStr); + const QVersionNumber versionReply = QVersionNumber::fromString(versionReplyStr); if (!versionReply.isNull()) { latestVersion = versionReply; } diff --git a/src/common/UpdateWorker.h b/src/common/UpdateWorker.h index 46854f87..8432f01c 100644 --- a/src/common/UpdateWorker.h +++ b/src/common/UpdateWorker.h @@ -11,21 +11,19 @@ #if CUTTER_UPDATE_WORKER_AVAILABLE # include -# include # include -# include - +# include # include +# include #endif #if CUTTER_UPDATE_WORKER_AVAILABLE class QNetworkReply; /** - * @class UpdateWorker - * @brief The UpdateWorker class is a class providing API to check for current Cutter version. + * @brief The UpdateWorker class is a class providing API to check for current/latest Cutter + * version. */ - class UpdateWorker : public QObject { Q_OBJECT @@ -43,7 +41,6 @@ public: * * @sa checkComplete(const QString& verson, const QString& errorMsg) */ - void checkCurrentVersion(time_t timeoutMs); /** diff --git a/src/core/Basefind.cpp b/src/core/Basefind.cpp index f1fdd4c7..39b1fbb6 100644 --- a/src/core/Basefind.cpp +++ b/src/core/Basefind.cpp @@ -1,15 +1,16 @@ #include "Basefind.h" +#include "Cutter.h" + bool Basefind::threadCallback(const RzBaseFindThreadInfo *info, void *user) { auto th = reinterpret_cast(user); return th->updateProgress(info); } -Basefind::Basefind(CutterCore *core) - : core(core), - scores(nullptr), - continue_run(true) +Basefind::Basefind() + : scores(nullptr), + continueRun(true) #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) , mutex(QMutex::Recursive) @@ -61,14 +62,13 @@ void Basefind::run() mutex.lock(); rz_list_free(scores); scores = nullptr; - continue_run = true; + continueRun = true; mutex.unlock(); - core->coreMutex.lock(); + auto core = Core()->lock(); options.callback = threadCallback; options.user = this; - scores = rz_basefind(core->core_, &options); - core->coreMutex.unlock(); + scores = rz_basefind(core, &options); emit complete(); } @@ -76,7 +76,7 @@ void Basefind::run() void Basefind::cancel() { mutex.lock(); - continue_run = false; + continueRun = false; mutex.unlock(); } @@ -103,7 +103,7 @@ bool Basefind::updateProgress(const RzBaseFindThreadInfo *info) status.percentage = info->percentage; emit progress(status); - bool ret = continue_run; + const bool ret = continueRun; mutex.unlock(); return ret; } diff --git a/src/core/Basefind.h b/src/core/Basefind.h index ded42fd1..5f81c7d9 100644 --- a/src/core/Basefind.h +++ b/src/core/Basefind.h @@ -1,21 +1,25 @@ -#ifndef CUTTER_BASEFIND_CORE_H -#define CUTTER_BASEFIND_CORE_H +#ifndef BASEFIND_H +#define BASEFIND_H -#include -#include - -#include "Cutter.h" #include "CutterDescriptions.h" + +#include +#include + #include class CutterCore; +/** + * @brief Threaded wrapper for Rizin's basefind functionality to identify the base address of a + * binary + */ class Basefind : public QThread { Q_OBJECT public: - explicit Basefind(CutterCore *core); + explicit Basefind(); virtual ~Basefind(); void run(); @@ -30,9 +34,8 @@ signals: void complete(); private: - CutterCore *const core; RzList *scores; - bool continue_run; + bool continueRun; RzBaseFindOpt options; #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) QMutex mutex; @@ -44,4 +47,4 @@ private: static bool threadCallback(const RzBaseFindThreadInfo *info, void *user); }; -#endif // CUTTER_BASEFIND_CORE_H +#endif // BASEFIND_H diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index a595e498..e5777333 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -1,27 +1,27 @@ +#include "core/Cutter.h" + +#include "CutterDescriptions.h" +#include "Decompiler.h" +#include "common/AsyncTask.h" +#include "common/BasicInstructionHighlighter.h" +#include "common/Configuration.h" +#include "common/Json.h" +#include "common/RizinTask.h" +#include "common/TempConfig.h" +#include "dialogs/MarkDialog.h" +#include "dialogs/RizinTaskDialog.h" + +#include +#include #include #include #include -#include -#include -#include -#include #include +#include +#include #include #include - -#include "CutterDescriptions.h" -#include "common/TempConfig.h" -#include "common/BasicInstructionHighlighter.h" -#include "common/Configuration.h" -#include "common/AsyncTask.h" -#include "common/RizinTask.h" -#include "dialogs/MarkDialog.h" -#include "dialogs/RizinTaskDialog.h" -#include "common/Json.h" -#include "core/Cutter.h" -#include "Decompiler.h" - #include #include #include @@ -35,7 +35,7 @@ namespace RJsonKey { RZ_JSON_KEY(addr); RZ_JSON_KEY(address); RZ_JSON_KEY(addrs); -RZ_JSON_KEY(addr_end); +RZ_JSON_KEY(addr_end); // NOLINT RZ_JSON_KEY(arrow); RZ_JSON_KEY(baddr); RZ_JSON_KEY(bind); @@ -55,8 +55,8 @@ RZ_JSON_KEY(ebbs); RZ_JSON_KEY(edges); RZ_JSON_KEY(enabled); RZ_JSON_KEY(entropy); -RZ_JSON_KEY(fcn_addr); -RZ_JSON_KEY(fcn_name); +RZ_JSON_KEY(fcn_addr); // NOLINT +RZ_JSON_KEY(fcn_name); // NOLINT RZ_JSON_KEY(fields); RZ_JSON_KEY(file); RZ_JSON_KEY(flag); @@ -68,7 +68,7 @@ RZ_JSON_KEY(functions); RZ_JSON_KEY(graph); RZ_JSON_KEY(haddr); RZ_JSON_KEY(hw); -RZ_JSON_KEY(in_functions); +RZ_JSON_KEY(in_functions); // NOLINT RZ_JSON_KEY(index); RZ_JSON_KEY(jump); RZ_JSON_KEY(laddr); @@ -125,7 +125,7 @@ static void updateOwnedCharPtr(char *&variable, const QString &newValue) variable = strdup(data.data()); } -static bool reg_sync(RzCore *core, RzRegisterType type, bool write) +static bool regSync(RzCore *core, RzRegisterType type, bool write) { if (rz_core_is_debug(core)) { return rz_debug_reg_sync(core->dbg, type, write); @@ -157,12 +157,12 @@ RzCoreLocked::~RzCoreLocked() RzCoreLocked::operator RzCore *() & { - return core->core_; + return core->rzCore; } RzCore *RzCoreLocked::operator->() & { - return core->core_; + return core->rzCore; } #define CORE_LOCK() RzCoreLocked core(this) @@ -194,7 +194,7 @@ CutterCore *CutterCore::instance() void CutterCore::initialize(bool loadPlugins) { rz_cons_new(); // initialize console - core_ = rz_core_new(); + rzCore = rz_core_new(); #if defined(MACOS_RZ_BUNDLED) auto app_path = QDir(QCoreApplication::applicationDirPath()); @@ -202,24 +202,24 @@ void CutterCore::initialize(bool loadPlugins) app_path.cd("Resources"); qInfo() << "Setting Rizin prefix =" << app_path.absolutePath() << " for macOS Application Bundle."; - rz_path_set_prefix(core_->sys_path, app_path.absolutePath().toUtf8().constData()); + rz_path_set_prefix(rzCore->sys_path, app_path.absolutePath().toUtf8().constData()); #endif char **env = rz_sys_get_environ(); - core_->io->envprofile = rz_run_get_environ_profile(env); - rz_core_task_sync_begin(&core_->tasks); + rzCore->io->envprofile = rz_run_get_environ_profile(env); + rz_core_task_sync_begin(&rzCore->tasks); coreBed = rz_cons_sleep_begin(); CORE_LOCK(); - rz_event_hook(core_->ev, RZ_EVENT_ALL, cutterREventCallback, this); + rz_event_hook(rzCore->ev, RZ_EVENT_ALL, cutterREventCallback, this); if (loadPlugins) { setConfig("cfg.plugins", true); - rz_core_loadlibs(this->core_, RZ_CORE_LOADLIBS_ALL); + rz_core_loadlibs(this->rzCore, RZ_CORE_LOADLIBS_ALL); } else { setConfig("cfg.plugins", false); } - // IMPLICIT rz_bin_iobind (core_->bin, core_->io); + // IMPLICIT rz_bin_iobind (rzCore->bin, rzCore->io); // Otherwise Rizin may ask the user for input and Cutter would freeze setConfig("scr.interactive", false); @@ -240,8 +240,8 @@ CutterCore::~CutterCore() { delete bbHighlighter; rz_cons_sleep_end(coreBed); - rz_core_task_sync_end(&core_->tasks); - rz_core_free(this->core_); + rz_core_task_sync_end(&rzCore->tasks); + rz_core_free(this->rzCore); rz_cons_free(); assert(uniqueInstance == this); uniqueInstance = nullptr; @@ -266,7 +266,8 @@ QVector CutterCore::getCutterRCFilePaths() const { QVector result; result.push_back(QFileInfo(QDir::home(), ".cutterrc").absoluteFilePath()); - QStringList locations = QStandardPaths::standardLocations(QStandardPaths::AppConfigLocation); + const QStringList locations = + QStandardPaths::standardLocations(QStandardPaths::AppConfigLocation); for (auto &location : locations) { result.push_back(QFileInfo(QDir(location), ".cutterrc").absoluteFilePath()); } @@ -303,11 +304,11 @@ void CutterCore::loadDefaultCutterRC() rz_cons_flush(); } -QList CutterCore::sdbList(QString path) +QList CutterCore::sdbList(const QString &path) { CORE_LOCK(); QList list = QList(); - Sdb *root = sdb_ns_path(core->sdb, path.toUtf8().constData(), 0); + const Sdb *root = sdb_ns_path(core->sdb, path.toUtf8().constData(), 0); if (root && root->ns) { for (const auto &nsi : CutterRzList(root->ns)) { list << nsi->name; @@ -322,42 +323,44 @@ static PVectorPtr makePVectorPtr(RzPVector *vec) return { vec, rz_pvector_free }; } -static bool foreach_keys_cb(void *user, const SdbKv *kv) +static bool foreachKeysCb(void *user, const SdbKv *kv) { auto list = reinterpret_cast *>(user); *list << kv->base.key; return true; } -QList CutterCore::sdbListKeys(QString path) +QList CutterCore::sdbListKeys(const QString &path) { CORE_LOCK(); QList list = QList(); Sdb *root = sdb_ns_path(core->sdb, path.toUtf8().constData(), 0); if (root) { - sdb_foreach(root, foreach_keys_cb, &list); + sdb_foreach(root, foreachKeysCb, &list); } return list; } -QString CutterCore::sdbGet(QString path, QString key) +QString CutterCore::sdbGet(const QString &path, const QString &key) { CORE_LOCK(); Sdb *db = sdb_ns_path(core->sdb, path.toUtf8().constData(), 0); if (db) { const char *val = sdb_const_get(db, key.toUtf8().constData()); - if (val && *val) + if (val && *val) { return val; + } } return QString(); } -bool CutterCore::sdbSet(QString path, QString key, QString val) +bool CutterCore::sdbSet(const QString &path, const QString &key, const QString &val) { CORE_LOCK(); Sdb *db = sdb_ns_path(core->sdb, path.toUtf8().constData(), 1); - if (!db) + if (!db) { return false; + } return sdb_set(db, key.toUtf8().constData(), val.toUtf8().constData()); } @@ -371,7 +374,7 @@ QString CutterCore::cmd(const char *str) { CORE_LOCK(); - RVA offset = core->offset; + const RVA offset = core->offset; char *res = rz_core_cmd_str(core, str); QString o = fromOwnedCharPtr(res); @@ -385,25 +388,25 @@ QString CutterCore::getFunctionExecOut(const std::function &fcn, { CORE_LOCK(); - RVA offset = core->offset; + const RVA offset = core->offset; seekSilent(addr); QString o = {}; rz_cons_push(); - bool is_pipe = core->is_pipe; + const bool isPipe = core->is_pipe; core->is_pipe = true; if (!fcn(core)) { - core->is_pipe = is_pipe; + core->is_pipe = isPipe; rz_cons_pop(); goto clean_return; } - core->is_pipe = is_pipe; + core->is_pipe = isPipe; rz_cons_filter(); o = rz_cons_get_buffer(); rz_cons_pop(); - rz_cons_echo(NULL); + rz_cons_echo(nullptr); clean_return: if (offset != core->offset) { @@ -412,7 +415,7 @@ clean_return: return o; } -bool CutterCore::isRedirectableDebugee() +bool CutterCore::isRedirectableDebugee() const { if (!currentlyDebugging || currentlyAttachedToPID != -1) { return false; @@ -420,12 +423,12 @@ bool CutterCore::isRedirectableDebugee() // We are only able to redirect locally debugged unix processes RzCoreLocked core(Core()); - RzList *descs = rz_id_storage_list(core->io->files); + const RzList *descs = rz_id_storage_list(core->io->files); RzListIter *it; RzIODesc *desc; CutterRzListForeach (descs, it, RzIODesc, desc) { - QString URI = QString(desc->uri); - if (URI.contains("ptrace") || URI.contains("mach")) { + const QString uri = QString(desc->uri); + if (uri.contains("ptrace") || uri.contains("mach")) { return true; } } @@ -434,7 +437,7 @@ bool CutterCore::isRedirectableDebugee() bool CutterCore::isDebugTaskInProgress() { - if (!debugTask.isNull()) { + if (debugTask) { return true; } @@ -445,18 +448,19 @@ void CutterCore::setProfileDirectives(const QString &directives) { QString file = getConfig("dbg.profile"); if (file.isEmpty()) { - char *temp_path = rz_file_temp("rz-run"); - file = QString::fromUtf8(temp_path); - free(temp_path); + char *tempPath = rz_file_temp("rz-run"); + file = QString::fromUtf8(tempPath); + free(tempPath); setConfig("dbg.profile", file); } - QByteArray fileNameBytes = file.toUtf8(); + const QByteArray fileNameBytes = file.toUtf8(); QByteArray directiveBytes = directives.toUtf8(); const char *pathPtr = fileNameBytes.constData(); - rz_file_dump(pathPtr, (const ut8 *)directiveBytes.data(), (int)directiveBytes.size(), 0); - rz_file_dump(pathPtr, (const ut8 *)"\n", 1, 1); + rz_file_dump(pathPtr, reinterpret_cast(directiveBytes.data()), + static_cast(directiveBytes.size()), 0); + rz_file_dump(pathPtr, reinterpret_cast("\n"), 1, 1); } void CutterCore::setRegisterProfile(const QString &profile) @@ -466,7 +470,7 @@ void CutterCore::setRegisterProfile(const QString &profile) emit registersChanged(); } -QString CutterCore::convertGDBProfile(const QString &profilePath) +QString CutterCore::convertGdbProfile(const QString &profilePath) { return QString::fromUtf8(rz_reg_parse_gdb_profile(profilePath.toUtf8().constData())); } @@ -474,23 +478,23 @@ QString CutterCore::convertGDBProfile(const QString &profilePath) QString CutterCore::getRegisterProfile() { CORE_LOCK(); - RzReg *reg = core->dbg->reg; + const RzReg *reg = core->dbg->reg; if (reg && reg->reg_profile_str) { return QString::fromUtf8(reg->reg_profile_str); } return QString(); } -bool CutterCore::asyncTask(std::function fcn, QSharedPointer &task) +bool CutterCore::asyncTask(std::function fcn, std::shared_ptr &task) { - if (!task.isNull()) { + if (task) { return false; } CORE_LOCK(); - RVA offset = core->offset; - task = QSharedPointer(new RizinFunctionTask(std::move(fcn), true)); - connect(task.data(), &RizinTask::finished, task.data(), [this, offset, task]() { + const RVA offset = core->offset; + task = std::shared_ptr(new RizinFunctionTask(std::move(fcn), true)); + connect(task.get(), &RizinTask::finished, task.get(), [this, offset, task]() { CORE_LOCK(); if (offset != core->offset) { @@ -511,7 +515,7 @@ void CutterCore::functionTask(std::function fcn) QString CutterCore::cmdRawAt(const char *cmd, RVA address) { QString res; - RVA oldOffset = getOffset(); + const RVA oldOffset = getOffset(); seekSilent(address); res = cmdRaw(cmd); @@ -522,7 +526,7 @@ QString CutterCore::cmdRawAt(const char *cmd, RVA address) QString CutterCore::cmdRaw(const char *cmd) { - QString res; + const QString res; CORE_LOCK(); return rz_core_cmd_str(core, cmd); } @@ -552,7 +556,7 @@ CutterJson CutterCore::parseJson(const char *name, char *res, const char *cmd) return CutterJson(); } - RzJson *doc = rz_json_parse(res); + RzJson *doc = rz_json_parse(res); // NOLINT if (!doc) { if (cmd) { @@ -563,13 +567,13 @@ CutterJson CutterCore::parseJson(const char *name, char *res, const char *cmd) RZ_LOG_ERROR("%s: %s\n", name, res); } - return CutterJson(doc, QSharedPointer::create(doc, res)); + return CutterJson(doc, std::make_shared(doc, res)); } QStringList CutterCore::autocomplete(const QString &cmd, RzLinePromptType promptType) { RzLineBuffer buf; - int c = snprintf(buf.data, sizeof(buf.data), "%s", cmd.toUtf8().constData()); + const int c = snprintf(buf.data, sizeof(buf.data), "%s", cmd.toUtf8().constData()); if (c < 0) { return {}; } @@ -590,20 +594,8 @@ QStringList CutterCore::autocomplete(const QString &cmd, RzLinePromptType prompt return r; } -/** - * @brief CutterCore::loadFile - * Load initial file. - * @param path File path - * @param baddr Base (RzBin) address - * @param mapaddr Map address - * @param perms - * @param va - * @param loadbin Load RzBin information - * @param forceBinPlugin - * @return - */ -bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int va, bool loadbin, - const QString &forceBinPlugin) +bool CutterCore::loadFile(const QString &path, ut64 baddr, ut64 mapaddr, int perms, int va, + bool loadbin, const QString &forceBinPlugin) { CORE_LOCK(); RzCoreFile *f; @@ -631,22 +623,22 @@ bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int // load RzBin information // XXX only for sub-bins rz_core_bin_load(core, path.toUtf8(), baddr); - rz_bin_select_idx(core->bin, NULL, idx); + rz_bin_select_idx(core->bin, nullptr, idx); } #endif } - auto iod = core->io ? core->io->desc : NULL; + auto iod = core->io ? core->io->desc : nullptr; auto debug = core->file && iod && (core->file->fd == iod->fd) && iod->plugin && iod->plugin->isdbg; if (!debug && rz_flag_get(core->flags, "entry0")) { - ut64 addr = rz_num_math(core->num, "entry0"); + const ut64 addr = rz_num_math(core->num, "entry0"); rz_core_seek_and_save(core, addr, true); } if (perms & RZ_PERM_W) { - RzPVector *maps = rz_io_maps(core->io); + const RzPVector *maps = rz_io_maps(core->io); for (auto map : CutterPVector(maps)) { map->perm |= RZ_PERM_W; } @@ -657,7 +649,7 @@ bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int return true; } -bool CutterCore::tryFile(QString path, bool rw) +bool CutterCore::tryFile(const QString &path, bool rw) { if (path.isEmpty()) { // opening no file is always possible @@ -668,8 +660,9 @@ bool CutterCore::tryFile(QString path, bool rw) rz_cons_break_clear(); RzCoreFile *cf; int flags = RZ_PERM_R; - if (rw) + if (rw) { flags = RZ_PERM_RW; + } cf = rz_core_file_open(core, path.toUtf8().constData(), flags, 0LL); if (!cf) { return false; @@ -680,17 +673,11 @@ bool CutterCore::tryFile(QString path, bool rw) return true; } -/** - * @brief Maps a file using Rizin API - * @param path Path to file - * @param mapaddr Map Address - * @return bool - */ -bool CutterCore::mapFile(QString path, RVA mapaddr) +bool CutterCore::mapFile(const QString &path, RVA mapaddr) { CORE_LOCK(); - RVA addr = mapaddr != RVA_INVALID ? mapaddr : 0; - ut64 baddr = rz_bin_get_baddr(core->bin); + const RVA addr = mapaddr != RVA_INVALID ? mapaddr : 0; + const ut64 baddr = rz_bin_get_baddr(core->bin); if (rz_core_file_open(core, path.toUtf8().constData(), RZ_PERM_RX, addr)) { rz_core_bin_load(core, path.toUtf8().constData(), baddr); } else { @@ -713,17 +700,19 @@ void CutterCore::delFunction(RVA addr) emit functionsChanged(); } -void CutterCore::renameFlag(QString old_name, QString new_name) +void CutterCore::renameFlag(const QString &old_name, const QString &new_name) { CORE_LOCK(); RzFlagItem *flag = rz_flag_get(core->flags, old_name.toStdString().c_str()); - if (!flag) + if (!flag) { return; + } rz_flag_rename(core->flags, flag, new_name.toStdString().c_str()); emit flagsChanged(); } -void CutterCore::renameFunctionVariable(QString newName, QString oldName, RVA functionAddress) +void CutterCore::renameFunctionVariable(const QString &newName, const QString &oldName, + RVA functionAddress) { CORE_LOCK(); RzAnalysisFunction *function = rz_analysis_get_function_at(core->analysis, functionAddress); @@ -814,7 +803,7 @@ void CutterCore::editBytes(RVA addr, const QString &bytes) void CutterCore::editBytesEndian(RVA addr, const QString &bytes) { CORE_LOCK(); - ut64 value = rz_num_math(core->num, bytes.toUtf8().constData()); + const ut64 value = rz_num_math(core->num, bytes.toUtf8().constData()); if (core->num->nc.errors) { return; } @@ -883,7 +872,7 @@ QString CutterCore::getString(RVA addr, uint64_t len, RzStrEnc encoding, bool es opt.encoding = encoding; opt.escape_nl = escape_nl; auto seek = seekTemp(addr); - return fromOwnedCharPtr(rz_str_stringify_raw_buffer(&opt, NULL)); + return fromOwnedCharPtr(rz_str_stringify_raw_buffer(&opt, nullptr)); } QString CutterCore::getMetaString(RVA addr) @@ -928,11 +917,6 @@ void CutterCore::delComment(RVA addr) emit commentsChanged(addr); } -/** - * @brief Gets the comment present at a specific address - * @param addr The address to be checked - * @return String containing comment - */ QString CutterCore::getCommentAt(RVA addr) { CORE_LOCK(); @@ -945,7 +929,8 @@ void CutterCore::setImmediateBase(const QString &rzBaseName, RVA offset) offset = getOffset(); } CORE_LOCK(); - int base = (int)rz_num_base_of_string(core->num, rzBaseName.toUtf8().constData()); + const int base = + static_cast(rz_num_base_of_string(core->num, rzBaseName.toUtf8().constData())); rz_analysis_hint_set_immbase(core->analysis, offset, base); emit instructionChanged(offset); } @@ -994,9 +979,9 @@ void CutterCore::seek(ut64 offset) return; } - RVA o_offset = core->offset; + const RVA oOffset = core->offset; rz_core_seek_and_save(core, offset, true); - if (o_offset != core->offset) { + if (oOffset != core->offset) { updateSeek(); } } @@ -1012,16 +997,16 @@ void CutterCore::seekAndShow(ut64 offset) emit showAddressRequested(offset); } -void CutterCore::seekAndShow(QString offset) +void CutterCore::seekAndShow(const QString &offset) { seek(offset); emit showAddressRequested(math(offset)); } -void CutterCore::seek(QString thing) +void CutterCore::seek(const QString &thing) { CORE_LOCK(); - ut64 addr = rz_num_math(core->num, thing.toUtf8().constData()); + const ut64 addr = rz_num_math(core->num, thing.toUtf8().constData()); if (core->num->nc.errors) { return; } @@ -1061,33 +1046,33 @@ RVA CutterCore::nextOpAddr(RVA startAddr, int count) auto consumed = rz_core_analysis_ops_size(core, core->offset, core->block, (int)core->blocksize, count); - RVA addr = startAddr + consumed; + const RVA addr = startAddr + consumed; return addr; } RVA CutterCore::getOffset() { - return core_->offset; + return rzCore->offset; } void CutterCore::applySignature(const QString &filepath) { CORE_LOCK(); - int old_cnt, new_cnt; + int oldCnt, newCnt; const char *arch = rz_config_get(core->config, "asm.arch"); - ut8 expected_arch = rz_core_flirt_arch_from_name(arch); - if (expected_arch == RZ_FLIRT_SIG_ARCH_ANY && filepath.endsWith(".sig", Qt::CaseInsensitive)) { + const ut8 expectedArch = rz_core_flirt_arch_from_name(arch); + if (expectedArch == RZ_FLIRT_SIG_ARCH_ANY && filepath.endsWith(".sig", Qt::CaseInsensitive)) { QMessageBox::warning(nullptr, tr("Signatures"), tr("Cannot apply signature file because the requested arch is not " "supported by .sig " "files")); return; } - old_cnt = rz_flag_count(core->flags, "flirt"); - if (rz_sign_flirt_apply(core->analysis, filepath.toStdString().c_str(), expected_arch)) { - new_cnt = rz_flag_count(core->flags, "flirt"); + oldCnt = rz_flag_count(core->flags, "flirt"); + if (rz_sign_flirt_apply(core->analysis, filepath.toStdString().c_str(), expectedArch)) { + newCnt = rz_flag_count(core->flags, "flirt"); QMessageBox::information(nullptr, tr("Signatures"), - tr("Found %1 matching signatures!").arg(new_cnt - old_cnt)); + tr("Found %1 matching signatures!").arg(newCnt - oldCnt)); return; } QMessageBox::warning( @@ -1098,33 +1083,33 @@ void CutterCore::applySignature(const QString &filepath) void CutterCore::createSignature(const QString &filepath) { CORE_LOCK(); - ut32 n_modules = 0; - if (!rz_core_flirt_create_file(core, filepath.toStdString().c_str(), &n_modules)) { + ut32 nModules = 0; + if (!rz_core_flirt_create_file(core, filepath.toStdString().c_str(), &nModules)) { QMessageBox::warning( nullptr, tr("Signatures"), tr("Cannot create signature file (check the console for more details).")); return; } QMessageBox::information(nullptr, tr("Signatures"), - tr("Written %1 signatures to %2.").arg(n_modules).arg(filepath)); + tr("Written %1 signatures to %2.").arg(nModules).arg(filepath)); } bool CutterCore::isValidInputNumValue(const QString &expression) { CORE_LOCK(); - return rz_is_valid_input_num_value(core ? core->num : NULL, expression.toUtf8().constData()); + return rz_is_valid_input_num_value(core ? core->num : nullptr, expression.toUtf8().constData()); } ut64 CutterCore::math(const QString &expr) { CORE_LOCK(); - return rz_num_math(core ? core->num : NULL, expr.toUtf8().constData()); + return rz_num_math(core ? core->num : nullptr, expr.toUtf8().constData()); } ut64 CutterCore::num(const QString &expr) { CORE_LOCK(); - return rz_num_get(core ? core->num : NULL, expr.toUtf8().constData()); + return rz_num_get(core ? core->num : nullptr, expr.toUtf8().constData()); } QString CutterCore::itoa(ut64 num, int rdx) @@ -1152,7 +1137,7 @@ void CutterCore::setConfig(const char *k, const QString &v) AddressTypeHint CutterCore::getAddressType(RVA addr) { - CORE_LOCK(); + const auto core = Core()->lock(); if (functionIn(addr)) { return AddressTypeHint::Function; @@ -1207,7 +1192,7 @@ bool CutterCore::getConfigb(const char *k) QString CutterCore::getConfigDescription(const char *k) { CORE_LOCK(); - RzConfigNode *node = rz_config_node_get(core->config, k); + const RzConfigNode *node = rz_config_node_get(core->config, k); return node ? QString(node->desc) : QString("Unrecognized configuration key"); } @@ -1228,8 +1213,9 @@ void CutterCore::triggerGraphOptionsChanged() void CutterCore::message(const QString &msg, bool debug) { - if (msg.isEmpty()) + if (msg.isEmpty()) { return; + } if (debug) { qDebug() << msg; emit newDebugMessage(msg); @@ -1247,7 +1233,7 @@ QString CutterCore::getConfig(const char *k) QStringList CutterCore::getConfigOptions(const char *k) { CORE_LOCK(); - RzConfigNode *node = rz_config_node_get(core->config, k); + const RzConfigNode *node = rz_config_node_get(core->config, k); if (!(node && node->options)) { return {}; } @@ -1260,6 +1246,19 @@ QStringList CutterCore::getConfigOptions(const char *k) void CutterCore::setConfig(const char *k, const QVariant &v) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + switch (v.typeId()) { + case QMetaType::Type::Bool: + setConfig(k, v.toBool()); + break; + case QMetaType::Type::Int: + setConfig(k, v.toInt()); + break; + default: + setConfig(k, v.toString()); + break; + } +#else switch (v.type()) { case QVariant::Type::Bool: setConfig(k, v.toBool()); @@ -1271,9 +1270,10 @@ void CutterCore::setConfig(const char *k, const QVariant &v) setConfig(k, v.toString()); break; } +#endif } -void CutterCore::setCPU(QString arch, QString cpu, int bits) +void CutterCore::setCPU(const QString &arch, const QString &cpu, int bits) { if (arch != nullptr) { setConfig("asm.arch", arch); @@ -1323,7 +1323,7 @@ QString CutterCore::disassembleSingleInstruction(RVA addr) RzAnalysisFunction *CutterCore::functionIn(ut64 addr) { CORE_LOCK(); - RzAnalysisFunction *fcn = rz_analysis_get_function_at(core->analysis, addr); + RzAnalysisFunction *fcn = rz_analysis_get_function_at(core->analysis, addr); // NOLINT if (fcn) { return fcn; } @@ -1340,44 +1340,28 @@ RzAnalysisFunction *CutterCore::functionAt(ut64 addr) return rz_analysis_get_function_at(core->analysis, addr); } -/** - * @brief finds the start address of a function in a given address - * @param addr - an address which belongs to a function - * @returns if function exists, return its start address. Otherwise return RVA_INVALID - */ RVA CutterCore::getFunctionStart(RVA addr) { - CORE_LOCK(); - RzAnalysisFunction *fcn = Core()->functionIn(addr); + const auto core = Core()->lock(); + const RzAnalysisFunction *fcn = Core()->functionIn(addr); return fcn ? fcn->addr : RVA_INVALID; } -/** - * @brief finds the end address of a function in a given address - * @param addr - an address which belongs to a function - * @returns if function exists, return its end address. Otherwise return RVA_INVALID - */ RVA CutterCore::getFunctionEnd(RVA addr) { - CORE_LOCK(); - RzAnalysisFunction *fcn = Core()->functionIn(addr); + const auto core = Core()->lock(); + const RzAnalysisFunction *fcn = Core()->functionIn(addr); return fcn ? fcn->addr : RVA_INVALID; } -/** - * @brief finds the last instruction of a function in a given address - * @param addr - an address which belongs to a function - * @returns if function exists, return the address of its last instruction. Otherwise return - * RVA_INVALID - */ RVA CutterCore::getLastFunctionInstruction(RVA addr) { - CORE_LOCK(); - RzAnalysisFunction *fcn = Core()->functionIn(addr); + const auto core = Core()->lock(); + const RzAnalysisFunction *fcn = Core()->functionIn(addr); if (!fcn) { return RVA_INVALID; } - RzAnalysisBlock *lastBB = (RzAnalysisBlock *)rz_pvector_tail(fcn->bbs); + auto *lastBB = static_cast(rz_pvector_tail(fcn->bbs)); return lastBB ? rz_analysis_block_get_op_addr(lastBB, lastBB->ninstr - 1) : RVA_INVALID; } @@ -1387,8 +1371,8 @@ QString CutterCore::flagAt(RVA addr, bool getClosestFlag) // rz_flag_get_at and rz_flag_get_i can return different // flags for addresses containing multiple flags, so we must use rz_flag_get_i here // instead of setting rz_flag_get_at's "closest" argument to false - RzFlagItem *f = getClosestFlag ? rz_flag_get_at(core->flags, addr, true) - : rz_flag_get_i(core->flags, addr); + const RzFlagItem *f = getClosestFlag ? rz_flag_get_at(core->flags, addr, true) + : rz_flag_get_i(core->flags, addr); if (!f) { return {}; } @@ -1408,8 +1392,8 @@ void CutterCore::createFunctionAt(RVA addr, QString name) } CORE_LOCK(); - bool analyze_recursively = rz_config_get_i(core->config, "analysis.calls"); - rz_core_analysis_function_add(core, name.toStdString().c_str(), addr, analyze_recursively); + const bool analyzeRecursively = rz_config_get_i(core->config, "analysis.calls"); + rz_core_analysis_function_add(core, name.toStdString().c_str(), addr, analyzeRecursively); emit functionsChanged(); } @@ -1426,7 +1410,7 @@ QList CutterCore::getDecompilers() Decompiler *CutterCore::getDecompilerById(const QString &id) { - for (Decompiler *dec : decompilers) { + for (auto *dec : std::as_const(decompilers)) { if (dec->getId() == id) { return dec; } @@ -1448,7 +1432,7 @@ CutterJson CutterCore::getSignatureInfo() { CORE_LOCK(); RzBinFile *cur = rz_bin_cur(core->bin); - RzBinPlugin *plg = rz_bin_file_cur_plugin(cur); + const RzBinPlugin *plg = rz_bin_file_cur_plugin(cur); if (!plg || !plg->signature) { return {}; } @@ -1474,8 +1458,8 @@ bool CutterCore::existsFileInfo() } // Utility function to check if a telescoped item exists and add it with prefixes to the desc -static inline const QString appendVar(QString &dst, const QString val, const QString prepend_val, - const QString append_val) +static inline const QString appendVar(QString &dst, const QString &val, const QString &prepend_val, + const QString &append_val) { if (!val.isEmpty()) { dst += prepend_val + val + append_val; @@ -1483,7 +1467,7 @@ static inline const QString appendVar(QString &dst, const QString val, const QSt return val; } -RefDescription CutterCore::formatRefDesc(const QSharedPointer &refItem) +RefDescription CutterCore::formatRefDesc(const std::shared_ptr &refItem) { RefDescription desc; @@ -1491,12 +1475,12 @@ RefDescription CutterCore::formatRefDesc(const QSharedPointer &refItem return desc; } - QString str = refItem->string; + const QString str = refItem->string; if (!str.isEmpty()) { desc.ref = str; desc.refColor = ConfigColor("comment"); } else { - QSharedPointer cursor(refItem); + std::shared_ptr cursor(refItem); QString type, string; while (true) { desc.ref += " ->"; @@ -1506,14 +1490,14 @@ RefDescription CutterCore::formatRefDesc(const QSharedPointer &refItem appendVar(desc.ref, cursor->fcn, " ", ""); type = appendVar(desc.ref, cursor->type, " ", ""); appendVar(desc.ref, cursor->perms, " ", ""); - appendVar(desc.ref, cursor->asm_op, " \"", "\""); + appendVar(desc.ref, cursor->asmOp, " \"", "\""); string = appendVar(desc.ref, cursor->string, " ", ""); if (!string.isNull()) { // There is no point in adding ascii and addr info after a string break; } - if (cursor->has_value) { - appendVar(desc.ref, RzAddressString(cursor->value), " ", ""); + if (cursor->hasValue) { + appendVar(desc.ref, rzAddressString(cursor->value), " ", ""); } if (!cursor->ref) { break; @@ -1555,7 +1539,7 @@ QList CutterCore::getRegisterRefs(int depth) } CORE_LOCK(); - RzList *ritems = rz_core_reg_filter_items_sync(core, getReg(), reg_sync, nullptr); + RzList *ritems = rz_core_reg_filter_items_sync(core, getReg(), regSync, nullptr); if (!ritems) { return ret; } @@ -1580,12 +1564,12 @@ QList CutterCore::getStack(int size, int depth) } CORE_LOCK(); - RVA addr = rz_core_reg_getv_by_role_or_name(core, "SP"); + const RVA addr = rz_core_reg_getv_by_role_or_name(core, "SP"); if (addr == RVA_INVALID) { return stack; } - int base = rz_asm_get_bits(core->rasm); + const int base = rz_asm_get_bits(core->rasm); for (int i = 0; i < size; i += base / 8) { if ((base == 32 && addr + i >= UT32_MAX) || (base == 16 && addr + i >= UT16_MAX)) { break; @@ -1606,37 +1590,37 @@ AddrRefs CutterCore::getAddrRefs(RVA addr, int depth) } CORE_LOCK(); - int bits = rz_asm_get_bits(core->rasm); + const int bits = rz_asm_get_bits(core->rasm); QByteArray buf = QByteArray(); - ut64 type = rz_core_analysis_address(core, addr); + const ut64 type = rz_core_analysis_address(core, addr); refs.addr = addr; // Search for the section the addr is in, avoid duplication for heap/stack with type if (!(type & RZ_ANALYSIS_ADDR_TYPE_HEAP || type & RZ_ANALYSIS_ADDR_TYPE_STACK)) { // Attempt to find the address within a map - RzDebugMap *map = rz_debug_map_get(core->dbg, addr); + const RzDebugMap *map = rz_debug_map_get(core->dbg, addr); if (map && map->name && map->name[0]) { refs.mapname = map->name; } - RzBinSection *sect = rz_bin_get_section_at(rz_bin_cur_object(core->bin), addr, true); + const RzBinSection *sect = rz_bin_get_section_at(rz_bin_cur_object(core->bin), addr, true); if (sect && sect->name[0]) { refs.section = sect->name; } } // Check if the address points to a register - RzFlagItem *fi = rz_flag_get_i(core->flags, addr); + const RzFlagItem *fi = rz_flag_get_i(core->flags, addr); if (fi) { - RzRegItem *r = rz_reg_get(getReg(), fi->name, -1); + const RzRegItem *r = rz_reg_get(getReg(), fi->name, -1); if (r) { refs.reg = r->name; } } // Attempt to find the address within a function - RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, addr, 0); + const RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, addr, 0); if (fcn) { refs.fcn = fcn->name; } @@ -1669,10 +1653,12 @@ AddrRefs CutterCore::getAddrRefs(RVA addr, int depth) buf.resize(32); perms += "x"; // Instruction disassembly - rz_io_read_at_mapped(core->io, addr, (unsigned char *)buf.data(), buf.size()); + rz_io_read_at_mapped(core->io, addr, reinterpret_cast(buf.data()), + buf.size()); rz_asm_set_pc(core->rasm, addr); - rz_asm_disassemble(core->rasm, &op, (unsigned char *)buf.data(), buf.size()); - refs.asm_op = rz_asm_op_get_asm(&op); + rz_asm_disassemble(core->rasm, &op, reinterpret_cast(buf.data()), + buf.size()); + refs.asmOp = rz_asm_op_get_asm(&op); } if (!perms.isEmpty()) { @@ -1683,23 +1669,25 @@ AddrRefs CutterCore::getAddrRefs(RVA addr, int depth) // Try to telescope further if depth permits it if ((type & RZ_ANALYSIS_ADDR_TYPE_READ)) { buf.resize(64); - ut32 *n32 = (ut32 *)buf.data(); - ut64 *n64 = (ut64 *)buf.data(); - rz_io_read_at_mapped(core->io, addr, (unsigned char *)buf.data(), buf.size()); - ut64 n = (bits == 64) ? *n64 : *n32; + const ut32 *n32 = reinterpret_cast(buf.data()); + const ut64 *n64 = reinterpret_cast(buf.data()); + rz_io_read_at_mapped(core->io, addr, reinterpret_cast(buf.data()), + buf.size()); + const ut64 n = (bits == 64) ? *n64 : *n32; // The value of the next address will serve as an indication that there's more to // telescope if we have reached the depth limit refs.value = n; - refs.has_value = true; + refs.hasValue = true; if (depth && n != addr && !(type & RZ_ANALYSIS_ADDR_TYPE_EXEC)) { // Make sure we aren't telescoping the same address - AddrRefs ref = getAddrRefs(n, depth - 1); + const AddrRefs ref = getAddrRefs(n, depth - 1); if (!ref.type.isNull()) { // If the dereference of the current pointer is an ascii character we // might have a string in this address if (ref.type.contains("ascii")) { buf.resize(128); - rz_io_read_at_mapped(core->io, addr, (unsigned char *)buf.data(), buf.size()); + rz_io_read_at_mapped(core->io, addr, + reinterpret_cast(buf.data()), buf.size()); QString strVal = QString(buf); // Indicate that the string is longer than the printed value if (strVal.size() == buf.size()) { @@ -1707,7 +1695,7 @@ AddrRefs CutterCore::getAddrRefs(RVA addr, int depth) } refs.string = strVal; } - refs.ref = QSharedPointer::create(ref); + refs.ref = std::make_shared(ref); } } } @@ -1717,24 +1705,24 @@ AddrRefs CutterCore::getAddrRefs(RVA addr, int depth) QVector CutterCore::getHeapChunks(RVA arena_addr) { CORE_LOCK(); - QVector chunks_vector; - ut64 m_arena; + QVector chunksVector; + ut64 mArena; if (!arena_addr) { // if arena_addr is zero get base address of main arena RzList *arenas = rz_heap_arenas_list(core); if (arenas->length == 0) { rz_list_free(arenas); - return chunks_vector; + return chunksVector; } - m_arena = ((RzArenaListItem *)rz_list_first_val(arenas))->addr; + mArena = (reinterpret_cast(rz_list_first_val(arenas)))->addr; rz_list_free(arenas); } else { - m_arena = arena_addr; + mArena = arena_addr; } // Get chunks using api and store them in a chunks_vector - RzList *chunks = rz_heap_chunks_list(core, m_arena); + RzList *chunks = rz_heap_chunks_list(core, mArena); RzListIter *iter; RzHeapChunkListItem *data; CutterRzListForeach (chunks, iter, RzHeapChunkListItem, data) { @@ -1742,11 +1730,11 @@ QVector CutterCore::getHeapChunks(RVA arena_addr) chunk.offset = data->addr; chunk.size = (int)data->size; chunk.status = QString(data->status); - chunks_vector.append(chunk); + chunksVector.append(chunk); } rz_list_free(chunks); - return chunks_vector; + return chunksVector; } int CutterCore::getArchBits() @@ -1758,7 +1746,7 @@ int CutterCore::getArchBits() QVector CutterCore::getArenas() { CORE_LOCK(); - QVector arena_vector; + QVector arenaVector; // get arenas using API and store them in arena_vector RzList *arenas = rz_heap_arenas_list(core); @@ -1768,17 +1756,17 @@ QVector CutterCore::getArenas() Arena arena; arena.offset = data->addr; arena.type = QString(data->type); - arena.last_remainder = data->arena->last_remainder; + arena.lastRemainder = data->arena->last_remainder; arena.top = data->arena->top; arena.next = data->arena->next; - arena.next_free = data->arena->next_free; - arena.system_mem = data->arena->system_mem; - arena.max_system_mem = data->arena->max_system_mem; - arena_vector.append(arena); + arena.nextFree = data->arena->next_free; + arena.systemMem = data->arena->system_mem; + arena.maxSystemMem = data->arena->max_system_mem; + arenaVector.append(arena); } rz_list_free(arenas); - return arena_vector; + return arenaVector; } RzHeapChunkSimple *CutterCore::getHeapChunk(ut64 addr) @@ -1790,11 +1778,11 @@ RzHeapChunkSimple *CutterCore::getHeapChunk(ut64 addr) QVector CutterCore::getHeapBins(ut64 arena_addr) { CORE_LOCK(); - QVector bins_vector; + QVector binsVector; MallocState *arena = rz_heap_get_arena(core, arena_addr); if (!arena) { - return bins_vector; + return binsVector; } // get small, large, unsorted bins @@ -1807,7 +1795,7 @@ QVector CutterCore::getHeapBins(ut64 arena_addr) rz_heap_bin_free(bin); continue; } - bins_vector.append(bin); + binsVector.append(bin); } // get fastbins for (int i = 0; i < 10; i++) { @@ -1819,13 +1807,13 @@ QVector CutterCore::getHeapBins(ut64 arena_addr) rz_heap_bin_free(bin); continue; } - bins_vector.append(bin); + binsVector.append(bin); } // get tcache bins - RzList *tcache_bins = rz_heap_tcache_content(core, arena_addr); + const RzList *tcacheBins = rz_heap_tcache_content(core, arena_addr); RzListIter *iter; RzHeapBin *bin; - CutterRzListForeach (tcache_bins, iter, RzHeapBin, bin) { + CutterRzListForeach (tcacheBins, iter, RzHeapBin, bin) { if (!bin) { continue; } @@ -1833,9 +1821,9 @@ QVector CutterCore::getHeapBins(ut64 arena_addr) rz_heap_bin_free(bin); continue; } - bins_vector.append(bin); + binsVector.append(bin); } - return bins_vector; + return binsVector; } bool CutterCore::writeHeapChunk(RzHeapChunkSimple *chunk_simple) @@ -1848,7 +1836,7 @@ QList CutterCore::getVariables(RVA at) { QList ret; CORE_LOCK(); - RzAnalysisFunction *fcn = functionIn(at); + const RzAnalysisFunction *fcn = functionIn(at); if (!fcn) { return ret; } @@ -1885,7 +1873,7 @@ QList CutterCore::getAllGlobals() RzAnalysisVarGlobal *glob; if (core && core->analysis) { - RzTypeDB *typedb = rz_analysis_get_type_db(core->analysis); + const RzTypeDB *typedb = rz_analysis_get_type_db(core->analysis); if (typedb) { const RzList *globals = rz_analysis_var_global_get_all(core->analysis); CutterRzListForeach (globals, it, RzAnalysisVarGlobal, glob) { @@ -1909,7 +1897,7 @@ QVector CutterCore::getRegisterRefValues() { QVector result; CORE_LOCK(); - RzList *ritems = rz_core_reg_filter_items_sync(core, getReg(), reg_sync, nullptr); + RzList *ritems = rz_core_reg_filter_items_sync(core, getReg(), regSync, nullptr); if (!ritems) { return result; } @@ -1918,7 +1906,7 @@ QVector CutterCore::getRegisterRefValues() CutterRzListForeach (ritems, it, RzRegItem, ri) { RegisterRefValueDescription desc; desc.name = ri->name; - ut64 value = rz_reg_get_value(getReg(), ri); + const ut64 value = rz_reg_get_value(getReg(), ri); desc.value = "0x" + QString::number(value, 16); desc.ref = rz_core_analysis_hasrefs(core, value, RZ_OUTPUT_MODE_STANDARD); result.push_back(desc); @@ -1936,18 +1924,18 @@ RegisterRefValueDescription CutterCore::getRegisterRefValue(const QString ®Na return desc; } desc.name = ri->name; - ut64 value = rz_reg_get_value(getReg(), ri); - desc.value = RzAddressString(value); + const ut64 value = rz_reg_get_value(getReg(), ri); + desc.value = rzAddressString(value); desc.ref = rz_core_analysis_hasrefs(core, value, RZ_OUTPUT_MODE_STANDARD); return desc; } -QString CutterCore::getRegisterName(QString registerRole) +QString CutterCore::getRegisterName(const QString ®isterRole) { if (!currentlyDebugging) { return ""; } - CORE_LOCK(); + const auto core = Core()->lock(); return rz_reg_get_name_by_type(getReg(), registerRole.toUtf8().constData()); } @@ -1960,14 +1948,14 @@ RVA CutterCore::getProgramCounterValue() return RVA_INVALID; } -void CutterCore::setRegister(QString regName, QString regValue) +void CutterCore::setRegister(const QString ®Name, const QString ®Value) { if (!currentlyDebugging) { return; } CORE_LOCK(); - ut64 val = rz_num_math(core->num, regValue.toUtf8().constData()); - rz_core_reg_assign_sync(core, getReg(), reg_sync, regName.toUtf8().constData(), val); + const ut64 val = rz_num_math(core->num, regValue.toUtf8().constData()); + rz_core_reg_assign_sync(core, getReg(), regSync, regName.toUtf8().constData(), val); emit registersChanged(); emit refreshCodeViews(); } @@ -1977,15 +1965,15 @@ void CutterCore::setCurrentDebugThread(int tid) if (!asyncTask( [=](RzCore *core) { rz_debug_select(core->dbg, core->dbg->pid, tid); - return (void *)NULL; + return (void *)nullptr; }, debugTask)) { return; } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { - debugTask.clear(); + connect(debugTask.get(), &RizinTask::finished, this, [this]() { + debugTask.reset(); emit registersChanged(); emit refreshCodeViews(); emit stackChanged(); @@ -2004,15 +1992,15 @@ void CutterCore::setCurrentDebugProcess(int pid) [=](RzCore *core) { rz_debug_select(core->dbg, pid, core->dbg->tid); core->dbg->main_pid = pid; - return (void *)NULL; + return (void *)nullptr; }, debugTask)) { return; } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { - debugTask.clear(); + connect(debugTask.get(), &RizinTask::finished, this, [this]() { + debugTask.reset(); emit registersChanged(); emit refreshCodeViews(); emit stackChanged(); @@ -2043,9 +2031,9 @@ void CutterCore::startDebug() emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { + connect(debugTask.get(), &RizinTask::finished, this, [this]() { delete debugTaskDialog; - debugTask.clear(); + debugTask.reset(); emit registersChanged(); if (!currentlyDebugging) { @@ -2079,7 +2067,7 @@ void CutterCore::startEmulation() asyncTask( [&](RzCore *core) { rz_core_analysis_esil_reinit(core); - rz_core_analysis_esil_init_mem(core, NULL, UT64_MAX, UT32_MAX); + rz_core_analysis_esil_init_mem(core, nullptr, UT64_MAX, UT32_MAX); rz_core_analysis_esil_init_regs(core); return nullptr; }, @@ -2087,9 +2075,9 @@ void CutterCore::startEmulation() emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { + connect(debugTask.get(), &RizinTask::finished, this, [this]() { delete debugTaskDialog; - debugTask.clear(); + debugTask.reset(); if (!currentlyDebugging || !currentlyEmulating) { // prevent register flags from appearing during debug/emul @@ -2135,17 +2123,17 @@ void CutterCore::attachRemote(const QString &uri) } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this, uri]() { + connect(debugTask.get(), &RizinTask::finished, this, [this, uri]() { delete debugTaskDialog; - debugTask.clear(); + debugTask.reset(); // Check if we actually connected bool connected = false; RzCoreLocked core(Core()); - RzList *descs = rz_id_storage_list(core->io->files); + const RzList *descs = rz_id_storage_list(core->io->files); RzListIter *it; RzIODesc *desc; CutterRzListForeach (descs, it, RzIODesc, desc) { - QString fileUri = QString(desc->uri); + const QString fileUri = QString(desc->uri); if (!fileUri.compare(uri)) { connected = true; } @@ -2205,9 +2193,9 @@ void CutterCore::attachDebug(int pid) } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this, pid]() { + connect(debugTask.get(), &RizinTask::finished, this, [this, pid]() { delete debugTaskDialog; - debugTask.clear(); + debugTask.reset(); syncAndSeekProgramCounter(); if (!currentlyDebugging || !currentlyEmulating) { @@ -2244,7 +2232,7 @@ void CutterCore::stopDebug() return; } - if (!debugTask.isNull()) { + if (debugTask) { suspendDebug(); } @@ -2255,7 +2243,7 @@ void CutterCore::stopDebug() CORE_LOCK(); if (currentlyEmulating) { - rz_core_analysis_esil_init_mem_del(core, NULL, UT64_MAX, UT32_MAX); + rz_core_analysis_esil_init_mem_del(core, nullptr, UT64_MAX, UT32_MAX); rz_core_analysis_esil_deinit(core); resetWriteCache(); rz_core_debug_clear_register_flags(core); @@ -2293,7 +2281,7 @@ void CutterCore::continueDebug() if (currentlyEmulating) { if (!asyncTask( [](RzCore *core) { - rz_core_esil_step(core, UT64_MAX, "0", NULL, false); + rz_core_esil_step(core, UT64_MAX, "0", nullptr, false); rz_core_reg_update_flags(core); return nullptr; }, @@ -2312,8 +2300,8 @@ void CutterCore::continueDebug() } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { - debugTask.clear(); + connect(debugTask.get(), &RizinTask::finished, this, [this]() { + debugTask.reset(); syncAndSeekProgramCounter(); emit refreshCodeViews(); emit debugTaskStateChanged(); @@ -2350,8 +2338,8 @@ void CutterCore::continueBackDebug() } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { - debugTask.clear(); + connect(debugTask.get(), &RizinTask::finished, this, [this]() { + debugTask.reset(); syncAndSeekProgramCounter(); emit refreshCodeViews(); emit debugTaskStateChanged(); @@ -2369,7 +2357,7 @@ void CutterCore::continueUntilDebug(ut64 offset) if (currentlyEmulating) { if (!asyncTask( [=](RzCore *core) { - rz_core_esil_step(core, offset, NULL, NULL, false); + rz_core_esil_step(core, offset, nullptr, nullptr, false); rz_core_reg_update_flags(core); return nullptr; }, @@ -2387,8 +2375,8 @@ void CutterCore::continueUntilDebug(ut64 offset) } } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { - debugTask.clear(); + connect(debugTask.get(), &RizinTask::finished, this, [this]() { + debugTask.reset(); syncAndSeekProgramCounter(); emit refreshCodeViews(); emit debugTaskStateChanged(); @@ -2423,8 +2411,8 @@ void CutterCore::continueUntilCall() } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { - debugTask.clear(); + connect(debugTask.get(), &RizinTask::finished, this, [this]() { + debugTask.reset(); syncAndSeekProgramCounter(); emit refreshCodeViews(); emit debugTaskStateChanged(); @@ -2455,7 +2443,7 @@ void CutterCore::continueUntilSyscall() [](void *x) { rz_debug_stop(reinterpret_cast(x)); }, core->dbg); rz_reg_arena_swap(core->dbg->reg, true); - rz_debug_continue_syscalls(core->dbg, NULL, 0); + rz_debug_continue_syscalls(core->dbg, nullptr, 0); rz_cons_break_pop(); rz_core_dbg_follow_seek_register(core); return nullptr; @@ -2466,8 +2454,8 @@ void CutterCore::continueUntilSyscall() } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { - debugTask.clear(); + connect(debugTask.get(), &RizinTask::finished, this, [this]() { + debugTask.reset(); syncAndSeekProgramCounter(); emit refreshCodeViews(); emit debugTaskStateChanged(); @@ -2485,7 +2473,7 @@ void CutterCore::stepDebug() if (currentlyEmulating) { if (!asyncTask( [](RzCore *core) { - rz_core_esil_step(core, UT64_MAX, NULL, NULL, false); + rz_core_esil_step(core, UT64_MAX, nullptr, nullptr, false); rz_core_reg_update_flags(core); return nullptr; }, @@ -2504,8 +2492,8 @@ void CutterCore::stepDebug() } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { - debugTask.clear(); + connect(debugTask.get(), &RizinTask::finished, this, [this]() { + debugTask.reset(); syncAndSeekProgramCounter(); emit refreshCodeViews(); emit debugTaskStateChanged(); @@ -2540,8 +2528,8 @@ void CutterCore::stepOverDebug() } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { - debugTask.clear(); + connect(debugTask.get(), &RizinTask::finished, this, [this]() { + debugTask.reset(); syncAndSeekProgramCounter(); emit refreshCodeViews(); emit debugTaskStateChanged(); @@ -2565,8 +2553,8 @@ void CutterCore::stepOutDebug() }, debugTask); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { - debugTask.clear(); + connect(debugTask.get(), &RizinTask::finished, this, [this]() { + debugTask.reset(); syncAndSeekProgramCounter(); emit refreshCodeViews(); emit debugTaskStateChanged(); @@ -2602,8 +2590,8 @@ void CutterCore::stepBackDebug() } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { - debugTask.clear(); + connect(debugTask.get(), &RizinTask::finished, this, [this]() { + debugTask.reset(); syncAndSeekProgramCounter(); emit refreshCodeViews(); emit debugTaskStateChanged(); @@ -2617,7 +2605,7 @@ QStringList CutterCore::getDebugPlugins() QStringList plugins; CORE_LOCK(); CutterHtSP(core->dbg->plugins) - .ForEach([&plugins](const char *k, const RzDebugPlugin *plugin) { + .ForEach([&plugins](const char * /*k*/, const RzDebugPlugin *plugin) { plugins << plugin->name; return true; }); @@ -2629,7 +2617,7 @@ QString CutterCore::getActiveDebugPlugin() return getConfig("dbg.backend"); } -void CutterCore::setDebugPlugin(QString plugin) +void CutterCore::setDebugPlugin(const QString &plugin) { setConfig("dbg.backend", plugin); } @@ -2662,9 +2650,9 @@ void CutterCore::startTraceSession() } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { + connect(debugTask.get(), &RizinTask::finished, this, [this]() { delete debugTaskDialog; - debugTask.clear(); + debugTask.reset(); currentlyTracing = true; emit debugTaskStateChanged(); @@ -2698,7 +2686,7 @@ void CutterCore::stopTraceSession() if (!asyncTask( [](RzCore *core) { rz_debug_session_free(core->dbg->session); - core->dbg->session = NULL; + core->dbg->session = nullptr; return nullptr; }, debugTask)) { @@ -2707,9 +2695,9 @@ void CutterCore::stopTraceSession() } emit debugTaskStateChanged(); - connect(debugTask.data(), &RizinTask::finished, this, [this]() { + connect(debugTask.get(), &RizinTask::finished, this, [this]() { delete debugTaskDialog; - debugTask.clear(); + debugTask.reset(); currentlyTracing = false; emit debugTaskStateChanged(); @@ -2735,13 +2723,13 @@ void CutterCore::addBreakpoint(const BreakpointDescription &config) { CORE_LOCK(); RzBreakpointItem *breakpoint = nullptr; - int watchpoint_prot = 0; + int watchpointProt = 0; if (config.hw) { - watchpoint_prot = config.permission & ~(RZ_PERM_X); + watchpointProt = config.permission & ~(RZ_PERM_X); } auto address = config.addr; - char *module = nullptr; + const char *module = nullptr; QByteArray moduleNameData; if (config.type == BreakpointDescription::Named) { address = Core()->math(config.positionExpression); @@ -2750,8 +2738,8 @@ void CutterCore::addBreakpoint(const BreakpointDescription &config) moduleNameData = config.positionExpression.toUtf8(); module = moduleNameData.data(); } - breakpoint = rz_debug_bp_add(core->dbg, address, config.size, config.hw, (watchpoint_prot != 0), - watchpoint_prot, module, config.moduleDelta); + breakpoint = rz_debug_bp_add(core->dbg, address, config.size, config.hw, (watchpointProt != 0), + watchpointProt, module, config.moduleDelta); if (!breakpoint) { QMessageBox::critical(nullptr, tr("Breakpoint error"), tr("Failed to create breakpoint")); return; @@ -2767,8 +2755,8 @@ void CutterCore::addBreakpoint(const BreakpointDescription &config) updateOwnedCharPtr(breakpoint->name, config.positionExpression); } - int index = std::find(core->dbg->bp->bps_idx, - core->dbg->bp->bps_idx + core->dbg->bp->bps_idx_count, breakpoint) + const int index = std::find(core->dbg->bp->bps_idx, + core->dbg->bp->bps_idx + core->dbg->bp->bps_idx_count, breakpoint) - core->dbg->bp->bps_idx; breakpoint->enabled = config.enabled; @@ -2860,7 +2848,7 @@ int CutterCore::breakpointIndexAt(RVA addr) BreakpointDescription CutterCore::getBreakpointAt(RVA addr) { CORE_LOCK(); - int index = rz_bp_get_index_at(core->dbg->bp, addr); + const int index = rz_bp_get_index_at(core->dbg->bp, addr); auto bp = rz_bp_get_index(core->dbg->bp, index); if (bp) { return breakpointDescriptionFromRizin(index, bp); @@ -2912,11 +2900,11 @@ bool CutterCore::isBreakpoint(const QList &breakpoints, RVA addr) QList CutterCore::getProcessThreads(int pid) { CORE_LOCK(); - auto dbg = core_->dbg; + auto dbg = core->dbg; if (!dbg || !dbg->cur || !dbg->cur->threads) { return {}; } - RzList *list = core_->dbg->cur->threads(dbg, pid != -1 ? pid : dbg->pid); + RzList *list = core->dbg->cur->threads(dbg, pid != -1 ? pid : dbg->pid); RzListIter *iter; RzDebugPid *p; QList ret; @@ -2942,11 +2930,11 @@ QList CutterCore::getProcessThreads(int pid) QList CutterCore::getProcesses(int pid) { CORE_LOCK(); - auto dbg = core_->dbg; + auto dbg = core->dbg; if (!dbg || !dbg->cur || !dbg->cur->threads) { return {}; } - RzList *list = core_->dbg->cur->pids(dbg, pid >= 0 ? pid : dbg->pid); + RzList *list = core->dbg->cur->pids(dbg, pid >= 0 ? pid : dbg->pid); RzListIter *iter; RzDebugPid *p; QList ret; @@ -2997,14 +2985,14 @@ void CutterCore::setGraphEmpty(bool empty) emptyGraph = empty; } -bool CutterCore::isGraphEmpty() +bool CutterCore::isGraphEmpty() const { return emptyGraph; } void CutterCore::getRegs() { - CORE_LOCK(); + const auto core = Core()->lock(); this->regs = {}; const RzList *rs = rz_reg_get_list(getReg(), RZ_REG_TYPE_ANY); if (!rs) { @@ -3041,7 +3029,7 @@ QList CutterCore::getSeekHistory() QList ret; RzListIter *it; RzCoreSeekItem *undo; - RzList *list = rz_core_seek_list(core); + const RzList *list = rz_core_seek_list(core); CutterRzListForeach (list, it, RzCoreSeekItem, undo) { ret << undo->offset; } @@ -3054,7 +3042,7 @@ QStringList CutterCore::getAsmPluginNames() CORE_LOCK(); QStringList ret; CutterHtSP(rz_asm_get_plugins(core->rasm)) - .ForEach([&ret](const char *k, const RzAsmPlugin *ap) { + .ForEach([&ret](const char * /*k*/, const RzAsmPlugin *ap) { ret << ap->name; return true; }); @@ -3064,10 +3052,9 @@ QStringList CutterCore::getAsmPluginNames() QStringList CutterCore::getAnalysisPluginNames() { CORE_LOCK(); - RzListIter *it; QStringList ret; CutterHtSP(rz_analysis_get_plugins(core->analysis)) - .ForEach([&ret](const char *k, const RzAnalysisPlugin *ap) { + .ForEach([&ret](const char * /*k*/, const RzAnalysisPlugin *ap) { ret << ap->name; return true; }); @@ -3085,7 +3072,7 @@ bool CutterCore::hasAssembler() bool found = false; CutterHtSP(rz_asm_get_plugins(core->rasm)) - .ForEach([&](const char *k, const RzAsmPlugin *ap) { + .ForEach([&](const char * /*k*/, const RzAsmPlugin *ap) { if (!ap->arch || !ap->assemble || !(ap->bits & currBits)) { return true; } @@ -3104,7 +3091,7 @@ QList CutterCore::getBinPluginDescriptions(bool bin, boo QList ret; if (bin) { CutterHtSP(core->bin->plugins) - .ForEach([&ret](const char *k, const RzBinPlugin *bp) { + .ForEach([&ret](const char * /*k*/, const RzBinPlugin *bp) { RzBinPluginDescription desc; desc.name = bp->name ? bp->name : ""; desc.description = bp->desc ? bp->desc : ""; @@ -3116,7 +3103,7 @@ QList CutterCore::getBinPluginDescriptions(bool bin, boo } if (xtr) { CutterHtSP(core->bin->binxtrs) - .ForEach([&ret](const char *k, const RzBinXtrPlugin *bx) { + .ForEach([&ret](const char * /*k*/, const RzBinXtrPlugin *bx) { RzBinPluginDescription desc; desc.name = bx->name ? bx->name : ""; desc.description = bx->desc ? bx->desc : ""; @@ -3133,18 +3120,19 @@ QList CutterCore::getRIOPluginDescriptions() { CORE_LOCK(); QList ret; - CutterHtSP(core->io->plugins).ForEach([&ret](const char *k, const RzIOPlugin *p) { - RzIOPluginDescription desc; - desc.name = p->name ? p->name : ""; - desc.description = p->desc ? p->desc : ""; - desc.license = p->license ? p->license : ""; - desc.permissions = QString("r") + (p->write ? "w" : "_") + (p->isdbg ? "d" : "_"); - if (p->uris) { - desc.uris = QString::fromUtf8(p->uris).split(","); - } - ret.append(desc); - return true; - }); + CutterHtSP(core->io->plugins) + .ForEach([&ret](const char * /*k*/, const RzIOPlugin *p) { + RzIOPluginDescription desc; + desc.name = p->name ? p->name : ""; + desc.description = p->desc ? p->desc : ""; + desc.license = p->license ? p->license : ""; + desc.permissions = QString("r") + (p->write ? "w" : "_") + (p->isdbg ? "d" : "_"); + if (p->uris) { + desc.uris = QString::fromUtf8(p->uris).split(","); + } + ret.append(desc); + return true; + }); return ret; } @@ -3152,14 +3140,15 @@ QList CutterCore::getRCorePluginDescriptions() { CORE_LOCK(); QList ret; - CutterHtSP(core->plugins).ForEach([&ret](const char *k, const RzCorePlugin *p) { - RzCorePluginDescription desc; - desc.name = p->name ? p->name : ""; - desc.description = p->desc ? p->desc : ""; - desc.license = p->license ? p->license : ""; - ret.append(desc); - return true; - }); + CutterHtSP(core->plugins) + .ForEach([&ret](const char * /*k*/, const RzCorePlugin *p) { + RzCorePluginDescription desc; + desc.name = p->name ? p->name : ""; + desc.description = p->desc ? p->desc : ""; + desc.license = p->license ? p->license : ""; + ret.append(desc); + return true; + }); return ret; } @@ -3169,7 +3158,7 @@ QList CutterCore::getRAsmPluginDescriptions() QList ret; CutterHtSP(rz_asm_get_plugins(core->rasm)) - .ForEach([&ret, &core, this](const char *k, const RzAsmPlugin *ap) { + .ForEach([&ret, &core](const char * /*k*/, const RzAsmPlugin *ap) { RzAsmPluginDescription plugin; plugin.name = ap->name; @@ -3224,7 +3213,7 @@ QList CutterCore::getAllFunctions() { CORE_LOCK(); - RzList *fcns = rz_analysis_function_list(core->analysis); + const RzList *fcns = rz_analysis_function_list(core->analysis); QList funcList; funcList.reserve(rz_list_length(fcns)); @@ -3255,7 +3244,7 @@ static inline uint64_t rva(RzBinObject *o, uint64_t paddr, uint64_t vaddr, int v QList CutterCore::getAllImports() { CORE_LOCK(); - RzBinFile *bf = rz_bin_cur(core->bin); + const RzBinFile *bf = rz_bin_cur(core->bin); if (!bf) { return {}; } @@ -3265,7 +3254,7 @@ QList CutterCore::getAllImports() } QList qList; - bool va = core->io->va || core->bin->is_debugger; + const bool va = core->io->va || core->bin->is_debugger; for (const auto &import : CutterPVector(imports)) { if (RZ_STR_ISEMPTY(import->name)) { continue; @@ -3273,8 +3262,8 @@ QList CutterCore::getAllImports() ImportDescription importDescription; - RzBinSymbol *sym = rz_bin_object_get_symbol_of_import(bf->o, import); - ut64 addr = sym ? rva(bf->o, sym->paddr, sym->vaddr, va) : UT64_MAX; + const RzBinSymbol *sym = rz_bin_object_get_symbol_of_import(bf->o, import); + const ut64 addr = sym ? rva(bf->o, sym->paddr, sym->vaddr, va) : UT64_MAX; QString name { import->name }; if (RZ_STR_ISNOTEMPTY(import->classname)) { name = QString("%1.%2").arg(import->classname, import->name); @@ -3299,7 +3288,7 @@ QList CutterCore::getAllImports() QList CutterCore::getAllExports() { CORE_LOCK(); - RzBinFile *bf = rz_bin_cur(core->bin); + const RzBinFile *bf = rz_bin_cur(core->bin); if (!bf) { return {}; } @@ -3309,8 +3298,8 @@ QList CutterCore::getAllExports() return {}; } - bool va = core->io->va || core->bin->is_debugger; - bool demangle = rz_config_get_b(core->config, "bin.demangle"); + const bool va = core->io->va || core->bin->is_debugger; + const bool demangle = rz_config_get_b(core->config, "bin.demangle"); QList ret; for (const auto &symbol : CutterPVector(symbols)) { @@ -3327,7 +3316,7 @@ QList CutterCore::getAllExports() exportDescription.size = symbol->size; exportDescription.type = symbol->type; exportDescription.name = sn.symbolname; - exportDescription.flag_name = sn.nameflag; + exportDescription.flagName = sn.nameflag; ret << exportDescription; rz_core_sym_name_fini(&sn); @@ -3338,7 +3327,7 @@ QList CutterCore::getAllExports() QList CutterCore::getAllSymbols() { CORE_LOCK(); - RzBinFile *bf = rz_bin_cur(core->bin); + const RzBinFile *bf = rz_bin_cur(core->bin); if (!bf) { return {}; } @@ -3347,7 +3336,7 @@ QList CutterCore::getAllSymbols() const RzPVector *symbols = rz_bin_object_get_symbols(bf->o); if (symbols) { for (const auto &bs : CutterPVector(symbols)) { - QString type = QString(bs->bind) + " " + QString(bs->type); + const QString type = QString(bs->bind) + " " + QString(bs->type); SymbolDescription symbol; symbol.vaddr = bs->vaddr; symbol.name = QString(bs->name); @@ -3377,7 +3366,7 @@ QList CutterCore::getAllSymbols() QList CutterCore::getAllHeaders() { CORE_LOCK(); - RzBinFile *bf = rz_bin_cur(core->bin); + const RzBinFile *bf = rz_bin_cur(core->bin); if (!bf) { return {}; } @@ -3401,24 +3390,24 @@ QList CutterCore::getSignaturesDB() { CORE_LOCK(); - void *ptr = NULL; - RzListIter *iter = NULL; + void *ptr = nullptr; + const RzListIter *iter = nullptr; QList sigdb; RzList *list = rz_core_analysis_sigdb_list(core, true); rz_list_foreach(list, iter, ptr) { - RzSigDBEntry *sig = static_cast(ptr); + const auto *sig = static_cast(ptr); FlirtDescription flirt; - flirt.bin_name = sig->bin_name; - flirt.arch_name = sig->arch_name; - flirt.base_name = sig->base_name; - flirt.short_path = sig->short_path; - flirt.file_path = sig->file_path; + flirt.binName = sig->bin_name; + flirt.archName = sig->arch_name; + flirt.baseName = sig->base_name; + flirt.shortPath = sig->short_path; + flirt.filePath = sig->file_path; flirt.details = sig->details; - flirt.n_modules = QString::number(sig->n_modules); - flirt.arch_bits = QString::number(sig->arch_bits); + flirt.nModules = QString::number(sig->n_modules); + flirt.archBits = QString::number(sig->arch_bits); sigdb << flirt; } rz_list_free(list); @@ -3433,8 +3422,8 @@ QList CutterCore::getAllComments(const QString &filterType) RzIntervalTreeIter it; void *pVoid; RzAnalysisMetaItem *item; - RzSpace *spaces = rz_spaces_current(rz_analysis_get_meta_spaces(core->analysis)); - RzIntervalTree *tmeta = rz_analysis_get_meta(core->analysis); + const RzSpace *spaces = rz_spaces_current(rz_analysis_get_meta_spaces(core->analysis)); + const RzIntervalTree *tmeta = rz_analysis_get_meta(core->analysis); rz_interval_tree_foreach(tmeta, it, pVoid) { item = reinterpret_cast(pVoid); @@ -3448,7 +3437,7 @@ QList CutterCore::getAllComments(const QString &filterType) continue; } - RzIntervalNode *node = rz_interval_tree_iter_get(&it); + const RzIntervalNode *node = rz_interval_tree_iter_get(&it); CommentDescription comment; comment.offset = node->start; comment.name = fromOwnedCharPtr(rz_str_escape(item->str)); @@ -3468,16 +3457,17 @@ QList CutterCore::getAllRelocs() return ret; } for (size_t i = 0; i < relocs->relocs_count; i++) { - RzBinReloc *reloc = relocs->relocs[i]; + const RzBinReloc *reloc = relocs->relocs[i]; RelocDescription desc; desc.vaddr = reloc->vaddr; desc.paddr = reloc->paddr; desc.type = (reloc->additive ? "ADD_" : "SET_") + QString::number(reloc->type); - if (reloc->import) + if (reloc->import) { desc.name = reloc->import->name; - else + } else { desc.name = QString("reloc_%1").arg(QString::number(reloc->vaddr, 16)); + } ret << desc; } @@ -3498,12 +3488,12 @@ QList CutterCore::getAllStrings() return {}; } - RzPVector *strings = rz_core_bin_whole_strings(core, bf); + const RzPVector *strings = rz_core_bin_whole_strings(core, bf); if (!strings) { return {}; } - int va = core->io->va || core->bin->is_debugger; + const int va = core->io->va || core->bin->is_debugger; RzStrEscOptions opt = {}; opt.show_asciidot = false; opt.esc_bslash = true; @@ -3512,7 +3502,7 @@ QList CutterCore::getAllStrings() QList ret; for (const auto &str : CutterPVector(strings)) { - auto section = obj ? rz_bin_get_section_at(obj, str->paddr, 0) : NULL; + auto section = obj ? rz_bin_get_section_at(obj, str->paddr, 0) : nullptr; StringDescription string; string.string = rz_str_escape_utf8(str->string, &opt); @@ -3534,7 +3524,7 @@ QList CutterCore::getAllFlagspaces() QList flagspaces; RzSpaceIter it; RzSpace *space; - rz_flag_space_foreach(core->flags, it, space) + rz_flag_space_foreach(core->flags, it, space) // NOLINT { FlagspaceDescription flagspace; flagspace.name = space->name; @@ -3543,12 +3533,13 @@ QList CutterCore::getAllFlagspaces() return flagspaces; } -QList CutterCore::getAllFlags(QString flagspace) +QList CutterCore::getAllFlags(const QString &flagspace) { CORE_LOCK(); QList flags; - std::string name = flagspace.isEmpty() || flagspace.isNull() ? "*" : flagspace.toStdString(); - RzSpace *space = rz_flag_space_get(core->flags, name.c_str()); + const std::string name = + flagspace.isEmpty() || flagspace.isNull() ? "*" : flagspace.toStdString(); + const RzSpace *space = rz_flag_space_get(core->flags, name.c_str()); rz_flag_foreach_space( core->flags, space, [](RzFlagItem *item, void *user) { @@ -3571,7 +3562,7 @@ SectionDescription CutterCore::getSectionAtAddress(RVA addr) if (!o) { return {}; } - RzBinSection *section = rz_bin_get_section_at(o, addr, true); + const RzBinSection *section = rz_bin_get_section_at(o, addr, true); if (!section) { return {}; } @@ -3592,7 +3583,7 @@ SectionDescription CutterCore::getSectionAtAddress(RVA addr) return {}; } - const char *entropy = (const char *)ht_ss_find(digests, "entropy", NULL); + const char *entropy = (const char *)ht_ss_find(digests, "entropy", nullptr); desc.entropy = rz_str_get(entropy); ht_ss_free(digests); } @@ -3620,8 +3611,9 @@ QList CutterCore::getAllSections() } rz_list_push(hashnames, rz_str_dup("entropy")); for (const auto § : CutterPVector(sects)) { - if (RZ_STR_ISEMPTY(sect->name)) + if (RZ_STR_ISEMPTY(sect->name)) { continue; + } SectionDescription section; section.name = sect->name; @@ -3635,7 +3627,7 @@ QList CutterCore::getAllSections() if (!digests) { continue; } - const char *entropy = (const char *)ht_ss_find(digests, "entropy", NULL); + const char *entropy = (const char *)ht_ss_find(digests, "entropy", nullptr); section.entropy = rz_str_get(entropy); ht_ss_free(digests); } @@ -3667,7 +3659,7 @@ QStringList CutterCore::getSectionList() return ret; } -static inline QString perms_str(int perms) +static inline QString permsStr(int perms) { return QString((perms & RZ_PERM_SHAR) ? 's' : '-') + rz_str_rwx_i(perms); } @@ -3675,7 +3667,7 @@ static inline QString perms_str(int perms) QList CutterCore::getAllSegments() { CORE_LOCK(); - RzBinFile *bf = rz_bin_cur(core->bin); + const RzBinFile *bf = rz_bin_cur(core->bin); if (!bf) { return {}; } @@ -3692,7 +3684,7 @@ QList CutterCore::getAllSegments() segDesc.paddr = segment->paddr; segDesc.size = segment->size; segDesc.vsize = segment->vsize; - segDesc.perm = perms_str(segment->perm); + segDesc.perm = permsStr(segment->perm); ret << segDesc; } rz_pvector_free(segments); @@ -3703,13 +3695,13 @@ QList CutterCore::getAllSegments() QList CutterCore::getAllEntrypoint() { CORE_LOCK(); - RzBinFile *bf = rz_bin_cur(core->bin); + const RzBinFile *bf = rz_bin_cur(core->bin); if (!bf) { return {}; } - bool va = core->io->va || core->bin->is_debugger; - ut64 baddr = rz_bin_get_baddr(core->bin); - ut64 laddr = rz_bin_get_laddr(core->bin); + const bool va = core->io->va || core->bin->is_debugger; + const ut64 baddr = rz_bin_get_baddr(core->bin); + const ut64 laddr = rz_bin_get_laddr(core->bin); QList qList; const RzPVector *entries = rz_bin_object_get_entries(bf->o); @@ -3735,7 +3727,7 @@ QList CutterCore::getAllEntrypoint() QList CutterCore::getAllClassesFromBin() { CORE_LOCK(); - RzBinFile *bf = rz_bin_cur(core->bin); + const RzBinFile *bf = rz_bin_cur(core->bin); if (!bf) { return {}; } @@ -3775,18 +3767,18 @@ QList CutterCore::getAllClassesFromFlags() static const QRegularExpression classFlagRegExp("^class\\.(.*)$"); static const QRegularExpression methodFlagRegExp("^method\\.([^\\.]*)\\.(.*)$"); - CORE_LOCK(); + const auto core = Core()->lock(); QList ret; QMap classesCache; for (const auto &item : getAllFlags("classes")) { QRegularExpressionMatch match = classFlagRegExp.match(item.name); if (match.hasMatch()) { - QString className = match.captured(1); + const QString className = match.captured(1); BinClassDescription *desc = nullptr; auto it = classesCache.find(className); if (it == classesCache.end()) { - BinClassDescription cls = {}; + const BinClassDescription cls = {}; ret << cls; desc = &ret.last(); classesCache[className] = desc; @@ -3800,7 +3792,7 @@ QList CutterCore::getAllClassesFromFlags() match = methodFlagRegExp.match(item.name); if (match.hasMatch()) { - QString className = match.captured(1); + const QString className = match.captured(1); BinClassDescription *classDesc = nullptr; auto it = classesCache.find(className); if (it == classesCache.end()) { @@ -3829,7 +3821,7 @@ QList CutterCore::getAllAnalysisClasses(bool sorted) { CORE_LOCK(); QList ret; - PVectorPtr l = makePVectorPtr(rz_analysis_class_get_all(core->analysis, sorted)); + const PVectorPtr l = makePVectorPtr(rz_analysis_class_get_all(core->analysis, sorted)); if (!l) { return ret; } @@ -3977,7 +3969,7 @@ void CutterCore::renameAnalysisMethod(const QString &className, const QString &o QList CutterCore::getAllResources() { CORE_LOCK(); - RzBinFile *bf = rz_bin_cur(core->bin); + const RzBinFile *bf = rz_bin_cur(core->bin); if (!bf) { return {}; } @@ -4019,7 +4011,7 @@ QList CutterCore::getAllVTables() CutterRzVectorForeach(&table->methods, method, RVTableMethodInfo) { BinClassMethodDescription methodDesc; - RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, method->addr, 0); + const RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, method->addr, 0); const char *fname = fcn ? fcn->name : nullptr; methodDesc.addr = method->addr; methodDesc.name = fname; @@ -4070,7 +4062,7 @@ QList CutterCore::getBaseType(RzBaseTypeKind kind, const char * CORE_LOCK(); QList types; - RzTypeDB *typedb = rz_analysis_get_type_db(core->analysis); + const RzTypeDB *typedb = rz_analysis_get_type_db(core->analysis); RzList *ts = rz_type_db_get_base_types_of_kind(typedb, kind); RzBaseType *type; RzListIter *iter; @@ -4114,7 +4106,7 @@ QList CutterCore::getAllTypedefs() return getBaseType(RZ_BASE_TYPE_KIND_TYPEDEF, "Typedef"); } -QString CutterCore::getTypeAsC(QString name) +QString CutterCore::getTypeAsC(const QString &name) { CORE_LOCK(); QString output = "Failed to fetch the output."; @@ -4139,8 +4131,8 @@ bool CutterCore::isAddressMapped(RVA addr) return rz_io_map_get(core->io, addr); } -QList CutterCore::getAllSearchCommand(QString searchFor, SearchKind kind, - QString in) +QList CutterCore::getAllSearchCommand(const QString &searchFor, SearchKind kind, + const QString &in) { CORE_LOCK(); QList searchRef; @@ -4148,7 +4140,7 @@ QList CutterCore::getAllSearchCommand(QString searchFor, Sear TempConfig cfg; cfg.set("search.in", in); CutterJson searchArray; - char *arg = rz_cmd_escape_arg(searchFor.toUtf8().constData(), RZ_CMD_ESCAPE_ONE_ARG); + const char *arg = rz_cmd_escape_arg(searchFor.toUtf8().constData(), RZ_CMD_ESCAPE_ONE_ARG); if (!arg) { return {}; } @@ -4174,11 +4166,11 @@ QList CutterCore::getAllSearchCommand(QString searchFor, Sear auto cstr = QString("%1 %2").arg(cmd, kind == SearchKind::AsmCode ? searchFor : arg); searchArray = cmdj(cstr); if (kind == SearchKind::ROPGadgets || kind == SearchKind::ROPGadgetsRegex) { - for (CutterJson searchObject : searchArray) { + for (const auto &searchObject : searchArray) { SearchDescription exp; exp.code.clear(); - for (CutterJson gadget : searchObject[RJsonKey::opcodes]) { + for (const auto &gadget : searchObject[RJsonKey::opcodes]) { exp.code += gadget[RJsonKey::opcode].toString() + "; "; } @@ -4189,7 +4181,7 @@ QList CutterCore::getAllSearchCommand(QString searchFor, Sear } return searchRef; } - for (CutterJson searchObject : searchArray) { + for (const auto &searchObject : searchArray) { SearchDescription exp; exp.offset = searchObject[RJsonKey::offset].toRVA(); @@ -4209,14 +4201,13 @@ static UniquePtrC cutterSetupSearchOptions(RzC if (!searchOpts) { return {}; } - RzThreadNCores max_threads = - (RzThreadNCores)rz_config_get_i(core->config, "search.max_threads"); - max_threads = rz_th_max_threads(max_threads); - ut32 max_hits = rz_config_get_i(core->config, "search.maxhits"); - const char *show_progress = rz_config_get(core->config, "search.show_progress"); - if (!(rz_search_opt_set_max_threads(searchOpts.get(), max_threads) - && rz_search_opt_set_max_hits(searchOpts.get(), max_hits) - && rz_search_opt_set_show_progress_from_str(searchOpts.get(), show_progress))) { + auto maxThreads = (RzThreadNCores)rz_config_get_i(core->config, "search.max_threads"); + maxThreads = rz_th_max_threads(maxThreads); + const ut32 maxHits = rz_config_get_i(core->config, "search.maxhits"); + const char *showProgress = rz_config_get(core->config, "search.show_progress"); + if (!(rz_search_opt_set_max_threads(searchOpts.get(), maxThreads) + && rz_search_opt_set_max_hits(searchOpts.get(), maxHits) + && rz_search_opt_set_show_progress_from_str(searchOpts.get(), showProgress))) { RZ_LOG_ERROR("Failed setup find options.\n"); return {}; } @@ -4236,25 +4227,25 @@ static UniquePtrC cutterSetupSearchOptions(RzC class CutterSearchLock { public: - CutterSearchLock(RzCore *core) : core_(core) + CutterSearchLock(RzCore *core) : core(core) { - rz_cons_break_push(NULL, NULL); - core_->in_search = true; + rz_cons_break_push(nullptr, nullptr); + core->in_search = true; } ~CutterSearchLock() { rz_cons_break_pop(); - core_->in_search = false; + core->in_search = false; } private: - RzCore *core_ = nullptr; + RzCore *core = nullptr; }; static QString cutterGetSearchHitData(RzCore *core, SearchKind kind, RzSearchHit *hit) { QString data = ""; - size_t dataSize = RZ_MAX(hit->size, 16); + const size_t dataSize = RZ_MAX(hit->size, 16); std::vector buffer(dataSize); if (!rz_io_read_at_mapped(core->io, hit->address, buffer.data(), dataSize)) { @@ -4316,9 +4307,9 @@ static QString cutterGetSearchHitData(RzCore *core, SearchKind kind, RzSearchHit return data; } -static QString cutterValueAsHex(QString strVal, bool bigEndian, size_t size) +static QString cutterValueAsHex(const QString &strVal, bool bigEndian, size_t size) { - ut64 value = rz_num_math(nullptr, strVal.toUtf8().constData()); + const ut64 value = rz_num_math(nullptr, strVal.toUtf8().constData()); ut8 buffer[sizeof(ut64)] = { 0 }; char output[64] = { 0 }; rz_write_ble(buffer, value, bigEndian, size); @@ -4326,7 +4317,8 @@ static QString cutterValueAsHex(QString strVal, bool bigEndian, size_t size) return output; } -QList CutterCore::getAllSearch(QString searchFor, SearchKind kind, QString in) +QList CutterCore::getAllSearch(QString searchFor, SearchKind kind, + const QString &in) { if (searchFor.isEmpty() && kind != SearchKind::CryptographicMaterial && kind != SearchKind::MagicSignature) { @@ -4358,7 +4350,7 @@ QList CutterCore::getAllSearch(QString searchFor, SearchKind } // this takes ownership of the search lock - CutterSearchLock searchLock(core); + const CutterSearchLock searchLock(core); TempConfig cfg; cfg.set("search.in", in); @@ -4450,7 +4442,7 @@ QList CutterCore::getAllSearch(QString searchFor, SearchKind RzSearchHit *hit; CutterRzListForeach (hits, it, RzSearchHit, hit) { SearchDescription exp; - QString detail = fromOwnedCharPtr(rz_search_hit_detail_as_string(hit)); + const QString detail = fromOwnedCharPtr(rz_search_hit_detail_as_string(hit)); exp.offset = hit->address; exp.size = hit->size; @@ -4473,7 +4465,7 @@ QList CutterCore::getAllSearch(QString searchFor, SearchKind QList CutterCore::collectXRefsForVariable(const QString &variableName, RVA offset, int accessTypeMask, bool stopAtFirst) { - CORE_LOCK(); + const auto core = Core()->lock(); auto fcn = functionIn(offset); if (!fcn) { return {}; @@ -4491,14 +4483,14 @@ QList CutterCore::collectXRefsForVariable(const QString &variab continue; } XrefDescription xref; - RVA addr = fcn->addr + acc->offset; + const RVA addr = fcn->addr + acc->offset; xref.from = addr; xref.to = addr; if (acc->type & RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE) { - xref.from_str = RzAddressString(addr); + xref.fromStr = rzAddressString(addr); } else { - xref.to_str = RzAddressString(addr); + xref.toStr = rzAddressString(addr); } xrefs << xref; @@ -4510,16 +4502,17 @@ QList CutterCore::collectXRefsForVariable(const QString &variab return xrefs; } -QList CutterCore::getXRefsForVariable(QString variableName, bool findWrites, +QList CutterCore::getXRefsForVariable(const QString &variableName, bool findWrites, RVA offset) { - ut8 mask = findWrites ? RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE : RZ_ANALYSIS_VAR_ACCESS_TYPE_READ; + const ut8 mask = + findWrites ? RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE : RZ_ANALYSIS_VAR_ACCESS_TYPE_READ; return collectXRefsForVariable(variableName, offset, mask, false); } XrefDescription CutterCore::getFirstXRefForVariable(const QString &variableName, RVA offset) { - ut8 mask = RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE | RZ_ANALYSIS_VAR_ACCESS_TYPE_READ; + const ut8 mask = RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE | RZ_ANALYSIS_VAR_ACCESS_TYPE_READ; auto result = collectXRefsForVariable(variableName, offset, mask, true); return result.isEmpty() ? XrefDescription() : result.first(); @@ -4547,21 +4540,22 @@ QList CutterCore::getXRefs(RVA addr, bool to, bool whole_functi xd.to = xref->to; xd.type = rz_analysis_xrefs_type_tostring(xref->type); - if (!filterType.isNull() && filterType != xd.type) + if (!filterType.isNull() && filterType != xd.type) { continue; + } if (!whole_function && !to && xd.from != addr) { continue; } char *from = rz_core_addr_get_name_delta(core, xd.from); if (from) { - xd.from_str = QString::fromUtf8(from); + xd.fromStr = QString::fromUtf8(from); free(from); } else { - xd.from_str = RzAddressString(xd.from); + xd.fromStr = rzAddressString(xd.from); } - xd.to_str = Core()->flagAt(xd.to); + xd.toStr = Core()->flagAt(xd.to); xrefList << xd; } @@ -4581,11 +4575,11 @@ QString CutterCore::getXRefCommentAt(RVA offset) return commentStr; } -void CutterCore::addGlobalVariable(RVA offset, QString name, QString typ) +void CutterCore::addGlobalVariable(RVA offset, QString name, const QString &typ) { name = sanitizeStringForCommand(name); CORE_LOCK(); - char *errmsg = NULL; + char *errmsg = nullptr; RzType *globType = rz_type_parse_string_single(rz_analysis_get_type_db(core->analysis)->parser, typ.toStdString().c_str(), &errmsg); if (errmsg) { @@ -4602,7 +4596,7 @@ void CutterCore::addGlobalVariable(RVA offset, QString name, QString typ) emit globalVarsChanged(); } -void CutterCore::modifyGlobalVariable(RVA offset, QString name, QString typ) +void CutterCore::modifyGlobalVariable(RVA offset, QString name, const QString &typ) { name = sanitizeStringForCommand(name); CORE_LOCK(); @@ -4614,7 +4608,7 @@ void CutterCore::modifyGlobalVariable(RVA offset, QString name, QString typ) if (name.compare(glob->name)) { rz_analysis_var_global_rename(core->analysis, glob->name, name.toStdString().c_str()); } - char *errmsg = NULL; + char *errmsg = nullptr; RzType *globType = rz_type_parse_string_single(rz_analysis_get_type_db(core->analysis)->parser, typ.toStdString().c_str(), &errmsg); if (errmsg) { @@ -4648,7 +4642,7 @@ QString CutterCore::getGlobalVariableType(QString name) { name = sanitizeStringForCommand(name); CORE_LOCK(); - RzAnalysisVarGlobal *glob = + const RzAnalysisVarGlobal *glob = rz_analysis_var_global_get_byname(core->analysis, name.toStdString().c_str()); if (!glob) { return QString(""); @@ -4663,7 +4657,7 @@ QString CutterCore::getGlobalVariableType(QString name) QString CutterCore::getGlobalVariableType(RVA offset) { CORE_LOCK(); - RzAnalysisVarGlobal *glob = rz_analysis_var_global_get_byaddr_at(core->analysis, offset); + const RzAnalysisVarGlobal *glob = rz_analysis_var_global_get_byaddr_at(core->analysis, offset); if (!glob) { return QString(""); } @@ -4682,11 +4676,6 @@ void CutterCore::addFlag(RVA offset, QString name, RVA size) emit flagsChanged(); } -/** - * @brief Gets all the flags present at a specific address - * @param addr The address to be checked - * @return String containing all the flags which are comma-separated - */ QString CutterCore::listFlagsAsStringAt(RVA addr) { CORE_LOCK(); @@ -4708,7 +4697,8 @@ QString CutterCore::nearestFlag(RVA offset, RVA *flagOffsetOut) return r->name; } -void CutterCore::addMark(RVA from, RVA to, QString name, QString comment, QColor color) +void CutterCore::addMark(RVA from, RVA to, const QString &name, const QString &comment, + QColor color) { CORE_LOCK(); auto m = rz_mark_set(core->marks, name.toStdString().c_str(), from, to); @@ -4765,26 +4755,30 @@ QList CutterCore::getMarksAt(RVA addr) QColor CutterCore::getBlendedMarksColorAt(RVA addr) { const auto &marks = getMarksAt(addr); + QListIterator it(marks); + it.toBack(); + double r = 0, g = 0, b = 0, a = 0; bool first = true; // Iterate in reverse because the oldest/first mark is at the end - for (auto it = marks.crbegin(); it != marks.crend(); ++it) { - QColor c = it->color; + while (it.hasPrevious()) { + const auto mark = it.previous(); + const QColor c = mark.color; if (!c.isValid()) { continue; } - double cr = c.redF(), cg = c.greenF(), cb = c.blueF(); + const double cr = c.redF(), cg = c.greenF(), cb = c.blueF(); if (first) { - r = cr, g = cg, b = cb, a = MARK_ALPHA_F; + r = cr, g = cg, b = cb, a = markAlphaF; first = false; } else { - double a_out = MARK_ALPHA_F + a * (1.0 - MARK_ALPHA_F); - r = (cr * MARK_ALPHA_F + r * a * (1.0 - MARK_ALPHA_F)) / a_out; - g = (cg * MARK_ALPHA_F + g * a * (1.0 - MARK_ALPHA_F)) / a_out; - b = (cb * MARK_ALPHA_F + b * a * (1.0 - MARK_ALPHA_F)) / a_out; - a = a_out; + const double aOut = markAlphaF + a * (1.0 - markAlphaF); + r = (cr * markAlphaF + r * a * (1.0 - markAlphaF)) / aOut; + g = (cg * markAlphaF + g * a * (1.0 - markAlphaF)) / aOut; + b = (cb * markAlphaF + b * a * (1.0 - markAlphaF)) / aOut; + a = aOut; } } return first ? QColor() : QColor::fromRgbF(r, g, b, a); @@ -4878,13 +4872,13 @@ QList CutterCore::disassembleLines(RVA offset, int lines) rz_cons_singleton()->is_html = false; rz_cons_singleton()->was_html = true; } - rz_core_print_disasm(core, offset, core->block, core->blocksize, lines, NULL, &options); + rz_core_print_disasm(core, offset, core->block, core->blocksize, lines, nullptr, &options); } QList r; for (const auto &t : CutterPVector(vec.get())) { - QString text = t->text; - QStringList tokens = text.split('\n'); + const QString text = t->text; + const QStringList tokens = text.split('\n'); // text might contain multiple lines // so we split them and keep only one // arrow/jump to addr. @@ -4901,12 +4895,6 @@ QList CutterCore::disassembleLines(RVA offset, int lines) return r; } -/** - * @brief return hexdump of from an by a given formats - * @param address - the address from which to print the hexdump - * @param size - number of bytes to print - * @param format - the type of hexdump (qwords, words. decimal, etc) - */ QString CutterCore::hexdump(RVA address, int size, HexdumpFormats format) { CORE_LOCK(); @@ -4943,10 +4931,10 @@ QString CutterCore::hexdump(RVA address, int size, HexdumpFormats format) QByteArray CutterCore::hexStringToBytes(const QString &hex) { - QByteArray hexChars = hex.toUtf8(); + const QByteArray hexChars = hex.toUtf8(); QByteArray bytes; bytes.reserve(hexChars.length() / 2); - int size = rz_hex_str2bin(hexChars.constData(), reinterpret_cast(bytes.data())); + const int size = rz_hex_str2bin(hexChars.constData(), reinterpret_cast(bytes.data())); bytes.resize(size); return bytes; } @@ -4966,16 +4954,23 @@ void CutterCore::loadScript(const QString &scriptname) triggerRefreshAll(); } +bool CutterCore::isFileLoaded() +{ + CORE_LOCK(); + const RzList *descs = rz_id_storage_list(core->io->files); + return rz_list_empty(descs); +} + QString CutterCore::getRizinVersionReadable(const char *program) { - return fromOwnedCharPtr(rz_version_str(core_->sys_path, program)); + return fromOwnedCharPtr(rz_version_str(rzCore->sys_path, program)); } QString CutterCore::getVersionInformation() { int i; QString versionInfo; - struct vcs_t + const struct Vcs { const char *name; const char *(*callback)(); @@ -5000,12 +4995,12 @@ QString CutterCore::getVersionInformation() { "rz_syscall", &rz_syscall_version }, { "rz_util", &rz_util_version }, /* ... */ - { NULL, NULL } + { nullptr, nullptr } }; versionInfo.append(getRizinVersionReadable()); versionInfo.append("\n"); for (i = 0; vcs[i].name; i++) { - struct vcs_t *v = &vcs[i]; + struct Vcs const *v = &vcs[i]; const char *name = v->callback(); versionInfo.append(QString("%1 %2\n").arg(name, v->name)); } @@ -5016,14 +5011,14 @@ QStringList CutterCore::getColorThemes() { QStringList r; CORE_LOCK(); - RzPVector *themes_list = rz_core_get_themes(core); - if (!themes_list) { + RzPVector *themesList = rz_core_get_themes(core); + if (!themesList) { return r; } - for (const auto &th : CutterPVector(themes_list)) { + for (const auto &th : CutterPVector(themesList)) { r << fromOwnedCharPtr(rz_str_trim_dup(th)); } - rz_pvector_free(themes_list); + rz_pvector_free(themesList); return r; } @@ -5035,7 +5030,7 @@ QHash CutterCore::getTheme() if (!k) { break; } - RzColor color = rz_cons_pal_get_i(i); + const RzColor color = rz_cons_pal_get_i(i); theme.insert(k, QColor(color.r, color.g, color.b)); } return theme; @@ -5063,6 +5058,12 @@ bool CutterCore::setColor(const QString &key, const QString &color) return true; } +QString CutterCore::getColorNameFromOp(ut32 opType) +{ + CORE_LOCK(); + return rz_print_color_op_type(core->print, opType); +} + QString CutterCore::ansiEscapeToHtml(const QString &text) { int len; @@ -5112,7 +5113,7 @@ void CutterCore::commitWriteCache() TempConfig tempConfig; tempConfig.set("io.cache", false); auto desc = core->io->desc; - bool reopen = !isWriteModeEnabled() && desc; + const bool reopen = !isWriteModeEnabled() && desc; if (reopen) { rz_core_io_file_reopen(core, desc->fd, RZ_PERM_RW); } @@ -5132,7 +5133,7 @@ void CutterCore::resetWriteCache() // Enable or disable write-mode. Avoid unecessary changes if not need. void CutterCore::setWriteMode(bool enabled) { - bool writeModeState = isWriteModeEnabled(); + const bool writeModeState = isWriteModeEnabled(); if (writeModeState == enabled && !this->iocache) { // New mode is the same as current and IO Cache is disabled. Do nothing. @@ -5141,7 +5142,7 @@ void CutterCore::setWriteMode(bool enabled) CORE_LOCK(); // Change from read-only to write-mode - RzIODesc *desc = core->io->desc; + const RzIODesc *desc = core->io->desc; if (desc) { if (enabled) { if (!writeModeState) { @@ -5167,7 +5168,7 @@ bool CutterCore::isWriteModeEnabled() RzListIter *it; RzCoreFile *cf; CutterRzListForeach (core->files, it, RzCoreFile, cf) { - RzIODesc *desc = rz_io_desc_get(core->io, cf->fd); + const RzIODesc *desc = rz_io_desc_get(core->io, cf->fd); if (!desc) { continue; } @@ -5178,11 +5179,18 @@ bool CutterCore::isWriteModeEnabled() return false; } -/** - * @brief get a compact disassembly preview for tooltips - * @param address - the address from which to print the disassembly - * @param num_of_lines - number of instructions to print - */ +bool CutterCore::hasUncommitedChanges() +{ + + CORE_LOCK(); + for (auto c : CutterPVector(&core->io->cache)) { + if (!c->written) { + return false; + } + } + return true; +} + QStringList CutterCore::getDisassemblyPreview(RVA address, int num_of_lines) { QList disassemblyLines; @@ -5202,7 +5210,7 @@ QStringList CutterCore::getDisassemblyPreview(RVA address, int num_of_lines) disassemblyLines = disassembleLines(address, num_of_lines + 1); } QStringList disasmPreview; - for (const DisassemblyLine &line : disassemblyLines) { + for (const DisassemblyLine &line : std::as_const(disassemblyLines)) { disasmPreview << line.text; if (disasmPreview.length() >= num_of_lines) { disasmPreview << "..."; @@ -5216,11 +5224,6 @@ QStringList CutterCore::getDisassemblyPreview(RVA address, int num_of_lines) } } -/** - * @brief get a compact hexdump preview for tooltips - * @param address - the address from which to print the hexdump - * @param size - number of bytes to print - */ QString CutterCore::getHexdumpPreview(RVA address, int size) { // temporarily simplify the disasm output to get it colorful and simple to read @@ -5239,12 +5242,13 @@ QByteArray CutterCore::ioRead(RVA addr, int len) QByteArray array; - if (len <= 0) + if (len <= 0) { return array; + } /* Zero-copy */ array.resize(len); - if (!rz_io_read_at_mapped(core->io, addr, (uint8_t *)array.data(), len)) { + if (!rz_io_read_at_mapped(core->io, addr, reinterpret_cast(array.data()), len)) { array.fill(0xff); } @@ -5270,13 +5274,13 @@ QStringList CutterCore::getConfigVariableSpaces(const QString &key) char *CutterCore::getTextualGraphAt(RzCoreGraphType type, RzCoreGraphFormat format, RVA address) { CORE_LOCK(); - char *string = nullptr; + char *string = nullptr; // NOLINT RzGraph *graph = rz_core_graph(core, type, address); if (!graph) { if (address == RVA_INVALID) { qWarning() << tr("Cannot get global graph"); } else { - qWarning() << tr("Cannot get graph at ") << RzAddressString(address); + qWarning() << tr("Cannot get graph at ") << rzAddressString(address); } return nullptr; } @@ -5313,8 +5317,8 @@ char *CutterCore::getTextualGraphAt(RzCoreGraphType type, RzCoreGraphFormat form return string; } -void CutterCore::writeGraphvizGraphToFile(QString path, QString format, RzCoreGraphType type, - RVA address) +void CutterCore::writeGraphvizGraphToFile(const QString &path, const QString &format, + RzCoreGraphType type, RVA address) { TempConfig tempConfig; tempConfig.set("scr.color", false); @@ -5327,7 +5331,7 @@ void CutterCore::writeGraphvizGraphToFile(QString path, QString format, RzCoreGr if (address == RVA_INVALID) { qWarning() << tr("Cannot get global graph"); } else { - qWarning() << tr("Cannot get graph at ") << RzAddressString(address); + qWarning() << tr("Cannot get graph at ") << rzAddressString(address); } } } diff --git a/src/core/Cutter.h b/src/core/Cutter.h index 7bcc3b2c..30d05aa5 100644 --- a/src/core/Cutter.h +++ b/src/core/Cutter.h @@ -1,24 +1,25 @@ #ifndef CUTTER_H #define CUTTER_H +#include "RizinCpp.h" +#include "common/BasicInstructionHighlighter.h" +#include "core/Basefind.h" #include "core/CutterCommon.h" #include "core/CutterDescriptions.h" #include "core/CutterJson.h" -#include "core/Basefind.h" -#include "common/BasicInstructionHighlighter.h" +#include +#include +#include #include #include -#include -#include -#include -#include #include -#include #include -#include +#include +#include + #include -#include +// #include class AsyncTaskManager; class BasicInstructionHighlighter; @@ -32,9 +33,9 @@ class RizinTaskDialog; #include "common/BasicBlockHighlighter.h" #include "common/Helpers.h" +#include #include #include -#include #define Core() (CutterCore::instance()) @@ -48,12 +49,12 @@ struct CUTTER_EXPORT AddrRefs QString reg; QString fcn; QString type; - QString asm_op; + QString asmOp; QString perms; ut64 value; - bool has_value; + bool hasValue; QString string; - QSharedPointer ref; + std::shared_ptr ref; }; struct CUTTER_EXPORT RegisterRef @@ -63,7 +64,7 @@ struct CUTTER_EXPORT RegisterRef QString name; }; -enum class SearchKind { +enum class SearchKind : ut8 { AsmCode, HexString, ROPGadgets, @@ -79,8 +80,13 @@ enum class SearchKind { MagicSignature, }; -enum class AddressTypeHint { Function, Code, Data, Unknown }; +enum class AddressTypeHint : ut8 { Function, Code, Data, Unknown }; +/** + * @brief Core class that talks to rizin. + * + * Prefer the use of this class when functionality from rizin is needed + */ class CUTTER_EXPORT CutterCore : public QObject { Q_OBJECT @@ -101,7 +107,7 @@ public: AsyncTaskManager *getAsyncTaskManager() { return asyncTaskManager; } - RVA getOffset() const { return core_->offset; } + RVA getOffset() const { return rzCore->offset; } /* Core functions (commands) */ /* Almost the same as core_cmd_raw, @@ -123,7 +129,7 @@ public: * @param fcn the task you want to execute * @return execute successful? */ - bool asyncTask(std::function fcn, QSharedPointer &task); + bool asyncTask(std::function fcn, std::shared_ptr &task); void functionTask(std::function fcn); /** @@ -174,7 +180,7 @@ public: Core()->seekSilent(returnAddress); } } - SeekReturn(SeekReturn &&from) + SeekReturn(SeekReturn &&from) noexcept { if (this != &from) { returnAddress = from.returnAddress; @@ -191,7 +197,7 @@ public: return returner; } - enum class SeekHistoryType { New, Undo, Redo }; + enum class SeekHistoryType : ut8 { New, Undo, Redo }; CutterJson cmdj(const char *str); CutterJson cmdj(const QString &str) { return cmdj(str.toUtf8().constData()); } @@ -211,7 +217,7 @@ public: /* Functions methods */ void renameFunction(const RVA offset, const QString &newName); void delFunction(RVA addr); - void renameFlag(QString old_name, QString new_name); + void renameFlag(const QString &old_name, const QString &new_name); /** * @brief Renames the specified local variable in the function specified by the * address given. @@ -220,7 +226,8 @@ public: * @param oldName Specifies the current name of the function variable. * @param functionAddress Specifies the exact address of the function. */ - void renameFunctionVariable(QString newName, QString oldName, RVA functionAddress); + void renameFunctionVariable(const QString &newName, const QString &oldName, + RVA functionAddress); /** * @param addr @@ -234,19 +241,45 @@ public: */ RzAnalysisFunction *functionAt(ut64 addr); + /** + * @brief finds the start address of a function in a given address + * @param addr - an address which belongs to a function + * @returns if function exists, return its start address. Otherwise return RVA_INVALID + */ RVA getFunctionStart(RVA addr); + /** + * @brief finds the end address of a function in a given address + * @param addr - an address which belongs to a function + * @returns if function exists, return its end address. Otherwise return RVA_INVALID + */ RVA getFunctionEnd(RVA addr); + /** + * @brief finds the last instruction of a function in a given address + * @param addr - an address which belongs to a function + * @returns if function exists, return the address of its last instruction. Otherwise return + * RVA_INVALID + */ RVA getLastFunctionInstruction(RVA addr); QString flagAt(RVA addr, bool getClosestFlag = true); AddressTypeHint getAddressType(RVA addr); void createFunctionAt(RVA addr); void createFunctionAt(RVA addr, QString name); + /** + * @brief get a compact disassembly preview for tooltips + * @param address - the address from which to print the disassembly + * @param num_of_lines - number of instructions to print + */ QStringList getDisassemblyPreview(RVA address, int num_of_lines); /* Flags */ void delFlag(RVA addr); void delFlag(const QString &name); void addFlag(RVA offset, QString name, RVA size); + /** + * @brief Gets all the flags present at a specific address + * @param addr The address to be checked + * @return String containing all the flags which are comma-separated + */ QString listFlagsAsStringAt(RVA addr); /** * @brief Get nearest flag at or before offset. @@ -258,7 +291,8 @@ public: void triggerFlagsChanged(); /* Marks */ - void addMark(RVA from, RVA to, QString name, QString comment = {}, QColor color = {}); + void addMark(RVA from, RVA to, const QString &name, const QString &comment = {}, + QColor color = {}); void delMark(const QString &name); QList getMarks(); QList getMarksAt(RVA addr); @@ -271,10 +305,10 @@ public: QColor getBlendedMarksColorAt(RVA addr); /* Global Variables */ - void addGlobalVariable(RVA offset, QString name, QString typ); + void addGlobalVariable(RVA offset, QString name, const QString &typ); void delGlobalVariable(QString name); void delGlobalVariable(RVA offset); - void modifyGlobalVariable(RVA offset, QString name, QString typ); + void modifyGlobalVariable(RVA offset, QString name, const QString &typ); QString getGlobalVariableType(QString name); QString getGlobalVariableType(RVA offset); @@ -290,13 +324,13 @@ public: /* Code/Data */ void setToCode(RVA addr); - enum class StringTypeFormats { None, ASCII_LATIN1, UTF8 }; + enum class StringTypeFormats : ut8 { None, ASCII_LATIN1, UTF8 }; /** * @brief Adds string at address * That function calls the 'Cs' command - * \param addr The address of the array where the string will be applied - * \param size The size of string - * \param type The type of string + * @param addr The address of the array where the string will be applied + * @param size The size of string + * @param type The type of string */ void setAsString(RVA addr, int size = 0, StringTypeFormats type = StringTypeFormats::None); /** @@ -308,14 +342,14 @@ public: /** * @brief Gets string at address * That function correspond the 'Cs.' command - * \param addr The address of the string + * @param addr The address of the string * @return string at requested address */ QString getMetaString(RVA addr); /** * @brief Gets string at address * That function calls the 'ps' command - * \param addr The address of the first byte of the array + * @param addr The address of the first byte of the array * @return string at requested address */ QString getString(RVA addr); @@ -326,6 +360,11 @@ public: /* Comments */ void setComment(RVA addr, const QString &cmt); void delComment(RVA addr); + /** + * @brief Gets the comment present at a specific address + * @param addr The address to be checked + * @return String containing comment + */ QString getCommentAt(RVA addr); void setImmediateBase(const QString &rzBaseName, RVA offset = RVA_INVALID); void setCurrentBits(int bits, RVA offset = RVA_INVALID); @@ -334,8 +373,8 @@ public: * @brief Changes immediate displacement to structure offset * This function makes use of the "aht" command of Rizin to apply structure * offset to the immediate displacement used in the given instruction - * \param structureOffset The name of struct which will be applied - * \param offset The address of the instruction where the struct will be applied + * @param structureOffset The name of struct which will be applied + * @param offset The address of the instruction where the struct will be applied */ void applyStructureOffset(const QString &structureOffset, RVA offset = RVA_INVALID); @@ -354,17 +393,41 @@ public: void setAnalysisMethod(const QString &cls, const AnalysisMethodDescription &meth); /* File related methods */ - bool loadFile(QString path, ut64 baddr = 0LL, ut64 mapaddr = 0LL, int perms = RZ_PERM_R, + + /** + * @brief CutterCore::loadFile + * Load initial file. + * @param path File path + * @param baddr Base (RzBin) address + * @param mapaddr Map address + * @param perms + * @param va + * @param loadbin Load RzBin information + * @param forceBinPlugin + * @return + */ + bool loadFile(const QString &path, ut64 baddr = 0LL, ut64 mapaddr = 0LL, int perms = RZ_PERM_R, int va = 0, bool loadbin = false, const QString &forceBinPlugin = QString()); - bool tryFile(QString path, bool rw); - bool mapFile(QString path, RVA mapaddr); + bool tryFile(const QString &path, bool rw); + /** + * @brief Maps a file using Rizin API + * @param path Path to file + * @param mapaddr Map Address + * @return bool + */ + bool mapFile(const QString &path, RVA mapaddr); void loadScript(const QString &scriptname); + /** + * @brief Check whether any file is loaded + * @return True if any file is loaded, false otherwise + */ + bool isFileLoaded(); /* Seek functions */ - void seek(QString thing); + void seek(const QString &thing); void seek(ut64 offset); void seekSilent(ut64 offset); - void seekSilent(QString thing) { seekSilent(math(thing)); } + void seekSilent(const QString &thing) { seekSilent(math(thing)); } void seekPrev(); void seekNext(); void updateSeek(SeekHistoryType type = SeekHistoryType::New); @@ -374,15 +437,15 @@ public: */ void showMemoryWidget(); /** - * @brief Seek to \p offset and raise a memory widget showing it. + * @brief Seek to @p offset and raise a memory widget showing it. * @param offset */ void seekAndShow(ut64 offset); /** - * @brief \see CutterCore::show(ut64) + * @brief @see CutterCore::show(ut64) * @param thing - addressable expression */ - void seekAndShow(QString thing); + void seekAndShow(const QString &thing); RVA getOffset(); RVA prevOpAddr(RVA startAddr, int count); RVA nextOpAddr(RVA startAddr, int count); @@ -426,6 +489,7 @@ public: QHash getTheme(); QStringList getThemeKeys(); bool setColor(const QString &key, const QString &color); + QString getColorNameFromOp(ut32 opType); QStringList getConfigVariableSpaces(const QString &key = ""); /* Assembly\Hexdump related methods */ @@ -436,23 +500,34 @@ public: static QByteArray hexStringToBytes(const QString &hex); static QString bytesToHexString(const QByteArray &bytes); - enum class HexdumpFormats { Normal, Half, Word, Quad, Signed, Octal }; + enum class HexdumpFormats : ut8 { Normal, Half, Word, Quad, Signed, Octal }; + /** + * @brief return hexdump of from an by a given formats + * @param address - the address from which to print the hexdump + * @param size - number of bytes to print + * @param format - the type of hexdump (qwords, words. decimal, etc) + */ QString hexdump(RVA offset, int size, HexdumpFormats format); + /** + * @brief get a compact hexdump preview for tooltips + * @param address - the address from which to print the hexdump + * @param size - number of bytes to print + */ QString getHexdumpPreview(RVA offset, int size); - void setCPU(QString arch, QString cpu, int bits); + void setCPU(const QString &arch, const QString &cpu, int bits); void setEndianness(bool big); /* SDB */ - QList sdbList(QString path); - QList sdbListKeys(QString path); - QString sdbGet(QString path, QString key); - bool sdbSet(QString path, QString key, QString val); + QList sdbList(const QString &path); + QList sdbListKeys(const QString &path); + QString sdbGet(const QString &path, const QString &key); + bool sdbSet(const QString &path, const QString &key, const QString &val); /* Debug */ - QString getRegisterName(QString registerRole); + QString getRegisterName(const QString ®isterRole); RVA getProgramCounterValue(); - void setRegister(QString regName, QString regValue); + void setRegister(const QString ®Name, const QString ®Value); void setCurrentDebugThread(int tid); /** * @brief Attach to a given pid from a debug session @@ -475,7 +550,7 @@ public: * @brief return a RefDescription with a formatted ref string and configured colors * @param ref the "ref" JSON node from getAddrRefs */ - RefDescription formatRefDesc(const QSharedPointer &ref); + RefDescription formatRefDesc(const std::shared_ptr &ref); /** * @brief Get a list of a given process's threads * @param pid The pid of the process, -1 for the currently debugged process @@ -587,7 +662,7 @@ public: * @param profilePath Path to the GDB profile * @return Converted profile string */ - QString convertGDBProfile(const QString &profilePath); + QString convertGdbProfile(const QString &profilePath); /** * @brief Retrieves the current register profile string @@ -601,12 +676,12 @@ public: QList getBreakpointsInFunction(RVA funcAddr); QString getActiveDebugPlugin(); QStringList getDebugPlugins(); - void setDebugPlugin(QString plugin); + void setDebugPlugin(const QString &plugin); bool isDebugTaskInProgress(); /** * @brief Check if we can use output/input redirection with the currently debugged process */ - bool isRedirectableDebugee(); + bool isRedirectableDebugee() const; bool currentlyDebugging = false; bool currentlyEmulating = false; bool currentlyTracing = false; @@ -633,7 +708,7 @@ public: CutterJson getSignatureInfo(); bool existsFileInfo(); void setGraphEmpty(bool empty); - bool isGraphEmpty(); + bool isGraphEmpty() const; void getRegs(); QList regs; @@ -672,7 +747,7 @@ public: QList getAllRelocs(); QList getAllStrings(); QList getAllFlagspaces(); - QList getAllFlags(QString flagspace = QString()); + QList getAllFlags(const QString &flagspace = QString()); QList getAllSections(); QList getAllSegments(); QList getAllEntrypoint(); @@ -717,7 +792,7 @@ public: * @param name - the name or the type of the given Type * @return The type decleration as C output */ - QString getTypeAsC(QString name); + QString getTypeAsC(const QString &name); /** * @brief Check if a type exists using its name @@ -740,7 +815,7 @@ public: bool isAddressMapped(RVA addr); QList getMemoryMap(); - QList getAllSearch(QString searchFor, SearchKind kind, QString in); + QList getAllSearch(QString searchFor, SearchKind kind, const QString &in); QList getBreakpoints(); /** * @brief Get list of processes attachable by debugger @@ -776,7 +851,8 @@ public: * @return A list of XrefDescriptions that contains details of all the writes or reads that * happen to the variable 'variableName'. */ - QList getXRefsForVariable(QString variableName, bool findWrites, RVA offset); + QList getXRefsForVariable(const QString &variableName, bool findWrites, + RVA offset); QList getXRefs(RVA addr, bool to, bool whole_function, const QString &filterType = QString()); /** @@ -849,6 +925,12 @@ public: */ bool isWriteModeEnabled(); + /** + * @brief Check if there are modified blocks in the IO cache that haven't been saved + * @return true if the cache contains "dirty" (unwritten) data, false otherwise. + */ + bool hasUncommitedChanges(); + /** * @brief Returns the textual version of global or specific graph. * @param type Graph type, example RZ_CORE_GRAPH_TYPE_FUNCALL or RZ_CORE_GRAPH_TYPE_IMPORT @@ -866,7 +948,8 @@ public: * RZ_CORE_GRAPH_TYPE_IMPORT * @param address The object address (if global set it to RVA_INVALID) */ - void writeGraphvizGraphToFile(QString path, QString format, RzCoreGraphType type, RVA address); + void writeGraphvizGraphToFile(const QString &path, const QString &format, RzCoreGraphType type, + RVA address); signals: void refreshAll(); @@ -924,10 +1007,10 @@ signals: /** * @brief seekChanged is emitted each time Rizin's seek value is modified - * @param offset - * @param historyType + * @param offset Offset to seek at + * @param historyType Type of seek history */ - void seekChanged(RVA offset, SeekHistoryType type = SeekHistoryType::New); + void seekChanged(RVA offset, CutterCore::SeekHistoryType type = SeekHistoryType::New); void toggleDebugView(); @@ -947,7 +1030,7 @@ private: * Internal reference to the RzCore. * NEVER use this directly! Always use the CORE_LOCK(); macro and access it like core->... */ - RzCore *core_ = nullptr; + RzCore *rzCore = nullptr; #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) QMutex coreMutex; #else @@ -967,12 +1050,13 @@ private: bool iocache = false; BasicInstructionHighlighter biHighlighter; - QSharedPointer debugTask; + std::shared_ptr debugTask; RizinTaskDialog *debugTaskDialog; QVector getCutterRCFilePaths() const; QList getBaseType(RzBaseTypeKind kind, const char *category); - QList getAllSearchCommand(QString searchFor, SearchKind kind, QString in); + QList getAllSearchCommand(const QString &searchFor, SearchKind kind, + const QString &in); QList convertMarks(RzList *marks); /** * @brief Collect cross-references for the specified local variable @@ -994,7 +1078,7 @@ public: explicit RzCoreLocked(CutterCore *core); RzCoreLocked(const RzCoreLocked &) = delete; RzCoreLocked &operator=(const RzCoreLocked &) = delete; - RzCoreLocked(RzCoreLocked &&); + RzCoreLocked(RzCoreLocked &&) noexcept; ~RzCoreLocked(); operator RzCore *() &; RzCore *operator->() &; diff --git a/src/core/CutterCommon.h b/src/core/CutterCommon.h index 15130ac8..fd5111a1 100644 --- a/src/core/CutterCommon.h +++ b/src/core/CutterCommon.h @@ -1,13 +1,13 @@ -/** \file CutterCommon.h +/** @file CutterCommon.h * This file contains any definition that is useful in the whole project. * For example, it may contain custom types (RVA, ut64), list iterators, etc. */ #ifndef CUTTERCORE_H #define CUTTERCORE_H -#include "rz_core.h" +#include "rz_core.h" // IWYU pragma: keep + #include -#include "RizinCpp.h" // Workaround for compile errors on Windows #ifdef Q_OS_WIN @@ -46,19 +46,19 @@ typedef quint64 RVA; */ #define RVA_INVALID RVA_MAX -inline QString RzAddressString(RVA addr) +inline QString rzAddressString(RVA addr) { - return QString::asprintf("%#010" PFMT64x, addr); + return QString::asprintf("%#010llx", static_cast(addr)); } -inline QString RzSizeString(RVA size) +inline QString rzSizeString(RVA size) { - return QString::asprintf("%#" PFMT64x, size); + return QString::asprintf("%#llx", static_cast(size)); } -inline QString RzHexString(RVA size) +inline QString rzHexString(RVA size) { - return QString::asprintf("%#" PFMT64x, size); + return QString::asprintf("%#llx", static_cast(size)); } #ifdef CUTTER_SOURCE_BUILD diff --git a/src/core/CutterDescriptions.h b/src/core/CutterDescriptions.h index 1d44ae90..9e920252 100644 --- a/src/core/CutterDescriptions.h +++ b/src/core/CutterDescriptions.h @@ -1,17 +1,18 @@ -/** \file CutterDescriptions.h +/** @file CutterDescriptions.h * This file contains every structure description that are used in widgets. * The descriptions are used for the Qt metatypes. */ #ifndef DESCRIPTIONS_H #define DESCRIPTIONS_H -#include -#include -#include -#include -#include #include "core/CutterCommon.h" +#include +#include +#include +#include +#include + struct FunctionDescription { RVA offset; @@ -49,7 +50,7 @@ struct ExportDescription RVA size; QString type; QString name; - QString flag_name; + QString flagName; }; struct HeaderDescription @@ -62,14 +63,14 @@ struct HeaderDescription struct FlirtDescription { - QString bin_name; - QString arch_name; - QString arch_bits; - QString base_name; - QString short_path; - QString file_path; + QString binName; + QString archName; + QString archBits; + QString baseName; + QString shortPath; + QString filePath; QString details; - QString n_modules; + QString nModules; }; struct TypeDescription @@ -168,9 +169,9 @@ struct EntrypointDescription struct XrefDescription { RVA from; - QString from_str; + QString fromStr; RVA to; - QString to_str; + QString toStr; QString type; }; @@ -318,7 +319,7 @@ struct MemoryMapDescription struct BreakpointDescription { - enum PositionType { + enum PositionType : ut8 { Address, Named, Module, @@ -401,11 +402,11 @@ struct Arena RVA offset; QString type; quint64 top; - quint64 last_remainder; + quint64 lastRemainder; quint64 next; - quint64 next_free; - quint64 system_mem; - quint64 max_system_mem; + quint64 nextFree; + quint64 systemMem; + quint64 maxSystemMem; }; struct BasefindCoreStatusDescription diff --git a/src/core/CutterJson.cpp b/src/core/CutterJson.cpp index dc6667c0..fb81f58d 100644 --- a/src/core/CutterJson.cpp +++ b/src/core/CutterJson.cpp @@ -2,7 +2,7 @@ CutterJson CutterJson::last() const { - if (!has_children()) { + if (!hasChildren()) { return CutterJson(); } diff --git a/src/core/CutterJson.h b/src/core/CutterJson.h index e733ca6c..b16a8a03 100644 --- a/src/core/CutterJson.h +++ b/src/core/CutterJson.h @@ -3,29 +3,34 @@ #include "core/CutterCommon.h" -#include #include #include + +#include #include +#include class CutterJsonOwner; +/** + * @brief Cutter wrapper for handling Json + */ class CUTTER_EXPORT CutterJson { public: - class iterator + class Iterator { public: - iterator(const RzJson *value, QSharedPointer owner) - : value(value), owner(owner) + Iterator(const RzJson *value, std::shared_ptr owner) + : value(value), owner(std::move(owner)) { } CutterJson operator*() const { return CutterJson(value, owner); } - bool operator!=(const iterator &other) const { return value != other.value; } + bool operator!=(const Iterator &other) const { return value != other.value; } - iterator &operator++() + Iterator &operator++() { value = value->next; return *this; @@ -33,19 +38,19 @@ public: private: const RzJson *value; - QSharedPointer owner; + std::shared_ptr owner; }; - CutterJson() : value(nullptr), owner(nullptr) {} + CutterJson() : value(nullptr) {} - CutterJson(const RzJson *value, QSharedPointer owner) - : value(value), owner(owner) + CutterJson(const RzJson *value, std::shared_ptr owner) + : value(value), owner(std::move(owner)) { } CutterJson first() const { - return CutterJson(has_children() ? value->children.first : nullptr, owner); + return CutterJson(hasChildren() ? value->children.first : nullptr, owner); } CutterJson last() const; @@ -62,12 +67,12 @@ public: value && value->type == RZ_JSON_OBJECT ? rz_json_get(value, key) : nullptr, owner); } - iterator begin() const + Iterator begin() const { - return iterator(has_children() ? value->children.first : nullptr, owner); + return Iterator(hasChildren() ? value->children.first : nullptr, owner); } - iterator end() const { return iterator(nullptr, nullptr); } + Iterator end() const { return Iterator(nullptr, nullptr); } bool toBool() const { return value && value->type == RZ_JSON_BOOLEAN && value->num.u_value; } st64 toSt64() const { return value && value->type == RZ_JSON_INTEGER ? value->num.s_value : 0; } @@ -85,19 +90,19 @@ public: QString key() const { return value ? value->key : QString(); } QStringList keys() const; - size_t size() const { return has_children() ? value->children.count : 0; } + size_t size() const { return hasChildren() ? value->children.count : 0; } RzJsonType type() const { return value ? value->type : RZ_JSON_NULL; } bool valid() const { return value ? true : false; } const RzJson *lowLevelValue() const { return value; } private: - bool has_children() const + bool hasChildren() const { return value && (value->type == RZ_JSON_OBJECT || value->type == RZ_JSON_ARRAY); } const RzJson *value; - QSharedPointer owner; + std::shared_ptr owner; }; class CUTTER_EXPORT CutterJsonOwner diff --git a/src/core/MainWindow.cpp b/src/core/MainWindow.cpp index e2134d3b..a3c31d9e 100644 --- a/src/core/MainWindow.cpp +++ b/src/core/MainWindow.cpp @@ -1,79 +1,76 @@ #include "core/MainWindow.h" + #include "ui_MainWindow.h" // Common Headers +#include "CutterApplication.h" +#include "CutterConfig.h" #include "common/AnalysisTask.h" #include "common/BugReporting.h" -#include "common/Highlighter.h" #include "common/Helpers.h" -#include "common/SvgIconEngine.h" -#include "common/ProgressIndicator.h" -#include "common/TempConfig.h" -#include "common/RunScriptTask.h" #include "common/PythonManager.h" +#include "common/RunScriptTask.h" +#include "common/SvgIconEngine.h" +#include "common/TempConfig.h" #include "plugins/CutterPlugin.h" #include "plugins/PluginManager.h" -#include "CutterConfig.h" -#include "CutterApplication.h" #include "shortcuts/ShortcutManager.h" +#include "widgets/ProgressIndicator.h" // Dialogs -#include "dialogs/WelcomeDialog.h" -#include "dialogs/NewFileDialog.h" -#include "dialogs/InitialOptionsDialog.h" -#include "dialogs/CommentsDialog.h" #include "dialogs/AboutDialog.h" -#include "dialogs/preferences/PreferencesDialog.h" -#include "dialogs/MapFileDialog.h" #include "dialogs/AsyncTaskDialog.h" +#include "dialogs/CommentsDialog.h" +#include "dialogs/InitialOptionsDialog.h" #include "dialogs/LayoutManager.h" +#include "dialogs/MapFileDialog.h" +#include "dialogs/NewFileDialog.h" +#include "dialogs/WelcomeDialog.h" +#include "dialogs/preferences/PreferencesDialog.h" // Widgets Headers +#include "widgets/BacktraceWidget.h" +#include "widgets/BreakpointWidget.h" +#include "widgets/CallGraph.h" +#include "widgets/ClassesWidget.h" +#include "widgets/CommentsWidget.h" +#include "widgets/ConsoleWidget.h" +#include "widgets/Dashboard.h" +#include "widgets/DebugActions.h" +#include "widgets/DecompilerWidget.h" #include "widgets/DisassemblerGraphView.h" -#include "widgets/GraphView.h" -#include "widgets/GraphWidget.h" -#include "widgets/GlobalsWidget.h" -#include "widgets/OverviewWidget.h" -#include "widgets/OverviewView.h" +#include "widgets/DisassemblyWidget.h" +#include "widgets/EntrypointWidget.h" +#include "widgets/ExportsWidget.h" +#include "widgets/FlagsWidget.h" +#include "widgets/FlirtWidget.h" #include "widgets/FunctionsWidget.h" +#include "widgets/GlobalsWidget.h" +#include "widgets/GraphWidget.h" +#include "widgets/HeadersWidget.h" +#include "widgets/HeapDockWidget.h" +#include "widgets/HexdumpWidget.h" +#include "widgets/ImportsWidget.h" +#include "widgets/MemoryMapWidget.h" +#include "widgets/Omnibar.h" +#include "widgets/OverviewWidget.h" +#include "widgets/ProcessesWidget.h" +#include "widgets/RegisterRefsWidget.h" +#include "widgets/RegistersWidget.h" +#include "widgets/RelocsWidget.h" +#include "widgets/ResourcesWidget.h" +#include "widgets/RizinGraphWidget.h" +#include "widgets/SdbWidget.h" +#include "widgets/SearchWidget.h" #include "widgets/SectionsWidget.h" #include "widgets/SegmentsWidget.h" -#include "widgets/CommentsWidget.h" -#include "widgets/ImportsWidget.h" -#include "widgets/ExportsWidget.h" -#include "widgets/TypesWidget.h" -#include "widgets/SearchWidget.h" -#include "widgets/SymbolsWidget.h" -#include "widgets/StringsWidget.h" -#include "widgets/RelocsWidget.h" -#include "widgets/FlagsWidget.h" -#include "widgets/VisualNavbar.h" -#include "widgets/Dashboard.h" -#include "widgets/SdbWidget.h" -#include "widgets/Omnibar.h" -#include "widgets/ConsoleWidget.h" -#include "widgets/EntrypointWidget.h" -#include "widgets/ClassesWidget.h" -#include "widgets/ResourcesWidget.h" -#include "widgets/VTablesWidget.h" -#include "widgets/HeadersWidget.h" -#include "widgets/FlirtWidget.h" -#include "widgets/DebugActions.h" -#include "widgets/MemoryMapWidget.h" -#include "widgets/BreakpointWidget.h" -#include "widgets/RegisterRefsWidget.h" -#include "widgets/DisassemblyWidget.h" #include "widgets/StackWidget.h" +#include "widgets/StringsWidget.h" +#include "widgets/SymbolsWidget.h" #include "widgets/ThreadsWidget.h" -#include "widgets/ProcessesWidget.h" -#include "widgets/RegistersWidget.h" -#include "widgets/BacktraceWidget.h" -#include "widgets/HexdumpWidget.h" -#include "widgets/DecompilerWidget.h" -#include "widgets/HexWidget.h" -#include "widgets/RizinGraphWidget.h" -#include "widgets/CallGraph.h" -#include "widgets/HeapDockWidget.h" +#include "widgets/TypesWidget.h" +#include "widgets/VTablesWidget.h" +#include "widgets/VisualNavbar.h" // Qt Headers #include @@ -88,29 +85,28 @@ #include #include #include +#include +#include +#include #include #include #include #include #include #include -#include -#include -#include -#include - #include #include #include #include -#include #include +#include +#include +#include #include -#include #include #include #include -#include +#include // Graphics #include @@ -129,10 +125,13 @@ T *getNewInstance(MainWindow *m) using namespace Cutter; MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent), core(Core()), ui(new Ui::MainWindow), ioModesController(this) + : QMainWindow(parent), + core(Core()), + tabsOnTop(false), + ui(new Ui::MainWindow), + ioModesController(this), + configuration(Config()) { - tabsOnTop = false; - configuration = Config(); initUI(); } @@ -174,23 +173,22 @@ void MainWindow::initUI() */ // Period goes to command entry - QShortcut *cmd_shortcut = Shortcuts()->makeQShortcut("Console.focusConsole", this); - connect(cmd_shortcut, &QShortcut::activated, consoleDock, &ConsoleWidget::focusInputLineEdit); + const QShortcut *cmdShortcut = Shortcuts()->makeQShortcut("Console.focusConsole", this); + connect(cmdShortcut, &QShortcut::activated, consoleDock, &ConsoleWidget::focusInputLineEdit); // S goes to goto entry - QShortcut *seek_shortcut = Shortcuts()->makeQShortcut("General.seek", this); - connect(seek_shortcut, &QShortcut::activated, this->omnibar, + const QShortcut *seekShortcut = Shortcuts()->makeQShortcut("General.seek", this); + connect(seekShortcut, &QShortcut::activated, this->omnibar, [this]() { this->omnibar->setFocus(); }); - QShortcut *seek_to_func_end_shortcut = + const QShortcut *seekToFuncEndShortcut = Shortcuts()->makeQShortcut("General.seekToFunctionEnd", this); - connect(seek_to_func_end_shortcut, &QShortcut::activated, this, + connect(seekToFuncEndShortcut, &QShortcut::activated, this, &MainWindow::seekToFunctionLastInstruction); - QShortcut *seek_to_func_start_shortcut = + const QShortcut *seekToFuncStartShortcut = Shortcuts()->makeQShortcut("General.seekToFunctionStart", this); - connect(seek_to_func_start_shortcut, &QShortcut::activated, this, - &MainWindow::seekToFunctionStart); + connect(seekToFuncStartShortcut, &QShortcut::activated, this, &MainWindow::seekToFunctionStart); - Shortcuts()->setupAction(*ui->actionRefresh_contents, "General.refreshContents"); + Shortcuts()->setupAction(*ui->actionRefreshContents, "General.refreshContents"); connect(ui->actionZoomIn, &QAction::triggered, this, &MainWindow::onZoomIn); connect(ui->actionZoomOut, &QAction::triggered, this, &MainWindow::onZoomOut); @@ -222,7 +220,7 @@ void MainWindow::initUI() connect(core, &CutterCore::ioModeChanged, this, &MainWindow::setAvailableIOModeOptions); - QActionGroup *ioModeActionGroup = new QActionGroup(this); + auto *ioModeActionGroup = new QActionGroup(this); ioModeActionGroup->addAction(ui->actionCacheMode); ioModeActionGroup->addAction(ui->actionWriteMode); @@ -285,14 +283,14 @@ void MainWindow::initToolBar() chooseThemeIcons(); // Sepparator between undo/redo and goto lineEdit - QWidget *spacer3 = new QWidget(); + auto *spacer3 = new QWidget(); spacer3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); spacer3->setStyleSheet("background-color: rgba(0,0,0,0)"); spacer3->setMinimumSize(20, 20); spacer3->setMaximumWidth(100); ui->mainToolBar->addWidget(spacer3); - DebugActions *debugActions = new DebugActions(ui->mainToolBar, this); + const auto *debugActions = new DebugActions(ui->mainToolBar, this); // Debug menu auto debugViewAction = ui->menuDebug->addAction(tr("View")); debugViewAction->setMenu(ui->menuAddDebugWidgets); @@ -316,7 +314,7 @@ void MainWindow::initToolBar() ui->menuDebug->addAction(debugActions->actionTrace); // Sepparator between undo/redo and goto lineEdit - QWidget *spacer4 = new QWidget(); + auto *spacer4 = new QWidget(); spacer4->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); spacer4->setStyleSheet("background-color: rgba(0,0,0,0)"); spacer4->setMinimumSize(10, 10); @@ -328,7 +326,7 @@ void MainWindow::initToolBar() ui->mainToolBar->addWidget(this->omnibar); // Add special separators to the toolbar that expand to separate groups of elements - QWidget *spacer2 = new QWidget(); + auto *spacer2 = new QWidget(); spacer2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); spacer2->setStyleSheet("background-color: rgba(0,0,0,0)"); spacer2->setMinimumSize(10, 10); @@ -336,7 +334,7 @@ void MainWindow::initToolBar() ui->mainToolBar->addWidget(spacer2); // Separator between back/forward and undo/redo buttons - QWidget *spacer = new QWidget(); + auto *spacer = new QWidget(); spacer->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); spacer->setStyleSheet("background-color: rgba(0,0,0,0)"); spacer->setMinimumSize(20, 20); @@ -346,7 +344,7 @@ void MainWindow::initToolBar() tasksProgressIndicator->setStyleSheet("background-color: rgba(0,0,0,0)"); ui->mainToolBar->addWidget(tasksProgressIndicator); - QWidget *spacerEnd = new QWidget(); + auto *spacerEnd = new QWidget(); spacerEnd->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); spacerEnd->setStyleSheet("background-color: rgba(0,0,0,0)"); spacerEnd->setMinimumSize(4, 0); @@ -362,6 +360,46 @@ void MainWindow::initToolBar() [this]() { this->visualNavbar->updateGraphicsScene(); }); QObject::connect(configuration, &Configuration::interfaceThemeChanged, this, &MainWindow::chooseThemeIcons); + + connect(ui->actionNew, &QAction::triggered, this, &MainWindow::onActionNewTriggered); + connect(ui->actionSave, &QAction::triggered, this, &MainWindow::onActionSaveTriggered); + connect(ui->actionSaveAs, &QAction::triggered, this, &MainWindow::onActionSaveAsTriggered); + connect(ui->actionQuit, &QAction::triggered, this, &MainWindow::onActionQuitTriggered); + + connect(ui->actionBaseFind, &QAction::triggered, this, &MainWindow::onActionBaseFindTriggered); + connect(ui->actionBackward, &QAction::triggered, this, &MainWindow::onActionBackwardTriggered); + connect(ui->actionForward, &QAction::triggered, this, &MainWindow::onActionForwardTriggered); + connect(ui->actionRefreshContents, &QAction::triggered, this, + &MainWindow::onActionRefreshContentsTriggered); + connect(ui->actionPreferences, &QAction::triggered, this, + &MainWindow::onActionPreferencesTriggered); + + connect(ui->actionRefreshPanels, &QAction::triggered, this, + &MainWindow::onActionRefreshPanelsTriggered); + connect(ui->actionDefaultLayout, &QAction::triggered, this, + &MainWindow::onActionDefaultTriggered); + connect(ui->actionTabsOnTop, &QAction::triggered, this, + &MainWindow::onActionTabsOnTopTriggered); + connect(ui->actionGroupedDockDragging, &QAction::toggled, this, + &MainWindow::onActionGroupedDockDraggingTriggered); + + connect(ui->actionDisasAddComment, &QAction::triggered, this, + &MainWindow::onActionDisasAddCommentTriggered); + connect(ui->actionMap, &QAction::triggered, this, &MainWindow::onActionMapTriggered); + connect(ui->actionImportPdb, &QAction::triggered, this, + &MainWindow::onActionImportPdbTriggered); + connect(ui->actionExportAsCode, &QAction::triggered, this, + &MainWindow::onActionExportAsCodeTriggered); + connect(ui->actionApplySigFromFile, &QAction::triggered, this, + &MainWindow::onActionApplySigFromFileTriggered); + connect(ui->actionCreateNewSig, &QAction::triggered, this, + &MainWindow::onActionCreateNewSigTriggered); + + connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::onActionAboutTriggered); + connect(ui->actionIssue, &QAction::triggered, this, &MainWindow::onActionIssueTriggered); + connect(ui->actionResetSettings, &QAction::triggered, this, + &MainWindow::onActionResetSettingsTriggered); + connect(ui->actionTheme, &QAction::triggered, this, &MainWindow::chooseThemeIcons); } void MainWindow::initDocks() @@ -384,17 +422,17 @@ void MainWindow::initDocks() commentsDock = new CommentsWidget(this); stringsDock = new StringsWidget(this); - QList debugDocks = { stackDock = new StackWidget(this), - threadsDock = new ThreadsWidget(this), - processesDock = new ProcessesWidget(this), - backtraceDock = new BacktraceWidget(this), - registersDock = new RegistersWidget(this), - memoryMapDock = new MemoryMapWidget(this), - breakpointDock = new BreakpointWidget(this), - registerRefsDock = new RegisterRefsWidget(this), - heapDock = new HeapDockWidget(this) }; + const QList debugDocks = { stackDock = new StackWidget(this), + threadsDock = new ThreadsWidget(this), + processesDock = new ProcessesWidget(this), + backtraceDock = new BacktraceWidget(this), + registersDock = new RegistersWidget(this), + memoryMapDock = new MemoryMapWidget(this), + breakpointDock = new BreakpointWidget(this), + registerRefsDock = new RegisterRefsWidget(this), + heapDock = new HeapDockWidget(this) }; - QList infoDocks = { + const QList infoDocks = { classesDock = new ClassesWidget(this), entrypointDock = new EntrypointWidget(this), exportsDock = new ExportsWidget(this), @@ -415,7 +453,7 @@ void MainWindow::initDocks() globalCallGraphDock = new CallGraphWidget(this, true), }; - auto makeActionList = [this](QList docks) { + auto makeActionList = [this](const QList &docks) { QList result; for (auto dock : docks) { if (dock != nullptr) { @@ -429,12 +467,12 @@ void MainWindow::initDocks() return result; }; - QList windowDocks = { + const QList windowDocks = { dashboardDock, nullptr, functionsDock, overviewDock, nullptr, searchDock, stringsDock, typesDock, nullptr, }; ui->menuWindows->insertActions(ui->actionExtraDecompiler, makeActionList(windowDocks)); - QList windowDocks2 = { + const QList windowDocks2 = { consoleDock, commentsDock, nullptr, @@ -463,7 +501,7 @@ void MainWindow::toggleOverview(bool visibility, GraphWidget *targetGraph) void MainWindow::updateTasksIndicator() { - bool running = core->getAsyncTaskManager()->getTasksRunning(); + const bool running = core->getAsyncTaskManager()->getTasksRunning(); tasksProgressIndicator->setProgressIndicatorVisible(running); } @@ -541,7 +579,7 @@ void MainWindow::openNewFile(InitialOptions &options, bool skipOptionsDialog) /* Prompt to load filename.rz script */ if (options.script.isEmpty()) { - QString script = QString("%1.rz").arg(this->filename); + const QString script = QString("%1.rz").arg(this->filename); if (rz_file_exists(script.toStdString().data())) { QMessageBox mb(this); mb.setWindowTitle(tr("Script loading")); @@ -569,13 +607,6 @@ void MainWindow::openNewFileFailed() mb.exec(); } -/** - * @brief displays the WelocmeDialog - * - * Upon first execution of Cutter, the WelcomeDialog would be showed to the user. - * The Welcome dialog would be showed after a reset of Cutter's preferences by the user. - */ - void MainWindow::displayWelcomeDialog() { WelcomeDialog w; @@ -584,7 +615,7 @@ void MainWindow::displayWelcomeDialog() void MainWindow::displayNewFileDialog() { - NewFileDialog *n = new NewFileDialog(this); + auto *n = new NewFileDialog(this); newFileDialog = n; n->setAttribute(Qt::WA_DeleteOnClose); n->show(); @@ -665,7 +696,7 @@ void MainWindow::finalizeOpen() dockWidget->hide(); } - QSettings settings; + const QSettings settings; auto geometry = settings.value("geometry").toByteArray(); if (!geometry.isEmpty()) { restoreGeometry(geometry); @@ -675,7 +706,7 @@ void MainWindow::finalizeOpen() } Config()->adjustColorThemeDarkness(); - setViewLayout(getViewLayout(LAYOUT_DEFAULT)); + setViewLayout(getViewLayout(layoutDefault)); // Set focus to disasm or graph widget // Graph with function in it has focus priority over DisasmWidget. @@ -707,7 +738,7 @@ void MainWindow::finalizeOpen() RzProjectErr MainWindow::saveProject(bool *canceled) { - QString file = core->getConfig("prj.file"); + const QString file = core->getConfig("prj.file"); if (file.isEmpty()) { return saveProjectAs(canceled); } @@ -715,7 +746,7 @@ RzProjectErr MainWindow::saveProject(bool *canceled) *canceled = false; } auto rizin = core->lock(); - RzProjectErr err = rz_project_save_file(rizin, file.toUtf8().constData(), false); + const RzProjectErr err = rz_project_save_file(rizin, file.toUtf8().constData(), false); if (err == RZ_PROJECT_ERR_SUCCESS) { Config()->addRecentProject(file); } @@ -733,8 +764,8 @@ RzProjectErr MainWindow::saveProjectAs(bool *canceled) QFileDialog fileDialog(this); // Append 'rzdb' suffix if it does not exist fileDialog.setDefaultSuffix("rzdb"); - QString file = fileDialog.getSaveFileName(this, tr("Save Project"), projectFile, - tr("Rizin Project (*.rzdb)")); + const QString file = fileDialog.getSaveFileName(this, tr("Save Project"), projectFile, + tr("Rizin Project (*.rzdb)")); if (file.isEmpty()) { if (canceled) { *canceled = true; @@ -745,7 +776,7 @@ RzProjectErr MainWindow::saveProjectAs(bool *canceled) *canceled = false; } auto rizin = core->lock(); - RzProjectErr err = rz_project_save_file(rizin, file.toUtf8().constData(), false); + const RzProjectErr err = rz_project_save_file(rizin, file.toUtf8().constData(), false); if (err == RZ_PROJECT_ERR_SUCCESS) { Config()->addRecentProject(file); } @@ -781,7 +812,7 @@ void MainWindow::closeEvent(QCloseEvent *event) activateWindow(); - QMessageBox::StandardButton ret = QMessageBox::question( + const QMessageBox::StandardButton ret = QMessageBox::question( this, APPNAME, tr("Do you really want to exit?\nSave your project before closing!"), (QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel)); @@ -792,13 +823,13 @@ void MainWindow::closeEvent(QCloseEvent *event) if (ret == QMessageBox::Save) { bool canceled; - RzProjectErr save_err = saveProject(&canceled); + const RzProjectErr saveErr = saveProject(&canceled); if (canceled) { event->ignore(); return; - } else if (save_err != RZ_PROJECT_ERR_SUCCESS) { + } else if (saveErr != RZ_PROJECT_ERR_SUCCESS) { event->ignore(); - showProjectSaveError(save_err); + showProjectSaveError(saveErr); return; } } @@ -833,9 +864,9 @@ void MainWindow::readSettings() lockDocks(settings.value("panelLock").toBool()); tabsOnTop = settings.value("tabsOnTop").toBool(); setTabLocation(); - bool dockGroupedDragging = settings.value("docksGroupedDragging", false).toBool(); - ui->actionGrouped_dock_dragging->setChecked(dockGroupedDragging); - on_actionGrouped_dock_dragging_triggered(dockGroupedDragging); + const bool dockGroupedDragging = settings.value("docksGroupedDragging", false).toBool(); + ui->actionGroupedDockDragging->setChecked(dockGroupedDragging); + onActionGroupedDockDraggingTriggered(dockGroupedDragging); loadLayouts(settings); } @@ -846,10 +877,10 @@ void MainWindow::saveSettings() settings.setValue("panelLock", !ui->actionUnlock->isChecked()); settings.setValue("tabsOnTop", tabsOnTop); - settings.setValue("docksGroupedDragging", ui->actionGrouped_dock_dragging->isChecked()); + settings.setValue("docksGroupedDragging", ui->actionGroupedDockDragging->isChecked()); settings.setValue("geometry", saveGeometry()); - layouts[Core()->currentlyDebugging ? LAYOUT_DEBUG : LAYOUT_DEFAULT] = getViewLayout(); + layouts[Core()->currentlyDebugging ? layoutDebug : layoutDefault] = getViewLayout(); saveLayouts(settings); } @@ -857,10 +888,10 @@ void MainWindow::setTabLocation() { if (tabsOnTop) { this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); - ui->actionTabs_on_Top->setChecked(true); + ui->actionTabsOnTop->setChecked(true); } else { this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South); - ui->actionTabs_on_Top->setChecked(false); + ui->actionTabsOnTop->setChecked(false); } } @@ -1040,7 +1071,7 @@ MemoryDockWidget *MainWindow::getOrCreateMemoryWidget(MemoryWidgetType type, RVA QMenu *MainWindow::createShowInMenu(QWidget *parent, RVA address, AddressTypeHint addressType) { - QMenu *menu = new QMenu(parent); + auto *menu = new QMenu(parent); // Memory dock widgets for (auto &dock : dockWidgets) { if (auto memoryWidget = qobject_cast(dock)) { @@ -1050,7 +1081,7 @@ QMenu *MainWindow::createShowInMenu(QWidget *parent, RVA address, AddressTypeHin continue; } } - QAction *action = new QAction(memoryWidget->windowTitle(), menu); + auto *action = new QAction(memoryWidget->windowTitle(), menu); connect(action, &QAction::triggered, this, [memoryWidget, address]() { memoryWidget->getSeekable()->seek(address); memoryWidget->raiseMemoryWidget(); @@ -1065,7 +1096,7 @@ QMenu *MainWindow::createShowInMenu(QWidget *parent, RVA address, AddressTypeHin if (qobject_cast(dock)) { continue; } - QAction *action = new QAction(memoryWidget->windowTitle(), menu); + auto *action = new QAction(memoryWidget->windowTitle(), menu); connect(action, &QAction::triggered, this, [memoryWidget, address]() { memoryWidget->getSeekable()->seek(address); memoryWidget->raiseMemoryWidget(); @@ -1074,8 +1105,9 @@ QMenu *MainWindow::createShowInMenu(QWidget *parent, RVA address, AddressTypeHin } } menu->addSeparator(); - auto createAddNewWidgetAction = [this, menu, address](QString label, MemoryWidgetType type) { - QAction *action = new QAction(label, menu); + auto createAddNewWidgetAction = [this, menu, address](const QString &label, + MemoryWidgetType type) { + auto *action = new QAction(label, menu); connect(action, &QAction::triggered, this, [this, address, type]() { addNewMemoryWidget(type, address, false); }); menu->addAction(action); @@ -1105,7 +1137,7 @@ MemoryDockWidget *MainWindow::getLastMemoryWidget() void MainWindow::showAddress(RVA addr) { if (lastMemoryWidget && lastMemoryWidget->getType() == MemoryWidgetType::Graph) { - AddressTypeHint addressType = core->getAddressType(addr); + const AddressTypeHint addressType = core->getAddressType(addr); MemoryWidgetType targetType; if (addressType == AddressTypeHint::Data) { @@ -1156,18 +1188,18 @@ MemoryDockWidget *MainWindow::addNewMemoryWidget(MemoryWidgetType type, RVA addr void MainWindow::initBackForwardMenu() { auto prepareButtonMenu = [this](QAction *action) -> QMenu * { - QToolButton *button = qobject_cast(ui->mainToolBar->widgetForAction(action)); + auto *button = qobject_cast(ui->mainToolBar->widgetForAction(action)); if (!button) { return nullptr; } - QMenu *menu = new QMenu(button); + auto *menu = new QMenu(button); button->setMenu(menu); button->setPopupMode(QToolButton::DelayedPopup); button->setContextMenuPolicy(Qt::CustomContextMenu); connect(button, &QWidget::customContextMenuRequested, button, [menu, button](const QPoint &pos) { menu->exec(button->mapToGlobal(pos)); }); - QFontMetrics metrics(font()); + const QFontMetrics metrics(font()); // Roughly 10-16 lines depending on padding size, no need to calculate more precisely menu->setMaximumHeight(metrics.lineSpacing() * 20); @@ -1190,44 +1222,44 @@ void MainWindow::updateHistoryMenu(QMenu *menu, bool redo) { // Not too long so that whole screen doesn't get covered, // not too short so that reasonable length c++ names can be seen most of the time - const int MAX_NAME_LENGTH = 64; + const int maxNameLength = 64; RzListIter *it; RzCoreSeekItem *undo; RzCoreLocked core(Core()); - RzList *list = rz_core_seek_list(core); + const RzList *list = rz_core_seek_list(core); bool history = true; QList actions; CutterRzListForeach (list, it, RzCoreSeekItem, undo) { - RzFlagItem *f = rz_flag_get_at(core->flags, undo->offset, true); - char *fname = NULL; + const RzFlagItem *f = rz_flag_get_at(core->flags, undo->offset, true); + const char *fname = nullptr; if (f) { if (f->offset != undo->offset) { - qint64 diff = undo->offset - f->offset; + const qint64 diff = undo->offset - f->offset; fname = rz_str_newf("%s+%" PFMT64d, f->name, diff); } else { fname = strdup(f->name); } } QString name = fname; - RVA offset = undo->offset; - bool current = undo->is_current; + const RVA offset = undo->offset; + const bool current = undo->is_current; if (current) { history = false; } if (history != redo || current) { // Include current in both directions - QString addressString = RzAddressString(offset); + const QString addressString = rzAddressString(offset); - QString toolTip = + const QString toolTip = QString("%1 %2").arg(addressString, name); // show non truncated name in tooltip - name.truncate(MAX_NAME_LENGTH); // TODO:#1904 use common name shortening function + name.truncate(maxNameLength); // TODO:#1904 use common name shortening function QString label = QString("%1 (%2)").arg(name, addressString); if (current) { label = tr("current position (%1)").arg(addressString); } - QAction *action = new QAction(label, menu); + auto *action = new QAction(label, menu); action->setToolTip(toolTip); actions.push_back(action); if (current) { @@ -1243,7 +1275,7 @@ void MainWindow::updateHistoryMenu(QMenu *menu, bool redo) menu->clear(); menu->addActions(actions); int steps = 0; - for (QAction *item : menu->actions()) { + for (const QAction *item : menu->actions()) { if (redo) { connect(item, &QAction::triggered, item, [steps]() { for (int i = 0; i < steps; i++) { @@ -1265,7 +1297,7 @@ void MainWindow::updateLayoutsMenu() { ui->menuLayouts->clear(); for (auto it = layouts.begin(), end = layouts.end(); it != end; ++it) { - QString name = it.key(); + const QString &name = it.key(); if (isBuiltinLayoutName(name)) { continue; } @@ -1281,8 +1313,8 @@ void MainWindow::saveNamedLayout() bool ok = false; QString name; QStringList names = layouts.keys(); - names.removeAll(LAYOUT_DEBUG); - names.removeAll(LAYOUT_DEFAULT); + names.removeAll(layoutDebug); + names.removeAll(layoutDefault); while (name.isEmpty() || isBuiltinLayoutName(name)) { if (ok) { QMessageBox::warning(this, tr("Save layout error"), @@ -1425,7 +1457,7 @@ CutterLayout MainWindow::getViewLayout() if (auto cutterDock = qobject_cast(dock)) { properties = cutterDock->serializeViewProprties(); } - layout.viewProperties.insert(dock->objectName(), std::move(properties)); + layout.viewProperties.insert(dock->objectName(), properties); } return layout; } @@ -1441,8 +1473,8 @@ CutterLayout MainWindow::getViewLayout(const QString &name) void MainWindow::setViewLayout(const CutterLayout &layout) { - bool isDefault = layout.state.isEmpty() || layout.geometry.isEmpty(); - bool isDebug = Core()->currentlyDebugging; + const bool isDefault = layout.state.isEmpty() || layout.geometry.isEmpty(); + const bool isDebug = Core()->currentlyDebugging; // make a copy to avoid iterating over container from which items are being removed auto widgetsToClose = dockWidgets; @@ -1521,11 +1553,11 @@ void MainWindow::setViewLayout(const CutterLayout &layout) void MainWindow::loadLayouts(QSettings &settings) { this->layouts.clear(); - int size = settings.beginReadArray("layouts"); + const int size = settings.beginReadArray("layouts"); for (int i = 0; i < size; i++) { CutterLayout layout; settings.setArrayIndex(i); - QString name = settings.value("name", "layout").toString(); + const QString name = settings.value("name", "layout").toString(); layout.geometry = settings.value("geometry").toByteArray(); layout.state = settings.value("state").toByteArray(); @@ -1534,7 +1566,7 @@ void MainWindow::loadLayouts(QSettings &settings) layout.viewProperties.insert(it.key(), it.value().toMap()); } - layouts.insert(name, std::move(layout)); + layouts.insert(name, layout); } settings.endArray(); updateLayoutsMenu(); @@ -1560,38 +1592,34 @@ void MainWindow::saveLayouts(QSettings &settings) settings.endArray(); } -void MainWindow::on_actionDefault_triggered() +void MainWindow::onActionDefaultTriggered() { if (core->currentlyDebugging) { - layouts[LAYOUT_DEBUG] = {}; - setViewLayout(layouts[LAYOUT_DEBUG]); + layouts[layoutDebug] = {}; + setViewLayout(layouts[layoutDebug]); } else { - layouts[LAYOUT_DEFAULT] = {}; - setViewLayout(layouts[LAYOUT_DEFAULT]); + layouts[layoutDefault] = {}; + setViewLayout(layouts[layoutDefault]); } } -/** - * @brief MainWindow::on_actionNew_triggered - * Open a new Cutter session. - */ -void MainWindow::on_actionNew_triggered() +void MainWindow::onActionNewTriggered() { // Create a new Cutter process static_cast(qApp)->launchNewInstance(); } -void MainWindow::on_actionSave_triggered() +void MainWindow::onActionSaveTriggered() { showProjectSaveError(saveProject(nullptr)); } -void MainWindow::on_actionSaveAs_triggered() +void MainWindow::onActionSaveAsTriggered() { showProjectSaveError(saveProjectAs(nullptr)); } -void MainWindow::on_actionRun_Script_triggered() +void MainWindow::onActionRunScriptTriggered() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::ExistingFile); @@ -1600,15 +1628,16 @@ void MainWindow::on_actionRun_Script_triggered() const QString &fileName = QDir::toNativeSeparators(dialog.getOpenFileName(this, tr("Select Rizin script"))); - if (fileName.isEmpty()) // Cancel was pressed + if (fileName.isEmpty()) { // Cancel was pressed return; + } - RunScriptTask *runScriptTask = new RunScriptTask(); + auto *runScriptTask = new RunScriptTask(); runScriptTask->setFileName(fileName); - AsyncTask::Ptr runScriptTaskPtr(runScriptTask); + const AsyncTask::Ptr runScriptTaskPtr(runScriptTask); - AsyncTaskDialog *taskDialog = new AsyncTaskDialog(runScriptTaskPtr, this); + auto *taskDialog = new AsyncTaskDialog(runScriptTaskPtr, this); taskDialog->setInterruptOnClose(true); taskDialog->setAttribute(Qt::WA_DeleteOnClose); taskDialog->show(); @@ -1616,11 +1645,7 @@ void MainWindow::on_actionRun_Script_triggered() Core()->getAsyncTaskManager()->start(runScriptTaskPtr); } -/** - * @brief MainWindow::on_actionOpen_triggered - * Open a file as in "load (add) a file in current session". - */ -void MainWindow::on_actionMap_triggered() +void MainWindow::onActionMapTriggered() { MapFileDialog dialog(this); dialog.exec(); @@ -1634,50 +1659,50 @@ void MainWindow::toggleResponsive(bool maybe) settings.setValue("responsive", this->responsive); } -void MainWindow::on_actionTabs_on_Top_triggered() +void MainWindow::onActionTabsOnTopTriggered() { - this->on_actionTabs_triggered(); + this->onActionTabsTriggered(); } -void MainWindow::on_actionReset_settings_triggered() +void MainWindow::onActionResetSettingsTriggered() { - QMessageBox::StandardButton ret = (QMessageBox::StandardButton)QMessageBox::question( + const QMessageBox::StandardButton ret = (QMessageBox::StandardButton)QMessageBox::question( this, APPNAME, tr("Do you really want to clear all settings?"), QMessageBox::Ok | QMessageBox::Cancel); if (ret == QMessageBox::Ok) { Config()->resetAll(); readSettings(); - setViewLayout(getViewLayout(Core()->currentlyDebugging ? LAYOUT_DEBUG : LAYOUT_DEFAULT)); + setViewLayout(getViewLayout(Core()->currentlyDebugging ? layoutDebug : layoutDefault)); } } -void MainWindow::on_actionQuit_triggered() +void MainWindow::onActionQuitTriggered() { close(); } -void MainWindow::on_actionBackward_triggered() +void MainWindow::onActionBackwardTriggered() { core->seekPrev(); } -void MainWindow::on_actionForward_triggered() +void MainWindow::onActionForwardTriggered() { core->seekNext(); } -void MainWindow::on_actionDisasAdd_comment_triggered() +void MainWindow::onActionDisasAddCommentTriggered() { CommentsDialog c(this); c.exec(); } -void MainWindow::on_actionRefresh_contents_triggered() +void MainWindow::onActionRefreshContentsTriggered() { refreshAll(); } -void MainWindow::on_actionPreferences_triggered() +void MainWindow::onActionPreferencesTriggered() { if (!findChild()) { auto dialog = new PreferencesDialog(this); @@ -1685,26 +1710,26 @@ void MainWindow::on_actionPreferences_triggered() } } -void MainWindow::on_actionTabs_triggered() +void MainWindow::onActionTabsTriggered() { tabsOnTop = !tabsOnTop; setTabLocation(); } -void MainWindow::on_actionBaseFind_triggered() +void MainWindow::onActionBaseFindTriggered() { auto dialog = new BaseFindDialog(this); dialog->show(); } -void MainWindow::on_actionAbout_triggered() +void MainWindow::onActionAboutTriggered() { - AboutDialog *a = new AboutDialog(this); + auto *a = new AboutDialog(this); a->setAttribute(Qt::WA_DeleteOnClose); a->open(); } -void MainWindow::on_actionIssue_triggered() +void MainWindow::onActionIssueTriggered() { openIssue(); } @@ -1714,21 +1739,18 @@ void MainWindow::documentationClicked() QDesktopServices::openUrl(QUrl("https://cutter.re/docs/user-docs")); } -void MainWindow::on_actionRefresh_Panels_triggered() +void MainWindow::onActionRefreshPanelsTriggered() { this->refreshAll(); } -/** - * @brief A signal that creates an AsyncTask to re-analyze the current file - */ -void MainWindow::on_actionAnalyze_triggered() +void MainWindow::onActionAnalyzeTriggered() const { auto *analysisTask = new AnalysisTask(); InitialOptions options; options.analysisCmd = { { "aaa", QT_TRANSLATE_NOOP("InitialOptionsDialog", "Auto analysis") } }; analysisTask->setOptions(options); - AsyncTask::Ptr analysisTaskPtr(analysisTask); + const AsyncTask::Ptr analysisTaskPtr(analysisTask); auto *taskDialog = new AsyncTaskDialog(analysisTaskPtr); taskDialog->setInterruptOnClose(true); @@ -1739,7 +1761,7 @@ void MainWindow::on_actionAnalyze_triggered() Core()->getAsyncTaskManager()->start(analysisTaskPtr); } -void MainWindow::on_actionImportPDB_triggered() +void MainWindow::onActionImportPdbTriggered() { QFileDialog dialog(this); dialog.setWindowTitle(tr("Select PDB file")); @@ -1758,11 +1780,11 @@ void MainWindow::on_actionImportPDB_triggered() } } -void MainWindow::on_actionExport_as_code_triggered() +void MainWindow::onActionExportAsCodeTriggered() { QStringList filters; QMap typMap; - const bool big_endian = Core()->getConfigb("big_endian"); + const bool bigEndian = Core()->getConfigb("big_endian"); filters << tr("C uin8_t array (*.c)"); typMap[filters.last()] = RZ_LANG_BYTE_ARRAY_C_CPP_BYTES; @@ -1770,11 +1792,11 @@ void MainWindow::on_actionExport_as_code_triggered() #define TYPE_BIG_ENDIAN(type, big_endian) big_endian ? type##_BE : type##_LE filters << tr("C uin16_t array (*.c)"); - typMap[filters.last()] = TYPE_BIG_ENDIAN(RZ_LANG_BYTE_ARRAY_C_CPP_HALFWORDS, big_endian); + typMap[filters.last()] = TYPE_BIG_ENDIAN(RZ_LANG_BYTE_ARRAY_C_CPP_HALFWORDS, bigEndian); filters << tr("C uin32_t array (*.c)"); - typMap[filters.last()] = TYPE_BIG_ENDIAN(RZ_LANG_BYTE_ARRAY_C_CPP_WORDS, big_endian); + typMap[filters.last()] = TYPE_BIG_ENDIAN(RZ_LANG_BYTE_ARRAY_C_CPP_WORDS, bigEndian); filters << tr("C uin64_t array (*.c)"); - typMap[filters.last()] = TYPE_BIG_ENDIAN(RZ_LANG_BYTE_ARRAY_C_CPP_DOUBLEWORDS, big_endian); + typMap[filters.last()] = TYPE_BIG_ENDIAN(RZ_LANG_BYTE_ARRAY_C_CPP_DOUBLEWORDS, bigEndian); #undef TYPE_BIG_ENDIAN @@ -1808,7 +1830,7 @@ void MainWindow::on_actionExport_as_code_triggered() filters << tr("Yara (*.yar)"); typMap[filters.last()] = RZ_LANG_BYTE_ARRAY_YARA; /* special case */ - QString instructionsInComments = tr(".bytes with instructions in comments (*.txt)"); + const QString instructionsInComments = tr(".bytes with instructions in comments (*.txt)"); filters << instructionsInComments; QFileDialog dialog(this, tr("Export as code")); @@ -1817,8 +1839,9 @@ void MainWindow::on_actionExport_as_code_triggered() dialog.setNameFilters(filters); dialog.selectFile("dump"); dialog.setDefaultSuffix("c"); - if (!dialog.exec()) + if (!dialog.exec()) { return; + } QFile file(dialog.selectedFiles()[0]); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { @@ -1844,7 +1867,7 @@ void MainWindow::on_actionExport_as_code_triggered() fileOut << string.get(); } -void MainWindow::on_actionApplySigFromFile_triggered() +void MainWindow::onActionApplySigFromFileTriggered() { QStringList filters; filters << tr("Signature File (*.sig)"); @@ -1866,7 +1889,7 @@ void MainWindow::on_actionApplySigFromFile_triggered() } } -void MainWindow::on_actionCreateNewSig_triggered() +void MainWindow::onActionCreateNewSigTriggered() { QStringList filters; filters << tr("Signature File (*.sig)"); @@ -1878,8 +1901,9 @@ void MainWindow::on_actionCreateNewSig_triggered() dialog.setNameFilters(filters); dialog.selectFile(""); dialog.setDefaultSuffix("sig"); - if (!dialog.exec()) + if (!dialog.exec()) { return; + } const QString &sigfile = QDir::toNativeSeparators(dialog.selectedFiles().first()); @@ -1888,7 +1912,7 @@ void MainWindow::on_actionCreateNewSig_triggered() } } -void MainWindow::on_actionGrouped_dock_dragging_triggered(bool checked) +void MainWindow::onActionGroupedDockDraggingTriggered(bool checked) { #if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) auto options = dockOptions(); @@ -1911,14 +1935,14 @@ void MainWindow::seekToFunctionStart() void MainWindow::toggleDebugView() { - MemoryWidgetType memType = getMemoryWidgetTypeToRestore(); + const MemoryWidgetType memType = getMemoryWidgetTypeToRestore(); if (Core()->currentlyDebugging) { - layouts[LAYOUT_DEFAULT] = getViewLayout(); - setViewLayout(getViewLayout(LAYOUT_DEBUG)); + layouts[layoutDefault] = getViewLayout(); + setViewLayout(getViewLayout(layoutDebug)); enableDebugWidgetsMenu(true); } else { - layouts[LAYOUT_DEBUG] = getViewLayout(); - setViewLayout(getViewLayout(LAYOUT_DEFAULT)); + layouts[layoutDebug] = getViewLayout(); + setViewLayout(getViewLayout(layoutDefault)); enableDebugWidgetsMenu(false); } showMemoryWidget(memType); @@ -1949,7 +1973,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event) } if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); + auto *mouseEvent = static_cast(event); if (mouseEvent->button() == Qt::ForwardButton || mouseEvent->button() == Qt::BackButton) { mousePressEvent(mouseEvent); return true; @@ -1972,12 +1996,7 @@ bool MainWindow::event(QEvent *event) return QMainWindow::event(event); } -/** - * @brief Show a warning message box. - * - * This API can either be used in Cutter internals, or by Python plugins. - */ -void MainWindow::messageBoxWarning(QString title, QString message) +void MainWindow::messageBoxWarning(const QString &title, const QString &message) { QMessageBox mb(this); mb.setIcon(QMessageBox::Warning); @@ -1987,9 +2006,6 @@ void MainWindow::messageBoxWarning(QString title, QString message) mb.exec(); } -/** - * @brief When theme changed, change icons which have a special version for the theme. - */ void MainWindow::chooseThemeIcons() { // List of QActions which have alternative icons in different themes diff --git a/src/core/MainWindow.h b/src/core/MainWindow.h index c598d4cb..b336e485 100644 --- a/src/core/MainWindow.h +++ b/src/core/MainWindow.h @@ -1,20 +1,20 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include "core/Cutter.h" // only needed for ut64 +// #include "core/Cutter.h" // only needed for ut64 #include "dialogs/NewFileDialog.h" -#include "dialogs/WelcomeDialog.h" -#include "common/Configuration.h" -#include "common/InitialOptions.h" -#include "common/IOModesController.h" -#include "common/CutterLayout.h" +// #include "dialogs/WelcomeDialog.h" #include "MemoryDockWidget.h" +#include "common/Configuration.h" +#include "common/CutterLayout.h" +#include "common/IOModesController.h" +#include "common/InitialOptions.h" + +#include +#include #include -#include -#include - class CutterCore; class Omnibar; class ProgressIndicator; @@ -61,6 +61,9 @@ namespace Ui { class MainWindow; } +/** + * @brief Cutter main window + */ class CUTTER_EXPORT MainWindow : public QMainWindow { Q_OBJECT @@ -73,6 +76,11 @@ public: void openNewFile(InitialOptions &options, bool skipOptionsDialog = false); void displayNewFileDialog(); + /** + * @brief displays the WelocmeDialog + * Upon first execution of Cutter, the WelcomeDialog would be showed to the user. + * The Welcome dialog would be showed after a reset of Cutter's preferences by the user. + */ void displayWelcomeDialog(); void closeNewFileDialog(); bool openProject(const QString &project_name); @@ -100,7 +108,7 @@ public: addPluginDockWidget(dockWidget); } void addPluginDockWidget(CutterDockWidget *dockWidget); - enum class MenuType { File, Edit, View, Windows, Debug, Help, Plugins }; + enum class MenuType : ut8 { File, Edit, View, Windows, Debug, Help, Plugins }; /** * @brief Getter for MainWindow's different menus * @param type The type which represents the desired menu @@ -110,7 +118,11 @@ public: void addMenuFileAction(QAction *action); QString getFilename() const { return filename; } - void messageBoxWarning(QString title, QString message); + /** + * @brief Show a warning message box. + * This API can either be used in Cutter internals, or by Python plugins. + */ + void messageBoxWarning(const QString &title, const QString &message); QString getUniqueObjectName(const QString &widgetType) const; void showMemoryWidget(); @@ -123,7 +135,7 @@ public: bool synchronized = true); /* Context menu plugins */ - enum class ContextMenuType { Disassembly, Addressable }; + enum class ContextMenuType : ut8 { Disassembly, Addressable }; /** * @brief Fetches the pointer to a context menu extension of type * @param type - the type of the context menu @@ -140,13 +152,16 @@ public slots: void seekToFunctionStart(); void setTabLocation(); - void on_actionTabs_triggered(); + void onActionTabsTriggered(); - void on_actionAnalyze_triggered(); + /** + * @brief A signal that creates an AsyncTask to re-analyze the current file + */ + void onActionAnalyzeTriggered() const; void lockDocks(bool lock); - void on_actionRun_Script_triggered(); + void onActionRunScriptTriggered(); void toggleResponsive(bool maybe); @@ -154,50 +169,58 @@ public slots: void toggleOverview(bool visibility, GraphWidget *targetGraph); private slots: - void on_actionBaseFind_triggered(); - void on_actionAbout_triggered(); - void on_actionIssue_triggered(); + void onActionBaseFindTriggered(); + void onActionAboutTriggered(); + void onActionIssueTriggered(); void documentationClicked(); void addExtraGraph(); void addExtraHexdump(); void addExtraDisassembly(); void addExtraDecompiler(); - void on_actionRefresh_Panels_triggered(); + void onActionRefreshPanelsTriggered(); - void on_actionDisasAdd_comment_triggered(); + void onActionDisasAddCommentTriggered(); - void on_actionDefault_triggered(); + void onActionDefaultTriggered(); - void on_actionNew_triggered(); + /** + * @brief MainWindow::on_actionNew_triggered + * Open a new Cutter session. + */ + void onActionNewTriggered(); - void on_actionSave_triggered(); - void on_actionSaveAs_triggered(); + void onActionSaveTriggered(); + void onActionSaveAsTriggered(); - void on_actionBackward_triggered(); - void on_actionForward_triggered(); + void onActionBackwardTriggered(); + void onActionForwardTriggered(); - void on_actionMap_triggered(); + /** + * @brief MainWindow::on_actionOpen_triggered + * Open a file as in "load (add) a file in current session". + */ + void onActionMapTriggered(); - void on_actionTabs_on_Top_triggered(); + void onActionTabsOnTopTriggered(); - void on_actionReset_settings_triggered(); + void onActionResetSettingsTriggered(); - void on_actionQuit_triggered(); + void onActionQuitTriggered(); - void on_actionRefresh_contents_triggered(); + void onActionRefreshContentsTriggered(); - void on_actionPreferences_triggered(); + void onActionPreferencesTriggered(); - void on_actionImportPDB_triggered(); + void onActionImportPdbTriggered(); - void on_actionExport_as_code_triggered(); + void onActionExportAsCodeTriggered(); - void on_actionApplySigFromFile_triggered(); + void onActionApplySigFromFileTriggered(); - void on_actionCreateNewSig_triggered(); + void onActionCreateNewSigTriggered(); - void on_actionGrouped_dock_dragging_triggered(bool checked); + void onActionGroupedDockDraggingTriggered(bool checked); void updateTasksIndicator(); @@ -205,6 +228,9 @@ private slots: bool eventFilter(QObject *object, QEvent *event) override; bool event(QEvent *event) override; void toggleDebugView(); + /** + * @brief When theme changed, change icons which have a special version for the theme. + */ void chooseThemeIcons(); void onZoomIn(); @@ -301,7 +327,7 @@ private: void enableDebugWidgetsMenu(bool enable); /** * @brief Fill menu with seek history entries. - * @param menu + * @param menu Menu to update * @param redo set to false for undo history, true for redo. */ void updateHistoryMenu(QMenu *menu, bool redo = false); @@ -313,7 +339,7 @@ private: bool isOverviewActive(); /** * @brief Check if a widget is one of debug specific dock widgets. - * @param dock + * @param dock DockWidget to check * @return true for debug specific widgets, false for all other including common dock widgets. */ bool isDebugWidget(QDockWidget *dock) const; diff --git a/src/core/MainWindow.ui b/src/core/MainWindow.ui index 70533651..5661bfe3 100644 --- a/src/core/MainWindow.ui +++ b/src/core/MainWindow.ui @@ -53,8 +53,8 @@ 2024 127 - 151 - 312 + 196 + 389 @@ -74,7 +74,7 @@ - + @@ -85,9 +85,9 @@ - + - + @@ -113,14 +113,14 @@ Layouts - + - - + + - - + + @@ -201,7 +201,7 @@ - Qt::DefaultContextMenu + Qt::ContextMenuPolicy::DefaultContextMenu Main toolbar @@ -216,7 +216,7 @@ - Qt::ToolButtonIconOnly + Qt::ToolButtonStyle::ToolButtonIconOnly TopToolBarArea @@ -227,7 +227,7 @@ - + Reset to default layout @@ -268,7 +268,7 @@ Close - + Save layout @@ -317,7 +317,7 @@ Delete - + Select all @@ -330,7 +330,7 @@ Find - + Find next @@ -338,7 +338,7 @@ Find next - + Find previous @@ -348,7 +348,7 @@ - + :/img/icons/arrow_left.svg:/img/icons/arrow_left.svg @@ -360,7 +360,7 @@ - + :/img/icons/arrow_right.svg:/img/icons/arrow_right.svg @@ -374,16 +374,17 @@ true + + + :/lock + :/unlock:/lock + Unlock Panels Toggle panel locks - - - :/lock:/unlock:/unlock - false @@ -393,7 +394,7 @@ false - + :/img/icons/themes.svg:/img/icons/themes.svg @@ -403,12 +404,12 @@ false - QAction::PreferencesRole + QAction::MenuRole::PreferencesRole - + :/img/icons/tabs.svg:/img/icons/tabs.svg @@ -418,16 +419,16 @@ Tabs up/down - + - + :/img/icons/spin.svg:/img/icons/spin.svg Refresh - + true @@ -438,12 +439,12 @@ Toggle tab position - + Dark Theme - + Load layout @@ -451,7 +452,7 @@ Load layout - + Default Theme @@ -466,12 +467,12 @@ Analysis - + Test menu - + Copy hexpair @@ -479,7 +480,7 @@ Copy hexpair - + Copy text @@ -487,12 +488,12 @@ Copy text - + Copy ASCII - + Insert string @@ -500,7 +501,7 @@ Insert string - + Insert hex @@ -518,17 +519,17 @@ Paste - + Show/Hide bytes - + Switch case - + Copy all @@ -536,7 +537,7 @@ Copy all - + Copy bytes @@ -544,7 +545,7 @@ Copy bytes - + Copy disasm @@ -560,12 +561,12 @@ Copy disasm - + true - + :/img/icons/cloud.svg:/img/icons/cloud.svg @@ -610,7 +611,7 @@ 64 - + Syntax AT&T/Intel @@ -635,17 +636,17 @@ Undefine - + Add comment - + true - + :/img/icons/down.svg:/img/icons/down.svg @@ -655,12 +656,12 @@ Show/Hide bottom panel - + Run Rizin script - + Reset Settings @@ -687,7 +688,7 @@ Show/Hide Exports panel - + Refresh Contents @@ -695,7 +696,7 @@ Refresh contents - + true @@ -703,7 +704,7 @@ Show ESIL rather than assembly - + true @@ -711,7 +712,7 @@ Show pseudocode rather than assembly - + true @@ -740,7 +741,7 @@ Graph - + Import PDB @@ -750,7 +751,7 @@ Analyze Program - + Export as code @@ -785,7 +786,7 @@ Add Graph - + true @@ -804,7 +805,7 @@ Ctrl++ - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut @@ -815,7 +816,7 @@ Ctrl+- - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut @@ -826,7 +827,7 @@ Ctrl+= - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut @@ -880,7 +881,7 @@ - + diff --git a/src/core/RizinCpp.h b/src/core/RizinCpp.h index 33727eaf..b1a39dbd 100644 --- a/src/core/RizinCpp.h +++ b/src/core/RizinCpp.h @@ -1,4 +1,4 @@ -/** \file RizinCpp.h +/** @file RizinCpp.h * Various utilities for easier and safer interactions with Rizin * from C++ code. */ @@ -6,7 +6,9 @@ #define RIZINCPP_H #include "rz_core.h" + #include + #include static inline QString fromOwnedCharPtr(char *str) @@ -59,9 +61,9 @@ static inline auto fromOwned(RZ_OWN RzList *data) -> UniquePtrCPa) \ - for (it = (type *)(vec)->a; \ - (char *)it != (char *)(vec)->a + ((vec)->len * (vec)->elem_size); \ - it = (type *)((char *)it + (vec)->elem_size)) + for (it = static_cast((vec)->a); reinterpret_cast(it) \ + != static_cast((vec)->a) + ((vec)->len * (vec)->elem_size); \ + it = reinterpret_cast(reinterpret_cast(it) + (vec)->elem_size)) template class CutterPVector @@ -70,7 +72,7 @@ private: const RzPVector *const vec; public: - class iterator + class Iterator { public: using iterator_category = std::input_iterator_tag; @@ -83,27 +85,27 @@ public: T **p; public: - iterator(T **p) : p(p) {} - iterator(const iterator &o) : p(o.p) {} - iterator &operator++() + Iterator(T **p) : p(p) {} + Iterator(const Iterator &o) : p(o.p) {} + Iterator &operator++() { p++; return *this; } - iterator operator++(int) + Iterator operator++(int) { - iterator tmp(*this); + Iterator tmp(*this); operator++(); return tmp; } - bool operator==(const iterator &rhs) const { return p == rhs.p; } - bool operator!=(const iterator &rhs) const { return p != rhs.p; } + bool operator==(const Iterator &rhs) const { return p == rhs.p; } + bool operator!=(const Iterator &rhs) const { return p != rhs.p; } T *operator*() { return *p; } }; CutterPVector(const RzPVector *vec) : vec(vec) {} - iterator begin() const { return iterator(reinterpret_cast(vec->v.a)); } - iterator end() const { return iterator(reinterpret_cast(vec->v.a) + vec->v.len); } + Iterator begin() const { return Iterator(reinterpret_cast(vec->v.a)); } + Iterator end() const { return Iterator(reinterpret_cast(vec->v.a) + vec->v.len); } }; template @@ -113,7 +115,7 @@ private: const RzList *const list; public: - class iterator + class Iterator { public: using iterator_category = std::input_iterator_tag; @@ -126,9 +128,9 @@ public: RzListIter *iter; public: - explicit iterator(RzListIter *iter) : iter(iter) {} - iterator(const iterator &o) : iter(o.iter) {} - iterator &operator++() + explicit Iterator(RzListIter *iter) : iter(iter) {} + Iterator(const Iterator &o) : iter(o.iter) {} + Iterator &operator++() { if (!iter) { return *this; @@ -136,14 +138,14 @@ public: iter = iter->next; return *this; } - iterator operator++(int) + Iterator operator++(int) { - iterator tmp(*this); + Iterator tmp(*this); operator++(); return tmp; } - bool operator==(const iterator &rhs) const { return iter == rhs.iter; } - bool operator!=(const iterator &rhs) const { return iter != rhs.iter; } + bool operator==(const Iterator &rhs) const { return iter == rhs.iter; } + bool operator!=(const Iterator &rhs) const { return iter != rhs.iter; } T *operator*() { if (!iter) { @@ -154,14 +156,14 @@ public: }; explicit CutterRzList(const RzList *l) : list(l) {} - iterator begin() const + Iterator begin() const { if (!list) { - return iterator(nullptr); + return Iterator(nullptr); } - return iterator(list->head); + return Iterator(list->head); } - iterator end() const { return iterator(nullptr); } + Iterator end() const { return Iterator(nullptr); } }; template diff --git a/src/dialogs/AboutDialog.cpp b/src/dialogs/AboutDialog.cpp index 705fe42a..90d3ef07 100644 --- a/src/dialogs/AboutDialog.cpp +++ b/src/dialogs/AboutDialog.cpp @@ -1,22 +1,22 @@ -#include "core/Cutter.h" #include "AboutDialog.h" -#include "ui_AboutDialog.h" +#include "CutterConfig.h" #include "RizinPluginsDialog.h" -#include "common/Configuration.h" #include "common/BugReporting.h" +#include "common/Configuration.h" +#include "core/Cutter.h" +#include "ui_AboutDialog.h" -#include -#include #include #include #include #include -#include -#include +#include +#include #include +#include -#include "CutterConfig.h" +#include AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog) { @@ -24,7 +24,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); ui->logoSvgWidget->load(Config()->getLogoFile()); - QString aboutString( + const QString aboutString( tr("Version") + " " CUTTER_VERSION_FULL "
" + tr("Using rizin ") + Core()->getRizinVersionReadable() + "
" + buildQtVersionString() + "

" + tr("Optional Features:") + "
" @@ -55,23 +55,42 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia "page for the full list of contributors.")); ui->label->setText(aboutString); - QSignalBlocker s(ui->updatesCheckBox); + const QSignalBlocker s(ui->updatesCheckBox); ui->updatesCheckBox->setChecked(Config()->getAutoUpdateEnabled()); if (!CUTTER_UPDATE_WORKER_AVAILABLE) { ui->updatesCheckBox->hide(); ui->checkForUpdatesButton->hide(); } + + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &AboutDialog::onButtonBoxRejected); + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + + connect(ui->showVersionButton, &QPushButton::clicked, this, + &AboutDialog::onShowVersionButtonClicked); + connect(ui->showPluginsButton, &QPushButton::clicked, this, + &AboutDialog::onShowPluginsButtonClicked); + connect(ui->issueButton, &QPushButton::clicked, this, &AboutDialog::onIssueClicked); + + connect(ui->checkForUpdatesButton, &QPushButton::clicked, this, + &AboutDialog::onCheckForUpdatesButtonClicked); +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + connect(ui->updatesCheckBox, &QCheckBox::checkStateChanged, this, + &AboutDialog::onUpdatesCheckBoxStateChanged); +#else + connect(ui->updatesCheckBox, &QCheckBox::stateChanged, this, + &AboutDialog::onUpdatesCheckBoxStateChanged); +#endif } AboutDialog::~AboutDialog() {} -void AboutDialog::on_buttonBox_rejected() +void AboutDialog::onButtonBoxRejected() { close(); } -void AboutDialog::on_showVersionButton_clicked() +void AboutDialog::onShowVersionButtonClicked() { QMessageBox popup(this); popup.setWindowTitle(tr("Rizin version information")); @@ -81,17 +100,17 @@ void AboutDialog::on_showVersionButton_clicked() popup.exec(); } -void AboutDialog::on_showPluginsButton_clicked() +void AboutDialog::onShowPluginsButtonClicked() { RizinPluginsDialog dialog(this); dialog.exec(); } -void AboutDialog::on_Issue_clicked() +void AboutDialog::onIssueClicked() { openIssue(); } -void AboutDialog::on_checkForUpdatesButton_clicked() +void AboutDialog::onCheckForUpdatesButtonClicked() { #if CUTTER_UPDATE_WORKER_AVAILABLE UpdateWorker updateWorker; @@ -99,7 +118,7 @@ void AboutDialog::on_checkForUpdatesButton_clicked() auto parentWindow = this; QProgressDialog waitDialog(parentWindow); - QProgressBar *bar = new QProgressBar(&waitDialog); + auto *bar = new QProgressBar(&waitDialog); bar->setMaximum(0); waitDialog.setBar(bar); @@ -125,7 +144,7 @@ void AboutDialog::on_checkForUpdatesButton_clicked() #endif } -void AboutDialog::on_updatesCheckBox_stateChanged(int) +void AboutDialog::onUpdatesCheckBoxStateChanged(int) { Config()->setAutoUpdateEnabled(!Config()->getAutoUpdateEnabled()); } @@ -133,7 +152,7 @@ void AboutDialog::on_updatesCheckBox_stateChanged(int) static QString compilerString() { #if defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too - QString isAppleString; + QString isAppleString; // NOLINT # if defined(__apple_build_version__) // Apple clang has other version numbers isAppleString = QLatin1String(" (Apple)"); # endif @@ -142,12 +161,15 @@ static QString compilerString() #elif defined(Q_CC_GNU) return QLatin1String("GCC ") + QLatin1String(__VERSION__); #elif defined(Q_CC_MSVC) - if (_MSC_VER > 1999) + if (_MSC_VER > 1999) { return QLatin1String("MSVC "); - if (_MSC_VER >= 1910) + } + if (_MSC_VER >= 1910) { return QLatin1String("MSVC 2017"); - if (_MSC_VER >= 1900) + } + if (_MSC_VER >= 1900) { return QLatin1String("MSVC 2015"); + } #endif return QLatin1String(""); } diff --git a/src/dialogs/AboutDialog.h b/src/dialogs/AboutDialog.h index c21baea5..84c753db 100644 --- a/src/dialogs/AboutDialog.h +++ b/src/dialogs/AboutDialog.h @@ -2,13 +2,17 @@ #define ABOUTDIALOG_H #include -#include #include +#include + namespace Ui { class AboutDialog; } +/** + * @brief Dialog that displays memory allocation details and offsets for a specific Arena. + */ class AboutDialog : public QDialog { Q_OBJECT @@ -18,24 +22,20 @@ public: ~AboutDialog(); private slots: - void on_buttonBox_rejected(); - void on_showVersionButton_clicked(); - void on_showPluginsButton_clicked(); - void on_Issue_clicked(); + void onButtonBoxRejected(); + void onShowVersionButtonClicked(); + void onShowPluginsButtonClicked(); + void onIssueClicked(); /** - * @fn AboutDialog::on_checkForUpdatesButton_clicked() - * * @brief Initiates process of checking for updates. */ - void on_checkForUpdatesButton_clicked(); + void onCheckForUpdatesButtonClicked(); /** - * @fn AboutDialog::on_updatesCheckBox_stateChanged(int state) - * * @brief Changes value of autoUpdateEnabled option in settings. */ - void on_updatesCheckBox_stateChanged(int state); + void onUpdatesCheckBoxStateChanged(int state); private: std::unique_ptr ui; diff --git a/src/dialogs/AboutDialog.ui b/src/dialogs/AboutDialog.ui index 13742312..093a9408 100644 --- a/src/dialogs/AboutDialog.ui +++ b/src/dialogs/AboutDialog.ui @@ -17,7 +17,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -30,7 +30,7 @@ - QDialogButtonBox::Close + QDialogButtonBox::StandardButton::Close @@ -68,7 +68,7 @@ - + @@ -81,7 +81,7 @@ - + <html><head/><body><p><span style=" font-size:28pt; font-weight:600;">Cutter</span></p></body></html> @@ -89,7 +89,7 @@ - + 0 @@ -144,7 +144,7 @@ <html><head/><body><p><br/></p></body></html> - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop 5 @@ -153,11 +153,11 @@ true - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse - + true @@ -181,10 +181,10 @@ - Qt::NoFocus + Qt::FocusPolicy::NoFocus - Qt::DefaultContextMenu + Qt::ContextMenuPolicy::DefaultContextMenu 0 diff --git a/src/dialogs/ArenaInfoDialog.cpp b/src/dialogs/ArenaInfoDialog.cpp index 977f58fe..70ad81c1 100644 --- a/src/dialogs/ArenaInfoDialog.cpp +++ b/src/dialogs/ArenaInfoDialog.cpp @@ -1,25 +1,23 @@ #include "ArenaInfoDialog.h" + #include "ui_ArenaInfoDialog.h" ArenaInfoDialog::ArenaInfoDialog(Arena &arena, QWidget *parent) : QDialog(parent), ui(new Ui::ArenaInfoDialog), arena(arena) { ui->setupUi(this); - setWindowTitle("Arena @ " + RzAddressString(arena.offset)); + setWindowTitle("Arena @ " + rzAddressString(arena.offset)); updateContents(); } void ArenaInfoDialog::updateContents() { - ui->lineEditTop->setText(RzAddressString(arena.top)); - ui->lineEditLastRem->setText(RzAddressString(arena.last_remainder)); - ui->lineEditNext->setText(RzAddressString(arena.next)); - ui->lineEditNextfree->setText(RzAddressString(arena.next_free)); - ui->lineEditSysMem->setText(RzAddressString(arena.system_mem)); - ui->lineEditMaxMem->setText(RzAddressString(arena.max_system_mem)); + ui->lineEditTop->setText(rzAddressString(arena.top)); + ui->lineEditLastRem->setText(rzAddressString(arena.lastRemainder)); + ui->lineEditNext->setText(rzAddressString(arena.next)); + ui->lineEditNextfree->setText(rzAddressString(arena.nextFree)); + ui->lineEditSysMem->setText(rzAddressString(arena.systemMem)); + ui->lineEditMaxMem->setText(rzAddressString(arena.maxSystemMem)); } -ArenaInfoDialog::~ArenaInfoDialog() -{ - delete ui; -} +ArenaInfoDialog::~ArenaInfoDialog() {} diff --git a/src/dialogs/ArenaInfoDialog.h b/src/dialogs/ArenaInfoDialog.h index 73f45345..2b531369 100644 --- a/src/dialogs/ArenaInfoDialog.h +++ b/src/dialogs/ArenaInfoDialog.h @@ -2,7 +2,9 @@ #define ARENAINFODIALOG_H #include + #include +#include namespace Ui { class ArenaInfoDialog; @@ -18,7 +20,7 @@ public: void updateContents(); private: - Ui::ArenaInfoDialog *ui; + std::unique_ptr ui; Arena arena; }; diff --git a/src/dialogs/AsyncTaskDialog.cpp b/src/dialogs/AsyncTaskDialog.cpp index bab99edf..55177082 100644 --- a/src/dialogs/AsyncTaskDialog.cpp +++ b/src/dialogs/AsyncTaskDialog.cpp @@ -1,21 +1,21 @@ #include "AsyncTaskDialog.h" -#include "common/AsyncTask.h" +#include "common/AsyncTask.h" #include "ui_AsyncTaskDialog.h" -AsyncTaskDialog::AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent) +AsyncTaskDialog::AsyncTaskDialog(const AsyncTask::Ptr &task, QWidget *parent) : QDialog(parent), ui(new Ui::AsyncTaskDialog), task(task) { ui->setupUi(this); - QString title = task->getTitle(); + const QString title = task->getTitle(); if (!title.isNull()) { setWindowTitle(title); } - connect(task.data(), &AsyncTask::logChanged, this, &AsyncTaskDialog::updateLog); - connect(task.data(), &AsyncTask::finished, this, [this]() { close(); }); + connect(task.get(), &AsyncTask::logChanged, this, &AsyncTaskDialog::updateLog); + connect(task.get(), &AsyncTask::finished, this, [this]() { close(); }); updateLog(task->getLog()); @@ -36,9 +36,9 @@ void AsyncTaskDialog::updateLog(const QString &log) void AsyncTaskDialog::updateProgressTimer() { - int secondsElapsed = (task->getElapsedTime() + 500) / 1000; - int minutesElapsed = secondsElapsed / 60; - int hoursElapsed = minutesElapsed / 60; + const int secondsElapsed = (task->getElapsedTime() + 500) / 1000; + const int minutesElapsed = secondsElapsed / 60; + const int hoursElapsed = minutesElapsed / 60; QString label; if (hoursElapsed) { diff --git a/src/dialogs/AsyncTaskDialog.h b/src/dialogs/AsyncTaskDialog.h index 08431c71..885f3848 100644 --- a/src/dialogs/AsyncTaskDialog.h +++ b/src/dialogs/AsyncTaskDialog.h @@ -1,28 +1,30 @@ - #ifndef ASYNCTASKDIALOG_H #define ASYNCTASKDIALOG_H -#include +#include "common/AsyncTask.h" #include #include -#include "common/AsyncTask.h" +#include namespace Ui { class AsyncTaskDialog; } +/** + * @brief Dialog for displaying progress, logs, and elapsed time @ref AsyncTask + */ class AsyncTaskDialog : public QDialog { Q_OBJECT public: - AsyncTaskDialog(AsyncTask::Ptr task, QWidget *parent = nullptr); + AsyncTaskDialog(const AsyncTask::Ptr &task, QWidget *parent = nullptr); ~AsyncTaskDialog(); void setInterruptOnClose(bool v) { interruptOnClose = v; } - bool getInterruptOnClose() { return interruptOnClose; } + bool getInterruptOnClose() const { return interruptOnClose; } public slots: void reject() override; diff --git a/src/dialogs/AttachProcDialog.cpp b/src/dialogs/AttachProcDialog.cpp index fa2180ec..9ced3a8d 100644 --- a/src/dialogs/AttachProcDialog.cpp +++ b/src/dialogs/AttachProcDialog.cpp @@ -1,9 +1,9 @@ -#include "core/MainWindow.h" -#include "core/Cutter.h" #include "AttachProcDialog.h" -#include "ui_AttachProcDialog.h" #include "common/Helpers.h" +#include "core/Cutter.h" +#include "core/MainWindow.h" +#include "ui_AttachProcDialog.h" #include @@ -36,8 +36,9 @@ int ProcessModel::columnCount(const QModelIndex &) const QVariant ProcessModel::data(const QModelIndex &index, int role) const { - if (index.row() >= processes.count()) + if (index.row() >= processes.count()) { return QVariant(); + } const ProcessDescription &proc = processes.at(index.row()); @@ -123,20 +124,18 @@ QString ProcessBeingAnalysedProxyModel::processPathToFilename(const QString &pat bool ProcessBeingAnalysedProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); - ProcessDescription item = - index.data(ProcessModel::ProcDescriptionRole).value(); + const QModelIndex index = sourceModel()->index(row, 0, parent); + const auto item = index.data(ProcessModel::ProcDescriptionRole).value(); - QString procFilename = processPathToFilename(item.path); + const QString procFilename = processPathToFilename(item.path); return procFilename == processBeingAnalysedFilename; } bool ProcessBeingAnalysedProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - ProcessDescription leftProc = - left.data(ProcessModel::ProcDescriptionRole).value(); - ProcessDescription rightProc = + const auto leftProc = left.data(ProcessModel::ProcDescriptionRole).value(); + const auto rightProc = right.data(ProcessModel::ProcDescriptionRole).value(); return ProcessModel::lessThan(leftProc, rightProc, left.column()); @@ -153,17 +152,15 @@ ProcessProxyModel::ProcessProxyModel(ProcessModel *sourceModel, QObject *parent) bool ProcessProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); - ProcessDescription item = - index.data(ProcessModel::ProcDescriptionRole).value(); + const QModelIndex index = sourceModel()->index(row, 0, parent); + const auto item = index.data(ProcessModel::ProcDescriptionRole).value(); return qhelpers::filterStringContains(item.path, this); } bool ProcessProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - ProcessDescription leftProc = - left.data(ProcessModel::ProcDescriptionRole).value(); - ProcessDescription rightProc = + const auto leftProc = left.data(ProcessModel::ProcDescriptionRole).value(); + const auto rightProc = right.data(ProcessModel::ProcDescriptionRole).value(); return ProcessModel::lessThan(leftProc, rightProc, left.column()); @@ -172,15 +169,17 @@ bool ProcessProxyModel::lessThan(const QModelIndex &left, const QModelIndex &rig // ---------------- // AttachProcDialog // ---------------- -AttachProcDialog::AttachProcDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AttachProcDialog) +AttachProcDialog::AttachProcDialog(QWidget *parent) + : QDialog(parent), + ui(new Ui::AttachProcDialog), + processModel(new ProcessModel(this)), + processProxyModel(new ProcessProxyModel(processModel, this)), + processBeingAnalyzedProxyModel(new ProcessBeingAnalysedProxyModel(processModel, this)), + timer(new QTimer(this)) { ui->setupUi(this); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); - processModel = new ProcessModel(this); - processProxyModel = new ProcessProxyModel(processModel, this); - processBeingAnalyzedProxyModel = new ProcessBeingAnalysedProxyModel(processModel, this); - // View of all processes auto allView = ui->allProcView; allView->setModel(processProxyModel); @@ -201,9 +200,22 @@ AttachProcDialog::AttachProcDialog(QWidget *parent) : QDialog(parent), ui(new Ui &QSortFilterProxyModel::setFilterWildcard); // Update the processes every 'updateIntervalMs' seconds - timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, &AttachProcDialog::updateModelData); timer->start(updateIntervalMs); + + connect(ui->filterLineEdit, &QLineEdit::textChanged, processProxyModel, + &QSortFilterProxyModel::setFilterWildcard); + + connect(allView, &QAbstractItemView::doubleClicked, this, + &AttachProcDialog::onAllProcViewDoubleClicked); + connect(smallView, &QAbstractItemView::doubleClicked, this, + &AttachProcDialog::onProcBeingAnalyzedViewDoubleClicked); + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, + &AttachProcDialog::onButtonBoxAccepted); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, + &AttachProcDialog::onButtonBoxRejected); } AttachProcDialog::~AttachProcDialog() @@ -222,8 +234,8 @@ void AttachProcDialog::updateModelData() // Save the old selection and scroll position so that we can update and // model and then restore it. - bool allViewHadSelection = allView->selectionModel()->hasSelection(); - bool smallViewHadSelection = smallView->selectionModel()->hasSelection(); + const bool allViewHadSelection = allView->selectionModel()->hasSelection(); + const bool smallViewHadSelection = smallView->selectionModel()->hasSelection(); int allViewPrevScrollPos = 0; int smallViewPrevScrollPos = 0; int allViewPrevPID = 0; @@ -278,9 +290,9 @@ void AttachProcDialog::updateModelData() } } -void AttachProcDialog::on_buttonBox_accepted() {} +void AttachProcDialog::onButtonBoxAccepted() {} -void AttachProcDialog::on_buttonBox_rejected() +void AttachProcDialog::onButtonBoxRejected() { close(); } @@ -329,14 +341,14 @@ int AttachProcDialog::getPID() return pid; } -void AttachProcDialog::on_allProcView_doubleClicked(const QModelIndex &index) +void AttachProcDialog::onAllProcViewDoubleClicked(const QModelIndex &index) { Q_UNUSED(index); accept(); } -void AttachProcDialog::on_procBeingAnalyzedView_doubleClicked(const QModelIndex &index) +void AttachProcDialog::onProcBeingAnalyzedViewDoubleClicked(const QModelIndex &index) { Q_UNUSED(index); diff --git a/src/dialogs/AttachProcDialog.h b/src/dialogs/AttachProcDialog.h index 6f60d459..5f17d2bc 100644 --- a/src/dialogs/AttachProcDialog.h +++ b/src/dialogs/AttachProcDialog.h @@ -1,12 +1,14 @@ #pragma once #include "core/Cutter.h" -#include -#include + #include +#include #include #include +#include + namespace Ui { class AttachProcDialog; } @@ -26,7 +28,7 @@ public: enum Column { PidColumn = 0, UidColumn, StatusColumn, PathColumn, ColumnCount }; enum Role { ProcDescriptionRole = Qt::UserRole }; - ProcessModel(QObject *parent = 0); + ProcessModel(QObject *parent = nullptr); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; @@ -68,6 +70,9 @@ private: QString processPathToFilename(const QString &path) const; }; +/** + * @brief Dialog for selecting and attaching to a running process for debugging + */ class AttachProcDialog : public QDialog { Q_OBJECT @@ -79,10 +84,10 @@ public: int getPID(); private slots: - void on_buttonBox_accepted(); - void on_buttonBox_rejected(); - void on_allProcView_doubleClicked(const QModelIndex &index); - void on_procBeingAnalyzedView_doubleClicked(const QModelIndex &index); + void onButtonBoxAccepted(); + void onButtonBoxRejected(); + void onAllProcViewDoubleClicked(const QModelIndex &index); + void onProcBeingAnalyzedViewDoubleClicked(const QModelIndex &index); void updateModelData(); private: diff --git a/src/dialogs/BreakpointsDialog.cpp b/src/dialogs/BreakpointsDialog.cpp index c4c3108a..ea3a54e2 100644 --- a/src/dialogs/BreakpointsDialog.cpp +++ b/src/dialogs/BreakpointsDialog.cpp @@ -1,11 +1,12 @@ #include "BreakpointsDialog.h" -#include "ui_BreakpointsDialog.h" + #include "Cutter.h" #include "Helpers.h" +#include "ui_BreakpointsDialog.h" -#include -#include #include +#include +#include BreakpointsDialog::BreakpointsDialog(bool editMode, QWidget *parent) : QDialog(parent), ui(new Ui::BreakpointsDialog), editMode(editMode) @@ -67,7 +68,7 @@ BreakpointsDialog::BreakpointsDialog(const BreakpointDescription &breakpoint, QW { switch (breakpoint.type) { case BreakpointDescription::Address: - ui->breakpointPosition->setText(RzAddressString(breakpoint.addr)); + ui->breakpointPosition->setText(rzAddressString(breakpoint.addr)); break; case BreakpointDescription::Named: ui->breakpointPosition->setText(breakpoint.positionExpression); @@ -102,7 +103,7 @@ BreakpointsDialog::BreakpointsDialog(RVA address, QWidget *parent) : BreakpointsDialog(false, parent) { if (address != RVA_INVALID) { - ui->breakpointPosition->setText(RzAddressString(address)); + ui->breakpointPosition->setText(rzAddressString(address)); } refreshOkButton(); } @@ -166,7 +167,8 @@ void BreakpointsDialog::refreshOkButton() void BreakpointsDialog::onTypeChanged() { - bool moduleEnabled = ui->positionType->currentData() == QVariant(BreakpointDescription::Module); + const bool moduleEnabled = + ui->positionType->currentData() == QVariant(BreakpointDescription::Module); ui->moduleLabel->setEnabled(moduleEnabled); ui->moduleName->setEnabled(moduleEnabled); ui->breakpointPosition->setPlaceholderText( diff --git a/src/dialogs/BreakpointsDialog.h b/src/dialogs/BreakpointsDialog.h index 6b267b56..ff960957 100644 --- a/src/dialogs/BreakpointsDialog.h +++ b/src/dialogs/BreakpointsDialog.h @@ -1,13 +1,18 @@ #pragma once -#include -#include #include "CutterDescriptions.h" +#include + +#include + namespace Ui { class BreakpointsDialog; } +/** + * @brief Dialog for creating and editing software or hardware breakpoints + */ class BreakpointsDialog : public QDialog { Q_OBJECT diff --git a/src/dialogs/CommentsDialog.cpp b/src/dialogs/CommentsDialog.cpp index 4d362d4f..99c29661 100644 --- a/src/dialogs/CommentsDialog.cpp +++ b/src/dialogs/CommentsDialog.cpp @@ -1,10 +1,10 @@ #include "CommentsDialog.h" + +#include "core/Cutter.h" #include "ui_CommentsDialog.h" #include -#include "core/Cutter.h" - CommentsDialog::CommentsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::CommentsDialog) { ui->setupUi(this); @@ -12,13 +12,16 @@ CommentsDialog::CommentsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Co // Event filter for capturing Ctrl/Cmd+Return ui->textEdit->installEventFilter(this); + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &CommentsDialog::onButtonBoxAccepted); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &CommentsDialog::onButtonBoxRejected); } CommentsDialog::~CommentsDialog() {} -void CommentsDialog::on_buttonBox_accepted() {} +void CommentsDialog::onButtonBoxAccepted() {} -void CommentsDialog::on_buttonBox_rejected() +void CommentsDialog::onButtonBoxRejected() { close(); } @@ -40,9 +43,9 @@ void CommentsDialog::addOrEditComment(RVA offset, QWidget *parent) CommentsDialog dialog(parent); if (comment.isNull() || comment.isEmpty()) { - dialog.setWindowTitle(tr("Add Comment at %1").arg(RzAddressString(offset))); + dialog.setWindowTitle(tr("Add Comment at %1").arg(rzAddressString(offset))); } else { - dialog.setWindowTitle(tr("Edit Comment at %1").arg(RzAddressString(offset))); + dialog.setWindowTitle(tr("Edit Comment at %1").arg(rzAddressString(offset))); } dialog.setComment(comment); @@ -59,7 +62,7 @@ void CommentsDialog::addOrEditComment(RVA offset, QWidget *parent) bool CommentsDialog::eventFilter(QObject * /*obj*/, QEvent *event) { if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); + const auto *keyEvent = static_cast(event); // Confirm comment by pressing Ctrl/Cmd+Return if ((keyEvent->modifiers() & Qt::ControlModifier) diff --git a/src/dialogs/CommentsDialog.h b/src/dialogs/CommentsDialog.h index e5650e00..63cae0cd 100644 --- a/src/dialogs/CommentsDialog.h +++ b/src/dialogs/CommentsDialog.h @@ -1,15 +1,19 @@ #ifndef COMMENTSDIALOG_H #define COMMENTSDIALOG_H -#include -#include - #include "core/CutterCommon.h" +#include + +#include + namespace Ui { class CommentsDialog; } +/** + * @brief Dialog for adding or editing code comments at a specific address + */ class CommentsDialog : public QDialog { Q_OBJECT @@ -23,9 +27,9 @@ public: static void addOrEditComment(RVA offset, QWidget *parent); private slots: - void on_buttonBox_accepted(); + void onButtonBoxAccepted(); - void on_buttonBox_rejected(); + void onButtonBoxRejected(); private: std::unique_ptr ui; diff --git a/src/dialogs/EditFunctionDialog.cpp b/src/dialogs/EditFunctionDialog.cpp index 72deac29..f20e8bc0 100644 --- a/src/dialogs/EditFunctionDialog.cpp +++ b/src/dialogs/EditFunctionDialog.cpp @@ -1,4 +1,5 @@ #include "EditFunctionDialog.h" + #include "ui_EditFunctionDialog.h" EditFunctionDialog::EditFunctionDialog(QWidget *parent) @@ -6,6 +7,11 @@ EditFunctionDialog::EditFunctionDialog(QWidget *parent) { ui->setupUi(this); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, + &EditFunctionDialog::onButtonBoxAccepted); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, + &EditFunctionDialog::onButtonBoxRejected); } EditFunctionDialog::~EditFunctionDialog() {} @@ -58,9 +64,9 @@ QString EditFunctionDialog::getCallConSelected() return ui->callConComboBox->currentText(); } -void EditFunctionDialog::on_buttonBox_accepted() {} +void EditFunctionDialog::onButtonBoxAccepted() {} -void EditFunctionDialog::on_buttonBox_rejected() +void EditFunctionDialog::onButtonBoxRejected() { close(); } diff --git a/src/dialogs/EditFunctionDialog.h b/src/dialogs/EditFunctionDialog.h index ef69e939..15fabe4f 100644 --- a/src/dialogs/EditFunctionDialog.h +++ b/src/dialogs/EditFunctionDialog.h @@ -2,12 +2,16 @@ #define EDITFUNCTIONDIALOG_H #include + #include namespace Ui { class EditFunctionDialog; } +/** + * @brief Dialog for editing functions + */ class EditFunctionDialog : public QDialog { Q_OBJECT @@ -28,9 +32,9 @@ public: QString getCallConSelected(); private slots: - void on_buttonBox_accepted(); + void onButtonBoxAccepted(); - void on_buttonBox_rejected(); + void onButtonBoxRejected(); private: std::unique_ptr ui; diff --git a/src/dialogs/EditInstructionDialog.cpp b/src/dialogs/EditInstructionDialog.cpp index 041aea91..14fa2ace 100644 --- a/src/dialogs/EditInstructionDialog.cpp +++ b/src/dialogs/EditInstructionDialog.cpp @@ -1,6 +1,7 @@ #include "EditInstructionDialog.h" -#include "ui_EditInstructionDialog.h" + #include "core/Cutter.h" +#include "ui_EditInstructionDialog.h" #include @@ -19,13 +20,18 @@ EditInstructionDialog::EditInstructionDialog(InstructionEditMode editMode, QWidg setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); connect(ui->lineEdit, &QLineEdit::textEdited, this, &EditInstructionDialog::updatePreview); + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, + &EditInstructionDialog::onButtonBoxAccepted); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, + &EditInstructionDialog::onButtonBoxRejected); } EditInstructionDialog::~EditInstructionDialog() {} -void EditInstructionDialog::on_buttonBox_accepted() {} +void EditInstructionDialog::onButtonBoxAccepted() {} -void EditInstructionDialog::on_buttonBox_rejected() +void EditInstructionDialog::onButtonBoxRejected() { close(); } @@ -59,10 +65,10 @@ void EditInstructionDialog::updatePreview(const QString &input) ui->instructionLabel->setText(""); return; } else if (editMode == EDIT_BYTES) { - QByteArray data = CutterCore::hexStringToBytes(input); + const QByteArray data = CutterCore::hexStringToBytes(input); result = Core()->disassemble(data).replace('\n', "; "); } else if (editMode == EDIT_TEXT) { - QByteArray data = Core()->assemble(input); + const QByteArray data = Core()->assemble(input); result = CutterCore::bytesToHexString(data).trimmed(); } diff --git a/src/dialogs/EditInstructionDialog.h b/src/dialogs/EditInstructionDialog.h index 1235a734..a6c5d1bb 100644 --- a/src/dialogs/EditInstructionDialog.h +++ b/src/dialogs/EditInstructionDialog.h @@ -1,15 +1,21 @@ #ifndef EDITINSTRUCTIONDIALOG_H #define EDITINSTRUCTIONDIALOG_H +#include "CutterDescriptions.h" // IWYU pragma: keep + #include + #include namespace Ui { class EditInstructionDialog; } -enum InstructionEditMode { EDIT_NONE, EDIT_BYTES, EDIT_TEXT }; +enum InstructionEditMode : ut8 { EDIT_NONE, EDIT_BYTES, EDIT_TEXT }; +/** + * @brief Dialog for editing instructions + */ class EditInstructionDialog : public QDialog { Q_OBJECT @@ -23,8 +29,8 @@ public: bool needsNops() const; private slots: - void on_buttonBox_accepted(); - void on_buttonBox_rejected(); + void onButtonBoxAccepted(); + void onButtonBoxRejected(); void updatePreview(const QString &input); diff --git a/src/dialogs/EditMethodDialog.cpp b/src/dialogs/EditMethodDialog.cpp index 9637b69b..b6d4b964 100644 --- a/src/dialogs/EditMethodDialog.cpp +++ b/src/dialogs/EditMethodDialog.cpp @@ -1,4 +1,7 @@ #include "EditMethodDialog.h" + +#include "Cutter.h" +#include "RizinCpp.h" #include "ui_EditMethodDialog.h" #include @@ -23,26 +26,38 @@ EditMethodDialog::EditMethodDialog(bool classFixed, QWidget *parent) updateVirtualUI(); validateInput(); +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + connect(ui->virtualCheckBox, &QCheckBox::checkStateChanged, this, + &EditMethodDialog::updateVirtualUI); + connect(ui->autoRenameCheckBox, &QCheckBox::checkStateChanged, this, + &EditMethodDialog::updateAutoRenameEnabled); +#else connect(ui->virtualCheckBox, &QCheckBox::stateChanged, this, &EditMethodDialog::updateVirtualUI); - connect(ui->nameEdit, &QLineEdit::textChanged, this, &EditMethodDialog::validateInput); - connect(ui->realNameEdit, &QLineEdit::textChanged, this, &EditMethodDialog::updateName); connect(ui->autoRenameCheckBox, &QCheckBox::stateChanged, this, &EditMethodDialog::updateAutoRenameEnabled); +#endif + connect(ui->nameEdit, &QLineEdit::textChanged, this, &EditMethodDialog::validateInput); + connect(ui->realNameEdit, &QLineEdit::textChanged, this, &EditMethodDialog::updateName); + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, + &EditMethodDialog::onButtonBoxAccepted); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, + &EditMethodDialog::onButtonBoxRejected); } EditMethodDialog::~EditMethodDialog() {} -void EditMethodDialog::on_buttonBox_accepted() {} +void EditMethodDialog::onButtonBoxAccepted() {} -void EditMethodDialog::on_buttonBox_rejected() +void EditMethodDialog::onButtonBoxRejected() { close(); } void EditMethodDialog::updateVirtualUI() { - bool enabled = ui->virtualCheckBox->isChecked(); + const bool enabled = ui->virtualCheckBox->isChecked(); ui->vtableOffsetEdit->setEnabled(enabled); ui->vtableOffsetLabel->setEnabled(enabled); } @@ -98,7 +113,7 @@ void EditMethodDialog::setClass(const QString &className) } for (int i = 0; i < classComboBox->count(); i++) { - QString cls = classComboBox->itemData(i).toString(); + const QString cls = classComboBox->itemData(i).toString(); if (cls == className) { classComboBox->setCurrentIndex(i); break; @@ -116,7 +131,7 @@ void EditMethodDialog::setMethod(const AnalysisMethodDescription &desc) { ui->nameEdit->setText(desc.name); ui->realNameEdit->setText(desc.realName); - ui->addressEdit->setText(desc.addr != RVA_INVALID ? RzAddressString(desc.addr) : nullptr); + ui->addressEdit->setText(desc.addr != RVA_INVALID ? rzAddressString(desc.addr) : nullptr); if (desc.vtableOffset >= 0) { ui->virtualCheckBox->setChecked(true); @@ -127,7 +142,7 @@ void EditMethodDialog::setMethod(const AnalysisMethodDescription &desc) } // Check if auto-rename should be enabled - bool enableAutoRename = ui->nameEdit->text().isEmpty() + const bool enableAutoRename = ui->nameEdit->text().isEmpty() || ui->nameEdit->text() == convertRealNameToName(ui->realNameEdit->text()); ui->autoRenameCheckBox->setChecked(enableAutoRename); @@ -143,7 +158,7 @@ void EditMethodDialog::setMethod(const AnalysisMethodDescription &desc) QString EditMethodDialog::getClass() const { if (classComboBox) { - int index = classComboBox->currentIndex(); + const int index = classComboBox->currentIndex(); if (index < 0) { return nullptr; } @@ -174,7 +189,7 @@ bool EditMethodDialog::showDialog(const QString &title, bool classFixed, QString dialog.setWindowTitle(title); dialog.setClass(*className); dialog.setMethod(*desc); - int result = dialog.exec(); + const int result = dialog.exec(); *className = dialog.getClass(); *desc = dialog.getMethod(); return result == QDialog::DialogCode::Accepted; diff --git a/src/dialogs/EditMethodDialog.h b/src/dialogs/EditMethodDialog.h index 7da8aab3..eaf39976 100644 --- a/src/dialogs/EditMethodDialog.h +++ b/src/dialogs/EditMethodDialog.h @@ -1,16 +1,22 @@ #ifndef EDITMETHODDIALOG_H #define EDITMETHODDIALOG_H -#include -#include +#include "CutterDescriptions.h" -#include "core/Cutter.h" +#include +#include + +#include namespace Ui { class EditMethodDialog; } class QComboBox; + +/** + * @brief Dialog for creating and editing class methods + */ class EditMethodDialog : public QDialog { Q_OBJECT @@ -54,8 +60,8 @@ public: QWidget *parent = nullptr); private slots: - void on_buttonBox_accepted(); - void on_buttonBox_rejected(); + void onButtonBoxAccepted(); + void onButtonBoxRejected(); void updateVirtualUI(); void validateInput(); diff --git a/src/dialogs/EditRegProfileDialog.cpp b/src/dialogs/EditRegProfileDialog.cpp index 93e83f9d..f105b781 100644 --- a/src/dialogs/EditRegProfileDialog.cpp +++ b/src/dialogs/EditRegProfileDialog.cpp @@ -1,21 +1,23 @@ #include "EditRegProfileDialog.h" + #include "ui_EditRegProfileDialog.h" +#include +#include #include #include -#include -#include EditRegProfileDialog::EditRegProfileDialog(QWidget *parent) - : QDialog(parent), ui(new Ui::EditRegProfileDialog) + : QDialog(parent), + aliasModel(new QStandardItemModel(0, ALIAS_MAX_COL, this)), + regModel(new QStandardItemModel(0, REG_MAX_COL, this)), + ui(new Ui::EditRegProfileDialog) { ui->setupUi(this); - aliasModel = new QStandardItemModel(0, ALIAS_MAX_COL, this); aliasModel->setHorizontalHeaderLabels({ tr("Alias"), tr("Register") }); ui->aliasTable->setModel(aliasModel); - regModel = new QStandardItemModel(0, REG_MAX_COL, this); regModel->setHorizontalHeaderLabels({ tr("Type"), tr("Name"), tr("Size"), tr("Offset"), tr("Packed"), tr("Flags/Comment") }); ui->regTable->setModel(regModel); @@ -74,7 +76,7 @@ void EditRegProfileDialog::parseToTables(const QString &data) bool parsingRegisters = false; for (const QString &line : lines) { - QString trimmed = line.trimmed(); + const QString trimmed = line.trimmed(); if (trimmed.isEmpty()) { continue; } @@ -85,7 +87,7 @@ void EditRegProfileDialog::parseToTables(const QString &data) // handle comments if (trimmed.startsWith('#')) { - QStandardItem *commentItem = new QStandardItem(trimmed); + auto *commentItem = new QStandardItem(trimmed); commentItem->setData(true, CommentRole); if (parsingRegisters) { @@ -93,12 +95,12 @@ void EditRegProfileDialog::parseToTables(const QString &data) for (int i = 1; i < REG_MAX_COL; ++i) { items << new QStandardItem(""); } - int rowIdx = regModel->rowCount(); + const int rowIdx = regModel->rowCount(); regModel->appendRow(items); ui->regTable->setSpan(rowIdx, 0, 1, REG_MAX_COL); } else { - QList items = { commentItem, new QStandardItem("") }; - int rowIdx = aliasModel->rowCount(); + const QList items = { commentItem, new QStandardItem("") }; + const int rowIdx = aliasModel->rowCount(); aliasModel->appendRow(items); ui->aliasTable->setSpan(rowIdx, 0, 1, ALIAS_MAX_COL); } @@ -130,7 +132,7 @@ QString EditRegProfileDialog::tablesToText() const // Aliases for (int i = 0; i < aliasModel->rowCount(); ++i) { - QStandardItem *firstItem = aliasModel->item(i, 0); + const QStandardItem *firstItem = aliasModel->item(i, 0); if (firstItem && firstItem->data(CommentRole).toBool()) { ts << firstItem->text() << "\n"; } else { @@ -147,7 +149,7 @@ QString EditRegProfileDialog::tablesToText() const // Registers for (int i = 0; i < regModel->rowCount(); ++i) { - QStandardItem *firstItem = regModel->item(i, 0); + const QStandardItem *firstItem = regModel->item(i, 0); if (firstItem && firstItem->data(CommentRole).toBool()) { ts << firstItem->text() << "\n"; } else { @@ -165,24 +167,24 @@ QString EditRegProfileDialog::tablesToText() const void EditRegProfileDialog::onAddRow() { - TabContext tabCtx = getActiveTab(); + const TabContext tabCtx = getActiveTab(); auto model = tabCtx.model; auto view = tabCtx.view; - QModelIndex current = view->currentIndex(); - int row = current.isValid() ? current.row() + 1 : model->rowCount(); + const QModelIndex current = view->currentIndex(); + const int row = current.isValid() ? current.row() + 1 : model->rowCount(); model->insertRow(row); - QModelIndex newIdx = model->index(row, 0); + const QModelIndex newIdx = model->index(row, 0); view->setCurrentIndex(newIdx); view->edit(newIdx); } void EditRegProfileDialog::onRemoveRow() { - TabContext tabCtx = getActiveTab(); + const TabContext tabCtx = getActiveTab(); auto model = tabCtx.model; auto view = tabCtx.view; - QModelIndex current = view->currentIndex(); + const QModelIndex current = view->currentIndex(); if (current.isValid()) { model->removeRow(current.row()); } @@ -190,7 +192,7 @@ void EditRegProfileDialog::onRemoveRow() void EditRegProfileDialog::onTabChanged(int index) { - bool raw = (index == TAB_RAW); + const bool raw = (index == TAB_RAW); if (raw) { ui->rawProfileEdit->setPlainText(tablesToText()); } else { @@ -202,21 +204,21 @@ void EditRegProfileDialog::onTabChanged(int index) void EditRegProfileDialog::showContextMenu(const QPoint &pos) { - TabContext tabCtx = getActiveTab(); + const TabContext tabCtx = getActiveTab(); auto view = tabCtx.view; auto model = tabCtx.model; - QModelIndex index = view->indexAt(pos); - int row = index.isValid() ? index.row() : model->rowCount(); + const QModelIndex index = view->indexAt(pos); + const int row = index.isValid() ? index.row() : model->rowCount(); QMenu menu(this); - QAction *addAbove = menu.addAction(tr("Add Row Above")); - QAction *addBelow = menu.addAction(tr("Add Row Below")); + const QAction *addAbove = menu.addAction(tr("Add Row Above")); + const QAction *addBelow = menu.addAction(tr("Add Row Below")); menu.addSeparator(); QAction *remove = menu.addAction(tr("Remove Row")); remove->setEnabled(index.isValid()); - QAction *selected = menu.exec(view->viewport()->mapToGlobal(pos)); + const QAction *selected = menu.exec(view->viewport()->mapToGlobal(pos)); if (!selected) { return; diff --git a/src/dialogs/EditRegProfileDialog.h b/src/dialogs/EditRegProfileDialog.h index c8c0d4ce..c7eadce8 100644 --- a/src/dialogs/EditRegProfileDialog.h +++ b/src/dialogs/EditRegProfileDialog.h @@ -1,9 +1,12 @@ #ifndef EDITREGPROFILEDIALOG_H #define EDITREGPROFILEDIALOG_H +#include "CutterDescriptions.h" // IWYU pragma: keep + #include #include #include + #include namespace Ui { @@ -57,10 +60,10 @@ private slots: void showContextMenu(const QPoint &pos); private: - enum CustomRole { CommentRole = Qt::UserRole + 1 }; - enum TabIndex { TAB_ALIASES, TAB_REGISTERS, TAB_RAW }; - enum AliasCol { ALIAS_NAME = 0, ALIAS_REG, ALIAS_MAX_COL }; - enum RegCol { + enum CustomRole : ut16 { CommentRole = Qt::UserRole + 1 }; + enum TabIndex : ut8 { TAB_ALIASES, TAB_REGISTERS, TAB_RAW }; + enum AliasCol : ut8 { ALIAS_NAME = 0, ALIAS_REG, ALIAS_MAX_COL }; + enum RegCol : ut8 { REG_TYPE = 0, REG_NAME, REG_SIZE, diff --git a/src/dialogs/EditStringDialog.cpp b/src/dialogs/EditStringDialog.cpp index 8b7cd640..04eda0a8 100644 --- a/src/dialogs/EditStringDialog.cpp +++ b/src/dialogs/EditStringDialog.cpp @@ -1,48 +1,49 @@ #include "EditStringDialog.h" + #include "ui_EditStringDialog.h" EditStringDialog::EditStringDialog(QWidget *parent) : QDialog(parent), ui(new Ui::EditStringDialog {}) { ui->setupUi(this); - ui->spinBox_size->setMinimum(0); - ui->lineEdit_address->setMinimumWidth(150); - ui->spinBox_size->setFocus(); - ui->comboBox_type->addItems({ "Auto", "ASCII/Latin1", "UTF-8" }); - connect(ui->checkBox_autoSize, &QCheckBox::toggled, ui->spinBox_size, &QSpinBox::setDisabled); + ui->spinBoxSize->setMinimum(0); + ui->lineEditAddress->setMinimumWidth(150); + ui->spinBoxSize->setFocus(); + ui->comboBoxType->addItems({ "Auto", "ASCII/Latin1", "UTF-8" }); + connect(ui->checkBoxAutoSize, &QCheckBox::toggled, ui->spinBoxSize, &QSpinBox::setDisabled); } EditStringDialog::~EditStringDialog() {} void EditStringDialog::setStringStartAddress(uint64_t address) { - ui->lineEdit_address->setText(QString::number(address, 16)); + ui->lineEditAddress->setText(QString::number(address, 16)); } bool EditStringDialog::getStringStartAddress(uint64_t &returnValue) const { bool status = false; - returnValue = ui->lineEdit_address->text().toLongLong(&status, 16); + returnValue = ui->lineEditAddress->text().toLongLong(&status, 16); return status; } void EditStringDialog::setStringSizeValue(uint32_t size) { - ui->spinBox_size->setValue(size); + ui->spinBoxSize->setValue(size); } int EditStringDialog::getStringSizeValue() const { - if (ui->checkBox_autoSize->isChecked()) { + if (ui->checkBoxAutoSize->isChecked()) { return -1; } - return ui->spinBox_size->value(); + return ui->spinBoxSize->value(); } EditStringDialog::StringType EditStringDialog::getStringType() const { - const int indexVal = ui->comboBox_type->currentIndex(); + const int indexVal = ui->comboBoxType->currentIndex(); switch (indexVal) { case 0: { diff --git a/src/dialogs/EditStringDialog.h b/src/dialogs/EditStringDialog.h index 2b48e830..042ad95a 100644 --- a/src/dialogs/EditStringDialog.h +++ b/src/dialogs/EditStringDialog.h @@ -1,19 +1,25 @@ #ifndef EDITSTRINGDIALOG_H #define EDITSTRINGDIALOG_H -#include +#include "CutterDescriptions.h" // IWYU pragma: keep + #include +#include + namespace Ui { class EditStringDialog; } +/** + * @brief Dialog for editing strings + */ class EditStringDialog : public QDialog { Q_OBJECT public: - enum class StringType { Auto, ASCII_LATIN1, UTF8 }; + enum class StringType : ut8 { Auto, ASCII_LATIN1, UTF8 }; explicit EditStringDialog(QWidget *parent = nullptr); ~EditStringDialog(); diff --git a/src/dialogs/EditStringDialog.ui b/src/dialogs/EditStringDialog.ui index d265fb1d..d9eca3ba 100644 --- a/src/dialogs/EditStringDialog.ui +++ b/src/dialogs/EditStringDialog.ui @@ -3,14 +3,14 @@ EditStringDialog - Qt::WindowModal + Qt::WindowModality::WindowModal 0 0 - 243 - 109 + 286 + 139 @@ -32,7 +32,7 @@ - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok @@ -41,7 +41,7 @@ - + 0 @@ -54,14 +54,14 @@ - + Type: - + Address: @@ -72,7 +72,7 @@ - + 150 @@ -82,10 +82,10 @@ - + - + @@ -93,8 +93,8 @@ - - + + Auto @@ -105,10 +105,10 @@ - spinBox_size - checkBox_autoSize - comboBox_type - lineEdit_address + spinBoxSize + checkBoxAutoSize + comboBoxType + lineEditAddress dialogButtonBox diff --git a/src/dialogs/EditVariablesDialog.cpp b/src/dialogs/EditVariablesDialog.cpp index 8b7a09a0..756a9f15 100644 --- a/src/dialogs/EditVariablesDialog.cpp +++ b/src/dialogs/EditVariablesDialog.cpp @@ -1,12 +1,13 @@ #include "EditVariablesDialog.h" + +#include "Cutter.h" #include "ui_EditVariablesDialog.h" -#include #include #include #include -EditVariablesDialog::EditVariablesDialog(RVA offset, QString initialVar, QWidget *parent) +EditVariablesDialog::EditVariablesDialog(RVA offset, const QString &initialVar, QWidget *parent) : QDialog(parent), ui(new Ui::EditVariablesDialog), functionAddress(RVA_INVALID) { ui->setupUi(this); @@ -15,8 +16,8 @@ EditVariablesDialog::EditVariablesDialog(RVA offset, QString initialVar, QWidget &EditVariablesDialog::updateFields); auto core = Core()->lock(); - RzAnalysisFunction *f = rz_analysis_get_function_at(core->analysis, offset); - QString fcnName = f->name; + const RzAnalysisFunction *f = rz_analysis_get_function_at(core->analysis, offset); + const QString fcnName = f->name; functionAddress = offset; setWindowTitle(tr("Edit Variables in Function: %1").arg(fcnName)); @@ -39,10 +40,7 @@ EditVariablesDialog::EditVariablesDialog(RVA offset, QString initialVar, QWidget updateFields(); } -EditVariablesDialog::~EditVariablesDialog() -{ - delete ui; -} +EditVariablesDialog::~EditVariablesDialog() {} bool EditVariablesDialog::empty() const { @@ -55,10 +53,10 @@ void EditVariablesDialog::applyFields() // nothing was selected or list is empty return; } - VariableDescription desc = ui->dropdownLocalVars->currentData().value(); + const auto desc = ui->dropdownLocalVars->currentData().value(); RzCoreLocked core(Core()); - RzAnalysisFunction *fcn = Core()->functionIn(core->offset); + auto *fcn = const_cast(Core()->functionIn(core->offset)); if (!fcn) { return; } @@ -68,20 +66,20 @@ void EditVariablesDialog::applyFields() return; } - char *error_msg = NULL; - RzType *v_type = rz_type_parse_string_single( + char *errorMsg; + RzType *vType = rz_type_parse_string_single( rz_analysis_get_type_db(core->analysis)->parser, - ui->typeComboBox->currentText().toUtf8().constData(), &error_msg); - if (!v_type || error_msg) { + ui->typeComboBox->currentText().toUtf8().constData(), &errorMsg); + if (!vType || errorMsg) { return; } - rz_analysis_var_set_type(v, v_type, true); + rz_analysis_var_set_type(v, vType, true); // TODO Remove all those replace once rizin command parser is fixed - QString newName = ui->nameEdit->text() - .replace(QLatin1Char(' '), QLatin1Char('_')) - .replace(QLatin1Char('\\'), QLatin1Char('_')) - .replace(QLatin1Char('/'), QLatin1Char('_')); + const QString newName = ui->nameEdit->text() + .replace(QLatin1Char(' '), QLatin1Char('_')) + .replace(QLatin1Char('\\'), QLatin1Char('_')) + .replace(QLatin1Char('/'), QLatin1Char('_')); if (newName != desc.name) { Core()->renameFunctionVariable(newName, desc.name, functionAddress); } @@ -92,19 +90,19 @@ void EditVariablesDialog::applyFields() void EditVariablesDialog::updateFields() { - bool hasSelection = ui->dropdownLocalVars->currentIndex() >= 0; + const bool hasSelection = ui->dropdownLocalVars->currentIndex() >= 0; auto okButton = ui->buttonBox->button(QDialogButtonBox::Ok); okButton->setEnabled(hasSelection); if (!hasSelection) { ui->nameEdit->clear(); return; } - VariableDescription desc = ui->dropdownLocalVars->currentData().value(); + const auto desc = ui->dropdownLocalVars->currentData().value(); ui->nameEdit->setText(desc.name); ui->typeComboBox->setCurrentText(desc.type); } -static void addTypeDescriptionsToComboBox(QComboBox *comboBox, QList list) +static void addTypeDescriptionsToComboBox(QComboBox *comboBox, const QList &list) { for (const TypeDescription &thisType : list) { comboBox->addItem(thisType.type); diff --git a/src/dialogs/EditVariablesDialog.h b/src/dialogs/EditVariablesDialog.h index 10eda901..98751274 100644 --- a/src/dialogs/EditVariablesDialog.h +++ b/src/dialogs/EditVariablesDialog.h @@ -1,19 +1,25 @@ #ifndef EDITVARIABLESDIALOG_H #define EDITVARIABLESDIALOG_H -#include "core/Cutter.h" +#include "CutterDescriptions.h" + #include +#include + namespace Ui { class EditVariablesDialog; } +/** + * @brief Dialog for editing local variables within a specific function + */ class EditVariablesDialog : public QDialog { Q_OBJECT public: - explicit EditVariablesDialog(RVA offset, QString initialVar = QString(), + explicit EditVariablesDialog(RVA offset, const QString &initialVar = QString(), QWidget *parent = nullptr); ~EditVariablesDialog(); @@ -23,7 +29,7 @@ private slots: void updateFields(); private: - Ui::EditVariablesDialog *ui; + std::unique_ptr ui; RVA functionAddress; QList variables; diff --git a/src/dialogs/EditVariablesDialog.ui b/src/dialogs/EditVariablesDialog.ui index 701a824f..1b3baf14 100644 --- a/src/dialogs/EditVariablesDialog.ui +++ b/src/dialogs/EditVariablesDialog.ui @@ -7,7 +7,7 @@ 0 0 435 - 137 + 138 @@ -17,7 +17,7 @@ - + Modify: @@ -58,10 +58,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok diff --git a/src/dialogs/FlagDialog.cpp b/src/dialogs/FlagDialog.cpp index 17f2bc8f..62c0f865 100644 --- a/src/dialogs/FlagDialog.cpp +++ b/src/dialogs/FlagDialog.cpp @@ -1,14 +1,17 @@ #include "FlagDialog.h" + +#include "core/Cutter.h" #include "ui_FlagDialog.h" #include -#include "core/Cutter.h" + +#include FlagDialog::FlagDialog(RVA offset, QWidget *parent, QString flagNameHint) : QDialog(parent), ui(new Ui::FlagDialog), offset(offset), - flagName(flagNameHint), + flagName(std::move(flagNameHint)), flagOffset(RVA_INVALID) { // Setup UI @@ -18,21 +21,21 @@ FlagDialog::FlagDialog(RVA offset, QWidget *parent, QString flagNameHint) flagOffset = offset; } else { RzCoreLocked core(Core()); - RzFlagItem *flag = rz_flag_get_i(core->flags, offset); + const RzFlagItem *flag = rz_flag_get_i(core->flags, offset); if (flag) { flagName = QString(flag->name); flagOffset = flag->offset; } } - auto size_validator = new QIntValidator(ui->sizeEdit); - size_validator->setBottom(1); - ui->sizeEdit->setValidator(size_validator); + auto sizeValidator = new QIntValidator(ui->sizeEdit); + sizeValidator->setBottom(1); + ui->sizeEdit->setValidator(sizeValidator); if (!flagName.isEmpty()) { ui->nameEdit->setText(flagName); - ui->labelAction->setText(tr("Edit flag at %1").arg(RzAddressString(offset))); + ui->labelAction->setText(tr("Edit flag at %1").arg(rzAddressString(offset))); } else { - ui->labelAction->setText(tr("Add flag at %1").arg(RzAddressString(offset))); + ui->labelAction->setText(tr("Add flag at %1").arg(rzAddressString(offset))); } // Connect slots @@ -44,8 +47,8 @@ FlagDialog::~FlagDialog() {} void FlagDialog::buttonBoxAccepted() { - RVA size = ui->sizeEdit->text().toULongLong(); - QString name = ui->nameEdit->text(); + const RVA size = ui->sizeEdit->text().toULongLong(); + const QString name = ui->nameEdit->text(); if (name.isEmpty()) { if (flagOffset != RVA_INVALID) { diff --git a/src/dialogs/FlagDialog.h b/src/dialogs/FlagDialog.h index 6ea0a72f..3780c87a 100644 --- a/src/dialogs/FlagDialog.h +++ b/src/dialogs/FlagDialog.h @@ -1,14 +1,19 @@ #ifndef FLAGDIALOG_H #define FLAGDIALOG_H -#include -#include #include "core/CutterCommon.h" +#include + +#include + namespace Ui { class FlagDialog; } +/** + * @brief Dialog for modifying flags at a specific offset + */ class FlagDialog : public QDialog { Q_OBJECT @@ -25,7 +30,7 @@ private: std::unique_ptr ui; RVA offset; QString flagName; - ut64 flagOffset; + RVA flagOffset; }; #endif // FLAGDIALOG_H diff --git a/src/dialogs/GlibcHeapBinsDialog.cpp b/src/dialogs/GlibcHeapBinsDialog.cpp index 999dfb64..90361d1b 100644 --- a/src/dialogs/GlibcHeapBinsDialog.cpp +++ b/src/dialogs/GlibcHeapBinsDialog.cpp @@ -1,13 +1,17 @@ -#include #include "GlibcHeapBinsDialog.h" -#include "ui_GlibcHeapBinsDialog.h" -#include "GlibcHeapInfoDialog.h" -GlibcHeapBinsDialog::GlibcHeapBinsDialog(RVA m_state, MainWindow *main, QWidget *parent) +#include "Cutter.h" +#include "GlibcHeapInfoDialog.h" +#include "ui_GlibcHeapBinsDialog.h" + +#include + +GlibcHeapBinsDialog::GlibcHeapBinsDialog(RVA mState, MainWindow *main, QWidget *parent) : QDialog(parent), ui(new Ui::GlibcHeapBinsDialog), - m_state(m_state), - binsModel(new BinsModel(m_state, this)), + mState(mState), + binsModel(new BinsModel(mState, this)), + graphView(nullptr), main(main) { ui->setupUi(this); @@ -24,14 +28,11 @@ GlibcHeapBinsDialog::GlibcHeapBinsDialog(RVA m_state, MainWindow *main, QWidget binsModel->reload(); ui->viewBins->resizeColumnsToContents(); - graphView = nullptr; - this->setWindowTitle(tr("Bins info for arena @ ") + RzAddressString(m_state)); + + this->setWindowTitle(tr("Bins info for arena @ ") + rzAddressString(mState)); } -GlibcHeapBinsDialog::~GlibcHeapBinsDialog() -{ - delete ui; -} +GlibcHeapBinsDialog::~GlibcHeapBinsDialog() {} void GlibcHeapBinsDialog::onCurrentChanged(const QModelIndex ¤t, const QModelIndex &prev) { @@ -47,15 +48,15 @@ void GlibcHeapBinsDialog::setChainInfo(int index) // get chunks for the selected bin and construct chain info string RzListIter *iter; RzHeapChunkListItem *item; - RzList *chunks = binsModel->getChunks(index); + const RzList *chunks = binsModel->getChunks(index); QString chainInfo; CutterRzListForeach (chunks, iter, RzHeapChunkListItem, item) { - chainInfo += " → " + RzAddressString(item->addr); + chainInfo += " → " + rzAddressString(item->addr); } // Add bin message at the end of the list // responsible for messages like corrupted list, double free - QString message = binsModel->getBinMessage(index); + const QString message = binsModel->getBinMessage(index); if (!message.isEmpty()) { chainInfo += " " + message; } @@ -65,10 +66,10 @@ void GlibcHeapBinsDialog::setChainInfo(int index) void GlibcHeapBinsDialog::showHeapInfoDialog() { - QString str = ui->lineEdit->text(); + const QString str = ui->lineEdit->text(); if (!str.isEmpty()) { // summon glibcHeapInfoDialog box with the offset entered - RVA offset = Core()->math(str); + const RVA offset = Core()->math(str); if (!offset) { ui->lineEdit->setText(QString()); return; @@ -91,7 +92,7 @@ void GlibcHeapBinsDialog::setGraphView(int index) } BinsModel::BinsModel(RVA arena_addr, QObject *parent) - : QAbstractTableModel(parent), arena_addr(arena_addr) + : QAbstractTableModel(parent), arenaAddr(arena_addr) { } @@ -99,7 +100,7 @@ void BinsModel::reload() { beginResetModel(); clearData(); - values = Core()->getHeapBins(arena_addr); + values = Core()->getHeapBins(arenaAddr); endResetModel(); } @@ -115,8 +116,9 @@ int BinsModel::columnCount(const QModelIndex &) const QVariant BinsModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= values.count()) + if (!index.isValid() || index.row() >= values.count()) { return QVariant(); + } const auto &item = values.at(index.row()); @@ -126,15 +128,15 @@ QVariant BinsModel::data(const QModelIndex &index, int role) const case BinNumColumn: return item->bin_num; case FdColumn: - return (item->fd == 0) ? tr("N/A") : RzAddressString(item->fd); + return (item->fd == 0) ? tr("N/A") : rzAddressString(item->fd); case BkColumn: - return (item->bk == 0) ? tr("N/A") : RzAddressString(item->bk); + return (item->bk == 0) ? tr("N/A") : rzAddressString(item->bk); case TypeColumn: return tr(item->type); case CountColumn: return rz_list_length(item->chunks); case SizeColumn: - return (item->size == 0) ? tr("N/A") : RzHexString(item->size); + return (item->size == 0) ? tr("N/A") : rzHexString(item->size); default: return QVariant(); } diff --git a/src/dialogs/GlibcHeapBinsDialog.h b/src/dialogs/GlibcHeapBinsDialog.h index a3561161..91f2f877 100644 --- a/src/dialogs/GlibcHeapBinsDialog.h +++ b/src/dialogs/GlibcHeapBinsDialog.h @@ -1,11 +1,11 @@ #ifndef GLIBCHEAPBINSDIALOG_H #define GLIBCHEAPBINSDIALOG_H -#include #include -#include "core/Cutter.h" -#include +#include + #include +#include namespace Ui { class GlibcHeapBinsDialog; @@ -16,7 +16,7 @@ class BinsModel : public QAbstractTableModel Q_OBJECT public: explicit BinsModel(RVA arena_addr, QObject *parent = nullptr); - enum Column { + enum Column : ut8 { TypeColumn = 0, BinNumColumn, FdColumn, @@ -31,7 +31,7 @@ public: void clearData(); QVariant data(const QModelIndex &index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - RVA arena_addr = 0; + RVA arenaAddr = 0; RzList *getChunks(int index); QString getBinMessage(int index); QVector values; @@ -39,6 +39,9 @@ public: private: }; +/** + * @brief Dialog for inspecting glibc heap bins + */ class GlibcHeapBinsDialog : public QDialog { Q_OBJECT @@ -53,8 +56,8 @@ private slots: void showHeapInfoDialog(); private: - Ui::GlibcHeapBinsDialog *ui; - RVA m_state; + std::unique_ptr ui; + RVA mState; BinsModel *binsModel {}; HeapBinsGraphView *graphView; MainWindow *main; diff --git a/src/dialogs/GlibcHeapInfoDialog.cpp b/src/dialogs/GlibcHeapInfoDialog.cpp index 304f3fb5..c858d142 100644 --- a/src/dialogs/GlibcHeapInfoDialog.cpp +++ b/src/dialogs/GlibcHeapInfoDialog.cpp @@ -1,15 +1,17 @@ #include "GlibcHeapInfoDialog.h" -#include +#include "Cutter.h" #include "ui_GlibcHeapInfoDialog.h" +#include + GlibcHeapInfoDialog::GlibcHeapInfoDialog(RVA offset, QString status, QWidget *parent) : QDialog(parent), ui(new Ui::GlibcHeapInfoDialog), offset(offset), status(std::move(status)) { ui->setupUi(this); // set window title - QString windowTitle = tr("Chunk @ ") + RzAddressString(offset); + QString windowTitle = tr("Chunk @ ") + rzAddressString(offset); if (!this->status.isEmpty()) { windowTitle += QString("(" + this->status + ")"); } @@ -20,10 +22,7 @@ GlibcHeapInfoDialog::GlibcHeapInfoDialog(RVA offset, QString status, QWidget *pa updateFields(); } -GlibcHeapInfoDialog::~GlibcHeapInfoDialog() -{ - delete ui; -} +GlibcHeapInfoDialog::~GlibcHeapInfoDialog() {} void GlibcHeapInfoDialog::updateFields() { @@ -34,13 +33,13 @@ void GlibcHeapInfoDialog::updateFields() } // Update the information in the widget - this->ui->baseEdit->setText(RzAddressString(offset)); - this->ui->sizeEdit->setText(RzHexString(chunk->size)); - this->ui->bkEdit->setText(RzAddressString(chunk->bk)); - this->ui->fdEdit->setText(RzAddressString(chunk->fd)); - this->ui->bknsEdit->setText(RzAddressString(chunk->bk_nextsize)); - this->ui->fdnsEdit->setText(RzAddressString(chunk->fd_nextsize)); - this->ui->prevSizeEdit->setText(RzHexString(chunk->prev_size)); + this->ui->baseEdit->setText(rzAddressString(offset)); + this->ui->sizeEdit->setText(rzHexString(chunk->size)); + this->ui->bkEdit->setText(rzAddressString(chunk->bk)); + this->ui->fdEdit->setText(rzAddressString(chunk->fd)); + this->ui->bknsEdit->setText(rzAddressString(chunk->bk_nextsize)); + this->ui->fdnsEdit->setText(rzAddressString(chunk->fd_nextsize)); + this->ui->prevSizeEdit->setText(rzHexString(chunk->prev_size)); if (chunk->is_mmapped) { this->ui->rbIM->setChecked(true); } else { @@ -69,7 +68,7 @@ void GlibcHeapInfoDialog::saveChunkInfo() msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel); msgBox.setDefaultButton(QMessageBox::Save); - int ret = msgBox.exec(); + const int ret = msgBox.exec(); switch (ret) { case QMessageBox::Save: // Save was clicked diff --git a/src/dialogs/GlibcHeapInfoDialog.h b/src/dialogs/GlibcHeapInfoDialog.h index 684628e0..a20febef 100644 --- a/src/dialogs/GlibcHeapInfoDialog.h +++ b/src/dialogs/GlibcHeapInfoDialog.h @@ -1,13 +1,19 @@ #ifndef HEAPINFODIALOG_H #define HEAPINFODIALOG_H +#include "CutterDescriptions.h" // IWYU pragma: keep + #include -#include "core/Cutter.h" + +#include namespace Ui { class GlibcHeapInfoDialog; } +/** + * @brief Dialog for inspecting and editing the metadata of a single glibc heap chunk + */ class GlibcHeapInfoDialog : public QDialog { Q_OBJECT @@ -20,7 +26,7 @@ private slots: void saveChunkInfo(); private: - Ui::GlibcHeapInfoDialog *ui; + std::unique_ptr ui; void updateFields(); RVA offset; QString status; diff --git a/src/dialogs/GlobalVariableDialog.cpp b/src/dialogs/GlobalVariableDialog.cpp index 5586ad5e..74a57d70 100644 --- a/src/dialogs/GlobalVariableDialog.cpp +++ b/src/dialogs/GlobalVariableDialog.cpp @@ -1,8 +1,9 @@ #include "GlobalVariableDialog.h" + +#include "core/Cutter.h" #include "ui_GlobalVariableDialog.h" #include -#include "core/Cutter.h" GlobalVariableDialog::GlobalVariableDialog(RVA offset, QWidget *parent) : QDialog(parent), @@ -15,7 +16,7 @@ GlobalVariableDialog::GlobalVariableDialog(RVA offset, QWidget *parent) ui->setupUi(this); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); RzCoreLocked core = Core()->lock(); - RzAnalysisVarGlobal *globalVariable = + const RzAnalysisVarGlobal *globalVariable = rz_analysis_var_global_get_byaddr_at(core->analysis, offset); if (globalVariable) { globalVariableName = QString(globalVariable->name); @@ -24,11 +25,11 @@ GlobalVariableDialog::GlobalVariableDialog(RVA offset, QWidget *parent) if (globalVariable) { ui->nameEdit->setText(globalVariable->name); - QString globalVarType = Core()->getGlobalVariableType(globalVariable->name); + const QString globalVarType = Core()->getGlobalVariableType(globalVariable->name); ui->typeEdit->setText(globalVarType); - ui->labelAction->setText(tr("Edit global variable at %1").arg(RzAddressString(offset))); + ui->labelAction->setText(tr("Edit global variable at %1").arg(rzAddressString(offset))); } else { - ui->labelAction->setText(tr("Add global variable at %1").arg(RzAddressString(offset))); + ui->labelAction->setText(tr("Add global variable at %1").arg(rzAddressString(offset))); } // Connect slots @@ -42,8 +43,8 @@ GlobalVariableDialog::~GlobalVariableDialog() {} void GlobalVariableDialog::buttonBoxAccepted() { - QString name = ui->nameEdit->text(); - QString typ = ui->typeEdit->text(); + const QString name = ui->nameEdit->text(); + const QString typ = ui->typeEdit->text(); if (name.isEmpty()) { if (globalVariableOffset != RVA_INVALID) { diff --git a/src/dialogs/GlobalVariableDialog.h b/src/dialogs/GlobalVariableDialog.h index 5100b367..5daac081 100644 --- a/src/dialogs/GlobalVariableDialog.h +++ b/src/dialogs/GlobalVariableDialog.h @@ -1,14 +1,19 @@ #ifndef GLOBALVARIABLEDIALOG_H #define GLOBALVARIABLEDIALOG_H -#include -#include #include "core/CutterCommon.h" +#include + +#include + namespace Ui { class GlobalVariableDialog; } +/** + * @brief Dialog for defining, modifying, or deleting global variables at a specific address + */ class GlobalVariableDialog : public QDialog { Q_OBJECT diff --git a/src/dialogs/HexdumpRangeDialog.cpp b/src/dialogs/HexdumpRangeDialog.cpp index 7f781e2e..c3646325 100644 --- a/src/dialogs/HexdumpRangeDialog.cpp +++ b/src/dialogs/HexdumpRangeDialog.cpp @@ -1,16 +1,18 @@ #include "HexdumpRangeDialog.h" + +#include "core/Cutter.h" #include "ui_HexdumpRangeDialog.h" -#include #include +#include + #include -#include "core/Cutter.h" HexdumpRangeDialog::HexdumpRangeDialog(QWidget *parent, bool allowEmpty) : QDialog(parent), ui(new Ui::HexdumpRangeDialog), allowEmpty(allowEmpty) { ui->setupUi(this); - QRegularExpressionValidator *v = + const auto *v = new QRegularExpressionValidator(QRegularExpression("(?:0[xX])?[0-9a-fA-F]+"), this); ui->lengthLineEdit->setValidator(v); ui->startAddressLineEdit->setValidator(v); @@ -22,27 +24,24 @@ HexdumpRangeDialog::HexdumpRangeDialog(QWidget *parent, bool allowEmpty) connect(ui->endAddressLineEdit, &QLineEdit::textEdited, this, &HexdumpRangeDialog::textEdited); connect(ui->lengthLineEdit, &QLineEdit::textEdited, this, &HexdumpRangeDialog::textEdited); connect(ui->endAddressRadioButton, &QRadioButton::clicked, this, - &HexdumpRangeDialog::on_radioButtonClicked); + &HexdumpRangeDialog::onRadioButtonClicked); connect(ui->lengthRadioButton, &QRadioButton::clicked, this, - &HexdumpRangeDialog::on_radioButtonClicked); + &HexdumpRangeDialog::onRadioButtonClicked); } -HexdumpRangeDialog::~HexdumpRangeDialog() -{ - delete ui; -} +HexdumpRangeDialog::~HexdumpRangeDialog() {} -bool HexdumpRangeDialog::empty() +bool HexdumpRangeDialog::empty() const { return emptyRange; } -ut64 HexdumpRangeDialog::getStartAddress() const +RVA HexdumpRangeDialog::getStartAddress() const { return startAddress; } -ut64 HexdumpRangeDialog::getEndAddress() const +RVA HexdumpRangeDialog::getEndAddress() const { return endAddress; } @@ -62,7 +61,7 @@ void HexdumpRangeDialog::setStartAddress(ut64 start) ui->startAddressLineEdit->setText(QString("0x%1").arg(start, 0, 16)); } -void HexdumpRangeDialog::open(ut64 start) +void HexdumpRangeDialog::openAt(ut64 start) { setStartAddress(start); setModal(false); @@ -123,11 +122,11 @@ bool HexdumpRangeDialog::validate() void HexdumpRangeDialog::textEdited() { - bool valid = validate(); + const bool valid = validate(); ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid); } -void HexdumpRangeDialog::on_radioButtonClicked(bool checked) +void HexdumpRangeDialog::onRadioButtonClicked(bool checked) { if (sender() == ui->endAddressRadioButton && checked == true) { ui->lengthLineEdit->setEnabled(false); diff --git a/src/dialogs/HexdumpRangeDialog.h b/src/dialogs/HexdumpRangeDialog.h index c3f3d288..22b92902 100644 --- a/src/dialogs/HexdumpRangeDialog.h +++ b/src/dialogs/HexdumpRangeDialog.h @@ -1,9 +1,12 @@ #ifndef HEXDUMPRANGEDIALOG_H #define HEXDUMPRANGEDIALOG_H -#include "core/CutterCommon.h" +#include "core/CutterCommon.h" // IWYU pragma: keep + #include +#include + namespace Ui { class HexdumpRangeDialog; } @@ -15,12 +18,12 @@ class HexdumpRangeDialog : public QDialog public: explicit HexdumpRangeDialog(QWidget *parent = nullptr, bool allowEmpty = false); ~HexdumpRangeDialog(); - bool empty(); - ut64 getStartAddress() const; - ut64 getEndAddress() const; + bool empty() const; + RVA getStartAddress() const; + RVA getEndAddress() const; void setStartAddress(ut64 start); - void open(ut64 start); + void openAt(ut64 start); public slots: void textEdited(); @@ -30,14 +33,14 @@ private: bool getLengthRadioButtonChecked() const; bool validate(); - Ui::HexdumpRangeDialog *ui; + std::unique_ptr ui; bool emptyRange = true; - ut64 startAddress; - ut64 endAddress; + RVA startAddress; + RVA endAddress; bool allowEmpty = false; private slots: - void on_radioButtonClicked(bool checked); + void onRadioButtonClicked(bool checked); }; #endif // HEXDUMPRANGEDIALOG_H diff --git a/src/dialogs/InitialOptionsDialog.cpp b/src/dialogs/InitialOptionsDialog.cpp index c53df2fb..73d0f595 100644 --- a/src/dialogs/InitialOptionsDialog.cpp +++ b/src/dialogs/InitialOptionsDialog.cpp @@ -1,21 +1,19 @@ -#include "common/AsyncTask.h" #include "InitialOptionsDialog.h" -#include "ui_InitialOptionsDialog.h" -#include "core/MainWindow.h" -#include "dialogs/NewFileDialog.h" -#include "dialogs/AsyncTaskDialog.h" +#include "CutterApplication.h" +#include "common/AnalysisTask.h" +#include "common/AsyncTask.h" #include "common/Helpers.h" #include "core/Cutter.h" +#include "core/MainWindow.h" +#include "dialogs/AsyncTaskDialog.h" +#include "dialogs/NewFileDialog.h" +#include "ui_InitialOptionsDialog.h" -#include -#include -#include #include - -#include "core/Cutter.h" -#include "common/AnalysisTask.h" -#include "CutterApplication.h" +#include +#include +#include QString CommandDescription::translatedDescription() const { @@ -25,8 +23,7 @@ QString CommandDescription::translatedDescription() const InitialOptionsDialog::InitialOptionsDialog(MainWindow *main) : QDialog(nullptr), // parent must not be main ui(new Ui::InitialOptionsDialog), - main(main), - core(Core()) + main(main) { ui->setupUi(this); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); @@ -35,8 +32,8 @@ InitialOptionsDialog::InitialOptionsDialog(MainWindow *main) ui->debuginfodLineEdit->setText(Core()->getConfig("bin.dbginfo.debuginfod_urls")); // Fill the plugins combo - asmPlugins = core->getRAsmPluginDescriptions(); - for (const auto &plugin : asmPlugins) { + asmPlugins = Core()->getRAsmPluginDescriptions(); + for (const auto &plugin : std::as_const(asmPlugins)) { ui->archComboBox->addItem(plugin.name, plugin.name); } @@ -56,7 +53,7 @@ InitialOptionsDialog::InitialOptionsDialog(MainWindow *main) setTooltipWithConfigHelp(ui->kernelComboBox, "asm.os"); setTooltipWithConfigHelp(ui->bitsComboBox, "asm.bits"); - for (const auto &plugin : core->getBinPluginDescriptions(true, false)) { + for (const auto &plugin : Core()->getBinPluginDescriptions(true, false)) { ui->formatComboBox->addItem(plugin.name, QVariant::fromValue(plugin)); } @@ -123,7 +120,7 @@ InitialOptionsDialog::InitialOptionsDialog(MainWindow *main) item.checkbox->setText(item.commandDesc.translatedDescription()); item.checkbox->setToolTip(item.commandDesc.command); item.checkbox->setChecked(item.checked); - ui->verticalLayout_7->addWidget(item.checkbox); + ui->verticalLayout7->addWidget(item.checkbox); } ui->hideFrame->setVisible(false); @@ -133,19 +130,40 @@ InitialOptionsDialog::InitialOptionsDialog(MainWindow *main) updateDebuginfodLayout(); updatePDBLayout(); +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + connect(ui->pdbCheckBox, &QCheckBox::checkStateChanged, this, + &InitialOptionsDialog::updatePDBLayout); + connect(ui->scriptCheckBox, &QCheckBox::checkStateChanged, this, + &InitialOptionsDialog::updateScriptLayout); + connect(ui->debuginfodCheckBox, &QCheckBox::checkStateChanged, this, + &InitialOptionsDialog::updateDebuginfodLayout); +#else connect(ui->pdbCheckBox, &QCheckBox::stateChanged, this, &InitialOptionsDialog::updatePDBLayout); - - updateScriptLayout(); - connect(ui->scriptCheckBox, &QCheckBox::stateChanged, this, &InitialOptionsDialog::updateScriptLayout); connect(ui->debuginfodCheckBox, &QCheckBox::stateChanged, this, &InitialOptionsDialog::updateDebuginfodLayout); +#endif + updateScriptLayout(); connect(ui->cancelButton, &QPushButton::clicked, this, &InitialOptionsDialog::reject); ui->programLineEdit->setText(main->getFilename()); + + connect(ui->okButton, &QPushButton::clicked, this, &InitialOptionsDialog::onOkButtonClicked); + connect(ui->analysisSlider, &QSlider::valueChanged, this, + &InitialOptionsDialog::onAnalysisSliderValueChanged); + connect(ui->analysisCheckBox, &QCheckBox::clicked, this, + &InitialOptionsDialog::onAnalysisCheckBoxClicked); + connect(ui->advOptButton, &QToolButton::clicked, this, + &InitialOptionsDialog::onAdvOptButtonClicked); + connect(ui->archComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, + &InitialOptionsDialog::onArchComboBoxCurrentIndexChanged); + connect(ui->pdbSelectButton, &QPushButton::clicked, this, + &InitialOptionsDialog::onPdbSelectButtonClicked); + connect(ui->scriptSelectButton, &QPushButton::clicked, this, + &InitialOptionsDialog::onScriptSelectButtonClicked); } void InitialOptionsDialog::updateDebuginfodLayout() @@ -157,7 +175,7 @@ InitialOptionsDialog::~InitialOptionsDialog() {} void InitialOptionsDialog::updateCPUComboBox() { - QString currentText = ui->cpuComboBox->lineEdit()->text(); + const QString currentText = ui->cpuComboBox->lineEdit()->text(); ui->cpuComboBox->clear(); QString arch = getSelectedArch(); @@ -201,7 +219,7 @@ void InitialOptionsDialog::loadOptions(const InitialOptions &options) } else { analysisLevel = 3; AnalysisCommands item; - QList commands = getAnalysisCommands(options); + const QList commands = getAnalysisCommands(options); foreach (item, analysisCommands) { qInfo() << item.commandDesc.command; item.checkbox->setChecked(commands.contains(item.commandDesc.command)); @@ -228,11 +246,11 @@ void InitialOptionsDialog::loadOptions(const InitialOptions &options) } if (options.binLoadAddr != RVA_INVALID) { - ui->entry_loadOffset->setText(RzAddressString(options.binLoadAddr)); + ui->entryLoadOffset->setText(rzAddressString(options.binLoadAddr)); } if (options.mapAddr != RVA_INVALID) { - ui->entry_mapOffset->setText(RzAddressString(options.mapAddr)); + ui->entryMapOffset->setText(rzAddressString(options.mapAddr)); } ui->vaCheckBox->setChecked(options.useVA); @@ -285,12 +303,12 @@ void InitialOptionsDialog::loadOptions(const InitialOptions &options) void InitialOptionsDialog::setTooltipWithConfigHelp(QWidget *w, const char *config) { - w->setToolTip(QString("%1 (%2)").arg(core->getConfigDescription(config)).arg(config)); + w->setToolTip(QString("%1 (%2)").arg(Core()->getConfigDescription(config)).arg(config)); } QString InitialOptionsDialog::getSelectedArch() const { - QVariant archValue = ui->archComboBox->currentData(); + const QVariant archValue = ui->archComboBox->currentData(); return archValue.isValid() ? archValue.toString() : nullptr; } @@ -305,9 +323,9 @@ QString InitialOptionsDialog::getSelectedCPU() const int InitialOptionsDialog::getSelectedBits() const { - QString sel_bits = ui->bitsComboBox->currentText(); - if (sel_bits != "Auto") { // TODO: #3187 using potentially trtanslated text for logic - return sel_bits.toInt(); + const QString selBits = ui->bitsComboBox->currentText(); + if (selBits != "Auto") { // TODO: #3187 using potentially trtanslated text for logic + return selBits.toInt(); } return 0; @@ -327,7 +345,7 @@ InitialOptions::Endianness InitialOptionsDialog::getSelectedEndianness() const QString InitialOptionsDialog::getSelectedOS() const { - QVariant os = ui->kernelComboBox->currentData(); + const QVariant os = ui->kernelComboBox->currentData(); return os.isValid() ? os.toString() : nullptr; } @@ -356,12 +374,12 @@ void InitialOptionsDialog::setupAndStartAnalysis() options.shellcode = this->shellcode; // Where the bin header is located in the file (-B) - if (ui->entry_loadOffset->text().length() > 0) { - options.binLoadAddr = Core()->math(ui->entry_loadOffset->text()); + if (ui->entryLoadOffset->text().length() > 0) { + options.binLoadAddr = Core()->math(ui->entryLoadOffset->text()); } options.mapAddr = - Core()->math(ui->entry_mapOffset->text()); // Where to map the file once loaded (-m) + Core()->math(ui->entryMapOffset->text()); // Where to map the file once loaded (-m) options.arch = getSelectedArch(); options.cpu = getSelectedCPU(); options.bits = getSelectedBits(); @@ -369,9 +387,9 @@ void InitialOptionsDialog::setupAndStartAnalysis() options.writeEnabled = ui->writeCheckBox->isChecked(); options.loadBinInfo = !ui->binCheckBox->isChecked(); options.useVA = ui->vaCheckBox->isChecked(); - QVariant forceBinPluginData = ui->formatComboBox->currentData(); + const QVariant forceBinPluginData = ui->formatComboBox->currentData(); if (!forceBinPluginData.isNull()) { - RzBinPluginDescription pluginDesc = forceBinPluginData.value(); + const auto pluginDesc = forceBinPluginData.value(); options.forceBinPlugin = pluginDesc.name; } options.demangle = ui->demangleCheckBox->isChecked(); @@ -388,7 +406,7 @@ void InitialOptionsDialog::setupAndStartAnalysis() options.endian = getSelectedEndianness(); - int level = ui->analysisSlider->value(); + const int level = ui->analysisSlider->value(); switch (level) { case 1: options.analysisCmd = { { "aaa", @@ -407,7 +425,7 @@ void InitialOptionsDialog::setupAndStartAnalysis() break; } - AnalysisTask *analysisTask = new AnalysisTask(); + auto *analysisTask = new AnalysisTask(); analysisTask->setOptions(options); MainWindow *main = this->main; @@ -419,9 +437,10 @@ void InitialOptionsDialog::setupAndStartAnalysis() main->finalizeOpen(); }); - AsyncTask::Ptr analysisTaskPtr(analysisTask); + const AsyncTask::Ptr analysisTaskPtr(analysisTask); + + auto *taskDialog = new AsyncTaskDialog(analysisTaskPtr); - AsyncTaskDialog *taskDialog = new AsyncTaskDialog(analysisTaskPtr); taskDialog->setInterruptOnClose(true); taskDialog->setAttribute(Qt::WA_DeleteOnClose); taskDialog->show(); @@ -433,7 +452,7 @@ void InitialOptionsDialog::setupAndStartAnalysis() static_cast(qApp)->setInitialOptions(options); } -void InitialOptionsDialog::on_okButton_clicked() +void InitialOptionsDialog::onOkButtonClicked() { ui->okButton->setEnabled(false); setupAndStartAnalysis(); @@ -461,7 +480,7 @@ QString InitialOptionsDialog::analysisDescription(int level) } } -void InitialOptionsDialog::on_analysisSlider_valueChanged(int value) +void InitialOptionsDialog::onAnalysisSliderValueChanged(int value) { ui->analDescription->setText(tr("Level") + QString(": %1").arg(analysisDescription(value))); if (value == 0) { @@ -480,18 +499,18 @@ void InitialOptionsDialog::on_analysisSlider_valueChanged(int value) } } -void InitialOptionsDialog::on_AdvOptButton_clicked() +void InitialOptionsDialog::onAdvOptButtonClicked() { - if (ui->AdvOptButton->isChecked()) { + if (ui->advOptButton->isChecked()) { ui->hideFrame->setVisible(true); - ui->AdvOptButton->setArrowType(Qt::DownArrow); + ui->advOptButton->setArrowType(Qt::DownArrow); } else { ui->hideFrame->setVisible(false); - ui->AdvOptButton->setArrowType(Qt::RightArrow); + ui->advOptButton->setArrowType(Qt::RightArrow); } } -void InitialOptionsDialog::on_analysisCheckBox_clicked(bool checked) +void InitialOptionsDialog::onAnalysisCheckBoxClicked(bool checked) { if (!checked) { analysisLevel = ui->analysisSlider->value(); @@ -499,7 +518,7 @@ void InitialOptionsDialog::on_analysisCheckBox_clicked(bool checked) ui->analysisSlider->setValue(checked ? analysisLevel : 0); } -void InitialOptionsDialog::on_archComboBox_currentIndexChanged(int) +void InitialOptionsDialog::onArchComboBoxCurrentIndexChanged(int) { updateCPUComboBox(); } @@ -509,7 +528,7 @@ void InitialOptionsDialog::updatePDBLayout() ui->pdbWidget->setEnabled(ui->pdbCheckBox->isChecked()); } -void InitialOptionsDialog::on_pdbSelectButton_clicked() +void InitialOptionsDialog::onPdbSelectButtonClicked() { QFileDialog dialog(this); dialog.setWindowTitle(tr("Select PDB file")); @@ -519,7 +538,11 @@ void InitialOptionsDialog::on_pdbSelectButton_clicked() return; } - const QString &fileName = QDir::toNativeSeparators(dialog.selectedFiles().first()); + const auto files = dialog.selectedFiles(); + if (files.first().isEmpty()) { + return; + } + const QString &fileName = QDir::toNativeSeparators(files.first()); if (!fileName.isEmpty()) { ui->pdbLineEdit->setText(fileName); @@ -531,7 +554,7 @@ void InitialOptionsDialog::updateScriptLayout() ui->scriptWidget->setEnabled(ui->scriptCheckBox->isChecked()); } -void InitialOptionsDialog::on_scriptSelectButton_clicked() +void InitialOptionsDialog::onScriptSelectButtonClicked() { QFileDialog dialog(this); dialog.setWindowTitle(tr("Select Rizin script file")); @@ -541,7 +564,11 @@ void InitialOptionsDialog::on_scriptSelectButton_clicked() return; } - const QString &fileName = QDir::toNativeSeparators(dialog.selectedFiles().first()); + const auto files = dialog.selectedFiles(); + if (files.first().isEmpty()) { + return; + } + const QString &fileName = QDir::toNativeSeparators(files.first()); if (!fileName.isEmpty()) { ui->scriptLineEdit->setText(fileName); diff --git a/src/dialogs/InitialOptionsDialog.h b/src/dialogs/InitialOptionsDialog.h index 76a970ef..2fd914e3 100644 --- a/src/dialogs/InitialOptionsDialog.h +++ b/src/dialogs/InitialOptionsDialog.h @@ -1,11 +1,13 @@ #ifndef OPTIONSDIALOG_H #define OPTIONSDIALOG_H -#include -#include -#include #include "common/InitialOptions.h" +#include +#include + +#include + namespace Ui { class InitialOptionsDialog; } @@ -23,13 +25,13 @@ public: void setupAndStartAnalysis(); private slots: - void on_okButton_clicked(); - void on_analysisSlider_valueChanged(int value); - void on_AdvOptButton_clicked(); - void on_analysisCheckBox_clicked(bool checked); - void on_archComboBox_currentIndexChanged(int index); - void on_pdbSelectButton_clicked(); - void on_scriptSelectButton_clicked(); + void onOkButtonClicked(); + void onAnalysisSliderValueChanged(int value); + void onAdvOptButtonClicked(); + void onAnalysisCheckBoxClicked(bool checked); + void onArchComboBoxCurrentIndexChanged(int index); + void onPdbSelectButtonClicked(); + void onScriptSelectButtonClicked(); void updatePDBLayout(); void updateScriptLayout(); @@ -42,7 +44,6 @@ private: std::unique_ptr ui; MainWindow *main; - CutterCore *core; QString analysisDescription(int level); QString shellcode; diff --git a/src/dialogs/InitialOptionsDialog.ui b/src/dialogs/InitialOptionsDialog.ui index 72c38500..b4cd51f9 100644 --- a/src/dialogs/InitialOptionsDialog.ui +++ b/src/dialogs/InitialOptionsDialog.ui @@ -416,9 +416,9 @@ 0 - -49 + 0 564 - 479 + 453 @@ -483,7 +483,7 @@ 0 - + 6 @@ -563,7 +563,7 @@ 0 - + ... @@ -582,7 +582,7 @@ - + 0 @@ -605,7 +605,7 @@ - + 0 @@ -836,7 +836,7 @@ - + Qt::Orientation::Horizontal @@ -876,7 +876,7 @@ - + @@ -914,7 +914,7 @@ - + diff --git a/src/dialogs/LayoutManager.cpp b/src/dialogs/LayoutManager.cpp index d1548964..ddd52853 100644 --- a/src/dialogs/LayoutManager.cpp +++ b/src/dialogs/LayoutManager.cpp @@ -1,7 +1,10 @@ #include "LayoutManager.h" + #include "ui_LayoutManager.h" -#include + #include +#include +#include using namespace Cutter; @@ -18,7 +21,7 @@ LayoutManager::LayoutManager(QMap &layouts, QWidg LayoutManager::~LayoutManager() {} -void LayoutManager::refreshNameList(QString selection) +void LayoutManager::refreshNameList(const QString &selection) { ui->layoutSelector->clear(); for (auto it = layouts.begin(), end = layouts.end(); it != end; ++it) { @@ -34,7 +37,7 @@ void LayoutManager::refreshNameList(QString selection) void LayoutManager::renameCurrentLayout() { - QString current = ui->layoutSelector->currentText(); + const QString current = ui->layoutSelector->currentText(); if (layouts.contains(current)) { QString newName; while (newName.isEmpty() || isBuiltinLayoutName(newName) || layouts.contains(newName)) { @@ -67,7 +70,7 @@ void LayoutManager::deleteLayout() void LayoutManager::updateButtons() { - bool hasSelection = !ui->layoutSelector->currentText().isEmpty(); + const bool hasSelection = !ui->layoutSelector->currentText().isEmpty(); ui->renameButton->setEnabled(hasSelection); ui->deleteButton->setEnabled(hasSelection); } diff --git a/src/dialogs/LayoutManager.h b/src/dialogs/LayoutManager.h index cac19103..fda04f64 100644 --- a/src/dialogs/LayoutManager.h +++ b/src/dialogs/LayoutManager.h @@ -1,15 +1,19 @@ #ifndef LAYOUT_MANAGER_H #define LAYOUT_MANAGER_H -#include -#include -#include "core/Cutter.h" #include "common/CutterLayout.h" +#include + +#include + namespace Ui { class LayoutManager; } +/** + * @brief Dialog for managing custom UI layouts + */ class LayoutManager : public QDialog { Q_OBJECT @@ -19,7 +23,7 @@ public: ~LayoutManager(); private: - void refreshNameList(QString selection = ""); + void refreshNameList(const QString &selection = ""); void renameCurrentLayout(); void deleteLayout(); void updateButtons(); diff --git a/src/dialogs/MapFileDialog.cpp b/src/dialogs/MapFileDialog.cpp index 24cbbf7a..cee8c6f7 100644 --- a/src/dialogs/MapFileDialog.cpp +++ b/src/dialogs/MapFileDialog.cpp @@ -1,21 +1,26 @@ #include "MapFileDialog.h" -#include "ui_MapFileDialog.h" #include "common/Configuration.h" +#include "ui_MapFileDialog.h" #include MapFileDialog::MapFileDialog(QWidget *parent) : QDialog(parent), ui(new Ui::MapFileDialog) { ui->setupUi(this); + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &MapFileDialog::onButtonBoxAccepted); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &MapFileDialog::onButtonBoxRejected); + connect(ui->selectFileButton, &QPushButton::clicked, this, + &MapFileDialog::onSelectFileButtonClicked); } MapFileDialog::~MapFileDialog() {} -void MapFileDialog::on_selectFileButton_clicked() +void MapFileDialog::onSelectFileButtonClicked() { - QString currentDir = Config()->getRecentFolder(); - QString fileName = QFileDialog::getOpenFileName(this, tr("Select file"), currentDir); + const QString currentDir = Config()->getRecentFolder(); + const QString fileName = QFileDialog::getOpenFileName(this, tr("Select file"), currentDir); if (!fileName.isEmpty()) { ui->filenameLineEdit->setText(fileName); @@ -23,11 +28,11 @@ void MapFileDialog::on_selectFileButton_clicked() } } -void MapFileDialog::on_buttonBox_accepted() +void MapFileDialog::onButtonBoxAccepted() { const QString &filePath = QDir::toNativeSeparators(ui->filenameLineEdit->text()); RVA mapAddress = RVA_INVALID; - QString mapAddressStr = ui->mapAddressLineEdit->text(); + const QString mapAddressStr = ui->mapAddressLineEdit->text(); if (!mapAddressStr.isEmpty()) { mapAddress = Core()->math(mapAddressStr); } @@ -39,7 +44,7 @@ void MapFileDialog::on_buttonBox_accepted() close(); } -void MapFileDialog::on_buttonBox_rejected() +void MapFileDialog::onButtonBoxRejected() { close(); } diff --git a/src/dialogs/MapFileDialog.h b/src/dialogs/MapFileDialog.h index 04aa87d6..61d19b10 100644 --- a/src/dialogs/MapFileDialog.h +++ b/src/dialogs/MapFileDialog.h @@ -2,13 +2,17 @@ #define MAPFILEDIALOG_H #include + #include -#include "core/Cutter.h" namespace Ui { class MapFileDialog; } +/** + * @brief Dialog for mapping an external file into the current IO session at a specific memory + * address + */ class MapFileDialog : public QDialog { Q_OBJECT @@ -18,9 +22,9 @@ public: ~MapFileDialog(); private slots: - void on_selectFileButton_clicked(); - void on_buttonBox_accepted(); - void on_buttonBox_rejected(); + void onSelectFileButtonClicked(); + void onButtonBoxAccepted(); + void onButtonBoxRejected(); private: std::unique_ptr ui; diff --git a/src/dialogs/MarkDialog.cpp b/src/dialogs/MarkDialog.cpp index cf069a36..d2591142 100644 --- a/src/dialogs/MarkDialog.cpp +++ b/src/dialogs/MarkDialog.cpp @@ -1,14 +1,18 @@ #include "MarkDialog.h" + #include "Cutter.h" #include "CutterCommon.h" #include "ui_MarkDialog.h" + #include #include +#include + MarkDialog::MarkDialog(RVA start, RVA end, QWidget *parent, QString name) : QDialog(parent), ui(new Ui::MarkDialog), - markName(name), + markName(std::move(name)), markFrom(start), markTo(end), markColor(Qt::black), @@ -21,7 +25,7 @@ MarkDialog::MarkDialog(RVA start, RVA end, QWidget *parent, QString name) // Editing existing Mark setWindowTitle("Edit Mark"); RzCoreLocked core(Core()); - RzMarkItem *mark = rz_mark_get(core->marks, markName.toStdString().c_str()); + const RzMarkItem *mark = rz_mark_get(core->marks, markName.toStdString().c_str()); if (mark) { markFrom = mark->from; markTo = mark->to; @@ -32,11 +36,11 @@ MarkDialog::MarkDialog(RVA start, RVA end, QWidget *parent, QString name) } else { // Creating new Mark setWindowTitle("Add Mark"); - markName = QString("%1_%2").arg(RzAddressString(markFrom), RzAddressString(markTo)); + markName = QString("%1_%2").arg(rzAddressString(markFrom), rzAddressString(markTo)); } - ui->startAddressEdit->setText(RzAddressString(markFrom)); - ui->endAddressEdit->setText(RzAddressString(markTo)); + ui->startAddressEdit->setText(rzAddressString(markFrom)); + ui->endAddressEdit->setText(rzAddressString(markTo)); ui->nameEdit->setText(markName); ui->commentEdit->setText(markComment); ui->colorDisplay->setStyleSheet(colorToStyle(markColor)); @@ -72,7 +76,7 @@ void MarkDialog::accept() return; } - QString name = ui->nameEdit->text(); + const QString name = ui->nameEdit->text(); if (edit && !name.isEmpty() && name != markName) { Core()->delMark(markName); // Delete the old mark } else if (name.isEmpty()) { @@ -91,7 +95,7 @@ MarkDialog::~MarkDialog() {} void MarkDialog::onPickColor() { - QColor c = QColorDialog::getColor(markColor, this, tr("Pick Background Color")); + const QColor c = QColorDialog::getColor(markColor, this, tr("Pick Background Color")); if (c.isValid()) { markColor = c; ui->colorDisplay->setStyleSheet(colorToStyle(markColor)); @@ -104,5 +108,5 @@ QString MarkDialog::colorToStyle(const QColor &color) .arg(color.red()) .arg(color.green()) .arg(color.blue()) - .arg(MARK_ALPHA_F); + .arg(markAlphaF); } diff --git a/src/dialogs/MarkDialog.h b/src/dialogs/MarkDialog.h index 26399cf7..1a357df5 100644 --- a/src/dialogs/MarkDialog.h +++ b/src/dialogs/MarkDialog.h @@ -2,15 +2,23 @@ #define MARKDIALOG_H #include "CutterCommon.h" -#include -#include -constexpr qreal MARK_ALPHA_F = 0.5; // 50% alpha to show blending of multiple overalapping marks +#include +#include + +#include + +constexpr qreal markAlphaF = 0.5; // 50% alpha to show blending of multiple overalapping marks namespace Ui { class MarkDialog; } +/** + * @brief Dialog for managing marks + * + * Marks are similar to bookmarking a specific address or range of addresses + */ class MarkDialog : public QDialog { Q_OBJECT diff --git a/src/dialogs/MultitypeFileSaveDialog.cpp b/src/dialogs/MultitypeFileSaveDialog.cpp index 4e3d7a2c..4b8b1fa1 100644 --- a/src/dialogs/MultitypeFileSaveDialog.cpp +++ b/src/dialogs/MultitypeFileSaveDialog.cpp @@ -1,5 +1,3 @@ -#include "CutterConfig.h" - #include "MultitypeFileSaveDialog.h" #include @@ -15,7 +13,7 @@ MultitypeFileSaveDialog::MultitypeFileSaveDialog(QWidget *parent, const QString } void MultitypeFileSaveDialog::setTypes( - const QVector types, bool useDetection) + const QVector &types, bool useDetection) { this->hasTypeDetection = useDetection; this->types.clear(); @@ -39,7 +37,11 @@ MultitypeFileSaveDialog::TypeDescription MultitypeFileSaveDialog::selectedType() return {}; } if (hasTypeDetection && filterIt == this->types.begin()) { - QFileInfo info(this->selectedFiles().first()); +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) + const QFileInfo info(this->selectedFiles().constFirst()); +#else + const QFileInfo info(this->selectedFiles().first()); +#endif QString currentSuffix = info.suffix(); filterIt = std::find_if(types.begin(), types.end(), [¤tSuffix](const TypeDescription &v) { @@ -57,7 +59,11 @@ MultitypeFileSaveDialog::TypeDescription MultitypeFileSaveDialog::selectedType() void MultitypeFileSaveDialog::done(int r) { if (r == QDialog::Accepted) { - QFileInfo info(selectedFiles().first()); +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) + const QFileInfo info(selectedFiles().constFirst()); +#else + const QFileInfo info(selectedFiles().first()); +#endif auto selectedType = this->selectedType(); if (selectedType.extension.isEmpty()) { QMessageBox::warning(this, tr("File save error"), @@ -74,17 +80,21 @@ void MultitypeFileSaveDialog::onFilterSelected(const QString &filter) if (it == types.end()) { return; } - bool detectionSelected = hasTypeDetection && it == types.begin(); + const bool detectionSelected = hasTypeDetection && it == types.begin(); if (detectionSelected) { setDefaultSuffix(types[1].extension); } else { setDefaultSuffix(it->extension); } if (!this->selectedFiles().empty()) { - QString currentSelection = this->selectedFiles().first(); - QFileInfo info(currentSelection); +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) + const QString currentSelection = this->selectedFiles().constFirst(); +#else + const QString currentSelection = this->selectedFiles().first(); +#endif + const QFileInfo info(currentSelection); if (!detectionSelected) { - QString currentSuffix = info.suffix(); + const QString currentSuffix = info.suffix(); if (currentSuffix != it->extension) { selectFile(info.dir().filePath(info.completeBaseName() + "." + it->extension)); } diff --git a/src/dialogs/MultitypeFileSaveDialog.h b/src/dialogs/MultitypeFileSaveDialog.h index 51ccb7f7..b5e1c09a 100644 --- a/src/dialogs/MultitypeFileSaveDialog.h +++ b/src/dialogs/MultitypeFileSaveDialog.h @@ -5,6 +5,10 @@ #include #include +/** + * @brief Save dialog that handles multiple file extensions and automatically updates file + * suffix based on the selected filter + */ class MultitypeFileSaveDialog : public QFileDialog { Q_OBJECT @@ -20,7 +24,7 @@ public: explicit MultitypeFileSaveDialog(QWidget *parent = nullptr, const QString &caption = QString(), const QString &directory = QString()); - void setTypes(const QVector types, bool useDetection = true); + void setTypes(const QVector &types, bool useDetection = true); TypeDescription selectedType() const; protected: diff --git a/src/dialogs/NativeDebugDialog.cpp b/src/dialogs/NativeDebugDialog.cpp index 2a214026..8e9e1b57 100644 --- a/src/dialogs/NativeDebugDialog.cpp +++ b/src/dialogs/NativeDebugDialog.cpp @@ -1,11 +1,12 @@ #include "NativeDebugDialog.h" -#include "ui_NativeDebugDialog.h" -#include "shortcuts/ShortcutManager.h" -#include "ProfileDirectivesDialog.h" +#include "ProfileDirectivesDialog.h" +#include "shortcuts/ShortcutManager.h" +#include "ui_NativeDebugDialog.h" + +#include #include #include -#include #include NativeDebugDialog::NativeDebugDialog(QWidget *parent) @@ -82,7 +83,7 @@ DebugConfigMethod NativeDebugDialog::getSelectedMethod() const void NativeDebugDialog::profilePathBtnClicked() { - QString filePath = + const QString filePath = QFileDialog::getOpenFileName(this, tr("Open RzRun Profile"), QString(), tr("RzRun Profiles (*.rz *.rrz);;All Files (*)")); setFileContents(filePath); @@ -99,7 +100,7 @@ void NativeDebugDialog::setFileContents(const QString &filePath) QFile file(filePath); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&file); - QString directives = in.readAll(); + const QString directives = in.readAll(); // These directives are loaded from the profile // If unmodified: 'dbg.profile' will point directly to the original file path diff --git a/src/dialogs/NativeDebugDialog.h b/src/dialogs/NativeDebugDialog.h index 2634dc5e..7481284f 100644 --- a/src/dialogs/NativeDebugDialog.h +++ b/src/dialogs/NativeDebugDialog.h @@ -1,14 +1,17 @@ #ifndef NATIVEDEBUGDIALOG_H #define NATIVEDEBUGDIALOG_H +#include "CutterCommon.h" // IWYU pragma: keep + #include + #include namespace Ui { class NativeDebugDialog; } -enum class DebugConfigMethod { CommandLine, RzRunProfile, RzRunDirectives }; +enum class DebugConfigMethod : ut8 { CommandLine, RzRunProfile, RzRunDirectives }; /** * @brief Dialog for connecting to native debug diff --git a/src/dialogs/NewFileDialog.cpp b/src/dialogs/NewFileDialog.cpp index 29746d23..5c6374a2 100644 --- a/src/dialogs/NewFileDialog.cpp +++ b/src/dialogs/NewFileDialog.cpp @@ -1,19 +1,20 @@ -#include "InitialOptionsDialog.h" -#include "core/MainWindow.h" #include "dialogs/NewFileDialog.h" -#include "dialogs/AboutDialog.h" -#include "ui_NewFileDialog.h" + +#include "InitialOptionsDialog.h" #include "common/Helpers.h" #include "common/HighDpiPixmap.h" +#include "core/MainWindow.h" +#include "dialogs/AboutDialog.h" +#include "ui_NewFileDialog.h" -#include -#include -#include #include -#include +#include #include +#include +#include +#include -const int NewFileDialog::MaxRecentFiles; +const int NewFileDialog::maxRecentFiles; static QColor getColorFor(int pos) { @@ -31,8 +32,8 @@ static QColor getColorFor(int pos) static QIcon getIconFor(const QString &str, int pos) { // Add to the icon list - int w = 64; - int h = 64; + const int w = 64; + const int h = 64; HighDpiPixmap pixmap(w, h); pixmap.fill(Qt::transparent); @@ -59,9 +60,9 @@ NewFileDialog::NewFileDialog(MainWindow *main) ui->setupUi(this); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); setAcceptDrops(true); - ui->recentsListWidget->addAction(ui->actionRemove_item); - ui->recentsListWidget->addAction(ui->actionClear_all); - ui->projectsListWidget->addAction(ui->actionRemove_project); + ui->recentsListWidget->addAction(ui->actionRemoveItem); + ui->recentsListWidget->addAction(ui->actionClearAll); + ui->projectsListWidget->addAction(ui->actionRemoveProject); ui->projectsListWidget->addAction(ui->actionClearProjects); ui->logoSvgWidget->load(Config()->getLogoFile()); @@ -79,18 +80,56 @@ NewFileDialog::NewFileDialog(MainWindow *main) ui->shellcodeText->installEventFilter(this); updateLoadProjectButton(); + + connect(ui->loadFileButton, &QPushButton::clicked, this, + &NewFileDialog::onLoadFileButtonClicked); + connect(ui->selectFileButton, &QPushButton::clicked, this, + &NewFileDialog::onSelectFileButtonClicked); + connect(ui->recentsListWidget, &QListWidget::itemClicked, this, + &NewFileDialog::onRecentsListWidgetItemClicked); + connect(ui->recentsListWidget, &QListWidget::currentItemChanged, this, + &NewFileDialog::onRecentsListWidgetCurrentItemChanged); + connect(ui->recentsListWidget, &QListWidget::itemDoubleClicked, this, + &NewFileDialog::onRecentsListWidgetItemDoubleClicked); + connect(ui->selectProjectFileButton, &QPushButton::clicked, this, + &NewFileDialog::onSelectProjectFileButtonClicked); + connect(ui->loadProjectButton, &QPushButton::clicked, this, + &NewFileDialog::onLoadProjectButtonClicked); + connect(ui->projectFileEdit, &QLineEdit::textChanged, this, + &NewFileDialog::onProjectFileEditTextChanged); + connect(ui->projectsListWidget, &QListWidget::itemClicked, this, + &NewFileDialog::onProjectsListWidgetItemClicked); + connect(ui->projectsListWidget, &QListWidget::itemDoubleClicked, this, + &NewFileDialog::onProjectsListWidgetItemDoubleClicked); + connect(ui->shellcodeButton, &QPushButton::clicked, this, + &NewFileDialog::onShellcodeButtonClicked); + connect(ui->aboutButton, &QPushButton::clicked, this, &NewFileDialog::onAboutButtonClicked); + connect(ui->tabWidget, &QTabWidget::currentChanged, this, + &NewFileDialog::onTabWidgetCurrentChanged); + connect(ui->newFileEdit, &QLineEdit::returnPressed, this, + &NewFileDialog::onLoadFileButtonClicked); + connect(ui->projectFileEdit, &QLineEdit::returnPressed, this, + &NewFileDialog::onLoadProjectButtonClicked); + connect(ui->actionRemoveItem, &QAction::triggered, this, + &NewFileDialog::onActionRemoveItemTriggered); + connect(ui->actionClearAll, &QAction::triggered, this, + &NewFileDialog::onActionClearAllTriggered); + connect(ui->actionRemoveProject, &QAction::triggered, this, + &NewFileDialog::onActionRemoveProjectTriggered); + connect(ui->actionClearProjects, &QAction::triggered, this, + &NewFileDialog::onActionClearProjectsTriggered); } NewFileDialog::~NewFileDialog() {} -void NewFileDialog::on_loadFileButton_clicked() +void NewFileDialog::onLoadFileButtonClicked() { loadFile(ui->newFileEdit->text()); } -void NewFileDialog::on_selectFileButton_clicked() +void NewFileDialog::onSelectFileButtonClicked() { - QString currentDir = Config()->getRecentFolder(); + const QString currentDir = Config()->getRecentFolder(); const QString &fileName = QDir::toNativeSeparators( QFileDialog::getOpenFileName(this, tr("Select file"), currentDir)); @@ -101,7 +140,7 @@ void NewFileDialog::on_selectFileButton_clicked() } } -void NewFileDialog::on_selectProjectFileButton_clicked() +void NewFileDialog::onSelectProjectFileButtonClicked() { const QString &fileName = QDir::toNativeSeparators(QFileDialog::getOpenFileName(this, tr("Open Project"))); @@ -112,74 +151,74 @@ void NewFileDialog::on_selectProjectFileButton_clicked() } } -void NewFileDialog::on_loadProjectButton_clicked() +void NewFileDialog::onLoadProjectButtonClicked() { loadProject(ui->projectFileEdit->text()); } -void NewFileDialog::on_shellcodeButton_clicked() +void NewFileDialog::onShellcodeButtonClicked() { - QString shellcode = ui->shellcodeText->toPlainText(); + const QString shellcode = ui->shellcodeText->toPlainText(); QString extractedCode = ""; static const QRegularExpression rx("([0-9a-f]{2})", QRegularExpression::CaseInsensitiveOption); QRegularExpressionMatchIterator i = rx.globalMatch(shellcode); while (i.hasNext()) { - QRegularExpressionMatch match = i.next(); + const QRegularExpressionMatch match = i.next(); extractedCode.append(match.captured(1)); } - int size = extractedCode.size() / 2; + const int size = extractedCode.size() / 2; if (size > 0) { loadShellcode(extractedCode, size); } } -void NewFileDialog::on_recentsListWidget_itemClicked(QListWidgetItem *item) +void NewFileDialog::onRecentsListWidgetItemClicked(QListWidgetItem *item) { updateSelectionFromItem(item); } -void NewFileDialog::on_recentsListWidget_currentItemChanged(QListWidgetItem *current) +void NewFileDialog::onRecentsListWidgetCurrentItemChanged(QListWidgetItem *current) { updateSelectionFromItem(current); } -void NewFileDialog::on_recentsListWidget_itemDoubleClicked(QListWidgetItem *item) +void NewFileDialog::onRecentsListWidgetItemDoubleClicked(QListWidgetItem *item) { const QStringList sitem = item->data(Qt::UserRole).toStringList(); loadFile(sitem.at(1)); } -void NewFileDialog::on_projectFileEdit_textChanged() +void NewFileDialog::onProjectFileEditTextChanged() { updateLoadProjectButton(); } -void NewFileDialog::on_projectsListWidget_itemClicked(QListWidgetItem *item) +void NewFileDialog::onProjectsListWidgetItemClicked(QListWidgetItem *item) { ui->projectFileEdit->setText(item->data(Qt::UserRole).toStringList().at(1)); } -void NewFileDialog::on_projectsListWidget_itemDoubleClicked(QListWidgetItem *item) +void NewFileDialog::onProjectsListWidgetItemDoubleClicked(QListWidgetItem *item) { loadProject(item->data(Qt::UserRole).toStringList().at(1)); } -void NewFileDialog::on_aboutButton_clicked() +void NewFileDialog::onAboutButtonClicked() { - AboutDialog *a = new AboutDialog(this); + auto *a = new AboutDialog(this); a->setAttribute(Qt::WA_DeleteOnClose); a->open(); } -void NewFileDialog::on_actionRemove_item_triggered() +void NewFileDialog::onActionRemoveItemTriggered() { // Remove selected item from recents list - QListWidgetItem *item = ui->recentsListWidget->currentItem(); + const QListWidgetItem *item = ui->recentsListWidget->currentItem(); if (item == nullptr) { return; } - QStringList sitem = item->data(Qt::UserRole).toStringList(); - RecentFileEntry file = { sitem.at(0), sitem.at(1) }; + const QStringList sitem = item->data(Qt::UserRole).toStringList(); + const RecentFileEntry file = { sitem.at(0), sitem.at(1) }; QList files = Config()->getRecentFiles(); files.removeAll(file); Config()->setRecentFiles(files); @@ -187,21 +226,21 @@ void NewFileDialog::on_actionRemove_item_triggered() ui->newFileEdit->clear(); } -void NewFileDialog::on_actionClear_all_triggered() +void NewFileDialog::onActionClearAllTriggered() { Config()->setRecentFiles({}); ui->recentsListWidget->clear(); ui->newFileEdit->clear(); } -void NewFileDialog::on_actionRemove_project_triggered() +void NewFileDialog::onActionRemoveProjectTriggered() { - QListWidgetItem *item = ui->projectsListWidget->currentItem(); + const QListWidgetItem *item = ui->projectsListWidget->currentItem(); if (item == nullptr) { return; } - QString sitem = item->data(Qt::UserRole).toString(); - RecentFileEntry project = { "", sitem }; + const QString sitem = item->data(Qt::UserRole).toString(); + const RecentFileEntry project = { "", sitem }; QList files = Config()->getRecentProjects(); files.removeAll(project); Config()->setRecentProjects(files); @@ -209,7 +248,7 @@ void NewFileDialog::on_actionRemove_project_triggered() ui->projectFileEdit->clear(); } -void NewFileDialog::on_actionClearProjects_triggered() +void NewFileDialog::onActionClearProjectsTriggered() { Config()->setRecentProjects({}); ui->projectsListWidget->clear(); @@ -236,7 +275,7 @@ void NewFileDialog::dropEvent(QDropEvent *event) loadFile(event->mimeData()->urls().first().toLocalFile()); } -/* +/** * @brief Add the existing files from the list to the widget. * @return the list of files that actually exist */ @@ -260,18 +299,18 @@ static QList fillFilesList(QListWidget *widget, filenameHome.replace(basename, ""); filenameHome.chop(1); // Remove last character that will be a path separator // Get file info - QFileInfo info(path); + const QFileInfo info(path); if (!info.exists()) { it.remove(); } else { // Format the text const QString text = QString("%1\n%2\nSize: %3") - .arg(basename, filenameHome, qhelpers::formatBytecount(info.size())); - QListWidgetItem *item = new QListWidgetItem(getIconFor(basename, i++), text); + .arg(basename, filenameHome, qhelpers::formatByteCount(info.size())); + auto *item = new QListWidgetItem(getIconFor(basename, i++), text); // add the item to the file list - QStringList fullpath = { ioMode, path }; + const QStringList fullpath = { ioMode, path }; item->setData(Qt::UserRole, fullpath); widget->addItem(item); } @@ -304,7 +343,7 @@ void NewFileDialog::fillIOPluginsList() Qt::ToolTipRole); int index = 1; - QList ioPlugins = Core()->getRIOPluginDescriptions(); + const QList ioPlugins = Core()->getRIOPluginDescriptions(); for (const RzIOPluginDescription &plugin : ioPlugins) { // Hide debug plugins if (plugin.permissions.contains('d')) { @@ -329,7 +368,7 @@ void NewFileDialog::updateLoadProjectButton() void NewFileDialog::loadFile(const QString &filename) { - bool isFileless = ui->checkBox_FilelessOpen->isChecked(); + const bool isFileless = ui->checkBoxFilelessOpen->isChecked(); QString ioFile; if (!isFileless) { const QString &nativeFn = QDir::toNativeSeparators(filename); @@ -344,12 +383,13 @@ void NewFileDialog::loadFile(const QString &filename) ioFile = ioMode + nativeFn; // Add file to recent file list - RecentFileEntry file = { ioMode, nativeFn }; + const RecentFileEntry file = { ioMode, nativeFn }; QList files = Config()->getRecentFiles(); files.removeAll(file); files.prepend(file); - while (files.size() > MaxRecentFiles) + while (files.size() > maxRecentFiles) { files.removeLast(); + } Config()->setRecentFiles(files); } @@ -363,7 +403,7 @@ void NewFileDialog::loadFile(const QString &filename) void NewFileDialog::loadProject(const QString &project) { - MainWindow *main = new MainWindow(); + auto *main = new MainWindow(); if (!main->openProject(project)) { return; } @@ -372,7 +412,7 @@ void NewFileDialog::loadProject(const QString &project) void NewFileDialog::loadShellcode(const QString &shellcode, const int size) { - MainWindow *main = new MainWindow(); + auto *main = new MainWindow(); InitialOptions options; options.filename = QString("malloc://%1").arg(size); options.shellcode = shellcode; @@ -380,27 +420,27 @@ void NewFileDialog::loadShellcode(const QString &shellcode, const int size) close(); } -void NewFileDialog::on_tabWidget_currentChanged(int index) +void NewFileDialog::onTabWidgetCurrentChanged(int index) { Config()->setNewFileLastClicked(index); } bool NewFileDialog::eventFilter(QObject * /*obj*/, QEvent *event) { - QString shellcode = ui->shellcodeText->toPlainText(); + const QString shellcode = ui->shellcodeText->toPlainText(); QString extractedCode = ""; static const QRegularExpression rx("([0-9a-f]{2})", QRegularExpression::CaseInsensitiveOption); QRegularExpressionMatchIterator i = rx.globalMatch(shellcode); int size = 0; if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); + const auto *keyEvent = static_cast(event); // Confirm comment by pressing Ctrl/Cmd+Return if ((keyEvent->modifiers() & Qt::ControlModifier) && ((keyEvent->key() == Qt::Key_Enter) || (keyEvent->key() == Qt::Key_Return))) { while (i.hasNext()) { - QRegularExpressionMatch match = i.next(); + const QRegularExpressionMatch match = i.next(); extractedCode.append(match.captured(1)); } size = extractedCode.size() / 2; @@ -419,7 +459,7 @@ void NewFileDialog::updateSelectionFromItem(QListWidgetItem *item) if (!item) { return; } - QStringList sitem = item->data(Qt::UserRole).toStringList(); + const QStringList sitem = item->data(Qt::UserRole).toStringList(); ui->ioPlugin->setCurrentIndex(ui->ioPlugin->findText(sitem.at(0))); ui->newFileEdit->setText(sitem.at(1)); } diff --git a/src/dialogs/NewFileDialog.h b/src/dialogs/NewFileDialog.h index 3142b407..ae260344 100644 --- a/src/dialogs/NewFileDialog.h +++ b/src/dialogs/NewFileDialog.h @@ -3,6 +3,7 @@ #include #include + #include namespace Ui { @@ -11,6 +12,9 @@ class NewFileDialog; class MainWindow; +/** + * @brief Dialog for opening a new file or project + */ class NewFileDialog : public QDialog { Q_OBJECT @@ -20,29 +24,29 @@ public: ~NewFileDialog(); private slots: - void on_loadFileButton_clicked(); - void on_selectFileButton_clicked(); - void on_selectProjectFileButton_clicked(); + void onLoadFileButtonClicked(); + void onSelectFileButtonClicked(); + void onSelectProjectFileButtonClicked(); - void on_loadProjectButton_clicked(); - void on_shellcodeButton_clicked(); + void onLoadProjectButtonClicked(); + void onShellcodeButtonClicked(); - void on_aboutButton_clicked(); + void onAboutButtonClicked(); - void on_recentsListWidget_itemClicked(QListWidgetItem *item); - void on_recentsListWidget_itemDoubleClicked(QListWidgetItem *item); - void on_recentsListWidget_currentItemChanged(QListWidgetItem *current); + void onRecentsListWidgetItemClicked(QListWidgetItem *item); + void onRecentsListWidgetItemDoubleClicked(QListWidgetItem *item); + void onRecentsListWidgetCurrentItemChanged(QListWidgetItem *current); - void on_projectFileEdit_textChanged(); - void on_projectsListWidget_itemClicked(QListWidgetItem *item); - void on_projectsListWidget_itemDoubleClicked(QListWidgetItem *item); + void onProjectFileEditTextChanged(); + void onProjectsListWidgetItemClicked(QListWidgetItem *item); + void onProjectsListWidgetItemDoubleClicked(QListWidgetItem *item); - void on_actionRemove_item_triggered(); - void on_actionClear_all_triggered(); - void on_actionRemove_project_triggered(); - void on_actionClearProjects_triggered(); + void onActionRemoveItemTriggered(); + void onActionClearAllTriggered(); + void onActionRemoveProjectTriggered(); + void onActionClearProjectsTriggered(); - void on_tabWidget_currentChanged(int index); + void onTabWidgetCurrentChanged(int index); protected: void dragEnterEvent(QDragEnterEvent *event); @@ -77,7 +81,7 @@ private: bool eventFilter(QObject *obj, QEvent *event); - static const int MaxRecentFiles = 5; + static const int maxRecentFiles = 5; }; #endif // NEWFILEDIALOG_H diff --git a/src/dialogs/NewFileDialog.ui b/src/dialogs/NewFileDialog.ui index 9e16c802..0a38a5b4 100755 --- a/src/dialogs/NewFileDialog.ui +++ b/src/dialogs/NewFileDialog.ui @@ -34,7 +34,7 @@ 2 - + @@ -63,7 +63,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -83,7 +83,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -121,10 +121,10 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain @@ -142,7 +142,7 @@ - 2 + 0 @@ -152,7 +152,7 @@ - QLayout::SetDefaultConstraint + QLayout::SizeConstraint::SetDefaultConstraint 5 @@ -214,7 +214,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -232,13 +232,13 @@ - Qt::ActionsContextMenu + Qt::ContextMenuPolicy::ActionsContextMenu - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain 0 @@ -250,16 +250,16 @@ - QAbstractItemView::ScrollPerPixel + QAbstractItemView::ScrollMode::ScrollPerPixel - QListView::Adjust + QListView::ResizeMode::Adjust 5 - QListView::ListMode + QListView::ViewMode::ListMode false @@ -280,7 +280,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -291,7 +291,7 @@ - + Don't open any file @@ -344,7 +344,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -373,7 +373,7 @@ - QLayout::SetDefaultConstraint + QLayout::SizeConstraint::SetDefaultConstraint 5 @@ -422,7 +422,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -440,13 +440,13 @@ - Qt::ActionsContextMenu + Qt::ContextMenuPolicy::ActionsContextMenu - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain 0 @@ -458,16 +458,16 @@ - QAbstractItemView::ScrollPerPixel + QAbstractItemView::ScrollMode::ScrollPerPixel - QListView::Adjust + QListView::ResizeMode::Adjust 5 - QListView::ListMode + QListView::ViewMode::ListMode false @@ -485,7 +485,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -514,17 +514,17 @@ - + Remove item - + Clear all - + Delete project diff --git a/src/dialogs/ProfileDirectivesDialog.cpp b/src/dialogs/ProfileDirectivesDialog.cpp index b986508d..e2a81fb4 100644 --- a/src/dialogs/ProfileDirectivesDialog.cpp +++ b/src/dialogs/ProfileDirectivesDialog.cpp @@ -1,18 +1,22 @@ #include "ProfileDirectivesDialog.h" + #include "ui_ProfileDirectivesDialog.h" #include ProfileDirectivesDialog::ProfileDirectivesDialog(QWidget *parent) - : QDialog(parent), ui(new Ui::ProfileDirectivesDialog) + : QDialog(parent), + ui(new Ui::ProfileDirectivesDialog), + model(new QStandardItemModel(this)), + proxyModel(new QSortFilterProxyModel(this)) { ui->setupUi(this); setWindowTitle(tr("Profile Directives")); - model = new QStandardItemModel(this); model->setHorizontalHeaderLabels({ tr("Key"), tr("Description") }); + // TODO: there should be a rizin function to query this addDirective("arg[0-511]", tr("Set value for argument N passed to the program")); addDirective("aslr", tr("Enable or disable ASLR")); addDirective("bits", tr("Set 32 or 64 bit (if the architecture supports it)")); @@ -64,7 +68,6 @@ ProfileDirectivesDialog::ProfileDirectivesDialog(QWidget *parent) tr("Signal to use when killing the child because the timeout happens")); addDirective("unsetenv", tr("Unset one environment variable")); - proxyModel = new QSortFilterProxyModel(this); proxyModel->setSourceModel(model); proxyModel->setFilterKeyColumn(0); proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); diff --git a/src/dialogs/ProfileDirectivesDialog.h b/src/dialogs/ProfileDirectivesDialog.h index e9cee5c1..e746d806 100644 --- a/src/dialogs/ProfileDirectivesDialog.h +++ b/src/dialogs/ProfileDirectivesDialog.h @@ -2,8 +2,9 @@ #define PROFILEDIRECTIVESDIALOG_H #include -#include #include +#include + #include namespace Ui { diff --git a/src/dialogs/RegisterProfileDialog.cpp b/src/dialogs/RegisterProfileDialog.cpp index 9a63874c..813d541b 100644 --- a/src/dialogs/RegisterProfileDialog.cpp +++ b/src/dialogs/RegisterProfileDialog.cpp @@ -1,15 +1,16 @@ #include "RegisterProfileDialog.h" -#include "ui_RegisterProfileDialog.h" -#include "Cutter.h" -#include "Configuration.h" -#include "EditRegProfileDialog.h" -#include -#include -#include +#include "Configuration.h" +#include "Cutter.h" +#include "EditRegProfileDialog.h" +#include "ui_RegisterProfileDialog.h" + #include -#include +#include #include +#include +#include +#include RegisterProfileDialog::RegisterProfileDialog(QWidget *parent) : QDialog(parent), ui(new Ui::RegisterProfileDialog) @@ -35,7 +36,7 @@ RegisterProfileDialog::~RegisterProfileDialog() = default; void RegisterProfileDialog::showContextMenu(const QPoint &pos) { - QListWidgetItem *item = ui->recentProfilesList->itemAt(pos); + const QListWidgetItem *item = ui->recentProfilesList->itemAt(pos); QMenu menu(this); if (item) { menu.addAction(tr("Remove Item"), this, &RegisterProfileDialog::removeItem); @@ -47,12 +48,12 @@ void RegisterProfileDialog::showContextMenu(const QPoint &pos) void RegisterProfileDialog::removeItem() { - QListWidgetItem *item = ui->recentProfilesList->currentItem(); + const QListWidgetItem *item = ui->recentProfilesList->currentItem(); if (!item) { return; } - QString serializedData = item->data(Qt::UserRole).toString(); + const QString serializedData = item->data(Qt::UserRole).toString(); Config()->removeRecentRegProfile(serializedData); delete ui->recentProfilesList->takeItem(ui->recentProfilesList->currentRow()); } @@ -68,15 +69,15 @@ void RegisterProfileDialog::fillProfilePaths(const QStringList &profilePaths) ui->recentProfilesList->clear(); for (const QString &p : profilePaths) { - bool isGdb = p.startsWith("gdb::"); - QString pathData = p.mid(p.indexOf("::") + 2); + const bool isGdb = p.startsWith("gdb::"); + const QString pathData = p.mid(p.indexOf("::") + 2); // Visible format: // [Rizin/GDB] /path/to/file // easier for user to remember if the opened file was a GDB profile or Rizin - QString displayText = QString("[%1] %2").arg(isGdb ? "GDB" : "Rizin", pathData); + const QString displayText = QString("[%1] %2").arg(isGdb ? "GDB" : "Rizin", pathData); - QListWidgetItem *item = new QListWidgetItem(displayText); + auto *item = new QListWidgetItem(displayText); item->setData(Qt::UserRole, p); ui->recentProfilesList->addItem(item); } @@ -84,8 +85,8 @@ void RegisterProfileDialog::fillProfilePaths(const QStringList &profilePaths) void RegisterProfileDialog::loadProfileBtnClicked() { - QString filePath = QFileDialog::getOpenFileName(this, tr("Open Register Profile"), QString(), - tr("All Files (*)")); + const QString filePath = QFileDialog::getOpenFileName(this, tr("Open Register Profile"), + QString(), tr("All Files (*)")); if (!filePath.isEmpty()) { setFileContents(filePath); loadedProfile = RegisterProfile::Rizin; @@ -94,13 +95,13 @@ void RegisterProfileDialog::loadProfileBtnClicked() void RegisterProfileDialog::loadGDBBtnClicked() { - QString filePath = QFileDialog::getOpenFileName(this, tr("Open GDB Profile"), QString(), - tr("All Files (*)")); + const QString filePath = QFileDialog::getOpenFileName(this, tr("Open GDB Profile"), QString(), + tr("All Files (*)")); if (filePath.isEmpty()) { return; } - QString profile = Core()->convertGDBProfile(filePath); + const QString profile = Core()->convertGdbProfile(filePath); if (profile.isEmpty()) { return; } @@ -119,7 +120,7 @@ void RegisterProfileDialog::setFileContents(const QString &filePath) QFile file(filePath); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&file); - QString data = in.readAll(); + const QString data = in.readAll(); setProfileData(data); setProfilePath(filePath); @@ -169,7 +170,7 @@ QString RegisterProfileDialog::getSerializedProfilePath() const // Saving format: // rizin::/path/to/profile // gdb::/path/to/profile - QString path = ui->profilePathEdit->text(); + const QString path = ui->profilePathEdit->text(); if (path.isEmpty()) { return QString(); } @@ -182,8 +183,8 @@ void RegisterProfileDialog::itemClicked(QListWidgetItem *item) return; } - QString fullSerialized = item->data(Qt::UserRole).toString(); - QString path = fullSerialized.mid(fullSerialized.indexOf("::") + 2); + const QString fullSerialized = item->data(Qt::UserRole).toString(); + const QString path = fullSerialized.mid(fullSerialized.indexOf("::") + 2); loadedProfile = fullSerialized.startsWith("gdb::") ? RegisterProfile::GDB : RegisterProfile::Rizin; @@ -198,8 +199,8 @@ void RegisterProfileDialog::exportProfileBtnClicked() return; } - QString filePath = QFileDialog::getSaveFileName(this, tr("Export Profile As"), QString(), - tr("All Files (*)")); + const QString filePath = QFileDialog::getSaveFileName(this, tr("Export Profile As"), QString(), + tr("All Files (*)")); if (filePath.isEmpty()) { return; } diff --git a/src/dialogs/RegisterProfileDialog.h b/src/dialogs/RegisterProfileDialog.h index a79b5f09..8c341623 100644 --- a/src/dialogs/RegisterProfileDialog.h +++ b/src/dialogs/RegisterProfileDialog.h @@ -1,15 +1,18 @@ #ifndef REGISTERPROFILEDIALOG_H #define REGISTERPROFILEDIALOG_H +#include "CutterCommon.h" // IWYU pragma: keep + #include #include + #include namespace Ui { class RegisterProfileDialog; } -enum class RegisterProfile { +enum class RegisterProfile : ut8 { Default, Rizin, GDB, diff --git a/src/dialogs/RemoteDebugDialog.cpp b/src/dialogs/RemoteDebugDialog.cpp index 600d22c2..7926317f 100644 --- a/src/dialogs/RemoteDebugDialog.cpp +++ b/src/dialogs/RemoteDebugDialog.cpp @@ -1,12 +1,14 @@ #include "RemoteDebugDialog.h" + +#include "CutterCommon.h" // IWYU pragma: keep #include "ui_RemoteDebugDialog.h" -#include #include +#include #include #include -enum DbgBackendType { GDB = 0, WINDBG = 1 }; +enum DbgBackendType : ut8 { GDB = 0, WINDBG = 1 }; struct DbgBackend { @@ -41,13 +43,18 @@ RemoteDebugDialog::RemoteDebugDialog(QWidget *parent) connect(ui->actionRemoveItem, &QAction::triggered, this, &RemoteDebugDialog::removeItem); connect(ui->recentsIpListWidget, &QListWidget::itemClicked, this, &RemoteDebugDialog::itemClicked); + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, + &RemoteDebugDialog::onButtonBoxAccepted); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, + &RemoteDebugDialog::onButtonBoxRejected); } RemoteDebugDialog::~RemoteDebugDialog() {} bool RemoteDebugDialog::validate() { - int debugger = getDebugger(); + const int debugger = getDebugger(); if (debugger == GDB) { return validatePort() && validateIp(); } else if (debugger == WINDBG) { @@ -63,7 +70,7 @@ bool RemoteDebugDialog::validateIp() { QMessageBox msgBox(this); - QString ip = getIpOrPath(); + const QString ip = getIpOrPath(); if (QHostAddress(ip).isNull()) { msgBox.setText(tr("Invalid IP address")); msgBox.exec(); @@ -76,8 +83,8 @@ bool RemoteDebugDialog::validatePath() { QMessageBox msgBox(this); - QString path = getIpOrPath(); - if (!QFileInfo(path).exists()) { + const QString path = getIpOrPath(); + if (!QFileInfo::exists(path)) { msgBox.setText(tr("Path does not exist")); msgBox.exec(); return false; @@ -89,7 +96,7 @@ bool RemoteDebugDialog::validatePort() { QMessageBox msgBox(this); - int port = getPort(); + const int port = getPort(); if (port < 1 || port > 65535) { msgBox.setText(tr("Invalid port")); msgBox.exec(); @@ -98,22 +105,23 @@ bool RemoteDebugDialog::validatePort() return true; } -void RemoteDebugDialog::on_buttonBox_accepted() {} +void RemoteDebugDialog::onButtonBoxAccepted() {} -void RemoteDebugDialog::on_buttonBox_rejected() +void RemoteDebugDialog::onButtonBoxRejected() { close(); } void RemoteDebugDialog::removeItem() { - QListWidgetItem *item = ui->recentsIpListWidget->currentItem(); + const QListWidgetItem *item = ui->recentsIpListWidget->currentItem(); - if (item == nullptr) + if (item == nullptr) { return; + } - QVariant data = item->data(Qt::UserRole); - QString sitem = data.toString(); + const QVariant data = item->data(Qt::UserRole); + const QString sitem = data.toString(); // Remove the item from recentIpList QSettings settings; @@ -138,7 +146,7 @@ void RemoteDebugDialog::clearAll() checkIfEmpty(); } -void RemoteDebugDialog::fillFormData(QString formdata) +void RemoteDebugDialog::fillFormData(const QString &formdata) { QString ipText = ""; QString portText = ""; @@ -154,7 +162,7 @@ void RemoteDebugDialog::fillFormData(QString formdata) if (backend->type == GDB) { // Format is | prefix | IP | : | PORT | - int lastColon = formdata.lastIndexOf(QString(":")); + const int lastColon = formdata.lastIndexOf(QString(":")); portText = formdata.mid(lastColon + 1, formdata.length()); ipText = formdata.mid(backend->prefix.length(), lastColon - backend->prefix.length()); } else if (backend->type == WINDBG) { @@ -168,7 +176,7 @@ void RemoteDebugDialog::fillFormData(QString formdata) QString RemoteDebugDialog::getUri() const { - int debugger = getDebugger(); + const int debugger = getDebugger(); if (debugger == WINDBG) { return QString("%1%2").arg(dbgBackends[WINDBG].prefix, getIpOrPath()); } else if (debugger == GDB) { @@ -180,7 +188,7 @@ QString RemoteDebugDialog::getUri() const bool RemoteDebugDialog::fillRecentIpList() { - QSettings settings; + const QSettings settings; // Fetch recentIpList QStringList ips = settings.value("recentIpList").toStringList(); @@ -188,7 +196,7 @@ bool RemoteDebugDialog::fillRecentIpList() while (it.hasNext()) { const QString ip = it.next(); const QString text = QString("%1").arg(ip); - QListWidgetItem *item = new QListWidgetItem(text); + auto *item = new QListWidgetItem(text); item->setData(Qt::UserRole, ip); // Fill recentsIpListWidget ui->recentsIpListWidget->addItem(item); @@ -205,8 +213,8 @@ bool RemoteDebugDialog::fillRecentIpList() void RemoteDebugDialog::checkIfEmpty() { - QSettings settings; - QStringList ips = settings.value("recentIpList").toStringList(); + const QSettings settings; + const QStringList ips = settings.value("recentIpList").toStringList(); if (ips.isEmpty()) { ui->recentsIpListWidget->setVisible(false); @@ -218,8 +226,8 @@ void RemoteDebugDialog::checkIfEmpty() void RemoteDebugDialog::itemClicked(QListWidgetItem *item) { - QVariant data = item->data(Qt::UserRole); - QString ipport = data.toString(); + const QVariant data = item->data(Qt::UserRole); + const QString ipport = data.toString(); fillFormData(ipport); } diff --git a/src/dialogs/RemoteDebugDialog.h b/src/dialogs/RemoteDebugDialog.h index c04909b7..b239c4f4 100644 --- a/src/dialogs/RemoteDebugDialog.h +++ b/src/dialogs/RemoteDebugDialog.h @@ -3,6 +3,7 @@ #include #include + #include namespace Ui { @@ -27,8 +28,8 @@ public: bool validate(); private slots: - void on_buttonBox_accepted(); - void on_buttonBox_rejected(); + void onButtonBoxAccepted(); + void onButtonBoxRejected(); /** * @brief Clears the list of recent connections. @@ -66,7 +67,7 @@ private: * @brief Fills the remote debug dialog form from a given URI * Eg: gdb://127.0.0.1:8754 or windbg:///tmp/abcd */ - void fillFormData(QString formdata); + void fillFormData(const QString &formdata); /** * @brief Checks if the recent connection list is empty or and hide/unhide the table view diff --git a/src/dialogs/RizinPluginsDialog.cpp b/src/dialogs/RizinPluginsDialog.cpp index 704e91fe..6be4ee44 100644 --- a/src/dialogs/RizinPluginsDialog.cpp +++ b/src/dialogs/RizinPluginsDialog.cpp @@ -1,11 +1,10 @@ #include "RizinPluginsDialog.h" -#include "ui_RizinPluginsDialog.h" #include "Configuration.h" #include "common/DisassemblyPreview.h" -#include "core/Cutter.h" #include "common/Helpers.h" -#include "plugins/PluginManager.h" +#include "core/Cutter.h" +#include "ui_RizinPluginsDialog.h" #include #include @@ -16,39 +15,39 @@ RizinPluginsDialog::RizinPluginsDialog(QWidget *parent) ui->setupUi(this); for (const auto &plugin : Core()->getBinPluginDescriptions()) { - QTreeWidgetItem *item = new QTreeWidgetItem(); + auto *item = new QTreeWidgetItem(); item->setText(0, plugin.name); item->setText(1, plugin.description); item->setText(2, plugin.license); item->setText(3, plugin.type); - ui->RzBinTreeWidget->addTopLevelItem(item); + ui->rzBinTreeWidget->addTopLevelItem(item); } - ui->RzBinTreeWidget->sortByColumn(0, Qt::AscendingOrder); - qhelpers::adjustColumns(ui->RzBinTreeWidget, 0); + ui->rzBinTreeWidget->sortByColumn(0, Qt::AscendingOrder); + qhelpers::adjustColumns(ui->rzBinTreeWidget, 0); for (const auto &plugin : Core()->getRIOPluginDescriptions()) { - QTreeWidgetItem *item = new QTreeWidgetItem(); + auto *item = new QTreeWidgetItem(); item->setText(0, plugin.name); item->setText(1, plugin.description); item->setText(2, plugin.license); item->setText(3, plugin.permissions); - ui->RzIOTreeWidget->addTopLevelItem(item); + ui->rzIOTreeWidget->addTopLevelItem(item); } - ui->RzIOTreeWidget->sortByColumn(0, Qt::AscendingOrder); - qhelpers::adjustColumns(ui->RzIOTreeWidget, 0); + ui->rzIOTreeWidget->sortByColumn(0, Qt::AscendingOrder); + qhelpers::adjustColumns(ui->rzIOTreeWidget, 0); for (const auto &plugin : Core()->getRCorePluginDescriptions()) { - QTreeWidgetItem *item = new QTreeWidgetItem(); + auto *item = new QTreeWidgetItem(); item->setText(0, plugin.name); item->setText(1, plugin.description); item->setText(2, plugin.license); - ui->RzCoreTreeWidget->addTopLevelItem(item); + ui->rzCoreTreeWidget->addTopLevelItem(item); } - ui->RzCoreTreeWidget->sortByColumn(0, Qt::AscendingOrder); - qhelpers::adjustColumns(ui->RzCoreTreeWidget, 0); + ui->rzCoreTreeWidget->sortByColumn(0, Qt::AscendingOrder); + qhelpers::adjustColumns(ui->rzCoreTreeWidget, 0); for (const auto &plugin : Core()->getRAsmPluginDescriptions()) { - QTreeWidgetItem *item = new QTreeWidgetItem(); + auto *item = new QTreeWidgetItem(); item->setText(0, plugin.name); item->setText(1, plugin.architecture); item->setText(2, plugin.cpus); @@ -71,19 +70,16 @@ RizinPluginsDialog::RizinPluginsDialog(QWidget *parent) item->setText(6, plugin.author); item->setText(7, plugin.capabilities); item->setText(8, plugin.bits); - ui->RzAsmTreeWidget->addTopLevelItem(item); + ui->rzAsmTreeWidget->addTopLevelItem(item); } - ui->RzAsmTreeWidget->sortByColumn(0, Qt::AscendingOrder); - ui->RzAsmTreeWidget->setStyleSheet(DisassemblyPreview::getToolTipStyleSheet()); - qhelpers::adjustColumns(ui->RzAsmTreeWidget, 0); + ui->rzAsmTreeWidget->sortByColumn(0, Qt::AscendingOrder); + ui->rzAsmTreeWidget->setStyleSheet(DisassemblyPreview::getToolTipStyleSheet()); + qhelpers::adjustColumns(ui->rzAsmTreeWidget, 0); - int cpuCol = 2; - if (ui->RzAsmTreeWidget->columnWidth(cpuCol) > 200) { - ui->RzAsmTreeWidget->setColumnWidth(cpuCol, 200); + const int cpuCol = 2; + if (ui->rzAsmTreeWidget->columnWidth(cpuCol) > 200) { + ui->rzAsmTreeWidget->setColumnWidth(cpuCol, 200); } } -RizinPluginsDialog::~RizinPluginsDialog() -{ - delete ui; -} +RizinPluginsDialog::~RizinPluginsDialog() {} diff --git a/src/dialogs/RizinPluginsDialog.h b/src/dialogs/RizinPluginsDialog.h index 2405b027..1de82108 100644 --- a/src/dialogs/RizinPluginsDialog.h +++ b/src/dialogs/RizinPluginsDialog.h @@ -1,15 +1,19 @@ #ifndef PLUGINSDIALOG_H #define PLUGINSDIALOG_H -#include #include +#include -#include "core/Cutter.h" +#include namespace Ui { class RizinPluginsDialog; } +/** + * @brief Dialog for listing and describing all loaded Rizin plugins, categorized by their subsystem + * (Bin, IO, Core, Asm) + */ class RizinPluginsDialog : public QDialog { Q_OBJECT @@ -19,7 +23,7 @@ public: ~RizinPluginsDialog(); private: - Ui::RizinPluginsDialog *ui; + std::unique_ptr ui; }; #endif // PLUGINSDIALOG_H diff --git a/src/dialogs/RizinPluginsDialog.ui b/src/dialogs/RizinPluginsDialog.ui index 4aa370d4..9725f0dc 100644 --- a/src/dialogs/RizinPluginsDialog.ui +++ b/src/dialogs/RizinPluginsDialog.ui @@ -17,22 +17,22 @@ - 4 + 1 - + RzBin - + RzBin plugins - + true @@ -60,20 +60,20 @@ - + RzIO - + RzIO plugins - + true @@ -101,20 +101,20 @@ - + RzCore - + RzCore plugins - + true @@ -137,20 +137,20 @@ - + RzAsm - + RzAsm plugins - + true @@ -208,10 +208,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QDialogButtonBox::Ok + QDialogButtonBox::StandardButton::Ok diff --git a/src/dialogs/RizinTaskDialog.cpp b/src/dialogs/RizinTaskDialog.cpp index dd363a96..1c659415 100644 --- a/src/dialogs/RizinTaskDialog.cpp +++ b/src/dialogs/RizinTaskDialog.cpp @@ -1,16 +1,16 @@ #include "RizinTaskDialog.h" + #include "common/RizinTask.h" +#include "ui_RizinTaskDialog.h" #include -#include "ui_RizinTaskDialog.h" - -RizinTaskDialog::RizinTaskDialog(RizinTask::Ptr task, QWidget *parent) +RizinTaskDialog::RizinTaskDialog(const RizinTask::Ptr &task, QWidget *parent) : QDialog(parent), ui(new Ui::RizinTaskDialog), task(task) { ui->setupUi(this); - connect(task.data(), &RizinTask::finished, this, [this]() { close(); }); + connect(task.get(), &RizinTask::finished, this, [this]() { close(); }); connect(&timer, &QTimer::timeout, this, &RizinTaskDialog::updateProgressTimer); timer.setInterval(1000); @@ -25,9 +25,9 @@ RizinTaskDialog::~RizinTaskDialog() {} void RizinTaskDialog::updateProgressTimer() { - int secondsElapsed = elapsedTimer.elapsed() / 1000; - int minutesElapsed = secondsElapsed / 60; - int hoursElapsed = minutesElapsed / 60; + const int secondsElapsed = elapsedTimer.elapsed() / 1000; + const int minutesElapsed = secondsElapsed / 60; + const int hoursElapsed = minutesElapsed / 60; QString label; if (hoursElapsed) { diff --git a/src/dialogs/RizinTaskDialog.h b/src/dialogs/RizinTaskDialog.h index 0b3a3eb0..08244808 100644 --- a/src/dialogs/RizinTaskDialog.h +++ b/src/dialogs/RizinTaskDialog.h @@ -1,31 +1,34 @@ #ifndef RZTASKDIALOG_H #define RZTASKDIALOG_H -#include - -#include -#include -#include - #include "common/RizinTask.h" #include "core/CutterCommon.h" +#include +#include +#include + +#include + class RizinTask; namespace Ui { class RizinTaskDialog; } +/** + * @brief A modal dialog that shows the progress of background @ref RizinTask + */ class CUTTER_EXPORT RizinTaskDialog : public QDialog { Q_OBJECT public: - using Ptr = QSharedPointer; - RizinTaskDialog(Ptr task, QWidget *parent = nullptr); + ; + RizinTaskDialog(const RizinTask::Ptr &task, QWidget *parent = nullptr); ~RizinTaskDialog(); void setBreakOnClose(bool v) { breakOnClose = v; } - bool getBreakOnClose() { return breakOnClose; } + bool getBreakOnClose() const { return breakOnClose; } void setDesc(const QString &label); public slots: @@ -39,7 +42,7 @@ protected: private: std::unique_ptr ui; - QSharedPointer task; + std::shared_ptr task; QTimer timer; QElapsedTimer elapsedTimer; diff --git a/src/dialogs/SetToDataDialog.cpp b/src/dialogs/SetToDataDialog.cpp index f611e2bb..3c8561d1 100644 --- a/src/dialogs/SetToDataDialog.cpp +++ b/src/dialogs/SetToDataDialog.cpp @@ -1,5 +1,7 @@ #include "SetToDataDialog.h" + #include "ui_SetToDataDialog.h" + #include SetToDataDialog::SetToDataDialog(RVA startAddr, QWidget *parent) @@ -10,14 +12,15 @@ SetToDataDialog::SetToDataDialog(RVA startAddr, QWidget *parent) validator->setBottom(1); ui->sizeEdit->setValidator(validator); ui->repeatEdit->setValidator(validator); - ui->startAddrLabel->setText(RzAddressString(startAddr)); + ui->startAddrLabel->setText(rzAddressString(startAddr)); updateEndAddress(); + + connect(ui->sizeEdit, &QLineEdit::textChanged, this, &SetToDataDialog::onSizeEditTextChanged); + connect(ui->repeatEdit, &QLineEdit::textChanged, this, + &SetToDataDialog::onRepeatEditTextChanged); } -SetToDataDialog::~SetToDataDialog() -{ - delete ui; -} +SetToDataDialog::~SetToDataDialog() {} int SetToDataDialog::getItemSize() { @@ -31,17 +34,17 @@ int SetToDataDialog::getItemCount() void SetToDataDialog::updateEndAddress() { - RVA endAddr = startAddress + (getItemSize() * getItemCount()); - ui->endAddrLabel->setText(RzAddressString(endAddr)); + const RVA endAddr = startAddress + (getItemSize() * getItemCount()); + ui->endAddrLabel->setText(rzAddressString(endAddr)); } -void SetToDataDialog::on_sizeEdit_textChanged(const QString &arg1) +void SetToDataDialog::onSizeEditTextChanged(const QString &arg1) { Q_UNUSED(arg1); updateEndAddress(); } -void SetToDataDialog::on_repeatEdit_textChanged(const QString &arg1) +void SetToDataDialog::onRepeatEditTextChanged(const QString &arg1) { Q_UNUSED(arg1); updateEndAddress(); diff --git a/src/dialogs/SetToDataDialog.h b/src/dialogs/SetToDataDialog.h index 49cb2918..13c9c804 100644 --- a/src/dialogs/SetToDataDialog.h +++ b/src/dialogs/SetToDataDialog.h @@ -1,13 +1,19 @@ #ifndef SETTODATADIALOG_H #define SETTODATADIALOG_H +#include "CutterCommon.h" + #include -#include "core/Cutter.h" + +#include namespace Ui { class SetToDataDialog; } +/** + * @brief A dialog for defining memory as a data type + */ class SetToDataDialog : public QDialog { Q_OBJECT @@ -20,13 +26,13 @@ public: int getItemCount(); private slots: - void on_sizeEdit_textChanged(const QString &arg1); - void on_repeatEdit_textChanged(const QString &arg1); + void onSizeEditTextChanged(const QString &arg1); + void onRepeatEditTextChanged(const QString &arg1); private: void updateEndAddress(); - Ui::SetToDataDialog *ui; + std::unique_ptr ui; RVA startAddress; }; diff --git a/src/dialogs/TypesInteractionDialog.cpp b/src/dialogs/TypesInteractionDialog.cpp index 86da1a6c..de819f8b 100644 --- a/src/dialogs/TypesInteractionDialog.cpp +++ b/src/dialogs/TypesInteractionDialog.cpp @@ -1,39 +1,46 @@ #include "dialogs/TypesInteractionDialog.h" -#include "ui_TypesInteractionDialog.h" -#include "core/Cutter.h" #include "common/Configuration.h" -#include "common/SyntaxHighlighter.h" -#include "widgets/TypesWidget.h" +#include "core/Cutter.h" +#include "ui_TypesInteractionDialog.h" #include #include +#include + TypesInteractionDialog::TypesInteractionDialog(QWidget *parent, bool readOnly) - : QDialog(parent), ui(new Ui::TypesInteractionDialog) + : QDialog(parent), + ui(new Ui::TypesInteractionDialog), + syntaxHighLighter(Config()->createSyntaxHighlighter(ui->plainTextEdit->document())) { ui->setupUi(this); - QFont font = Config()->getBaseFont(); + const QFont font = Config()->getBaseFont(); ui->plainTextEdit->setFont(font); ui->plainTextEdit->setPlainText(""); -#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) +#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) ui->plainTextEdit->setTabStopDistance(4 * QFontMetrics(font).horizontalAdvance(' ')); #endif - syntaxHighLighter = Config()->createSyntaxHighlighter(ui->plainTextEdit->document()); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); ui->plainTextEdit->setReadOnly(readOnly); + + connect(ui->selectFileButton, &QPushButton::clicked, this, + &TypesInteractionDialog::onSelectFileButtonClicked); + connect(ui->plainTextEdit, &QPlainTextEdit::textChanged, this, + &TypesInteractionDialog::onPlainTextEditTextChanged); } TypesInteractionDialog::~TypesInteractionDialog() {} void TypesInteractionDialog::setTypeName(QString name) { - this->typeName = name; + this->typeName = std::move(name); } -void TypesInteractionDialog::on_selectFileButton_clicked() +void TypesInteractionDialog::onSelectFileButtonClicked() { - QString filename = + const QString filename = QFileDialog::getOpenFileName(this, tr("Select file"), Config()->getRecentFolder(), "Header files (*.h *.hpp);;All files (*)"); if (filename.isEmpty()) { @@ -43,14 +50,14 @@ void TypesInteractionDialog::on_selectFileButton_clicked() QFile file(filename); if (!file.open(QIODevice::ReadOnly)) { QMessageBox::critical(this, tr("Error"), file.errorString()); - on_selectFileButton_clicked(); + onSelectFileButtonClicked(); return; } ui->filenameLineEdit->setText(filename); ui->plainTextEdit->setPlainText(file.readAll()); } -void TypesInteractionDialog::on_plainTextEdit_textChanged() +void TypesInteractionDialog::onPlainTextEditTextChanged() { if (ui->plainTextEdit->toPlainText().isEmpty()) { ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); @@ -70,14 +77,14 @@ void TypesInteractionDialog::done(int r) typedb, this->typeName.toUtf8().constData(), ui->plainTextEdit->toPlainText().toUtf8().constData()); } else { - char *error_msg = NULL; + char *errorMsg = nullptr; success = rz_type_parse_string_stateless( typedb->parser, ui->plainTextEdit->toPlainText().toUtf8().constData(), - &error_msg) + &errorMsg) == 0; - if (error_msg) { - RZ_LOG_ERROR("%s\n", error_msg); - rz_mem_free(error_msg); + if (errorMsg) { + RZ_LOG_ERROR("%s\n", errorMsg); + rz_mem_free(errorMsg); } } if (success) { @@ -96,7 +103,7 @@ void TypesInteractionDialog::done(int r) } } -void TypesInteractionDialog::fillTextArea(QString content) +void TypesInteractionDialog::fillTextArea(const QString &content) { ui->layoutWidget->hide(); ui->plainTextEdit->setPlainText(content); diff --git a/src/dialogs/TypesInteractionDialog.h b/src/dialogs/TypesInteractionDialog.h index 2c33328e..2f070a42 100644 --- a/src/dialogs/TypesInteractionDialog.h +++ b/src/dialogs/TypesInteractionDialog.h @@ -2,6 +2,7 @@ #define TYPESINTERACTIONDIALOG_H #include + #include namespace Ui { @@ -10,6 +11,9 @@ class TypesInteractionDialog; class QSyntaxHighlighter; +/** + * @brief A dialog for adding or editing C-style data types (structs, enums, unions) + */ class TypesInteractionDialog : public QDialog { Q_OBJECT @@ -25,7 +29,7 @@ public: * most likely will be a C representation of a Type. * @param readonly - Will be set as "true" for viewing mode */ - void fillTextArea(QString content); + void fillTextArea(const QString &content); /** * @brief Set the name of the type that is going to be changed @@ -39,13 +43,13 @@ private slots: * Opens a File Dialog from where the user can select a file from where * the types will be loaded. */ - void on_selectFileButton_clicked(); + void onSelectFileButtonClicked(); /** * @brief Executed whenever the text inside the textbox changes * When the text box is empty, the OK button is disabled. */ - void on_plainTextEdit_textChanged(); + void onPlainTextEditTextChanged(); /** * @brief done Closes the dialog and sets its result code to r diff --git a/src/dialogs/TypesVariablesDialog.cpp b/src/dialogs/TypesVariablesDialog.cpp index 4c959904..b721e7f2 100644 --- a/src/dialogs/TypesVariablesDialog.cpp +++ b/src/dialogs/TypesVariablesDialog.cpp @@ -1,4 +1,6 @@ #include "TypesVariablesDialog.h" + +#include "Cutter.h" #include "ui_TypesVariablesDialog.h" QString toString(VariableScope scope) @@ -50,7 +52,7 @@ QVariant TypesVariablesModel::data(const QModelIndex &index, int role) const } } - if (role == TypeVariableRole) { + if (role == typeVariableRole) { return QVariant::fromValue(v); } return QVariant(); @@ -88,11 +90,18 @@ TypesVariablesProxyModel::TypesVariablesProxyModel(QObject *parent) : QSortFilte void TypesVariablesProxyModel::setScope(VariableScope scope) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + beginFilterChange(); +#endif + selectedScope = scope; + #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) invalidateFilter(); -#else +#elif QT_VERSION < QT_VERSION_CHECK(6, 9, 0) invalidateRowsFilter(); +#else + endFilterChange(); #endif } @@ -103,13 +112,13 @@ bool TypesVariablesProxyModel::filterAcceptsRow(int source_row, return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); } - QVariant var = sourceModel()->data(sourceModel()->index(source_row, 0), - TypesVariablesModel::TypeVariableRole); + const QVariant var = sourceModel()->data(sourceModel()->index(source_row, 0), + TypesVariablesModel::typeVariableRole); if (!var.isValid()) { return false; } - VariableEntry v = var.value(); + const auto v = var.value(); return (v.scope == selectedScope) && QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); } @@ -117,12 +126,12 @@ bool TypesVariablesProxyModel::filterAcceptsRow(int source_row, bool TypesVariablesProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { if (left.column() == TypesVariablesModel::Column::ADDRESS) { - QVariant varLeft = sourceModel()->data(left, TypesVariablesModel::TypeVariableRole); - QVariant varRight = sourceModel()->data(right, TypesVariablesModel::TypeVariableRole); + const QVariant varLeft = sourceModel()->data(left, TypesVariablesModel::typeVariableRole); + const QVariant varRight = sourceModel()->data(right, TypesVariablesModel::typeVariableRole); if (varLeft.isValid() && varRight.isValid()) { - VariableEntry vLeft = varLeft.value(); - VariableEntry vRight = varRight.value(); + const auto vLeft = varLeft.value(); + const auto vRight = varRight.value(); return vLeft.offset < vRight.offset; } @@ -132,13 +141,14 @@ bool TypesVariablesProxyModel::lessThan(const QModelIndex &left, const QModelInd } TypesVariablesDialog::TypesVariablesDialog(QWidget *parent, const QString &typeName) - : QDialog(parent), ui(new Ui::TypesVariablesDialog) + : QDialog(parent), + ui(new Ui::TypesVariablesDialog), + sourceModel(new TypesVariablesModel(this)), + proxyModel(new TypesVariablesProxyModel(this)) { ui->setupUi(this); setWindowTitle(tr("Variables: %1").arg(typeName)); - sourceModel = new TypesVariablesModel(this); - proxyModel = new TypesVariablesProxyModel(this); proxyModel->setSourceModel(sourceModel); proxyModel->setFilterKeyColumn(-1); @@ -164,7 +174,7 @@ TypesVariablesDialog::TypesVariablesDialog(QWidget *parent, const QString &typeN connect(scopeCombo, QOverload::of(&QComboBox::currentIndexChanged), this, [this, scopeCombo, updateCount](int index) { - int scope = scopeCombo->itemData(index).toInt(); + const int scope = scopeCombo->itemData(index).toInt(); proxyModel->setScope(static_cast(scope)); updateCount(); }); @@ -214,7 +224,7 @@ void TypesVariablesDialog::onItemDoubleClicked(const QModelIndex &index) if (!index.isValid()) { return; } - VariableEntry v = index.data(TypesVariablesModel::TypeVariableRole).value(); + const auto v = index.data(TypesVariablesModel::typeVariableRole).value(); Core()->seekAndShow(v.offset); close(); } diff --git a/src/dialogs/TypesVariablesDialog.h b/src/dialogs/TypesVariablesDialog.h index 5c8ce143..6d24caba 100644 --- a/src/dialogs/TypesVariablesDialog.h +++ b/src/dialogs/TypesVariablesDialog.h @@ -1,17 +1,19 @@ #ifndef TYPESVARIABLESDIALOG_H #define TYPESVARIABLESDIALOG_H +#include "CutterCommon.h" + +#include #include #include -#include -#include "core/Cutter.h" +#include namespace Ui { class TypesVariablesDialog; } -enum VariableScope { ALL = 0, GLOBAL, LOCAL }; +enum VariableScope : ut8 { ALL = 0, GLOBAL, LOCAL }; /** * @brief Get a string representation of the given Scope. * @param scope The scope to convert. @@ -30,13 +32,16 @@ struct VariableEntry Q_DECLARE_METATYPE(VariableEntry) +/** + * @brief Source model for @ref TypesVariablesDialog + */ class TypesVariablesModel : public QAbstractTableModel { Q_OBJECT public: - enum Column { NAME = 0, ADDRESS, SCOPE, FUNCTION, COUNT }; - static const int TypeVariableRole = Qt::UserRole; + enum Column : ut8 { NAME = 0, ADDRESS, SCOPE, FUNCTION, COUNT }; + static const int typeVariableRole = Qt::UserRole; explicit TypesVariablesModel(QObject *parent = nullptr); @@ -50,6 +55,9 @@ public: QList variables; }; +/** + * @brief Proxy model for @ref TypesVariablesDialog + */ class TypesVariablesProxyModel : public QSortFilterProxyModel { Q_OBJECT @@ -66,6 +74,9 @@ private: VariableScope selectedScope = VariableScope::ALL; }; +/** + * @brief A dialog that lists and filters variables of a specific data type + */ class TypesVariablesDialog : public QDialog { Q_OBJECT diff --git a/src/dialogs/VersionInfoDialog.cpp b/src/dialogs/VersionInfoDialog.cpp index 292fff53..6f31f55d 100644 --- a/src/dialogs/VersionInfoDialog.cpp +++ b/src/dialogs/VersionInfoDialog.cpp @@ -1,18 +1,19 @@ #include "VersionInfoDialog.h" + +#include "Cutter.h" +#include "common/Helpers.h" #include "ui_VersionInfoDialog.h" -#include "common/Helpers.h" - -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include VersionInfoDialog::VersionInfoDialog(QWidget *parent) - : QDialog(parent), ui(new Ui::VersionInfoDialog), core(Core()) + : QDialog(parent), ui(new Ui::VersionInfoDialog) { ui->setupUi(this); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); @@ -42,10 +43,10 @@ VersionInfoDialog::VersionInfoDialog(QWidget *parent) // Connect Copy actions connect(copyActionLeftTreewidget, &QAction::triggered, this, - [this]() { CopyTreeWidgetSelection(ui->leftTreeWidget); }); + [this]() { copyTreeWidgetSelection(ui->leftTreeWidget); }); connect(copyActionRightTreewidget, &QAction::triggered, this, - [this]() { CopyTreeWidgetSelection(ui->rightTreeWidget); }); + [this]() { copyTreeWidgetSelection(ui->rightTreeWidget); }); // Connect select sll actions connect(selAllActionLeftTreewidget, &QAction::triggered, this, @@ -61,6 +62,11 @@ VersionInfoDialog::VersionInfoDialog(QWidget *parent) [this]() { ui->leftTreeWidget->clearSelection(); }); connect(this, &VersionInfoDialog::finished, this, &VersionInfoDialog::clearSelectionOnClose); + connect(ui->copyVersionInfoButton, &QPushButton::clicked, this, + &VersionInfoDialog::onCopyVersionInfoButtonClicked); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, + &VersionInfoDialog::onButtonBoxRejected); + // Add actions to context menu ui->leftTreeWidget->addAction(copyActionLeftTreewidget); ui->leftTreeWidget->addAction(selAllActionLeftTreewidget); @@ -77,12 +83,12 @@ void VersionInfoDialog::clearSelectionOnClose() ui->rightTreeWidget->clearSelection(); // remove default "current" item selection after dialog close - QModelIndex defaultIndex; + const QModelIndex defaultIndex; ui->leftTreeWidget->setCurrentIndex(defaultIndex); ui->rightTreeWidget->setCurrentIndex(defaultIndex); } -void VersionInfoDialog::CopyTreeWidgetSelection(QTreeWidget *t) +void VersionInfoDialog::copyTreeWidgetSelection(QTreeWidget *t) { QString vinfo, row; @@ -106,22 +112,23 @@ void VersionInfoDialog::contextMenuEvent(QContextMenuEvent *event) event->accept(); } -void VersionInfoDialog::on_buttonBox_rejected() +void VersionInfoDialog::onButtonBoxRejected() { close(); } -void VersionInfoDialog::on_copyVersionInfoButton_clicked() +void VersionInfoDialog::onCopyVersionInfoButtonClicked() { QString vinfo = "# " + ui->leftLabel->text() + "\n"; // Iterate & Copy leftTreeWidget items QTreeWidgetItemIterator itl(ui->leftTreeWidget); - int keyColumnIndex = 0, valueColumnIndex = 1; + const int keyColumnIndex = 0, valueColumnIndex = 1; while (*itl) { - QString row = (*itl)->text(keyColumnIndex) + " : " + (*itl)->text(valueColumnIndex) + "\n"; + const QString row = + (*itl)->text(keyColumnIndex) + " : " + (*itl)->text(valueColumnIndex) + "\n"; vinfo.append(row); ++itl; } @@ -132,7 +139,8 @@ void VersionInfoDialog::on_copyVersionInfoButton_clicked() QTreeWidgetItemIterator itr(ui->rightTreeWidget); while (*itr) { - QString row = (*itr)->text(keyColumnIndex) + " : " + (*itr)->text(valueColumnIndex) + "\n"; + const QString row = + (*itr)->text(keyColumnIndex) + " : " + (*itr)->text(valueColumnIndex) + "\n"; vinfo.append(row); ++itr; } @@ -168,27 +176,27 @@ void VersionInfoDialog::fillVersionInfo() } // Left tree - QTreeWidgetItem *addrItemL = new QTreeWidgetItem(); + auto *addrItemL = new QTreeWidgetItem(); addrItemL->setText(0, tr("Address:")); - addrItemL->setText(1, RzAddressString(sdb_num_get(sdb, "addr"))); + addrItemL->setText(1, rzAddressString(sdb_num_get(sdb, "addr"))); ui->leftTreeWidget->addTopLevelItem(addrItemL); - QTreeWidgetItem *offItemL = new QTreeWidgetItem(); + auto *offItemL = new QTreeWidgetItem(); offItemL->setText(0, tr("Offset:")); - offItemL->setText(1, RzAddressString(sdb_num_get(sdb, "offset"))); + offItemL->setText(1, rzAddressString(sdb_num_get(sdb, "offset"))); ui->leftTreeWidget->addTopLevelItem(offItemL); - QTreeWidgetItem *entriesItemL = new QTreeWidgetItem(); + auto *entriesItemL = new QTreeWidgetItem(); entriesItemL->setText(0, tr("Entries:")); - const ut64 num_entries = sdb_num_get(sdb, "num_entries"); - for (size_t i = 0; i < num_entries; ++i) { + const ut64 numEntries = sdb_num_get(sdb, "num_entries"); + for (size_t i = 0; i < numEntries; ++i) { auto key = QString("entry%0").arg(i); const char *const value = sdb_const_get(sdb, key.toStdString().c_str()); if (!value) { continue; } auto item = new QTreeWidgetItem(); - item->setText(KeyColumn, RzAddressString(i)); + item->setText(KeyColumn, rzAddressString(i)); item->setText(ValueColumn, value); entriesItemL->addChild(item); } @@ -199,46 +207,46 @@ void VersionInfoDialog::fillVersionInfo() sdb = sdb_ns_path(core->sdb, "bin/cur/info/versioninfo/verneed", 0); // Right tree - QTreeWidgetItem *addrItemR = new QTreeWidgetItem(); + auto *addrItemR = new QTreeWidgetItem(); addrItemR->setText(0, tr("Address:")); - addrItemR->setText(1, RzAddressString(sdb_num_get(sdb, "addr"))); + addrItemR->setText(1, rzAddressString(sdb_num_get(sdb, "addr"))); ui->rightTreeWidget->addTopLevelItem(addrItemR); - QTreeWidgetItem *offItemR = new QTreeWidgetItem(); + auto *offItemR = new QTreeWidgetItem(); offItemR->setText(0, tr("Offset:")); - offItemR->setText(1, RzAddressString(sdb_num_get(sdb, "offset"))); + offItemR->setText(1, rzAddressString(sdb_num_get(sdb, "offset"))); ui->rightTreeWidget->addTopLevelItem(offItemR); - QTreeWidgetItem *entriesItemR = new QTreeWidgetItem(); + auto *entriesItemR = new QTreeWidgetItem(); entriesItemR->setText(0, tr("Entries:")); - for (size_t num_version = 0;; num_version++) { - auto path_version = - QString("bin/cur/info/versioninfo/verneed/version%0").arg(num_version); - sdb = sdb_ns_path(core->sdb, path_version.toStdString().c_str(), 0); + for (size_t numVersion = 0;; numVersion++) { + auto pathVersion = + QString("bin/cur/info/versioninfo/verneed/version%0").arg(numVersion); + sdb = sdb_ns_path(core->sdb, pathVersion.toStdString().c_str(), 0); if (!sdb) { break; } const char *filename = sdb_const_get(sdb, "file_name"); auto *parentItem = new QTreeWidgetItem(); - parentItem->setText(0, RzAddressString(sdb_num_get(sdb, "idx"))); + parentItem->setText(0, rzAddressString(sdb_num_get(sdb, "idx"))); parentItem->setText(1, tr("Version: %0\t" "File: %1") .arg(QString::number(sdb_num_get(sdb, "vn_version")), QString(filename))); - int num_vernaux = 0; + int numVernaux = 0; while (true) { - auto path_vernaux = - QString("%0/vernaux%1").arg(path_version, QString::number(num_vernaux++)); - sdb = sdb_ns_path(core->sdb, path_vernaux.toStdString().c_str(), 0); + auto pathVernaux = + QString("%0/vernaux%1").arg(pathVersion, QString::number(numVernaux++)); + sdb = sdb_ns_path(core->sdb, pathVernaux.toStdString().c_str(), 0); if (!sdb) { break; } auto *childItem = new QTreeWidgetItem(); - childItem->setText(0, RzAddressString(sdb_num_get(sdb, "idx"))); - QString childString = + childItem->setText(0, rzAddressString(sdb_num_get(sdb, "idx"))); + const QString childString = tr("Name: %0\t" "Flags: %1\t" "Version: %2\t") @@ -259,105 +267,105 @@ void VersionInfoDialog::fillVersionInfo() // Set labels ui->leftLabel->setText(tr("VS Fixed file info")); ui->rightLabel->setText(tr("String table")); - Sdb *sdb = NULL; + Sdb *sdb = nullptr; // Left tree - auto path_version = QString("bin/cur/info/vs_version_info/VS_VERSIONINFO%0").arg(0); - auto path_fixedfileinfo = QString("%0/fixed_file_info").arg(path_version); - sdb = sdb_ns_path(core->sdb, path_fixedfileinfo.toStdString().c_str(), 0); + auto pathVersion = QString("bin/cur/info/vs_version_info/VS_VERSIONINFO%0").arg(0); + auto pathFixedfileinfo = QString("%0/fixed_file_info").arg(pathVersion); + sdb = sdb_ns_path(core->sdb, pathFixedfileinfo.toStdString().c_str(), 0); if (!sdb) { return; } - ut32 file_version_ms = sdb_num_get(sdb, "FileVersionMS"); - ut32 file_version_ls = sdb_num_get(sdb, "FileVersionLS"); - auto file_version = QString("%0.%1.%2.%3") - .arg(file_version_ms >> 16) - .arg(file_version_ms & 0xFFFF) - .arg(file_version_ls >> 16) - .arg(file_version_ls & 0xFFFF); - ut32 product_version_ms = sdb_num_get(sdb, "ProductVersionMS"); - ut32 product_version_ls = sdb_num_get(sdb, "ProductVersionLS"); - auto product_version = QString("%0.%1.%2.%3") - .arg(product_version_ms >> 16) - .arg(product_version_ms & 0xFFFF) - .arg(product_version_ls >> 16) - .arg(product_version_ls & 0xFFFF); + const ut32 fileVersionMs = sdb_num_get(sdb, "FileVersionMS"); + const ut32 fileVersionLs = sdb_num_get(sdb, "FileVersionLS"); + auto fileVersion = QString("%0.%1.%2.%3") + .arg(fileVersionMs >> 16) + .arg(fileVersionMs & 0xFFFF) + .arg(fileVersionLs >> 16) + .arg(fileVersionLs & 0xFFFF); + const ut32 productVersionMs = sdb_num_get(sdb, "ProductVersionMS"); + const ut32 productVersionLs = sdb_num_get(sdb, "ProductVersionLS"); + auto productVersion = QString("%0.%1.%2.%3") + .arg(productVersionMs >> 16) + .arg(productVersionMs & 0xFFFF) + .arg(productVersionLs >> 16) + .arg(productVersionLs & 0xFFFF); auto item = new QTreeWidgetItem(); item->setText(0, "Signature"); - item->setText(1, RzHexString(sdb_num_get(sdb, "Signature"))); + item->setText(1, rzHexString(sdb_num_get(sdb, "Signature"))); ui->leftTreeWidget->addTopLevelItem(item); item = new QTreeWidgetItem(); item->setText(0, "StrucVersion"); - item->setText(1, RzHexString(sdb_num_get(sdb, "StrucVersion"))); + item->setText(1, rzHexString(sdb_num_get(sdb, "StrucVersion"))); ui->leftTreeWidget->addTopLevelItem(item); item = new QTreeWidgetItem(); item->setText(KeyColumn, "FileVersion"); - item->setText(ValueColumn, file_version); + item->setText(ValueColumn, fileVersion); ui->leftTreeWidget->addTopLevelItem(item); item = new QTreeWidgetItem(); item->setText(KeyColumn, "ProductVersion"); - item->setText(ValueColumn, product_version); + item->setText(ValueColumn, productVersion); ui->leftTreeWidget->addTopLevelItem(item); item = new QTreeWidgetItem(); item->setText(0, "FileFlagsMask"); - item->setText(1, RzHexString(sdb_num_get(sdb, "FileFlagsMask"))); + item->setText(1, rzHexString(sdb_num_get(sdb, "FileFlagsMask"))); ui->leftTreeWidget->addTopLevelItem(item); item = new QTreeWidgetItem(); item->setText(0, "FileFlags"); - item->setText(1, RzHexString(sdb_num_get(sdb, "FileFlags"))); + item->setText(1, rzHexString(sdb_num_get(sdb, "FileFlags"))); ui->leftTreeWidget->addTopLevelItem(item); item = new QTreeWidgetItem(); item->setText(0, "FileOS"); - item->setText(1, RzHexString(sdb_num_get(sdb, "FileOS"))); + item->setText(1, rzHexString(sdb_num_get(sdb, "FileOS"))); ui->leftTreeWidget->addTopLevelItem(item); item = new QTreeWidgetItem(); item->setText(0, "FileType"); - item->setText(1, RzHexString(sdb_num_get(sdb, "FileType"))); + item->setText(1, rzHexString(sdb_num_get(sdb, "FileType"))); ui->leftTreeWidget->addTopLevelItem(item); item = new QTreeWidgetItem(); item->setText(0, "FileSubType"); - item->setText(1, RzHexString(sdb_num_get(sdb, "FileSubType"))); + item->setText(1, rzHexString(sdb_num_get(sdb, "FileSubType"))); ui->leftTreeWidget->addTopLevelItem(item); // Adjust columns to content qhelpers::adjustColumns(ui->leftTreeWidget, 0); // Right tree - for (int num_stringtable = 0;; num_stringtable++) { - auto path_stringtable = QString("%0/string_file_info/stringtable%1") - .arg(path_version) - .arg(num_stringtable); - sdb = sdb_ns_path(core->sdb, path_stringtable.toStdString().c_str(), 0); + for (int numStringtable = 0;; numStringtable++) { + auto pathStringtable = QString("%0/string_file_info/stringtable%1") + .arg(pathVersion) + .arg(numStringtable); + sdb = sdb_ns_path(core->sdb, pathStringtable.toStdString().c_str(), 0); if (!sdb) { break; } - for (int num_string = 0; sdb; num_string++) { - auto path_string = QString("%0/string%1").arg(path_stringtable).arg(num_string); - sdb = sdb_ns_path(core->sdb, path_string.toStdString().c_str(), 0); + for (int numString = 0; sdb; numString++) { + auto pathString = QString("%0/string%1").arg(pathStringtable).arg(numString); + sdb = sdb_ns_path(core->sdb, pathString.toStdString().c_str(), 0); if (!sdb) { continue; } int lenkey = 0; int lenval = 0; - ut8 *key_utf16 = sdb_decode(sdb_const_get(sdb, "key"), &lenkey); - ut8 *val_utf16 = sdb_decode(sdb_const_get(sdb, "value"), &lenval); + ut8 *keyUtf16 = sdb_decode(sdb_const_get(sdb, "key"), &lenkey); + ut8 *valUtf16 = sdb_decode(sdb_const_get(sdb, "value"), &lenval); item = new QTreeWidgetItem(); item->setText(KeyColumn, - QString::fromUtf16(reinterpret_cast(key_utf16))); + QString::fromUtf16(reinterpret_cast(keyUtf16))); item->setText(ValueColumn, - QString::fromUtf16(reinterpret_cast(val_utf16))); + QString::fromUtf16(reinterpret_cast(valUtf16))); ui->rightTreeWidget->addTopLevelItem(item); - free(key_utf16); - free(val_utf16); + free(keyUtf16); + free(valUtf16); } } qhelpers::adjustColumns(ui->rightTreeWidget, 0); diff --git a/src/dialogs/VersionInfoDialog.h b/src/dialogs/VersionInfoDialog.h index d21e1643..198a717d 100644 --- a/src/dialogs/VersionInfoDialog.h +++ b/src/dialogs/VersionInfoDialog.h @@ -1,10 +1,12 @@ #ifndef VERSIONINFODIALOG_H #define VERSIONINFODIALOG_H -#include -#include +#include "CutterCommon.h" // IWYU pragma: keep -#include "core/Cutter.h" +#include +#include + +#include namespace Ui { class VersionInfoDialog; @@ -18,10 +20,10 @@ public: explicit VersionInfoDialog(QWidget *parent = nullptr); ~VersionInfoDialog(); - enum Column { KeyColumn = 0, ValueColumn = 1 }; + enum Column : ut8 { KeyColumn = 0, ValueColumn = 1 }; private slots: - void CopyTreeWidgetSelection(QTreeWidget *t); + void copyTreeWidgetSelection(QTreeWidget *t); void clearSelectionOnClose(); protected: @@ -32,18 +34,17 @@ protected: QAction *selAllActionRightTreewidget = nullptr; void contextMenuEvent(QContextMenuEvent *event) override; - void on_buttonBox_rejected(); + void onButtonBoxRejected(); /** * @fn AboutDialog::on_copyVersionInfoButton_clicked() * * @brief Copies the table values to Clipboard. */ - void on_copyVersionInfoButton_clicked(); + void onCopyVersionInfoButtonClicked(); private: std::unique_ptr ui; - CutterCore *core; void fillVersionInfo(); }; diff --git a/src/dialogs/WelcomeDialog.cpp b/src/dialogs/WelcomeDialog.cpp index 28853956..98596618 100644 --- a/src/dialogs/WelcomeDialog.cpp +++ b/src/dialogs/WelcomeDialog.cpp @@ -1,16 +1,13 @@ -#include "core/MainWindow.h" -#include "CutterConfig.h" - -#include "common/Helpers.h" #include "WelcomeDialog.h" -#include "AboutDialog.h" +#include "AboutDialog.h" +#include "Configuration.h" +#include "CutterConfig.h" +#include "common/Helpers.h" #include "ui_WelcomeDialog.h" -/** - * @brief Constructs a WelcomeDialog object - * @param parent - */ +#include + WelcomeDialog::WelcomeDialog(QWidget *parent) : QDialog(parent), ui(new Ui::WelcomeDialog) { ui->setupUi(this); @@ -20,7 +17,7 @@ WelcomeDialog::WelcomeDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Welc + ""); ui->themeComboBox->setCurrentIndex(Config()->getInterfaceTheme()); - QSignalBlocker s(ui->updatesCheckBox); + const QSignalBlocker s(ui->updatesCheckBox); ui->updatesCheckBox->setChecked(Config()->getAutoUpdateEnabled()); auto langs = Config()->getAvailableTranslations(); @@ -48,22 +45,32 @@ WelcomeDialog::WelcomeDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Welc static_cast(&QComboBox::currentIndexChanged), this, &WelcomeDialog::onLanguageCurrentIndexChanged); + connect(ui->languageComboBox, + static_cast(&QComboBox::currentIndexChanged), this, + &WelcomeDialog::onLanguageCurrentIndexChanged); + + connect(ui->themeComboBox, + static_cast(&QComboBox::currentIndexChanged), this, + &WelcomeDialog::onThemeComboBoxCurrentIndexChanged); + + connect(ui->checkUpdateButton, &QPushButton::clicked, this, + &WelcomeDialog::onCheckUpdateButtonClicked); + + connect(ui->continueButton, &QPushButton::clicked, this, + &WelcomeDialog::onContinueButtonClicked); +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + connect(ui->updatesCheckBox, &QCheckBox::checkStateChanged, this, + &WelcomeDialog::onUpdatesCheckBoxStateChanged); +#else + connect(ui->updatesCheckBox, &QCheckBox::stateChanged, this, + &WelcomeDialog::onUpdatesCheckBoxStateChanged); +#endif Config()->adjustColorThemeDarkness(); } -/** - * @brief Destroys the WelcomeDialog - */ -WelcomeDialog::~WelcomeDialog() -{ - delete ui; -} +WelcomeDialog::~WelcomeDialog() {} -/** - * @brief change Cutter's QT Theme as selected by the user - * @param index - a Slot being called after theme's value changes its index - */ -void WelcomeDialog::on_themeComboBox_currentIndexChanged(int index) +void WelcomeDialog::onThemeComboBoxCurrentIndexChanged(int index) { Config()->setInterfaceTheme(index); @@ -71,13 +78,9 @@ void WelcomeDialog::on_themeComboBox_currentIndexChanged(int index) ui->logoSvgWidget->load(Config()->getLogoFile()); } -/** - * @brief change Cutter's interface language as selected by the user - * @param index - a Slot being called after language combo box value changes its index - */ void WelcomeDialog::onLanguageCurrentIndexChanged(int) { - QVariant language = ui->languageComboBox->currentData(); + const QVariant language = ui->languageComboBox->currentData(); if (language.canConvert()) { Config()->setLocale(language.toLocale()); } @@ -90,25 +93,19 @@ void WelcomeDialog::onLanguageCurrentIndexChanged(int) mb.exec(); } -/** - * @brief show Cutter's About dialog - */ -void WelcomeDialog::on_checkUpdateButton_clicked() +void WelcomeDialog::onCheckUpdateButtonClicked() { - AboutDialog *a = new AboutDialog(this); + auto *a = new AboutDialog(this); a->setAttribute(Qt::WA_DeleteOnClose); a->open(); } -/** - * @brief accept user preferences, close the window and continue Cutter's execution - */ -void WelcomeDialog::on_continueButton_clicked() +void WelcomeDialog::onContinueButtonClicked() { accept(); } -void WelcomeDialog::on_updatesCheckBox_stateChanged(int) +void WelcomeDialog::onUpdatesCheckBoxStateChanged(int) { Config()->setAutoUpdateEnabled(!Config()->getAutoUpdateEnabled()); } diff --git a/src/dialogs/WelcomeDialog.h b/src/dialogs/WelcomeDialog.h index 9a748c46..02df5168 100644 --- a/src/dialogs/WelcomeDialog.h +++ b/src/dialogs/WelcomeDialog.h @@ -3,37 +3,50 @@ #include -namespace Ui { +#include -/** - * @class WelcomeDialog - * @brief The WelcomeDialog class will show the user the Welcome windows - * upon first execution of Cutter. - * - * Upon first execution of Cutter, the WelcomeDialog would be showed to the user. - * The Welcome dialog would be showed after a reset of Cutter's preferences by the user. - */ +namespace Ui { class WelcomeDialog; } +/** + * @brief The WelcomeDialog class will show the user the Welcome windows + * upon first execution of Cutter. + * + * The Welcome dialog would also be showed after a reset of Cutter's preferences by the user. + */ class WelcomeDialog : public QDialog { Q_OBJECT public: - explicit WelcomeDialog(QWidget *parent = 0); + explicit WelcomeDialog(QWidget *parent = nullptr); ~WelcomeDialog(); private slots: - void on_themeComboBox_currentIndexChanged(int index); + /** + * @brief change Cutter's QT Theme as selected by the user + * @param index - a Slot being called after theme's value changes its index + */ + void onThemeComboBoxCurrentIndexChanged(int index); + /** + * @brief change Cutter's interface language as selected by the user + * @param index - a Slot being called after language combo box value changes its index + */ void onLanguageCurrentIndexChanged(int index); - void on_checkUpdateButton_clicked(); - void on_continueButton_clicked(); - void on_updatesCheckBox_stateChanged(int state); + /** + * @brief show Cutter's About dialog + */ + void onCheckUpdateButtonClicked(); + /** + * @brief accept user preferences, close the window and continue Cutter's execution + */ + void onContinueButtonClicked(); + void onUpdatesCheckBoxStateChanged(int state); private: - Ui::WelcomeDialog *ui; + std::unique_ptr ui; }; #endif // WELCOMEDIALOG_H diff --git a/src/dialogs/WelcomeDialog.ui b/src/dialogs/WelcomeDialog.ui index c2441a04..ff3009f7 100644 --- a/src/dialogs/WelcomeDialog.ui +++ b/src/dialogs/WelcomeDialog.ui @@ -24,7 +24,7 @@ - QLayout::SetDefaultConstraint + QLayout::SizeConstraint::SetDefaultConstraint @@ -32,7 +32,7 @@ 0 - QLayout::SetMinimumSize + QLayout::SizeConstraint::SetMinimumSize 2 @@ -46,7 +46,7 @@ 2 - + @@ -83,11 +83,11 @@ Cutter - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter - + @@ -108,10 +108,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -126,7 +126,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -142,7 +142,7 @@ 9 - QLayout::SetMaximumSize + QLayout::SizeConstraint::SetMaximumSize @@ -235,7 +235,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -252,10 +252,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -268,7 +268,7 @@ - QLayout::SetMinimumSize + QLayout::SizeConstraint::SetMinimumSize 0 @@ -276,7 +276,7 @@ 10 - + @@ -287,7 +287,6 @@ 12 - 75 true @@ -299,8 +298,8 @@ - - + + 0 @@ -324,7 +323,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Noto Sans'; font-size:10pt;">Join thousands of reverse engineers in our community:<br /></span><span style=" font-family:'Noto Sans'; font-size:10pt; font-weight:600;">Twitter:</span><span style=" font-family:'Noto Sans'; font-size:10pt;"> </span><a href="https://twitter.com/cutter_re"><span style=" font-family:'Noto Sans'; font-size:10pt; text-decoration: underline; color:#2980b9;">@cutter_re</span></a><span style=" font-family:'Noto Sans'; font-size:10pt;"><br /></span><span style=" font-family:'Noto Sans'; font-size:10pt; font-weight:600;">Telegram: </span><a href="https://t.me/cutter_re"><span style=" font-family:'Noto Sans'; font-size:10pt; text-decoration: underline; color:#2980b9;">@cutter_re <br /></span></a><span style=" font-family:'Noto Sans'; font-size:10pt; font-weight:600;">IRC: </span><span style=" font-family:'Noto Sans'; font-size:10pt;">#cutter on </span><a href="https://web.libera.chat/"><span style=" font-family:'Noto Sans'; font-size:10pt; text-decoration: underline; color:#2980b9;">https://web.libera.chat/</span></a></p></body></html> - Qt::RichText + Qt::TextFormat::RichText true @@ -333,11 +332,11 @@ p, li { white-space: pre-wrap; } true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction - + @@ -364,14 +363,14 @@ p, li { white-space: pre-wrap; } true - Qt::TextBrowserInteraction + Qt::TextInteractionFlag::TextBrowserInteraction - Qt::Horizontal + Qt::Orientation::Horizontal @@ -381,12 +380,11 @@ p, li { white-space: pre-wrap; } - + 12 - 75 true @@ -401,7 +399,7 @@ p, li { white-space: pre-wrap; } - Qt::Horizontal + Qt::Orientation::Horizontal diff --git a/src/dialogs/WriteCommandsDialogs.cpp b/src/dialogs/WriteCommandsDialogs.cpp index 9cd509a3..7ede26f1 100644 --- a/src/dialogs/WriteCommandsDialogs.cpp +++ b/src/dialogs/WriteCommandsDialogs.cpp @@ -1,10 +1,10 @@ #include "WriteCommandsDialogs.h" -#include "ui_Base64EnDecodedWriteDialog.h" -#include "ui_IncrementDecrementDialog.h" -#include "ui_DuplicateFromOffsetDialog.h" -#include "Cutter.h" -#include +#include "Cutter.h" +#include "ui_Base64EnDecodedWriteDialog.h" +#include "ui_DuplicateFromOffsetDialog.h" +#include "ui_IncrementDecrementDialog.h" + #include Base64EnDecodedWriteDialog::Base64EnDecodedWriteDialog(QWidget *parent) @@ -14,6 +14,8 @@ Base64EnDecodedWriteDialog::Base64EnDecodedWriteDialog(QWidget *parent) ui->decodeRB->click(); } +Base64EnDecodedWriteDialog::~Base64EnDecodedWriteDialog() {} + Base64EnDecodedWriteDialog::Mode Base64EnDecodedWriteDialog::getMode() const { return ui->decodeRB->isChecked() ? Decode : Encode; @@ -36,19 +38,21 @@ IncrementDecrementDialog::IncrementDecrementDialog(QWidget *parent) new QRegularExpressionValidator(QRegularExpression("[0-9a-fA-Fx]{1,18}"), ui->valueLE)); } +IncrementDecrementDialog::~IncrementDecrementDialog() {} + IncrementDecrementDialog::Mode IncrementDecrementDialog::getMode() const { return ui->incrementRB->isChecked() ? Increase : Decrease; } -uint8_t IncrementDecrementDialog::getNBytes() const +ut8 IncrementDecrementDialog::getNBytes() const { // Shift left to keep index powered by two // This is used to create the w1, w2, w4 and w8 commands based on the selected index. - return static_cast(1 << ui->nBytesCB->currentIndex()); + return static_cast(1 << ui->nBytesCB->currentIndex()); } -uint64_t IncrementDecrementDialog::getValue() const +ut64 IncrementDecrementDialog::getValue() const { return Core()->math(ui->valueLE->text()); } @@ -65,6 +69,8 @@ DuplicateFromOffsetDialog::DuplicateFromOffsetDialog(QWidget *parent) &DuplicateFromOffsetDialog::refresh); } +DuplicateFromOffsetDialog::~DuplicateFromOffsetDialog() {} + RVA DuplicateFromOffsetDialog::getOffset() const { return Core()->math(ui->offsetLE->text()); @@ -77,12 +83,11 @@ size_t DuplicateFromOffsetDialog::getNBytes() const void DuplicateFromOffsetDialog::refresh() { - QSignalBlocker sb(Core()); - RzCoreLocked core(Core()); + const QSignalBlocker sb(Core()); auto buf = Core()->ioRead(getOffset(), (int)getNBytes()); // Add space every two characters for word wrap in hex sequence - QRegularExpression re { "(.{2})" }; + const QRegularExpression re { "(.{2})" }; auto bytes = QString(buf).replace(re, "\\1 ").trimmed(); ui->bytesLabel->setText(bytes); } diff --git a/src/dialogs/WriteCommandsDialogs.h b/src/dialogs/WriteCommandsDialogs.h index 2f4a2052..d4240609 100644 --- a/src/dialogs/WriteCommandsDialogs.h +++ b/src/dialogs/WriteCommandsDialogs.h @@ -1,52 +1,67 @@ #ifndef WRITECOMMANDSDIALOGS_H #define WRITECOMMANDSDIALOGS_H -#include #include "CutterCommon.h" +#include + +#include + namespace Ui { class Base64EnDecodedWriteDialog; class IncrementDecrementDialog; class DuplicateFromOffsetDialog; } +/** + * @brief A dialog for writing Base64 encoded or decoded data to the current binary + */ class Base64EnDecodedWriteDialog : public QDialog { Q_OBJECT public: explicit Base64EnDecodedWriteDialog(QWidget *parent = nullptr); - enum Mode { Encode, Decode }; + ~Base64EnDecodedWriteDialog(); + enum Mode : ut8 { Encode, Decode }; Mode getMode() const; QByteArray getData() const; private: - Ui::Base64EnDecodedWriteDialog *ui; + std::unique_ptr ui; }; +/** + * @brief A dialog to increment or decrement binary values by a user-defined amount + */ class IncrementDecrementDialog : public QDialog { Q_OBJECT public: explicit IncrementDecrementDialog(QWidget *parent = nullptr); - enum Mode { Increase, Decrease }; + ~IncrementDecrementDialog(); + enum Mode : ut8 { Increase, Decrease }; Mode getMode() const; - uint8_t getNBytes() const; - uint64_t getValue() const; + ut8 getNBytes() const; + ut64 getValue() const; private: - Ui::IncrementDecrementDialog *ui; + std::unique_ptr ui; }; +/** + * @brief A dialog that duplicates a block of bytes from a source offset to the current location + */ class DuplicateFromOffsetDialog : public QDialog { Q_OBJECT public: explicit DuplicateFromOffsetDialog(QWidget *parent = nullptr); + ~DuplicateFromOffsetDialog(); RVA getOffset() const; size_t getNBytes() const; private: - Ui::DuplicateFromOffsetDialog *ui; + std::unique_ptr ui; private slots: void refresh(); diff --git a/src/dialogs/XrefsDialog.cpp b/src/dialogs/XrefsDialog.cpp index 61a71be2..df0ea8b8 100644 --- a/src/dialogs/XrefsDialog.cpp +++ b/src/dialogs/XrefsDialog.cpp @@ -1,15 +1,14 @@ #include "XrefsDialog.h" + +#include "common/Helpers.h" +#include "common/TempConfig.h" +#include "core/MainWindow.h" +#include "shortcuts/ShortcutManager.h" #include "ui_XrefsDialog.h" -#include "common/TempConfig.h" -#include "common/Helpers.h" - -#include "core/MainWindow.h" - +#include #include #include -#include "shortcuts/ShortcutManager.h" -#include XrefsDialog::XrefsDialog(MainWindow *parent, bool hideXrefFrom) : QDialog(parent), @@ -26,8 +25,8 @@ XrefsDialog::XrefsDialog(MainWindow *parent, bool hideXrefFrom) ui->toTreeWidget->setMainWindow(parent); ui->fromTreeWidget->setMainWindow(parent); - ui->toTreeWidget->setModel(&toProxyModel); - ui->fromTreeWidget->setModel(&fromProxyModel); + ui->toTreeWidget->setModel(static_cast(&toProxyModel)); + ui->fromTreeWidget->setModel(static_cast(&fromProxyModel)); ui->toTreeWidget->getItemContextMenu()->toggleBreakpointAction(true); ui->fromTreeWidget->getItemContextMenu()->toggleBreakpointAction(true); @@ -37,8 +36,8 @@ XrefsDialog::XrefsDialog(MainWindow *parent, bool hideXrefFrom) ui->splitter->setSizes(QList() << 300 << 400); // Increase asm text edit margin - QTextDocument *asm_docu = ui->previewTextEdit->document(); - asm_docu->setDocumentMargin(10); + QTextDocument *asmDocu = ui->previewTextEdit->document(); + asmDocu->setDocumentMargin(10); setupPreviewColors(); setupPreviewFont(); @@ -60,12 +59,13 @@ XrefsDialog::XrefsDialog(MainWindow *parent, bool hideXrefFrom) // SearchWidget shortcuts - QShortcut *searchShortcut = Shortcuts()->makeQShortcut("General.showFilter", ui->toTreeWidget); - QShortcut *clearShortcut = + const QShortcut *searchShortcut = + Shortcuts()->makeQShortcut("General.showFilter", ui->toTreeWidget); + const QShortcut *clearShortcut = Shortcuts()->makeQShortcut("General.clearFilter", ui->fromQuickFilter); connect(searchShortcut, &QShortcut::activated, this, [this]() { - QWidget *fw = QApplication::focusWidget(); + const QWidget *fw = QApplication::focusWidget(); if (ui->toTreeWidget->isAncestorOf(fw)) { ui->toQuickFilter->showFilter(); } else if (ui->fromTreeWidget->isAncestorOf(fw)) { @@ -74,7 +74,7 @@ XrefsDialog::XrefsDialog(MainWindow *parent, bool hideXrefFrom) }); connect(clearShortcut, &QShortcut::activated, [this]() { - QWidget *fw = QApplication::focusWidget(); + const QWidget *fw = QApplication::focusWidget(); if (ui->toQuickFilter->isAncestorOf(fw)) { ui->toQuickFilter->clearFilter(); } else if (ui->fromQuickFilter->isAncestorOf(fw)) { @@ -122,8 +122,7 @@ void XrefsDialog::setupPreviewColors() { ui->previewTextEdit->setStyleSheet( QString("QPlainTextEdit { background-color: %1; color: %2; }") - .arg(ConfigColor("gui.background").name()) - .arg(ConfigColor("btext").name())); + .arg(ConfigColor("gui.background").name(), ConfigColor("btext").name())); } void XrefsDialog::highlightCurrentLine() @@ -171,7 +170,7 @@ void XrefsDialog::updatePreview(RVA addr) tempConfig.set("asm.lines", false); tempConfig.set("asm.bytes", false); - QString disas = Core()->getFunctionExecOut( + const QString disas = Core()->getFunctionExecOut( [](RzCore *core) { ut64 offset = core->offset; if (!rz_core_prevop_addr(core, core->offset, 20, &offset)) { @@ -179,37 +178,36 @@ void XrefsDialog::updatePreview(RVA addr) } rz_core_seek(core, offset, true); rz_core_print_disasm(core, core->offset, core->block, (int)core->blocksize, 40, - NULL, NULL); + nullptr, nullptr); return true; }, addr); ui->previewTextEdit->document()->setHtml(disas); // Does it make any sense? - ui->previewTextEdit->find(normalizeAddr(RzAddressString(addr)), QTextDocument::FindBackward); + ui->previewTextEdit->find(normalizeAddr(rzAddressString(addr)), QTextDocument::FindBackward); ui->previewTextEdit->moveCursor(QTextCursor::StartOfLine, QTextCursor::MoveAnchor); } -void XrefsDialog::updateLabels(QString name) +void XrefsDialog::updateLabels(const QString &name) { - ui->label_xTo->setText(tr("X-Refs to %1 (%2 results):").arg(name).arg(toModel.rowCount())); - ui->label_xFrom->setText( - tr("X-Refs from %1 (%2 results):").arg(name).arg(fromModel.rowCount())); + ui->labelXTo->setText(tr("X-Refs to %1 (%2 results):").arg(name).arg(toModel.rowCount())); + ui->labelXFrom->setText(tr("X-Refs from %1 (%2 results):").arg(name).arg(fromModel.rowCount())); } -void XrefsDialog::updateLabelsForVariables(QString name) +void XrefsDialog::updateLabelsForVariables(const QString &name) { - ui->label_xTo->setText(tr("Writes to %1").arg(name)); - ui->label_xFrom->setText(tr("Reads from %1").arg(name)); + ui->labelXTo->setText(tr("Writes to %1").arg(name)); + ui->labelXFrom->setText(tr("Reads from %1").arg(name)); } void XrefsDialog::hideXrefFromSection() { - ui->label_xFrom->hide(); + ui->labelXFrom->hide(); ui->fromTreeWidget->hide(); } -void XrefsDialog::fillRefsForAddress(RVA addr, QString name, bool whole_function) +void XrefsDialog::fillRefsForAddress(RVA addr, const QString &name, bool whole_function) { setWindowTitle(tr("X-Refs for %1").arg(name)); @@ -228,7 +226,7 @@ void XrefsDialog::fillRefsForAddress(RVA addr, QString name, bool whole_function } } -void XrefsDialog::fillRefsForVariable(QString nameOfVariable, RVA offset) +void XrefsDialog::fillRefsForVariable(const QString &nameOfVariable, RVA offset) { setWindowTitle(tr("X-Refs for %1").arg(nameOfVariable)); updateLabelsForVariables(nameOfVariable); @@ -273,7 +271,7 @@ void XrefModel::readForOffset(RVA offset, bool to, bool whole_function) endResetModel(); } -void XrefModel::readForVariable(QString nameOfVariable, bool write, RVA offset) +void XrefModel::readForVariable(const QString &nameOfVariable, bool write, RVA offset) { beginResetModel(); this->to = write; @@ -305,7 +303,7 @@ QVariant XrefModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case OFFSET: - return to ? xref.from_str : xref.to_str; + return to ? xref.fromStr : xref.toStr; case TYPE: return xrefTypeString(xref.type); case CODE: @@ -318,7 +316,7 @@ QVariant XrefModel::data(const QModelIndex &index, int role) const return to ? Core()->getCommentAt(xref.from) : Core()->getCommentAt(xref.to); } return QVariant(); - case FlagDescriptionRole: + case flagDescriptionRole: return QVariant::fromValue(xref); default: break; @@ -375,23 +373,23 @@ XrefFilterProxyModel::XrefFilterProxyModel(XrefModel *source_model, QObject *par bool XrefFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); - XrefDescription xref = index.data(XrefModel::FlagDescriptionRole).value(); - return qhelpers::filterStringContains(to ? xref.to_str : xref.from_str, this); + const QModelIndex index = sourceModel()->index(row, 0, parent); + const auto xref = index.data(XrefModel::flagDescriptionRole).value(); + return qhelpers::filterStringContains(to ? xref.toStr : xref.fromStr, this); } bool XrefFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { auto source = static_cast(sourceModel()); - auto left_item = source->description(left); - auto right_item = source->description(right); + auto leftItem = source->description(left); + auto rightItem = source->description(right); switch (left.column()) { case XrefModel::OFFSET: - return to ? left_item->to < right_item->to : left_item->from < right_item->from; + return to ? leftItem->to < rightItem->to : leftItem->from < rightItem->from; case XrefModel::TYPE: - return left_item->type < right_item->type; + return leftItem->type < rightItem->type; default: return sourceModel()->data(left, Qt::DisplayRole).toString() < sourceModel()->data(right, Qt::DisplayRole).toString(); diff --git a/src/dialogs/XrefsDialog.h b/src/dialogs/XrefsDialog.h index a888be7a..3ca9fd2e 100644 --- a/src/dialogs/XrefsDialog.h +++ b/src/dialogs/XrefsDialog.h @@ -1,13 +1,14 @@ #ifndef XREFSDIALOG_H #define XREFSDIALOG_H +#include "CutterCommon.h" // IWYU pragma: keep +#include "CutterDescriptions.h" +#include "common/AddressableItemModel.h" + #include #include + #include -#include "common/Highlighter.h" -#include "core/Cutter.h" -#include "common/AddressableItemModel.h" -#include "QuickFilterView.h" class XrefModel : public AddressableItemModel { @@ -17,12 +18,12 @@ private: bool to; public: - enum Columns { OFFSET = 0, TYPE, CODE, COMMENT, COUNT }; - static const int FlagDescriptionRole = Qt::UserRole; + enum Columns : ut8 { OFFSET = 0, TYPE, CODE, COMMENT, COUNT }; + static const int flagDescriptionRole = Qt::UserRole; XrefModel(QObject *parent = nullptr); void readForOffset(RVA offset, bool to, bool whole_function); - void readForVariable(QString nameOfVariable, bool write, RVA offset); + void readForVariable(const QString &nameOfVariable, bool write, RVA offset); int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; @@ -58,6 +59,10 @@ namespace Ui { class XrefsDialog; } +/** + * @brief A dialog that displays X-refs to and from an address or variable, providing a live + * disassembly preview + */ class XrefsDialog : public QDialog { Q_OBJECT @@ -66,7 +71,7 @@ public: explicit XrefsDialog(MainWindow *parent, bool hideXrefFrom = false); ~XrefsDialog(); - void fillRefsForAddress(RVA addr, QString name, bool whole_function); + void fillRefsForAddress(RVA addr, const QString &name, bool whole_function); /** * @brief Initializes toModel and fromModel with the details about the references to the * specified local variable 'nameOfVariable'. @@ -74,7 +79,7 @@ public: * initialized. * @param offset An offset in the function in which the specified local variable exist. */ - void fillRefsForVariable(QString nameOfVariable, RVA offset); + void fillRefsForVariable(const QString &nameOfVariable, RVA offset); private slots: QString normalizeAddr(const QString &addr) const; @@ -89,7 +94,7 @@ private slots: private: RVA addr; - QString func_name; + QString funcName; XrefModel toModel; XrefFilterProxyModel toProxyModel; XrefModel fromModel; @@ -97,8 +102,8 @@ private: std::unique_ptr ui; - void updateLabels(QString name); - void updateLabelsForVariables(QString name); + void updateLabels(const QString &name); + void updateLabelsForVariables(const QString &name); void updatePreview(RVA addr); void hideXrefFromSection(); }; diff --git a/src/dialogs/XrefsDialog.ui b/src/dialogs/XrefsDialog.ui index 9cf65ebb..7b3356ff 100644 --- a/src/dialogs/XrefsDialog.ui +++ b/src/dialogs/XrefsDialog.ui @@ -43,7 +43,7 @@ 5 - + X-Refs to: @@ -69,7 +69,7 @@ - + X-Refs from: diff --git a/src/dialogs/preferences/AnalysisOptionsWidget.cpp b/src/dialogs/preferences/AnalysisOptionsWidget.cpp index a9c58bc4..9f9292f0 100644 --- a/src/dialogs/preferences/AnalysisOptionsWidget.cpp +++ b/src/dialogs/preferences/AnalysisOptionsWidget.cpp @@ -1,12 +1,10 @@ #include "AnalysisOptionsWidget.h" -#include "ui_AnalysisOptionsWidget.h" #include "PreferencesDialog.h" - -#include "common/Helpers.h" #include "common/Configuration.h" - +#include "common/Helpers.h" #include "core/MainWindow.h" +#include "ui_AnalysisOptionsWidget.h" static const QHash analysisBoundaries { { "io.maps.x", QT_TRANSLATE_NOOP("AnalysisOptionsWidget", "All executable maps") }, @@ -18,7 +16,7 @@ static const QHash analysisBoundaries { }; AnalysisOptionsWidget::AnalysisOptionsWidget(PreferencesDialog *dialog) - : QDialog(dialog), mainWindow(dialog->getMainWindow()), ui(new Ui::AnalysisOptionsWidget) + : QDialog(dialog), ui(new Ui::AnalysisOptionsWidget), mainWindow(dialog->getMainWindow()) { ui->setupUi(this); @@ -34,16 +32,21 @@ AnalysisOptionsWidget::AnalysisOptionsWidget(PreferencesDialog *dialog) createAnalysisInOptionsList(); // Connect each checkbox from "checkboxes" to the generic signal "checkboxEnabler" - for (ConfigCheckbox &confCheckbox : checkboxes) { - QString val = confCheckbox.config; + for (const ConfigCheckbox &confCheckbox : std::as_const(checkboxes)) { + const QString val = confCheckbox.config; QCheckBox &cb = *confCheckbox.checkBox; +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + connect(confCheckbox.checkBox, &QCheckBox::checkStateChanged, this, + [val, &cb]() { checkboxEnabler(&cb, val); }); +#else connect(confCheckbox.checkBox, &QCheckBox::stateChanged, this, [val, &cb]() { checkboxEnabler(&cb, val); }); +#endif } ui->analyzePushButton->setToolTip(tr("Analyze the program using Rizin's \"aaa\" command")); connect(ui->analyzePushButton, &QPushButton::clicked, mainWindow, - &MainWindow::on_actionAnalyze_triggered); + &MainWindow::onActionAnalyzeTriggered); connect(ui->analysisInComboBox, &QComboBox::currentIndexChanged, this, &AnalysisOptionsWidget::updateAnalysisIn); connect(ui->ptrDepthSpinBox, &QSpinBox::valueChanged, this, @@ -62,7 +65,7 @@ void AnalysisOptionsWidget::checkboxEnabler(QCheckBox *checkBox, const QString & void AnalysisOptionsWidget::updateAnalysisOptionsFromVars() { - for (ConfigCheckbox &confCheckbox : checkboxes) { + for (const ConfigCheckbox &confCheckbox : checkboxes) { qhelpers::setCheckedWithoutSignals(confCheckbox.checkBox, Core()->getConfigb(confCheckbox.config)); } diff --git a/src/dialogs/preferences/AnalysisOptionsWidget.h b/src/dialogs/preferences/AnalysisOptionsWidget.h index 55f6857c..49e72ede 100644 --- a/src/dialogs/preferences/AnalysisOptionsWidget.h +++ b/src/dialogs/preferences/AnalysisOptionsWidget.h @@ -1,10 +1,10 @@ #ifndef ANALOPTIONSWIDGET_H #define ANALOPTIONSWIDGET_H +#include #include -#include -#include "core/Cutter.h" +#include class MainWindow; @@ -14,6 +14,9 @@ namespace Ui { class AnalysisOptionsWidget; } +/** + * @brief Contains configurable options related to analysis + */ class AnalysisOptionsWidget : public QDialog { Q_OBJECT diff --git a/src/dialogs/preferences/AppearanceOptionsWidget.cpp b/src/dialogs/preferences/AppearanceOptionsWidget.cpp index 7365945e..77ac0e4d 100644 --- a/src/dialogs/preferences/AppearanceOptionsWidget.cpp +++ b/src/dialogs/preferences/AppearanceOptionsWidget.cpp @@ -1,27 +1,25 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "PreferencesDialog.h" #include "AppearanceOptionsWidget.h" + +#include "PreferencesDialog.h" +#include "common/ColorThemeWorker.h" +#include "common/Configuration.h" +#include "common/Helpers.h" +#include "dialogs/preferences/ColorThemeEditDialog.h" #include "ui_AppearanceOptionsWidget.h" -#include "common/Helpers.h" -#include "common/Configuration.h" - -#include "common/ColorThemeWorker.h" -#include "dialogs/preferences/ColorThemeEditDialog.h" -#include "widgets/ColorPicker.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include AppearanceOptionsWidget::AppearanceOptionsWidget(PreferencesDialog *dialog) : QDialog(dialog), ui(new Ui::AppearanceOptionsWidget) @@ -51,7 +49,7 @@ AppearanceOptionsWidget::AppearanceOptionsWidget(PreferencesDialog *dialog) } auto setIcons = [this]() { - QColor textColor = palette().text().color(); + const QColor textColor = palette().text().color(); ui->editButton->setIcon(getIconFromSvg(":/img/icons/pencil_thin.svg", textColor)); ui->deleteButton->setIcon(getIconFromSvg(":/img/icons/trash_bin.svg", textColor)); ui->copyButton->setIcon(getIconFromSvg(":/img/icons/copy.svg", textColor)); @@ -78,13 +76,33 @@ AppearanceOptionsWidget::AppearanceOptionsWidget(PreferencesDialog *dialog) ui->useDecompilerHighlighter->setChecked(Config()->isDecompilerAnnotationHighlighterEnabled()); connect(ui->useDecompilerHighlighter, &QCheckBox::toggled, this, [](bool checked) { Config()->enableDecompilerAnnotationHighlighter(checked); }); + + connect(ui->themeComboBox, + static_cast(&QComboBox::currentIndexChanged), this, + &AppearanceOptionsWidget::onThemeComboBoxCurrentIndexChanged); + + connect(ui->fontSelectionButton, &QPushButton::clicked, this, + &AppearanceOptionsWidget::onFontSelectionButtonClicked); + + connect(ui->editButton, &QPushButton::clicked, this, + &AppearanceOptionsWidget::onEditButtonClicked); + connect(ui->copyButton, &QPushButton::clicked, this, + &AppearanceOptionsWidget::onCopyButtonClicked); + connect(ui->deleteButton, &QPushButton::clicked, this, + &AppearanceOptionsWidget::onDeleteButtonClicked); + connect(ui->renameButton, &QPushButton::clicked, this, + &AppearanceOptionsWidget::onRenameButtonClicked); + connect(ui->importButton, &QPushButton::clicked, this, + &AppearanceOptionsWidget::onImportButtonClicked); + connect(ui->exportButton, &QPushButton::clicked, this, + &AppearanceOptionsWidget::onExportButtonClicked); } AppearanceOptionsWidget::~AppearanceOptionsWidget() {} void AppearanceOptionsWidget::updateFontFromConfig() { - QFont currentFont = Config()->getBaseFont(); + const QFont currentFont = Config()->getBaseFont(); ui->fontSelectionLabel->setText(currentFont.toString()); } @@ -92,7 +110,7 @@ void AppearanceOptionsWidget::updateThemeFromConfig(bool interfaceThemeChanged) { // Disconnect currentIndexChanged because clearing the comboxBox and refiling it causes its // index to change. - QSignalBlocker signalBlockerThemeBox(ui->themeComboBox); + const QSignalBlocker signalBlockerThemeBox(ui->themeComboBox); ui->themeComboBox->clear(); for (auto &it : Configuration::cutterInterfaceThemesList()) { @@ -110,28 +128,28 @@ void AppearanceOptionsWidget::updateThemeFromConfig(bool interfaceThemeChanged) void AppearanceOptionsWidget::onFontZoomBoxValueChanged(int zoom) { - qreal zoomFactor = zoom / 100.0; + const qreal zoomFactor = zoom / 100.0; Config()->setZoomFactor(zoomFactor); } -void AppearanceOptionsWidget::on_fontSelectionButton_clicked() +void AppearanceOptionsWidget::onFontSelectionButtonClicked() { - QFont currentFont = Config()->getBaseFont(); + const QFont currentFont = Config()->getBaseFont(); bool ok; - QFont newFont = QFontDialog::getFont(&ok, currentFont, this, QString(), - QFontDialog::DontUseNativeDialog); + const QFont newFont = QFontDialog::getFont(&ok, currentFont, this, QString(), + QFontDialog::DontUseNativeDialog); if (ok) { Config()->setFont(newFont); } } -void AppearanceOptionsWidget::on_themeComboBox_currentIndexChanged(int index) +void AppearanceOptionsWidget::onThemeComboBoxCurrentIndexChanged(int index) { Config()->setInterfaceTheme(index); updateThemeFromConfig(); } -void AppearanceOptionsWidget::on_editButton_clicked() +void AppearanceOptionsWidget::onEditButtonClicked() { ColorThemeEditDialog dial; dial.setWindowTitle(tr("Theme Editor - <%1>").arg(ui->colorComboBox->currentText())); @@ -139,9 +157,9 @@ void AppearanceOptionsWidget::on_editButton_clicked() ui->colorComboBox->updateFromConfig(false); } -void AppearanceOptionsWidget::on_copyButton_clicked() +void AppearanceOptionsWidget::onCopyButtonClicked() { - QString currColorTheme = ui->colorComboBox->currentText(); + const QString currColorTheme = ui->colorComboBox->currentText(); QString newThemeName; do { @@ -164,17 +182,17 @@ void AppearanceOptionsWidget::on_copyButton_clicked() updateThemeFromConfig(false); } -void AppearanceOptionsWidget::on_deleteButton_clicked() +void AppearanceOptionsWidget::onDeleteButtonClicked() { - QString currTheme = ui->colorComboBox->currentText(); + const QString currTheme = ui->colorComboBox->currentText(); if (!ThemeWorker().isCustomTheme(currTheme)) { QMessageBox::critical(this, tr("Error"), ThemeWorker().deleteTheme(currTheme)); return; } - int ret = QMessageBox::question( + const int ret = QMessageBox::question( this, tr("Delete"), tr("Are you sure you want to delete %1?").arg(currTheme)); if (ret == QMessageBox::Yes) { - QString err = ThemeWorker().deleteTheme(currTheme); + const QString err = ThemeWorker().deleteTheme(currTheme); updateThemeFromConfig(false); if (!err.isEmpty()) { QMessageBox::critical(this, tr("Error"), err); @@ -182,16 +200,16 @@ void AppearanceOptionsWidget::on_deleteButton_clicked() } } -void AppearanceOptionsWidget::on_importButton_clicked() +void AppearanceOptionsWidget::onImportButtonClicked() { - QString fileName = QFileDialog::getOpenFileName( + const QString fileName = QFileDialog::getOpenFileName( this, "", QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); if (fileName.isEmpty()) { return; } - QString err = ThemeWorker().importTheme(fileName); - QString themeName = QFileInfo(fileName).fileName(); + const QString err = ThemeWorker().importTheme(fileName); + const QString themeName = QFileInfo(fileName).fileName(); if (err.isEmpty()) { QMessageBox::information( this, tr("Success"), @@ -203,10 +221,10 @@ void AppearanceOptionsWidget::on_importButton_clicked() } } -void AppearanceOptionsWidget::on_exportButton_clicked() +void AppearanceOptionsWidget::onExportButtonClicked() { - QString theme = ui->colorComboBox->currentText(); - QString file = QFileDialog::getSaveFileName( + const QString theme = ui->colorComboBox->currentText(); + const QString file = QFileDialog::getSaveFileName( this, "", QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QDir::separator() + theme); @@ -215,10 +233,10 @@ void AppearanceOptionsWidget::on_exportButton_clicked() } // User already gave his consent for this in QFileDialog::getSaveFileName() - if (QFileInfo(file).exists()) { + if (QFileInfo::exists(file)) { QFile(file).remove(); } - QString err = ThemeWorker().save(ThemeWorker().getTheme(theme), file); + const QString err = ThemeWorker().save(ThemeWorker().getTheme(theme), file); if (err.isEmpty()) { QMessageBox::information(this, tr("Success"), tr("Color theme %1 was successfully exported.").arg(theme)); @@ -227,16 +245,16 @@ void AppearanceOptionsWidget::on_exportButton_clicked() } } -void AppearanceOptionsWidget::on_renameButton_clicked() +void AppearanceOptionsWidget::onRenameButtonClicked() { - QString currColorTheme = Config()->getColorTheme(); - QString newName = QInputDialog::getText(this, tr("Enter new theme name"), tr("Name:"), - QLineEdit::Normal, currColorTheme); + const QString currColorTheme = Config()->getColorTheme(); + const QString newName = QInputDialog::getText(this, tr("Enter new theme name"), tr("Name:"), + QLineEdit::Normal, currColorTheme); if (newName.isEmpty() || newName == currColorTheme) { return; } - QString err = ThemeWorker().renameTheme(currColorTheme, newName); + const QString err = ThemeWorker().renameTheme(currColorTheme, newName); if (!err.isEmpty()) { QMessageBox::critical(this, tr("Error"), err); } else { @@ -247,7 +265,7 @@ void AppearanceOptionsWidget::on_renameButton_clicked() void AppearanceOptionsWidget::onLanguageComboBoxCurrentIndexChanged(int) { - QVariant language = ui->languageComboBox->currentData(); + const QVariant language = ui->languageComboBox->currentData(); if (language.canConvert()) { Config()->setLocale(language.toLocale()); QMessageBox::information(this, tr("Language settings"), @@ -259,7 +277,7 @@ void AppearanceOptionsWidget::onLanguageComboBoxCurrentIndexChanged(int) void AppearanceOptionsWidget::updateModificationButtons(const QString &theme) { - bool editable = ThemeWorker().isCustomTheme(theme); + const bool editable = ThemeWorker().isCustomTheme(theme); ui->editButton->setEnabled(editable); ui->deleteButton->setEnabled(editable); ui->renameButton->setEnabled(editable); diff --git a/src/dialogs/preferences/AppearanceOptionsWidget.h b/src/dialogs/preferences/AppearanceOptionsWidget.h index de52fb38..5e0c4aff 100644 --- a/src/dialogs/preferences/AppearanceOptionsWidget.h +++ b/src/dialogs/preferences/AppearanceOptionsWidget.h @@ -1,12 +1,12 @@ - #ifndef AppearanceOptionsWidget_H #define AppearanceOptionsWidget_H +#include "core/Cutter.h" + #include #include -#include -#include "core/Cutter.h" +#include class PreferencesDialog; @@ -14,6 +14,9 @@ namespace Ui { class AppearanceOptionsWidget; } +/** + * @brief Contains configurable options related to appearance + */ class AppearanceOptionsWidget : public QDialog { Q_OBJECT @@ -29,29 +32,29 @@ private slots: void updateFontFromConfig(); void updateThemeFromConfig(bool interfaceThemeChanged = true); - void on_fontSelectionButton_clicked(); + void onFontSelectionButtonClicked(); void onFontZoomBoxValueChanged(int zoom); - void on_themeComboBox_currentIndexChanged(int index); - void on_copyButton_clicked(); - void on_deleteButton_clicked(); + void onThemeComboBoxCurrentIndexChanged(int index); + void onCopyButtonClicked(); + void onDeleteButtonClicked(); /** * @brief Imports theme file specified by user to custom themes * directory. */ - void on_importButton_clicked(); + void onImportButtonClicked(); /** * @brief Exports current color theme to file * specified by user. */ - void on_exportButton_clicked(); + void onExportButtonClicked(); /** * @brief Shows dialog to rename current color theme. */ - void on_renameButton_clicked(); - void on_editButton_clicked(); + void onRenameButtonClicked(); + void onEditButtonClicked(); void onLanguageComboBoxCurrentIndexChanged(int index); private: diff --git a/src/dialogs/preferences/AsmOptionsWidget.cpp b/src/dialogs/preferences/AsmOptionsWidget.cpp index 99b7a147..688c0533 100644 --- a/src/dialogs/preferences/AsmOptionsWidget.cpp +++ b/src/dialogs/preferences/AsmOptionsWidget.cpp @@ -1,13 +1,12 @@ -#include -#include - #include "AsmOptionsWidget.h" -#include "ui_AsmOptionsWidget.h" #include "PreferencesDialog.h" - -#include "common/Helpers.h" #include "common/Configuration.h" +#include "common/Helpers.h" +#include "ui_AsmOptionsWidget.h" + +#include +#include AsmOptionsWidget::AsmOptionsWidget(PreferencesDialog *dialog) : QDialog(dialog), ui(new Ui::AsmOptionsWidget) @@ -16,8 +15,9 @@ AsmOptionsWidget::AsmOptionsWidget(PreferencesDialog *dialog) ui->setupUi(this); ui->syntaxComboBox->blockSignals(true); - for (const auto &syntax : Core()->getConfigOptions("asm.syntax")) + for (const auto &syntax : Core()->getConfigOptions("asm.syntax")) { ui->syntaxComboBox->addItem(syntax, syntax); + } ui->syntaxComboBox->blockSignals(false); checkboxes = { { ui->describeCheckBox, "asm.describe" }, @@ -48,10 +48,15 @@ AsmOptionsWidget::AsmOptionsWidget(PreferencesDialog *dialog) // Connect each checkbox from "checkboxes" to the generic signal "checkboxEnabler" for (confCheckbox = checkboxes.begin(); confCheckbox != checkboxes.end(); ++confCheckbox) { - QString val = confCheckbox->config; + const QString val = confCheckbox->config; QCheckBox &cb = *confCheckbox->checkBox; +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + connect(confCheckbox->checkBox, &QCheckBox::checkStateChanged, + [this, val, &cb]() { checkboxEnabler(&cb, val); }); +#else connect(confCheckbox->checkBox, &QCheckBox::stateChanged, [this, val, &cb]() { checkboxEnabler(&cb, val); }); +#endif } using indexSignalType = void (QComboBox::*)(int); @@ -71,6 +76,29 @@ AsmOptionsWidget::AsmOptionsWidget(PreferencesDialog *dialog) triggerAsmOptionsChanged(); }); + connect(ui->syntaxComboBox, static_cast(&QComboBox::currentIndexChanged), this, + &AsmOptionsWidget::onSyntaxComboBoxCurrentIndexChanged); + connect(ui->caseComboBox, static_cast(&QComboBox::currentIndexChanged), this, + &AsmOptionsWidget::onCaseComboBoxCurrentIndexChanged); + + connect(ui->cmtcolSpinBox, static_cast(&QSpinBox::valueChanged), this, + &AsmOptionsWidget::onCmtcolSpinBoxValueChanged); + connect(ui->nbytesSpinBox, static_cast(&QSpinBox::valueChanged), this, + &AsmOptionsWidget::onNbytesSpinBoxValueChanged); + connect(ui->asmTabsSpinBox, static_cast(&QSpinBox::valueChanged), this, + &AsmOptionsWidget::onAsmTabsSpinBoxValueChanged); + connect(ui->asmTabsOffSpinBox, static_cast(&QSpinBox::valueChanged), + this, &AsmOptionsWidget::onAsmTabsOffSpinBoxValueChanged); + + connect(ui->bytesCheckBox, &QCheckBox::toggled, this, + &AsmOptionsWidget::onBytesCheckBoxToggled); + connect(ui->varsubCheckBox, &QCheckBox::toggled, this, + &AsmOptionsWidget::onVarsubCheckBoxToggled); + connect(ui->previewCheckBox, &QCheckBox::toggled, this, + &AsmOptionsWidget::onPreviewCheckBoxToggled); + + connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &AsmOptionsWidget::onButtonBoxClicked); + updateAsmOptionsFromVars(); } @@ -78,19 +106,19 @@ AsmOptionsWidget::~AsmOptionsWidget() {} void AsmOptionsWidget::updateAsmOptionsFromVars() { - bool cmtRightEnabled = Config()->getConfigBool("asm.cmt.right"); + const bool cmtRightEnabled = Config()->getConfigBool("asm.cmt.right"); ui->cmtcolSpinBox->blockSignals(true); ui->cmtcolSpinBox->setValue(Config()->getConfigInt("asm.cmt.col")); ui->cmtcolSpinBox->blockSignals(false); ui->cmtcolSpinBox->setEnabled(cmtRightEnabled); - bool offsetsEnabled = Config()->getConfigBool("asm.offset"); + const bool offsetsEnabled = Config()->getConfigBool("asm.offset"); ui->relOffsetLabel->setEnabled(offsetsEnabled); ui->relOffsetCheckBox->setEnabled(offsetsEnabled); ui->relOffFlagsCheckBox->setEnabled(Config()->getConfigBool("asm.offset") && Config()->getConfigBool("asm.reloff")); - bool bytesEnabled = Config()->getConfigBool("asm.bytes"); + const bool bytesEnabled = Config()->getConfigBool("asm.bytes"); ui->bytespaceCheckBox->setEnabled(bytesEnabled); ui->lbytesCheckBox->setEnabled(bytesEnabled); ui->nbytesSpinBox->blockSignals(true); @@ -98,7 +126,7 @@ void AsmOptionsWidget::updateAsmOptionsFromVars() ui->nbytesSpinBox->blockSignals(false); ui->nbytesLabel->setEnabled(bytesEnabled); ui->nbytesSpinBox->setEnabled(bytesEnabled); - bool varsubEnabled = Config()->getConfigBool("asm.sub.var"); + const bool varsubEnabled = Config()->getConfigBool("asm.sub.var"); ui->varsubOnlyCheckBox->setEnabled(varsubEnabled); ui->asmComboBox->blockSignals(true); @@ -111,7 +139,7 @@ void AsmOptionsWidget::updateAsmOptionsFromVars() } ui->asmComboBox->blockSignals(false); - QString currentSyntax = Config()->getConfigString("asm.syntax"); + const QString currentSyntax = Config()->getConfigString("asm.syntax"); for (int i = 0; i < ui->syntaxComboBox->count(); i++) { if (ui->syntaxComboBox->itemData(i) == currentSyntax) { ui->syntaxComboBox->blockSignals(true); @@ -161,7 +189,7 @@ void AsmOptionsWidget::resetToDefault() triggerAsmOptionsChanged(); } -void AsmOptionsWidget::triggerAsmOptionsChanged() +void AsmOptionsWidget::triggerAsmOptionsChanged() const { disconnect(Core(), &CutterCore::asmOptionsChanged, this, &AsmOptionsWidget::updateAsmOptionsFromVars); @@ -170,13 +198,13 @@ void AsmOptionsWidget::triggerAsmOptionsChanged() &AsmOptionsWidget::updateAsmOptionsFromVars); } -void AsmOptionsWidget::on_cmtcolSpinBox_valueChanged(int value) +void AsmOptionsWidget::onCmtcolSpinBoxValueChanged(int value) { Config()->setConfig("asm.cmt.col", value); triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_bytesCheckBox_toggled(bool checked) +void AsmOptionsWidget::onBytesCheckBoxToggled(bool checked) { Config()->setConfig("asm.bytes", checked); ui->bytespaceCheckBox->setEnabled(checked); @@ -186,20 +214,20 @@ void AsmOptionsWidget::on_bytesCheckBox_toggled(bool checked) triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_nbytesSpinBox_valueChanged(int value) +void AsmOptionsWidget::onNbytesSpinBoxValueChanged(int value) { Config()->setConfig("asm.nbytes", value); triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_syntaxComboBox_currentIndexChanged(int index) +void AsmOptionsWidget::onSyntaxComboBoxCurrentIndexChanged(int index) { Config()->setConfig("asm.syntax", ui->syntaxComboBox->itemData(index).toString().toUtf8().constData()); triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_caseComboBox_currentIndexChanged(int index) +void AsmOptionsWidget::onCaseComboBoxCurrentIndexChanged(int index) { bool ucase; bool capitalize; @@ -230,32 +258,32 @@ void AsmOptionsWidget::on_caseComboBox_currentIndexChanged(int index) triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_asmTabsSpinBox_valueChanged(int value) +void AsmOptionsWidget::onAsmTabsSpinBoxValueChanged(int value) { Config()->setConfig("asm.tabs", value); triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_asmTabsOffSpinBox_valueChanged(int value) +void AsmOptionsWidget::onAsmTabsOffSpinBoxValueChanged(int value) { Config()->setConfig("asm.tabs.off", value); triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_varsubCheckBox_toggled(bool checked) +void AsmOptionsWidget::onVarsubCheckBoxToggled(bool checked) { Config()->setConfig("asm.sub.var", checked); ui->varsubOnlyCheckBox->setEnabled(checked); triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_previewCheckBox_toggled(bool checked) +void AsmOptionsWidget::onPreviewCheckBoxToggled(bool checked) { Config()->setPreviewValue(checked); triggerAsmOptionsChanged(); } -void AsmOptionsWidget::on_buttonBox_clicked(QAbstractButton *button) +void AsmOptionsWidget::onButtonBoxClicked(QAbstractButton *button) { switch (ui->buttonBox->buttonRole(button)) { case QDialogButtonBox::ButtonRole::ResetRole: @@ -305,13 +333,7 @@ void AsmOptionsWidget::relOffCheckBoxToggled(bool checked) ui->relOffFlagsCheckBox->setEnabled(checked && Config()->getConfigBool("asm.offset")); } -/** - * @brief A generic signal to handle the simple cases where a checkbox is toggled - * while it only responsible for a single independent boolean configuration eval. - * @param checkBox - The checkbox which is responsible for the siganl - * @param config - the configuration string to be toggled - */ -void AsmOptionsWidget::checkboxEnabler(QCheckBox *checkBox, QString config) +void AsmOptionsWidget::checkboxEnabler(QCheckBox *checkBox, const QString &config) { Config()->setConfig(config, checkBox->isChecked()); triggerAsmOptionsChanged(); diff --git a/src/dialogs/preferences/AsmOptionsWidget.h b/src/dialogs/preferences/AsmOptionsWidget.h index a3ba832e..90fc0c12 100644 --- a/src/dialogs/preferences/AsmOptionsWidget.h +++ b/src/dialogs/preferences/AsmOptionsWidget.h @@ -1,12 +1,11 @@ - #ifndef ASMOPTIONSWIDGET_H #define ASMOPTIONSWIDGET_H +#include #include #include -#include -#include "core/Cutter.h" +#include class PreferencesDialog; @@ -14,6 +13,9 @@ namespace Ui { class AsmOptionsWidget; } +/** + * @brief Contains configurable options related to disassembly + */ class AsmOptionsWidget : public QDialog { Q_OBJECT @@ -31,32 +33,39 @@ private: }; QList checkboxes; - void triggerAsmOptionsChanged(); + void triggerAsmOptionsChanged() const; private slots: void resetToDefault(); void updateAsmOptionsFromVars(); - void on_cmtcolSpinBox_valueChanged(int value); + void onCmtcolSpinBoxValueChanged(int value); - void on_syntaxComboBox_currentIndexChanged(int index); - void on_caseComboBox_currentIndexChanged(int index); - void on_asmTabsSpinBox_valueChanged(int value); - void on_asmTabsOffSpinBox_valueChanged(int value); - void on_nbytesSpinBox_valueChanged(int value); + void onSyntaxComboBoxCurrentIndexChanged(int index); + void onCaseComboBoxCurrentIndexChanged(int index); + void onAsmTabsSpinBoxValueChanged(int value); + void onAsmTabsOffSpinBoxValueChanged(int value); + void onNbytesSpinBoxValueChanged(int value); - void on_bytesCheckBox_toggled(bool checked); - void on_varsubCheckBox_toggled(bool checked); - void on_previewCheckBox_toggled(bool checked); + void onBytesCheckBoxToggled(bool checked); + void onVarsubCheckBoxToggled(bool checked); + void onPreviewCheckBoxToggled(bool checked); - void on_buttonBox_clicked(QAbstractButton *button); + void onButtonBoxClicked(QAbstractButton *button); void commentsComboBoxChanged(int index); void asmComboBoxChanged(int index); void offsetCheckBoxToggled(bool checked); void relOffCheckBoxToggled(bool checked); - void checkboxEnabler(QCheckBox *checkbox, QString config); + + /** + * @brief A generic signal to handle the simple cases where a checkbox is toggled + * while it only responsible for a single independent boolean configuration eval. + * @param checkBox - The checkbox which is responsible for the siganl + * @param config - the configuration string to be toggled + */ + void checkboxEnabler(QCheckBox *checkbox, const QString &config); }; #endif // ASMOPTIONSWIDGET_H diff --git a/src/dialogs/preferences/ColorThemeEditDialog.cpp b/src/dialogs/preferences/ColorThemeEditDialog.cpp index 6063a261..dc8de3e8 100644 --- a/src/dialogs/preferences/ColorThemeEditDialog.cpp +++ b/src/dialogs/preferences/ColorThemeEditDialog.cpp @@ -1,14 +1,13 @@ #include "ColorThemeEditDialog.h" -#include "ui_ColorThemeEditDialog.h" #include "common/ColorThemeWorker.h" #include "common/Configuration.h" - +#include "ui_ColorThemeEditDialog.h" #include "widgets/ColorThemeListView.h" #include "widgets/DisassemblyWidget.h" -#include #include +#include #include ColorThemeEditDialog::ColorThemeEditDialog(QWidget *parent) @@ -16,6 +15,7 @@ ColorThemeEditDialog::ColorThemeEditDialog(QWidget *parent) ui(new Ui::ColorThemeEditDialog), configSignalBlocker( Config()), // Blocks signals from Config to avoid updating of widgets during editing + previewDisasmWidget(new DisassemblyWidget(nullptr)), colorTheme(Config()->getColorTheme()) { showAlphaOptions = { "gui.overview.border", "gui.overview.fill", "wordHighlight", @@ -23,7 +23,6 @@ ColorThemeEditDialog::ColorThemeEditDialog(QWidget *parent) ui->setupUi(this); ui->colorComboBox->setShowOnlyCustom(true); - previewDisasmWidget = new DisassemblyWidget(nullptr); previewDisasmWidget->setObjectName("Preview Disasm"); previewDisasmWidget->setPreviewMode(true); #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) @@ -42,10 +41,10 @@ ColorThemeEditDialog::ColorThemeEditDialog(QWidget *parent) connect(ui->colorThemeListView, &ColorThemeListView::itemChanged, this, [this](const QColor &color) { ui->colorPicker->updateColor(color); - QString optionName = ui->colorThemeListView->currentIndex() - .data(Qt::UserRole) - .value() - .optionName; + const QString optionName = ui->colorThemeListView->currentIndex() + .data(Qt::UserRole) + .value() + .optionName; ui->colorPicker->setAlphaEnabled(showAlphaOptions.contains(optionName)); }); @@ -65,16 +64,15 @@ ColorThemeEditDialog::ColorThemeEditDialog(QWidget *parent) ColorThemeEditDialog::~ColorThemeEditDialog() { - delete ui; previewDisasmWidget->deleteLater(); } void ColorThemeEditDialog::accept() { colorTheme = Config()->getColorTheme(); - ColorThemeWorker::Theme sch = ui->colorThemeListView->colorSettingsModel()->getTheme(); + const ColorThemeWorker::Theme sch = ui->colorThemeListView->colorSettingsModel()->getTheme(); if (ThemeWorker().isCustomTheme(colorTheme)) { - QString err = ThemeWorker().save(sch, colorTheme); + const QString err = ThemeWorker().save(sch, colorTheme); if (!err.isEmpty()) { QMessageBox::critical(this, tr("Error"), err); return; @@ -120,13 +118,13 @@ void ColorThemeEditDialog::keyPressEvent(QKeyEvent *event) void ColorThemeEditDialog::colorOptionChanged(const QColor &newColor) { - QModelIndex currIndex = ui->colorThemeListView->currentIndex(); + const QModelIndex currIndex = ui->colorThemeListView->currentIndex(); if (!currIndex.isValid()) { return; } - ColorOption currOption = currIndex.data(Qt::UserRole).value(); + auto currOption = currIndex.data(Qt::UserRole).value(); currOption.color = newColor; currOption.changed = true; ui->colorThemeListView->model()->setData(currIndex, QVariant::fromValue(currOption)); @@ -141,11 +139,11 @@ void ColorThemeEditDialog::colorOptionChanged(const QColor &newColor) void ColorThemeEditDialog::editThemeChanged(const QString &newTheme) { if (themeWasEdited(colorTheme)) { - int ret = QMessageBox::question(this, tr("Unsaved changes"), - tr("Are you sure you want to exit without saving? " - "All changes will be lost.")); + const int ret = QMessageBox::question(this, tr("Unsaved changes"), + tr("Are you sure you want to exit without saving? " + "All changes will be lost.")); if (ret == QMessageBox::No) { - QSignalBlocker s(ui->colorComboBox); // avoid second call of this func + const QSignalBlocker s(ui->colorComboBox); // avoid second call of this func int index = ui->colorComboBox->findText(colorTheme); index = index == -1 ? 0 : index; ui->colorComboBox->setCurrentIndex(index); diff --git a/src/dialogs/preferences/ColorThemeEditDialog.h b/src/dialogs/preferences/ColorThemeEditDialog.h index 2b4a39e7..477e37df 100644 --- a/src/dialogs/preferences/ColorThemeEditDialog.h +++ b/src/dialogs/preferences/ColorThemeEditDialog.h @@ -3,12 +3,17 @@ #include +#include + class DisassemblyWidget; namespace Ui { class ColorThemeEditDialog; } +/** + * @brief Dialog for editing color theme + */ class ColorThemeEditDialog : public QDialog { Q_OBJECT @@ -44,7 +49,7 @@ private: private: QList showAlphaOptions; - Ui::ColorThemeEditDialog *ui; + std::unique_ptr ui; QSignalBlocker configSignalBlocker; DisassemblyWidget *previewDisasmWidget; QString colorTheme; diff --git a/src/dialogs/preferences/DebugOptionsWidget.cpp b/src/dialogs/preferences/DebugOptionsWidget.cpp index 49000f77..3892c343 100644 --- a/src/dialogs/preferences/DebugOptionsWidget.cpp +++ b/src/dialogs/preferences/DebugOptionsWidget.cpp @@ -1,14 +1,15 @@ #include "DebugOptionsWidget.h" -#include "ui_DebugOptionsWidget.h" -#include -#include -#include -#include -#include -#include "PreferencesDialog.h" -#include "common/Helpers.h" +#include "PreferencesDialog.h" #include "common/Configuration.h" +#include "common/Helpers.h" +#include "ui_DebugOptionsWidget.h" + +#include +#include +#include +#include +#include DebugOptionsWidget::DebugOptionsWidget(PreferencesDialog *dialog) : QDialog(dialog), ui(new Ui::DebugOptionsWidget) @@ -35,20 +36,21 @@ void DebugOptionsWidget::updateDebugPlugin() disconnect(ui->pluginComboBox, &QComboBox::currentTextChanged, this, &DebugOptionsWidget::onDebugPluginChanged); - QStringList plugins = Core()->getDebugPlugins(); - for (const QString &str : plugins) + const QStringList plugins = Core()->getDebugPlugins(); + for (const QString &str : plugins) { ui->pluginComboBox->addItem(str); + } - QString plugin = Core()->getActiveDebugPlugin(); + const QString plugin = Core()->getActiveDebugPlugin(); ui->pluginComboBox->setCurrentText(plugin); connect(ui->pluginComboBox, &QComboBox::currentTextChanged, this, &DebugOptionsWidget::onDebugPluginChanged); - QString stackSize = Core()->getConfig("esil.stack.size"); + const QString stackSize = Core()->getConfig("esil.stack.size"); ui->stackSize->setText(stackSize); ui->stackSize->setPlaceholderText(stackSize); - QString stackAddr = Core()->getConfig("esil.stack.addr"); + const QString stackAddr = Core()->getConfig("esil.stack.addr"); ui->stackAddr->setText(stackAddr); ui->stackAddr->setPlaceholderText(stackAddr); connect(ui->stackAddr, &QLineEdit::editingFinished, this, &DebugOptionsWidget::updateStackAddr); @@ -62,14 +64,14 @@ void DebugOptionsWidget::onDebugPluginChanged(const QString &plugin) void DebugOptionsWidget::updateStackSize() { - QString newSize = ui->stackSize->text(); + const QString newSize = ui->stackSize->text(); Core()->setConfig("esil.stack.size", newSize); ui->stackSize->setPlaceholderText(newSize); } void DebugOptionsWidget::updateStackAddr() { - QString newAddr = ui->stackAddr->text(); + const QString newAddr = ui->stackAddr->text(); Core()->setConfig("esil.stack.addr", newAddr); ui->stackAddr->setPlaceholderText(newAddr); } diff --git a/src/dialogs/preferences/DebugOptionsWidget.h b/src/dialogs/preferences/DebugOptionsWidget.h index 3e8f781a..84032b8f 100644 --- a/src/dialogs/preferences/DebugOptionsWidget.h +++ b/src/dialogs/preferences/DebugOptionsWidget.h @@ -1,16 +1,19 @@ +#ifndef DEBUGOPTIONSWIDGET_H +#define DEBUGOPTIONSWIDGET_H -#pragma once +#include #include -#include "core/Cutter.h" - class PreferencesDialog; namespace Ui { class DebugOptionsWidget; } +/** + * @brief Contains configurable options related to debugging + */ class DebugOptionsWidget : public QDialog { Q_OBJECT @@ -28,3 +31,5 @@ private slots: void updateStackSize(); void onDebugPluginChanged(const QString &index); }; + +#endif // DEBUGOPTIONSWIDGET_H diff --git a/src/dialogs/preferences/GraphOptionsWidget.cpp b/src/dialogs/preferences/GraphOptionsWidget.cpp index 6dee5332..ddefb247 100644 --- a/src/dialogs/preferences/GraphOptionsWidget.cpp +++ b/src/dialogs/preferences/GraphOptionsWidget.cpp @@ -1,13 +1,12 @@ -#include -#include - #include "GraphOptionsWidget.h" + +#include "Cutter.h" +#include "PreferencesDialog.h" +#include "common/Configuration.h" #include "ui_GraphOptionsWidget.h" -#include "PreferencesDialog.h" - -#include "common/Helpers.h" -#include "common/Configuration.h" +#include +#include GraphOptionsWidget::GraphOptionsWidget(PreferencesDialog *dialog) : QDialog(dialog), ui(new Ui::GraphOptionsWidget) @@ -22,19 +21,35 @@ GraphOptionsWidget::GraphOptionsWidget(PreferencesDialog *dialog) connect(ui->bitmapGraphScale, (&QDoubleSpinBox::valueChanged), this, &GraphOptionsWidget::bitmapGraphScaleValueChanged); +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + connect(ui->checkTransparent, &QCheckBox::checkStateChanged, this, + &GraphOptionsWidget::checkTransparentStateChanged); + connect(ui->blockEntryCheckBox, &QCheckBox::checkStateChanged, this, + &GraphOptionsWidget::checkGraphBlockEntryOffsetChanged); +#else connect(ui->checkTransparent, &QCheckBox::stateChanged, this, &GraphOptionsWidget::checkTransparentStateChanged); connect(ui->blockEntryCheckBox, &QCheckBox::stateChanged, this, &GraphOptionsWidget::checkGraphBlockEntryOffsetChanged); - +#endif connect(Core(), &CutterCore::graphOptionsChanged, this, &GraphOptionsWidget::updateOptionsFromVars); - QSpinBox *graphSpacingWidgets[] = { ui->horizontalEdgeSpacing, ui->horizontalBlockSpacing, - ui->verticalEdgeSpacing, ui->verticalBlockSpacing }; + const QSpinBox *const graphSpacingWidgets[] = { ui->horizontalEdgeSpacing, + ui->horizontalBlockSpacing, + ui->verticalEdgeSpacing, + ui->verticalBlockSpacing }; for (auto widget : graphSpacingWidgets) { connect(widget, &QSpinBox::valueChanged, this, &GraphOptionsWidget::layoutSpacingChanged); } + + connect(ui->maxColsSpinBox, static_cast(&QSpinBox::valueChanged), this, + &GraphOptionsWidget::onMaxColsSpinBoxValueChanged); + connect(ui->minFontSizeSpinBox, static_cast(&QSpinBox::valueChanged), + this, &GraphOptionsWidget::onMinFontSizeSpinBoxValueChanged); + + connect(ui->graphPreviewCheckBox, &QCheckBox::toggled, this, + &GraphOptionsWidget::onGraphPreviewCheckBoxToggled); } GraphOptionsWidget::~GraphOptionsWidget() {} @@ -55,7 +70,7 @@ void GraphOptionsWidget::updateOptionsFromVars() ui->verticalEdgeSpacing->setValue(edgeSpacing.y()); } -void GraphOptionsWidget::triggerOptionsChanged() +void GraphOptionsWidget::triggerOptionsChanged() const { disconnect(Core(), &CutterCore::graphOptionsChanged, this, &GraphOptionsWidget::updateOptionsFromVars); @@ -64,19 +79,19 @@ void GraphOptionsWidget::triggerOptionsChanged() &GraphOptionsWidget::updateOptionsFromVars); } -void GraphOptionsWidget::on_maxColsSpinBox_valueChanged(int value) +void GraphOptionsWidget::onMaxColsSpinBoxValueChanged(int value) { Config()->setGraphBlockMaxChars(value); triggerOptionsChanged(); } -void GraphOptionsWidget::on_minFontSizeSpinBox_valueChanged(int value) +void GraphOptionsWidget::onMinFontSizeSpinBoxValueChanged(int value) { Config()->setGraphMinFontSize(value); triggerOptionsChanged(); } -void GraphOptionsWidget::on_graphPreviewCheckBox_toggled(bool checked) +void GraphOptionsWidget::onGraphPreviewCheckBoxToggled(bool checked) { Config()->setGraphPreview(checked); triggerOptionsChanged(); @@ -89,14 +104,16 @@ void GraphOptionsWidget::checkTransparentStateChanged(int checked) void GraphOptionsWidget::bitmapGraphScaleValueChanged(double value) { - double value_decimal = value / (double)100.0; - Config()->setBitmapExportScaleFactor(value_decimal); + const double valueDecimal = value / (double)100.0; + Config()->setBitmapExportScaleFactor(valueDecimal); } void GraphOptionsWidget::layoutSpacingChanged() { - QPoint blockSpacing { ui->horizontalBlockSpacing->value(), ui->verticalBlockSpacing->value() }; - QPoint edgeSpacing { ui->horizontalEdgeSpacing->value(), ui->verticalEdgeSpacing->value() }; + const QPoint blockSpacing { ui->horizontalBlockSpacing->value(), + ui->verticalBlockSpacing->value() }; + const QPoint edgeSpacing { ui->horizontalEdgeSpacing->value(), + ui->verticalEdgeSpacing->value() }; Config()->setGraphSpacing(blockSpacing, edgeSpacing); triggerOptionsChanged(); } diff --git a/src/dialogs/preferences/GraphOptionsWidget.h b/src/dialogs/preferences/GraphOptionsWidget.h index 39807ee9..620da042 100644 --- a/src/dialogs/preferences/GraphOptionsWidget.h +++ b/src/dialogs/preferences/GraphOptionsWidget.h @@ -1,12 +1,10 @@ - #ifndef GRAPHOPTIONSWIDGET_H #define GRAPHOPTIONSWIDGET_H #include #include -#include -#include "core/Cutter.h" +#include class PreferencesDialog; @@ -14,6 +12,9 @@ namespace Ui { class GraphOptionsWidget; } +/** + * @brief Contains configurable options related to graphs + */ class GraphOptionsWidget : public QDialog { Q_OBJECT @@ -25,14 +26,14 @@ public: private: std::unique_ptr ui; - void triggerOptionsChanged(); + void triggerOptionsChanged() const; private slots: void updateOptionsFromVars(); - void on_maxColsSpinBox_valueChanged(int value); - void on_minFontSizeSpinBox_valueChanged(int value); - void on_graphPreviewCheckBox_toggled(bool checked); + void onMaxColsSpinBoxValueChanged(int value); + void onMinFontSizeSpinBoxValueChanged(int value); + void onGraphPreviewCheckBoxToggled(bool checked); void checkTransparentStateChanged(int checked); void bitmapGraphScaleValueChanged(double value); diff --git a/src/dialogs/preferences/InitializationFileEditor.cpp b/src/dialogs/preferences/InitializationFileEditor.cpp index 52f120c0..9401a3fe 100644 --- a/src/dialogs/preferences/InitializationFileEditor.cpp +++ b/src/dialogs/preferences/InitializationFileEditor.cpp @@ -1,19 +1,17 @@ -#include -#include -#include -#include -#include -#include -#include -#include - #include "InitializationFileEditor.h" -#include "ui_InitializationFileEditor.h" #include "PreferencesDialog.h" - #include "common/Helpers.h" -#include "common/Configuration.h" +#include "ui_InitializationFileEditor.h" + +#include +#include +#include +#include +#include +#include +#include +#include InitializationFileEditor::InitializationFileEditor(PreferencesDialog *dialog) : QDialog(dialog), ui(new Ui::InitializationFileEditor) @@ -22,12 +20,12 @@ InitializationFileEditor::InitializationFileEditor(PreferencesDialog *dialog) connect(ui->saveRC, &QDialogButtonBox::accepted, this, &InitializationFileEditor::saveCutterRC); connect(ui->executeNow, &QDialogButtonBox::accepted, this, &InitializationFileEditor::executeCutterRC); - connect(ui->ConfigFileEdit, &QPlainTextEdit::modificationChanged, ui->saveRC, + connect(ui->configFileEdit, &QPlainTextEdit::modificationChanged, ui->saveRC, &QWidget::setEnabled); const QDir cutterRCDirectory = Core()->getCutterRCDefaultDirectory(); auto cutterRCFileInfo = QFileInfo(cutterRCDirectory, "rc"); - QString cutterRCLocation = cutterRCFileInfo.absoluteFilePath(); + const QString cutterRCLocation = cutterRCFileInfo.absoluteFilePath(); ui->cutterRCLoaded->setTextInteractionFlags(Qt::TextBrowserInteraction); ui->cutterRCLoaded->setOpenExternalLinks(true); @@ -37,11 +35,11 @@ InitializationFileEditor::InitializationFileEditor(PreferencesDialog *dialog) cutterRCLocation.toHtmlEscaped())); ui->executeNow->button(QDialogButtonBox::Retry)->setText(tr("Execute", "script")); - ui->ConfigFileEdit->clear(); + ui->configFileEdit->clear(); if (cutterRCFileInfo.exists()) { QFile cutterRC(cutterRCLocation); if (cutterRC.open(QIODevice::ReadWrite | QIODevice::Text)) { - ui->ConfigFileEdit->setPlainText(cutterRC.readAll()); + ui->configFileEdit->setPlainText(cutterRC.readAll()); } cutterRC.close(); } @@ -57,16 +55,16 @@ void InitializationFileEditor::saveCutterRC() cutterRCDirectory.mkpath("."); } auto cutterRCFileInfo = QFileInfo(cutterRCDirectory, "rc"); - QString cutterRCLocation = cutterRCFileInfo.absoluteFilePath(); + const QString cutterRCLocation = cutterRCFileInfo.absoluteFilePath(); QFile cutterRC(cutterRCLocation); if (cutterRC.open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Text)) { QTextStream out(&cutterRC); - QString text = ui->ConfigFileEdit->toPlainText(); + const QString text = ui->configFileEdit->toPlainText(); out << text; cutterRC.close(); } - ui->ConfigFileEdit->document()->setModified(false); + ui->configFileEdit->document()->setModified(false); } void InitializationFileEditor::executeCutterRC() diff --git a/src/dialogs/preferences/InitializationFileEditor.h b/src/dialogs/preferences/InitializationFileEditor.h index 688ffb31..b132e96f 100644 --- a/src/dialogs/preferences/InitializationFileEditor.h +++ b/src/dialogs/preferences/InitializationFileEditor.h @@ -3,8 +3,8 @@ #include #include + #include -#include "core/Cutter.h" class PreferencesDialog; @@ -12,6 +12,9 @@ namespace Ui { class InitializationFileEditor; } +/** + * @brief An editor for Cutter initialization script + */ class InitializationFileEditor : public QDialog { Q_OBJECT @@ -26,4 +29,4 @@ private: std::unique_ptr ui; }; -#endif // INITIALIZATIONFILEEDITOR_H \ No newline at end of file +#endif // INITIALIZATIONFILEEDITOR_H diff --git a/src/dialogs/preferences/InitializationFileEditor.ui b/src/dialogs/preferences/InitializationFileEditor.ui index 30c5ece8..05d5b7cb 100644 --- a/src/dialogs/preferences/InitializationFileEditor.ui +++ b/src/dialogs/preferences/InitializationFileEditor.ui @@ -30,17 +30,17 @@ - QDialogButtonBox::Save + QDialogButtonBox::StandardButton::Save - + - QDialogButtonBox::Retry + QDialogButtonBox::StandardButton::Retry false diff --git a/src/dialogs/preferences/InterfaceOptionsWidget.cpp b/src/dialogs/preferences/InterfaceOptionsWidget.cpp index 23c7a483..a0df6ea5 100644 --- a/src/dialogs/preferences/InterfaceOptionsWidget.cpp +++ b/src/dialogs/preferences/InterfaceOptionsWidget.cpp @@ -1,8 +1,8 @@ #include "InterfaceOptionsWidget.h" -#include "ui_InterfaceOptionsWidget.h" -#include "PreferencesDialog.h" #include "Configuration.h" +#include "PreferencesDialog.h" +#include "ui_InterfaceOptionsWidget.h" InterfaceOptionsWidget::InterfaceOptionsWidget(PreferencesDialog *dialog) : QDialog(dialog), ui(new Ui::InterfaceOptionsWidget) @@ -18,7 +18,7 @@ InterfaceOptionsWidget::~InterfaceOptionsWidget() {} void InterfaceOptionsWidget::setUpFunctions() { - bool truncate = Config()->getTruncateFunctionNameCol(); + const bool truncate = Config()->getTruncateFunctionNameCol(); ui->fcnTruncateCheckBox->setChecked(truncate); ui->fcnTruncateSpinBox->setEnabled(truncate); ui->fcnTruncateSpinBox->setValue(Config()->getFunctionNameColWidth()); diff --git a/src/dialogs/preferences/InterfaceOptionsWidget.h b/src/dialogs/preferences/InterfaceOptionsWidget.h index 563ca6fe..99ad3f16 100644 --- a/src/dialogs/preferences/InterfaceOptionsWidget.h +++ b/src/dialogs/preferences/InterfaceOptionsWidget.h @@ -2,6 +2,7 @@ #define INTERFACEOPTIONSWIDGET_H #include + #include namespace Ui { diff --git a/src/dialogs/preferences/PluginsOptionsWidget.cpp b/src/dialogs/preferences/PluginsOptionsWidget.cpp index 188d8f3e..563e8ac9 100644 --- a/src/dialogs/preferences/PluginsOptionsWidget.cpp +++ b/src/dialogs/preferences/PluginsOptionsWidget.cpp @@ -1,18 +1,15 @@ - #include "PluginsOptionsWidget.h" #include "PreferencesDialog.h" - #include "common/Helpers.h" -#include "common/Configuration.h" -#include "plugins/PluginManager.h" #include "dialogs/RizinPluginsDialog.h" +#include "plugins/PluginManager.h" #include #include #include -#include #include +#include PluginsOptionsWidget::PluginsOptionsWidget(PreferencesDialog *dialog) : QDialog(dialog) { diff --git a/src/dialogs/preferences/PluginsOptionsWidget.h b/src/dialogs/preferences/PluginsOptionsWidget.h index 5cca83c9..673a8ff4 100644 --- a/src/dialogs/preferences/PluginsOptionsWidget.h +++ b/src/dialogs/preferences/PluginsOptionsWidget.h @@ -1,4 +1,3 @@ - #ifndef PLUGINSOPTIONSWIDGET_H #define PLUGINSOPTIONSWIDGET_H @@ -6,6 +5,9 @@ class PreferencesDialog; +/** + * @brief Contains configurable options related to plugins + */ class PluginsOptionsWidget : public QDialog { Q_OBJECT diff --git a/src/dialogs/preferences/PreferenceCategory.cpp b/src/dialogs/preferences/PreferenceCategory.cpp index 4d352d88..17d2b445 100644 --- a/src/dialogs/preferences/PreferenceCategory.cpp +++ b/src/dialogs/preferences/PreferenceCategory.cpp @@ -24,11 +24,12 @@ PreferenceCategory::PreferenceCategory(const QString &name, const QIcon &icon, void PreferenceCategory::addItem(QTreeWidget &tree, QStackedWidget &panel) { - QTreeWidgetItem *w = new QTreeWidgetItem({ name }); + auto *w = new QTreeWidgetItem({ name }); tree.addTopLevelItem(w); - for (auto &c : children) + for (auto &c : children) { c.addItem(*w, panel); + } w->setExpanded(true); w->setIcon(0, icon); @@ -41,11 +42,12 @@ void PreferenceCategory::addItem(QTreeWidget &tree, QStackedWidget &panel) void PreferenceCategory::addItem(QTreeWidgetItem &tree, QStackedWidget &panel) { - QTreeWidgetItem *w = new QTreeWidgetItem({ name }); + auto *w = new QTreeWidgetItem({ name }); tree.addChild(w); - for (auto &c : children) + for (auto &c : children) { c.addItem(*w, panel); + } w->setExpanded(true); w->setIcon(0, icon); diff --git a/src/dialogs/preferences/PreferenceCategory.h b/src/dialogs/preferences/PreferenceCategory.h index b8a403ec..e71237f3 100644 --- a/src/dialogs/preferences/PreferenceCategory.h +++ b/src/dialogs/preferences/PreferenceCategory.h @@ -1,10 +1,16 @@ #ifndef PREFERENCECATEGORY_H #define PREFERENCECATEGORY_H +#include #include #include -#include +/** + * @brief Main class for that divides the view into two sides in Preferences: + * + * Left Side: Tree containing items for all options widget + * Right Side: Content for selected item + */ class PreferenceCategory { public: diff --git a/src/dialogs/preferences/PreferencesDialog.cpp b/src/dialogs/preferences/PreferencesDialog.cpp index 46642c13..ed4b7206 100644 --- a/src/dialogs/preferences/PreferencesDialog.cpp +++ b/src/dialogs/preferences/PreferencesDialog.cpp @@ -1,21 +1,19 @@ #include "PreferencesDialog.h" -#include "ui_PreferencesDialog.h" +#include "AnalysisOptionsWidget.h" #include "AppearanceOptionsWidget.h" #include "AsmOptionsWidget.h" -#include "GraphOptionsWidget.h" #include "DebugOptionsWidget.h" -#include "PluginsOptionsWidget.h" +#include "GraphOptionsWidget.h" #include "InitializationFileEditor.h" -#include "AnalysisOptionsWidget.h" +#include "InterfaceOptionsWidget.h" +#include "PluginsOptionsWidget.h" +#include "PreferenceCategory.h" #include "ShortcutOptionsWidget.h" #include "SymbolsOptionsWidget.h" -#include "InterfaceOptionsWidget.h" - -#include "PreferenceCategory.h" - -#include "common/Helpers.h" #include "common/Configuration.h" +#include "common/Helpers.h" +#include "ui_PreferencesDialog.h" #include @@ -87,13 +85,15 @@ void PreferencesDialog::showSection(PreferencesDialog::Section section) void PreferencesDialog::changePage(QTreeWidgetItem *current, QTreeWidgetItem *previous) { - if (!current) + if (!current) { current = previous; + } - int index = current->data(0, Qt::UserRole).toInt(); + const int index = current->data(0, Qt::UserRole).toInt(); - if (index) + if (index) { ui->configPanel->setCurrentIndex(index - 1); + } } void PreferencesDialog::chooseThemeIcons() diff --git a/src/dialogs/preferences/PreferencesDialog.h b/src/dialogs/preferences/PreferencesDialog.h index 408ab5f2..e4ee1ab4 100644 --- a/src/dialogs/preferences/PreferencesDialog.h +++ b/src/dialogs/preferences/PreferencesDialog.h @@ -1,11 +1,10 @@ - #ifndef PREFERENCESDIALOG_H #define PREFERENCESDIALOG_H -#include "core/Cutter.h" #include "core/MainWindow.h" #include + #include class QTreeWidgetItem; @@ -14,12 +13,15 @@ namespace Ui { class PreferencesDialog; } +/** + * @brief Main Dialog that contains preference settings + */ class PreferencesDialog : public QDialog { Q_OBJECT public: - enum class Section { Appearance, Disassembly }; + enum class Section : ut8 { Appearance, Disassembly }; explicit PreferencesDialog(MainWindow *parent = nullptr); ~PreferencesDialog(); diff --git a/src/dialogs/preferences/ShortcutOptionsWidget.cpp b/src/dialogs/preferences/ShortcutOptionsWidget.cpp index c0f28af3..c8cc9d87 100644 --- a/src/dialogs/preferences/ShortcutOptionsWidget.cpp +++ b/src/dialogs/preferences/ShortcutOptionsWidget.cpp @@ -1,6 +1,7 @@ #include "ShortcutOptionsWidget.h" -#include "ui_ShortcutOptionsWidget.h" + #include "shortcuts/ShortcutManager.h" +#include "ui_ShortcutOptionsWidget.h" ShortcutOptionsWidget::ShortcutOptionsWidget(QWidget *parent) : QDialog(parent), ui(new Ui::ShortcutOptionsWidget) @@ -43,7 +44,7 @@ void ShortcutOptionsWidget::populateShortcutTree() const auto shortcuts = Shortcuts()->getAllShortcuts(); for (auto it = shortcuts.cbegin(); it != shortcuts.cend(); ++it) { QString name = it.key(); - Shortcut s = it.value(); + const Shortcut &s = it.value(); QTreeWidgetItem *parent = prefixToItem["General"]; for (auto it = prefixToItem.cbegin(); it != prefixToItem.cend(); ++it) { @@ -55,7 +56,7 @@ void ShortcutOptionsWidget::populateShortcutTree() } } - QTreeWidgetItem *item = new QTreeWidgetItem(parent); + auto *item = new QTreeWidgetItem(parent); item->setText(0, name); QStringList shortcutTexts; @@ -71,7 +72,7 @@ void ShortcutOptionsWidget::populateShortcutTree() QTreeWidgetItem *ShortcutOptionsWidget::createCategoryItem(const QString &label) { - QTreeWidgetItem *item = new QTreeWidgetItem(ui->shortcutTree); + auto *item = new QTreeWidgetItem(ui->shortcutTree); QFont bold; bold.setBold(true); item->setText(0, label); @@ -86,7 +87,7 @@ void ShortcutOptionsWidget::filterShortcutTree(const QString &input) for (int i = 0; i < ui->shortcutTree->topLevelItemCount(); ++i) { QTreeWidgetItem *category = ui->shortcutTree->topLevelItem(i); - bool categoryMatches = category->text(0).toLower().contains(filter); + const bool categoryMatches = category->text(0).toLower().contains(filter); bool hasVisibleChildren = false; for (int j = 0; j < category->childCount(); ++j) { @@ -104,8 +105,9 @@ void ShortcutOptionsWidget::filterShortcutTree(const QString &input) } } child->setHidden(!match); - if (match) + if (match) { hasVisibleChildren = true; + } } category->setHidden(!(categoryMatches || hasVisibleChildren)); } diff --git a/src/dialogs/preferences/ShortcutOptionsWidget.h b/src/dialogs/preferences/ShortcutOptionsWidget.h index 5f8fb2d7..99117bc3 100644 --- a/src/dialogs/preferences/ShortcutOptionsWidget.h +++ b/src/dialogs/preferences/ShortcutOptionsWidget.h @@ -2,6 +2,7 @@ #define SHORTCUTOPTIONSWIDGET_H #include + #include class QTreeWidgetItem; @@ -10,6 +11,9 @@ namespace Ui { class ShortcutOptionsWidget; } +/** + * @brief Lists default shortcuts in preferences + */ class ShortcutOptionsWidget : public QDialog { Q_OBJECT diff --git a/src/dialogs/preferences/SymbolsOptionsWidget.cpp b/src/dialogs/preferences/SymbolsOptionsWidget.cpp index 83f2d2ee..f3d819ce 100644 --- a/src/dialogs/preferences/SymbolsOptionsWidget.cpp +++ b/src/dialogs/preferences/SymbolsOptionsWidget.cpp @@ -1,12 +1,14 @@ #include "SymbolsOptionsWidget.h" -#include "ui_SymbolsOptionsWidget.h" -#include -#include -#include -#include + +#include "PreferencesDialog.h" #include "core/Cutter.h" #include "core/MainWindow.h" -#include "PreferencesDialog.h" +#include "ui_SymbolsOptionsWidget.h" + +#include +#include +#include +#include SymbolsOptionsWidget::SymbolsOptionsWidget(PreferencesDialog *parent) : QDialog(parent), mainWindow(parent->getMainWindow()), ui(new Ui::SymbolsOptionsWidget) @@ -19,7 +21,7 @@ SymbolsOptionsWidget::SymbolsOptionsWidget(PreferencesDialog *parent) ui->debuginfodCheckBox->setChecked(Core()->getConfigb("bin.dbginfo.debuginfod")); ui->debuginfodLineEdit->setText(Core()->getConfig("bin.dbginfo.debuginfod_urls")); updateDebuginfodLayout(); -#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) connect(ui->debuginfodCheckBox, &QCheckBox::checkStateChanged, this, &SymbolsOptionsWidget::updateDebuginfodLayout); #else @@ -54,10 +56,10 @@ void SymbolsOptionsWidget::reanalyze() Core()->setConfig("bin.dbginfo.debuginfod_urls", ui->debuginfodLineEdit->text()); Core()->setConfig("pdb.server", ui->pdbServerEdit->text()); - mainWindow->on_actionAnalyze_triggered(); - QUrl pdbFile = QUrl::fromUserInput(ui->pdbLineEdit->text()); + mainWindow->onActionAnalyzeTriggered(); + const QUrl pdbFile = QUrl::fromUserInput(ui->pdbLineEdit->text()); if (pdbFile.isValid() && pdbFile.isLocalFile()) { - QFileInfo pdbFileInfo(pdbFile.toLocalFile()); + const QFileInfo pdbFileInfo(pdbFile.toLocalFile()); if (pdbFileInfo.exists() && pdbFileInfo.isFile()) { Core()->loadPDB(ui->pdbLineEdit->text()); mainWindow->refreshAll(); diff --git a/src/dialogs/preferences/SymbolsOptionsWidget.h b/src/dialogs/preferences/SymbolsOptionsWidget.h index 8c7464f4..4c2b16d9 100644 --- a/src/dialogs/preferences/SymbolsOptionsWidget.h +++ b/src/dialogs/preferences/SymbolsOptionsWidget.h @@ -1,10 +1,10 @@ #ifndef SYMBOLSOPTIONSWIDGET_H #define SYMBOLSOPTIONSWIDGET_H -#include - -#include #include +#include + +#include class MainWindow; @@ -14,6 +14,9 @@ namespace Ui { class SymbolsOptionsWidget; } +/** + * @brief Contains configurable options related to symbols + */ class SymbolsOptionsWidget : public QDialog { Q_OBJECT diff --git a/src/menus/AddressableItemContextMenu.cpp b/src/menus/AddressableItemContextMenu.cpp index d81d3817..dde45865 100644 --- a/src/menus/AddressableItemContextMenu.cpp +++ b/src/menus/AddressableItemContextMenu.cpp @@ -1,15 +1,18 @@ #include "AddressableItemContextMenu.h" -#include "dialogs/XrefsDialog.h" + #include "MainWindow.h" #include "dialogs/CommentsDialog.h" +#include "dialogs/XrefsDialog.h" #include "shortcuts/ShortcutManager.h" -#include -#include -#include -#include #include +#include +#include #include +#include +#include + +#include AddressableItemContextMenu::AddressableItemContextMenu(QWidget *parent, MainWindow *mainWindow) : QMenu(parent), mainWindow(mainWindow) @@ -68,7 +71,7 @@ void AddressableItemContextMenu::setOffset(RVA offset) void AddressableItemContextMenu::setTarget(RVA offset, QString name) { this->offset = offset; - this->name = name; + this->name = std::move(name); setHasTarget(true); } @@ -84,19 +87,19 @@ void AddressableItemContextMenu::toggleBreakpointAction(bool enabled) setHasTarget(hasTarget); } -void AddressableItemContextMenu::onActionCopyAddress() +void AddressableItemContextMenu::onActionCopyAddress() const { auto clipboard = QApplication::clipboard(); - clipboard->setText(RzAddressString(offset)); + clipboard->setText(rzAddressString(offset)); } void AddressableItemContextMenu::onActionShowXrefs() { emit xrefsTriggered(); XrefsDialog dialog(mainWindow, true); - QString tmpName = name; + const QString tmpName = name; if (name.isEmpty()) { - name = RzAddressString(offset); + name = rzAddressString(offset); } dialog.fillRefsForAddress(offset, name, wholeFunction); dialog.exec(); @@ -107,7 +110,7 @@ void AddressableItemContextMenu::onActionAddComment() CommentsDialog::addOrEditComment(offset, this); } -void AddressableItemContextMenu::onActionToggleBreakpoint() +void AddressableItemContextMenu::onActionToggleBreakpoint() const { Core()->toggleBreakpoint(offset); } diff --git a/src/menus/AddressableItemContextMenu.h b/src/menus/AddressableItemContextMenu.h index 420f976e..077e26d4 100644 --- a/src/menus/AddressableItemContextMenu.h +++ b/src/menus/AddressableItemContextMenu.h @@ -1,12 +1,16 @@ #ifndef ADDRESSABLEITEMCONTEXTMENU_H #define ADDRESSABLEITEMCONTEXTMENU_H -#include "core/Cutter.h" -#include +#include "CutterCommon.h" + #include +#include class MainWindow; +/** + * @brief Generic context menu for Addressable widgets + */ class CUTTER_EXPORT AddressableItemContextMenu : public QMenu { Q_OBJECT @@ -29,10 +33,10 @@ signals: void xrefsTriggered(); private: - void onActionCopyAddress(); + void onActionCopyAddress() const; void onActionShowXrefs(); void onActionAddComment(); - void onActionToggleBreakpoint(); + void onActionToggleBreakpoint() const; virtual void aboutToShowSlot(); diff --git a/src/menus/DecompilerContextMenu.cpp b/src/menus/DecompilerContextMenu.cpp index 3aa0f9f5..fd1c9027 100644 --- a/src/menus/DecompilerContextMenu.cpp +++ b/src/menus/DecompilerContextMenu.cpp @@ -1,20 +1,21 @@ #include "DecompilerContextMenu.h" -#include "dialogs/preferences/PreferencesDialog.h" + #include "MainWindow.h" #include "dialogs/BreakpointsDialog.h" #include "dialogs/CommentsDialog.h" #include "dialogs/EditVariablesDialog.h" #include "dialogs/XrefsDialog.h" -#include "common/Configuration.h" #include "shortcuts/ShortcutManager.h" -#include -#include -#include -#include #include -#include +#include #include +#include +#include +#include +#include + +#include DecompilerContextMenu::DecompilerContextMenu(QWidget *parent, MainWindow *mainWindow) : QMenu(parent), @@ -27,6 +28,7 @@ DecompilerContextMenu::DecompilerContextMenu(QWidget *parent, MainWindow *mainWi actionCopy(this), actionCopyInstructionAddress(tr("Copy instruction address (

)"), this), actionCopyReferenceAddress(this), + copySeparator(addSeparator()), actionShowInSubmenu(tr("Show in"), this), actionAddComment(this), actionDeleteComment(tr("Delete comment"), this), @@ -44,7 +46,6 @@ DecompilerContextMenu::DecompilerContextMenu(QWidget *parent, MainWindow *mainWi addSeparator(); setActionShowInSubmenu(); - copySeparator = addSeparator(); setActionAddComment(); setActionDeleteComment(); @@ -82,7 +83,7 @@ void DecompilerContextMenu::setAnnotationHere(RzCodeAnnotation *annotation) void DecompilerContextMenu::setCurHighlightedWord(QString word) { - curHighlightedWord = word; + curHighlightedWord = std::move(word); } void DecompilerContextMenu::setOffset(RVA newOffset) @@ -100,21 +101,21 @@ void DecompilerContextMenu::setFirstOffsetInLine(RVA firstOffset) firstOffsetInLine = firstOffset; } -RVA DecompilerContextMenu::getFirstOffsetInLine() +RVA DecompilerContextMenu::getFirstOffsetInLine() const { return firstOffsetInLine; } void DecompilerContextMenu::setAvailableBreakpoints(QVector offsetList) { - availableBreakpoints = offsetList; + availableBreakpoints = std::move(offsetList); } void DecompilerContextMenu::setupBreakpointsInLineMenu() { breakpointsInLineMenu->clear(); - for (auto curOffset : this->availableBreakpoints) { - QAction *action = breakpointsInLineMenu->addAction(RzAddressString(curOffset)); + for (auto curOffset : std::as_const(this->availableBreakpoints)) { + const QAction *action = breakpointsInLineMenu->addAction(rzAddressString(curOffset)); connect(action, &QAction::triggered, this, [this, curOffset] { BreakpointsDialog::editBreakpoint(Core()->getBreakpointAt(curOffset), this); }); @@ -139,7 +140,7 @@ void DecompilerContextMenu::setIsTogglingBreakpoints(bool isToggling) isTogglingBreakpoints = isToggling; } -bool DecompilerContextMenu::getIsTogglingBreakpoints() +bool DecompilerContextMenu::getIsTogglingBreakpoints() const { return isTogglingBreakpoints; } @@ -160,7 +161,7 @@ void DecompilerContextMenu::aboutToShowSlot() { if (this->firstOffsetInLine != RVA_MAX) { actionShowInSubmenu.setVisible(true); - QString comment = Core()->getCommentAt(firstOffsetInLine); + const QString comment = Core()->getCommentAt(firstOffsetInLine); actionAddComment.setVisible(true); if (comment.isEmpty()) { actionDeleteComment.setVisible(false); @@ -180,8 +181,8 @@ void DecompilerContextMenu::aboutToShowSlot() // Only show debug options if we are currently debugging debugMenu->menuAction()->setVisible(Core()->currentlyDebugging); - bool hasBreakpoint = !this->availableBreakpoints.isEmpty(); - int numberOfBreakpoints = this->availableBreakpoints.size(); + const bool hasBreakpoint = !this->availableBreakpoints.isEmpty(); + const int numberOfBreakpoints = this->availableBreakpoints.size(); if (numberOfBreakpoints == 0) { actionToggleBreakpoint.setText(tr("Add breakpoint")); } else if (numberOfBreakpoints == 1) { @@ -197,7 +198,7 @@ void DecompilerContextMenu::aboutToShowSlot() actionAdvancedBreakpoint.setText(hasBreakpoint ? tr("Edit breakpoint") : tr("Advanced breakpoint")); - QString progCounterName = Core()->getRegisterName("PC").toUpper(); + const QString progCounterName = Core()->getRegisterName("PC").toUpper(); actionSetPC.setText(tr("Set %1 here").arg(progCounterName)); if (!annotationHere @@ -213,7 +214,8 @@ void DecompilerContextMenu::aboutToShowSlot() tr("Rename function %1").arg(QString(annotationHere->reference.name))); } else if (annotationHere->type == RZ_CODE_ANNOTATION_TYPE_GLOBAL_VARIABLE) { RzCoreLocked core = Core()->lock(); - RzFlagItem *flagDetails = rz_flag_get_i(core->flags, annotationHere->reference.offset); + const RzFlagItem *flagDetails = + rz_flag_get_i(core->flags, annotationHere->reference.offset); if (flagDetails) { actionRenameThingHere.setText(tr("Rename %1").arg(QString(flagDetails->name))); actionDeleteName.setText(tr("Remove %1").arg(QString(flagDetails->name))); @@ -224,23 +226,23 @@ void DecompilerContextMenu::aboutToShowSlot() } } actionCopyInstructionAddress.setText( - tr("Copy instruction address (%1)").arg(RzAddressString(offset))); + tr("Copy instruction address (%1)").arg(rzAddressString(offset))); if (isReference()) { actionCopyReferenceAddress.setVisible(true); - RVA referenceAddr = annotationHere->reference.offset; + const RVA referenceAddr = annotationHere->reference.offset; RzCoreLocked core = Core()->lock(); - RzFlagItem *flagDetails = rz_flag_get_i(core->flags, referenceAddr); + const RzFlagItem *flagDetails = rz_flag_get_i(core->flags, referenceAddr); if (annotationHere->type == RZ_CODE_ANNOTATION_TYPE_FUNCTION_NAME) { actionCopyReferenceAddress.setText(tr("Copy address of %1 (%2)") .arg(QString(annotationHere->reference.name), - RzAddressString(referenceAddr))); + rzAddressString(referenceAddr))); } else if (flagDetails) { actionCopyReferenceAddress.setText( tr("Copy address of %1 (%2)") - .arg(flagDetails->name, RzAddressString(referenceAddr))); + .arg(flagDetails->name, rzAddressString(referenceAddr))); } else { actionCopyReferenceAddress.setText( - tr("Copy address (%1)").arg(RzAddressString(referenceAddr))); + tr("Copy address (%1)").arg(rzAddressString(referenceAddr))); } } else { actionXRefs.setVisible(false); @@ -373,16 +375,16 @@ void DecompilerContextMenu::actionCopyTriggered() emit copy(); } -void DecompilerContextMenu::actionCopyInstructionAddressTriggered() +void DecompilerContextMenu::actionCopyInstructionAddressTriggered() const { QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(RzAddressString(offset)); + clipboard->setText(rzAddressString(offset)); } void DecompilerContextMenu::actionCopyReferenceAddressTriggered() { QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(RzAddressString(annotationHere->reference.offset)); + clipboard->setText(rzAddressString(annotationHere->reference.offset)); } void DecompilerContextMenu::actionAddCommentTriggered() @@ -390,7 +392,7 @@ void DecompilerContextMenu::actionAddCommentTriggered() CommentsDialog::addOrEditComment(this->firstOffsetInLine, parentForDialog()); } -void DecompilerContextMenu::actionDeleteCommentTriggered() +void DecompilerContextMenu::actionDeleteCommentTriggered() const { Core()->delComment(this->firstOffsetInLine); } @@ -404,41 +406,41 @@ void DecompilerContextMenu::actionRenameThingHereTriggered() bool ok; auto type = annotationHere->type; if (type == RZ_CODE_ANNOTATION_TYPE_FUNCTION_NAME) { - QString currentName(annotationHere->reference.name); - RVA func_addr = annotationHere->reference.offset; - RzAnalysisFunction *func = Core()->functionAt(func_addr); - if (func == NULL) { - QString function_name = QInputDialog::getText( + const QString currentName(annotationHere->reference.name); + const RVA funcAddr = annotationHere->reference.offset; + const RzAnalysisFunction *func = Core()->functionAt(funcAddr); + if (func == nullptr) { + const QString functionName = QInputDialog::getText( parentForDialog(), - tr("Define this function at %2").arg(RzAddressString(func_addr)), + tr("Define this function at %2").arg(rzAddressString(funcAddr)), tr("Function name:"), QLineEdit::Normal, currentName, &ok); - if (ok && !function_name.isEmpty()) { - Core()->createFunctionAt(func_addr, function_name); + if (ok && !functionName.isEmpty()) { + Core()->createFunctionAt(funcAddr, functionName); } } else { - QString newName = QInputDialog::getText( + const QString newName = QInputDialog::getText( parentForDialog(), tr("Rename function %2").arg(currentName), tr("Function name:"), QLineEdit::Normal, currentName, &ok); if (ok && !newName.isEmpty()) { - Core()->renameFunction(func_addr, newName); + Core()->renameFunction(funcAddr, newName); } } } else if (type == RZ_CODE_ANNOTATION_TYPE_GLOBAL_VARIABLE) { - RVA var_addr = annotationHere->reference.offset; - RzFlagItem *flagDetails = rz_flag_get_i(core->flags, var_addr); + const RVA varAddr = annotationHere->reference.offset; + const RzFlagItem *flagDetails = rz_flag_get_i(core->flags, varAddr); if (flagDetails) { - QString newName = QInputDialog::getText( + const QString newName = QInputDialog::getText( parentForDialog(), tr("Rename %2").arg(flagDetails->name), tr("Enter name"), QLineEdit::Normal, flagDetails->name, &ok); if (ok && !newName.isEmpty()) { Core()->renameFlag(flagDetails->name, newName); } } else { - QString newName = QInputDialog::getText( + const QString newName = QInputDialog::getText( parentForDialog(), tr("Add name to %2").arg(curHighlightedWord), tr("Enter name"), QLineEdit::Normal, curHighlightedWord, &ok); if (ok && !newName.isEmpty()) { - Core()->addFlag(var_addr, newName, 1); + Core()->addFlag(varAddr, newName, 1); } } } else if (isFunctionVariable()) { @@ -451,9 +453,10 @@ void DecompilerContextMenu::actionRenameThingHereTriggered() "Only local variables defined in disassembly can be renamed.")); return; } - QString oldName(annotationHere->variable.name); - QString newName = QInputDialog::getText(parentForDialog(), tr("Rename %2").arg(oldName), - tr("Enter name"), QLineEdit::Normal, oldName, &ok); + const QString oldName(annotationHere->variable.name); + const QString newName = + QInputDialog::getText(parentForDialog(), tr("Rename %2").arg(oldName), + tr("Enter name"), QLineEdit::Normal, oldName, &ok); if (ok && !newName.isEmpty()) { Core()->renameFunctionVariable(newName, oldName, decompiledFunctionAddress); } @@ -488,9 +491,9 @@ void DecompilerContextMenu::actionXRefsTriggered() return; } XrefsDialog dialog(mainWindow); - QString displayString = (annotationHere->type == RZ_CODE_ANNOTATION_TYPE_FUNCTION_NAME) + const QString displayString = (annotationHere->type == RZ_CODE_ANNOTATION_TYPE_FUNCTION_NAME) ? QString(annotationHere->reference.name) - : RzAddressString(annotationHere->reference.offset); + : rzAddressString(annotationHere->reference.offset); dialog.fillRefsForAddress(annotationHere->reference.offset, displayString, false); dialog.exec(); } @@ -499,15 +502,16 @@ void DecompilerContextMenu::actionToggleBreakpointTriggered() { if (!this->availableBreakpoints.isEmpty()) { setIsTogglingBreakpoints(true); - for (auto offsetToRemove : this->availableBreakpoints) { + for (auto offsetToRemove : std::as_const(this->availableBreakpoints)) { Core()->toggleBreakpoint(offsetToRemove); } this->availableBreakpoints.clear(); setIsTogglingBreakpoints(false); return; } - if (this->firstOffsetInLine == RVA_MAX) + if (this->firstOffsetInLine == RVA_MAX) { return; + } Core()->toggleBreakpoint(this->firstOffsetInLine); } @@ -524,15 +528,15 @@ void DecompilerContextMenu::actionAdvancedBreakpointTriggered() } } -void DecompilerContextMenu::actionContinueUntilTriggered() +void DecompilerContextMenu::actionContinueUntilTriggered() const { Core()->continueUntilDebug(offset); } -void DecompilerContextMenu::actionSetPCTriggered() +void DecompilerContextMenu::actionSetPCTriggered() const { - QString progCounterName = Core()->getRegisterName("PC"); - Core()->setRegister(progCounterName, RzAddressString(offset).toUpper()); + const QString progCounterName = Core()->getRegisterName("PC"); + Core()->setRegister(progCounterName, rzAddressString(offset).toUpper()); } // Set up menus @@ -559,7 +563,7 @@ void DecompilerContextMenu::addDebugMenu() void DecompilerContextMenu::updateTargetMenuActions() { - for (auto action : showTargetMenuActions) { + for (auto action : std::as_const(showTargetMenuActions)) { removeAction(action); auto menu = action->menu(); if (menu) { @@ -576,18 +580,18 @@ void DecompilerContextMenu::updateTargetMenuActions() || annotationHere->type == RZ_CODE_ANNOTATION_TYPE_CONSTANT_VARIABLE) { menu = mainWindow->createShowInMenu(this, annotationHere->reference.offset, AddressTypeHint::Data); - RVA var_addr = annotationHere->reference.offset; - RzFlagItem *flagDetails = rz_flag_get_i(core->flags, var_addr); + const RVA varAddr = annotationHere->reference.offset; + const RzFlagItem *flagDetails = rz_flag_get_i(core->flags, varAddr); if (flagDetails) { name = tr("Show %1 in").arg(flagDetails->name); } else { - name = tr("Show %1 in").arg(RzAddressString(annotationHere->reference.offset)); + name = tr("Show %1 in").arg(rzAddressString(annotationHere->reference.offset)); } } else if (annotationHere->type == RZ_CODE_ANNOTATION_TYPE_FUNCTION_NAME) { menu = mainWindow->createShowInMenu(this, annotationHere->reference.offset, AddressTypeHint::Function); name = tr("%1 (%2)").arg(QString(annotationHere->reference.name), - RzAddressString(annotationHere->reference.offset)); + rzAddressString(annotationHere->reference.offset)); } auto action = new QAction(name, this); showTargetMenuActions.append(action); @@ -608,8 +612,8 @@ bool DecompilerContextMenu::isFunctionVariable() bool DecompilerContextMenu::variablePresentInRizin() { - QString variableName(annotationHere->variable.name); - QList variables = Core()->getVariables(offset); + const QString variableName(annotationHere->variable.name); + const QList variables = Core()->getVariables(offset); for (const VariableDescription &var : variables) { if (var.name == variableName) { return true; diff --git a/src/menus/DecompilerContextMenu.h b/src/menus/DecompilerContextMenu.h index c71a2d27..114f704e 100644 --- a/src/menus/DecompilerContextMenu.h +++ b/src/menus/DecompilerContextMenu.h @@ -1,14 +1,18 @@ #ifndef DECOMPILERCONTEXTMENU_H #define DECOMPILERCONTEXTMENU_H -#include "core/Cutter.h" -#include +#include "CutterCommon.h" + #include +#include #include class MainWindow; +/** + * @brief Context menu for @ref DecompilerWidget + */ class DecompilerContextMenu : public QMenu { Q_OBJECT @@ -17,9 +21,9 @@ public: DecompilerContextMenu(QWidget *parent, MainWindow *mainWindow); ~DecompilerContextMenu(); - bool getIsTogglingBreakpoints(); + bool getIsTogglingBreakpoints() const; void setAnnotationHere(RzCodeAnnotation *annotation); - RVA getFirstOffsetInLine(); + RVA getFirstOffsetInLine() const; signals: void copy(); @@ -36,11 +40,11 @@ private slots: void aboutToHideSlot(); void actionCopyTriggered(); - void actionCopyInstructionAddressTriggered(); + void actionCopyInstructionAddressTriggered() const; void actionCopyReferenceAddressTriggered(); void actionAddCommentTriggered(); - void actionDeleteCommentTriggered(); + void actionDeleteCommentTriggered() const; void actionRenameThingHereTriggered(); void actionDeleteNameTriggered(); @@ -52,8 +56,8 @@ private slots: void actionToggleBreakpointTriggered(); void actionAdvancedBreakpointTriggered(); - void actionContinueUntilTriggered(); - void actionSetPCTriggered(); + void actionContinueUntilTriggered() const; + void actionSetPCTriggered() const; private: // Private variables diff --git a/src/menus/DisassemblyContextMenu.cpp b/src/menus/DisassemblyContextMenu.cpp index ae9d69d5..589ce342 100644 --- a/src/menus/DisassemblyContextMenu.cpp +++ b/src/menus/DisassemblyContextMenu.cpp @@ -1,25 +1,25 @@ #include "DisassemblyContextMenu.h" -#include "dialogs/preferences/PreferencesDialog.h" -#include "dialogs/EditInstructionDialog.h" + +#include "MainWindow.h" +#include "dialogs/BreakpointsDialog.h" #include "dialogs/CommentsDialog.h" +#include "dialogs/EditFunctionDialog.h" +#include "dialogs/EditInstructionDialog.h" +#include "dialogs/EditStringDialog.h" +#include "dialogs/EditVariablesDialog.h" #include "dialogs/FlagDialog.h" #include "dialogs/GlobalVariableDialog.h" -#include "dialogs/XrefsDialog.h" -#include "dialogs/EditVariablesDialog.h" #include "dialogs/SetToDataDialog.h" -#include "dialogs/EditFunctionDialog.h" -#include "dialogs/EditStringDialog.h" -#include "dialogs/BreakpointsDialog.h" +#include "dialogs/XrefsDialog.h" #include "shortcuts/ShortcutManager.h" -#include "MainWindow.h" -#include -#include -#include -#include #include -#include +#include #include +#include +#include +#include +#include DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow *mainWindow) : QMenu(parent), @@ -32,6 +32,7 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow *main actionJmpReverse(this), actionEditBytes(this), actionCopy(this), + copySeparator(addSeparator()), actionCopyAddr(this), actionCopyInstrBytes(this), actionAddComment(this), @@ -71,46 +72,45 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow *main actionSetToDataQword(this), showInSubmenu(this) { - initShortcutAction(&actionCopy, "Disassembly.copy", SLOT(on_actionCopy_triggered())); + initShortcutAction(&actionCopy, "Disassembly.copy", &DisassemblyContextMenu::copyTriggered); addAction(&actionCopy); - initShortcutAction(&actionCopyAddr, "General.copyAddress", SLOT(on_actionCopyAddr_triggered())); + initShortcutAction(&actionCopyAddr, "General.copyAddress", + &DisassemblyContextMenu::copyAddrTriggered); addAction(&actionCopyAddr); initShortcutAction(&actionCopyInstrBytes, "Disassembly.copyInstructionBytes", - SLOT(on_actionCopyInstrBytes_triggered())); + &DisassemblyContextMenu::copyInstrBytesTriggered); addAction(&actionCopyInstrBytes); initAction(&showInSubmenu, tr("Show in"), nullptr); addAction(&showInSubmenu); - copySeparator = addSeparator(); - initShortcutAction(&actionAddComment, "General.addComment", - SLOT(on_actionAddComment_triggered())); + &DisassemblyContextMenu::addCommentTriggered); addAction(&actionAddComment); initShortcutAction(&actionSetFunctionVarTypes, "Disassembly.retypeLocals", - SLOT(on_actionSetFunctionVarTypes_triggered())); + &DisassemblyContextMenu::setFunctionVarTypesTriggered); addAction(&actionSetFunctionVarTypes); initShortcutAction(&actionEditFunction, "Disassembly.editFunction", - SLOT(on_actionEditFunction_triggered())); + &DisassemblyContextMenu::editFunctionTriggered); addAction(&actionEditFunction); initAction(&actionDeleteComment, tr("Delete comment"), - SLOT(on_actionDeleteComment_triggered())); + &DisassemblyContextMenu::deleteCommentTriggered); addAction(&actionDeleteComment); - initAction(&actionDeleteFlag, tr("Delete flag"), SLOT(on_actionDeleteFlag_triggered())); + initAction(&actionDeleteFlag, tr("Delete flag"), &DisassemblyContextMenu::deleteFlagTriggered); addAction(&actionDeleteFlag); initShortcutAction(&actionDeleteFunction, "Disassembly.undefineFunction", - SLOT(on_actionDeleteFunction_triggered())); + &DisassemblyContextMenu::deleteFunctionTriggered); addAction(&actionDeleteFunction); initShortcutAction(&actionAnalyzeFunction, "Disassembly.defineFunction", - SLOT(on_actionAnalyzeFunction_triggered())); + &DisassemblyContextMenu::analyzeFunctionTriggered); addAction(&actionAnalyzeFunction); addSeparator(); @@ -123,17 +123,17 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow *main structureOffsetMenu = addMenu(tr("Structure offset")); connect(structureOffsetMenu, &QMenu::triggered, this, - &DisassemblyContextMenu::on_actionStructureOffsetMenu_triggered); + &DisassemblyContextMenu::structureOffsetMenuTriggered); addSetAsMenu(); addSeparator(); - initShortcutAction(&actionXRefs, "General.showXRefs", SLOT(on_actionXRefs_triggered())); + initShortcutAction(&actionXRefs, "General.showXRefs", &DisassemblyContextMenu::xRefsTriggered); addAction(&actionXRefs); initShortcutAction(&actionXRefsForVariables, "Disassembly.XRefsForVariables", - SLOT(on_actionXRefsForVariables_triggered())); + &DisassemblyContextMenu::xRefsForVariablesTriggered); addAction(&actionXRefsForVariables); addSeparator(); @@ -171,11 +171,12 @@ void DisassemblyContextMenu::addAddAtMenu() { setAsMenu = addMenu(tr("Add at...")); - initShortcutAction(&actionRename, "Disassembly.rename", SLOT(on_actionRename_triggered())); + initShortcutAction(&actionRename, "Disassembly.rename", + &DisassemblyContextMenu::renameTriggered); setAsMenu->addAction(&actionRename); initShortcutAction(&actionGlobalVar, "Disassembly.globalVariable", - SLOT(on_actionGlobalVar_triggered())); + &DisassemblyContextMenu::globalVarTriggered); setAsMenu->addAction(&actionGlobalVar); } @@ -183,35 +184,35 @@ void DisassemblyContextMenu::addSetBaseMenu() { setBaseMenu = addMenu(tr("Set base of immediate value to..")); - initAction(&actionSetBaseBinary, tr("Binary")); + initAction(&actionSetBaseBinary, tr("Binary"), nullptr); setBaseMenu->addAction(&actionSetBaseBinary); connect(&actionSetBaseBinary, &QAction::triggered, this, [this] { setBase("b"); }); - initAction(&actionSetBaseOctal, tr("Octal")); + initAction(&actionSetBaseOctal, tr("Octal"), nullptr); setBaseMenu->addAction(&actionSetBaseOctal); connect(&actionSetBaseOctal, &QAction::triggered, this, [this] { setBase("o"); }); - initAction(&actionSetBaseDecimal, tr("Decimal")); + initAction(&actionSetBaseDecimal, tr("Decimal"), nullptr); setBaseMenu->addAction(&actionSetBaseDecimal); connect(&actionSetBaseDecimal, &QAction::triggered, this, [this] { setBase("d"); }); - initAction(&actionSetBaseHexadecimal, tr("Hexadecimal")); + initAction(&actionSetBaseHexadecimal, tr("Hexadecimal"), nullptr); setBaseMenu->addAction(&actionSetBaseHexadecimal); connect(&actionSetBaseHexadecimal, &QAction::triggered, this, [this] { setBase("h"); }); - initAction(&actionSetBasePort, tr("Network Port")); + initAction(&actionSetBasePort, tr("Network Port"), nullptr); setBaseMenu->addAction(&actionSetBasePort); connect(&actionSetBasePort, &QAction::triggered, this, [this] { setBase("p"); }); - initAction(&actionSetBaseIPAddr, tr("IP Address")); + initAction(&actionSetBaseIPAddr, tr("IP Address"), nullptr); setBaseMenu->addAction(&actionSetBaseIPAddr); connect(&actionSetBaseIPAddr, &QAction::triggered, this, [this] { setBase("i"); }); - initAction(&actionSetBaseSyscall, tr("Syscall")); + initAction(&actionSetBaseSyscall, tr("Syscall"), nullptr); setBaseMenu->addAction(&actionSetBaseSyscall); connect(&actionSetBaseSyscall, &QAction::triggered, this, [this] { setBase("S"); }); - initAction(&actionSetBaseString, tr("String")); + initAction(&actionSetBaseString, tr("String"), nullptr); setBaseMenu->addAction(&actionSetBaseString); connect(&actionSetBaseString, &QAction::triggered, this, [this] { setBase("s"); }); } @@ -220,15 +221,15 @@ void DisassemblyContextMenu::addSetBitsMenu() { setBitsMenu = addMenu(tr("Set current bits to...")); - initAction(&actionSetBits16, "16"); + initAction(&actionSetBits16, "16", nullptr); setBitsMenu->addAction(&actionSetBits16); connect(&actionSetBits16, &QAction::triggered, this, [this] { setBits(16); }); - initAction(&actionSetBits32, "32"); + initAction(&actionSetBits32, "32", nullptr); setBitsMenu->addAction(&actionSetBits32); connect(&actionSetBits32, &QAction::triggered, this, [this] { setBits(32); }); - initAction(&actionSetBits64, "64"); + initAction(&actionSetBits64, "64", nullptr); setBitsMenu->addAction(&actionSetBits64); connect(&actionSetBits64, &QAction::triggered, this, [this] { setBits(64); }); } @@ -238,17 +239,17 @@ void DisassemblyContextMenu::addSetAsMenu() setAsMenu = addMenu(tr("Set as...")); initShortcutAction(&actionSetToCode, "Disassembly.setToCode", - SLOT(on_actionSetToCode_triggered())); + &DisassemblyContextMenu::setToCodeTriggered); setAsMenu->addAction(&actionSetToCode); setAsString = setAsMenu->addMenu(tr("String...")); initShortcutAction(&actionSetAsStringAuto, "Disassembly.setAsString", - SLOT(on_actionSetAsString_triggered())); + &DisassemblyContextMenu::setAsStringTriggered); initAction(&actionSetAsStringRemove, tr("Remove"), - SLOT(on_actionSetAsStringRemove_triggered())); + &DisassemblyContextMenu::setAsStringRemoveTriggered); initShortcutAction(&actionSetAsStringAdvanced, "Disassembly.setAsStringAdvanced", - SLOT(on_actionSetAsStringAdvanced_triggered())); + &DisassemblyContextMenu::setAsStringAdvancedTriggered); setAsString->addAction(&actionSetAsStringAuto); setAsString->addAction(&actionSetAsStringRemove); @@ -261,29 +262,30 @@ void DisassemblyContextMenu::addSetToDataMenu() { setToDataMenu = setAsMenu->addMenu(tr("Data...")); - initAction(&actionSetToDataByte, tr("Byte")); + initAction(&actionSetToDataByte, tr("Byte"), nullptr); setToDataMenu->addAction(&actionSetToDataByte); connect(&actionSetToDataByte, &QAction::triggered, this, [this] { setToData(1); }); - initAction(&actionSetToDataWord, tr("Word")); + initAction(&actionSetToDataWord, tr("Word"), nullptr); setToDataMenu->addAction(&actionSetToDataWord); connect(&actionSetToDataWord, &QAction::triggered, this, [this] { setToData(2); }); - initAction(&actionSetToDataDword, tr("Dword")); + initAction(&actionSetToDataDword, tr("Dword"), nullptr); setToDataMenu->addAction(&actionSetToDataDword); connect(&actionSetToDataDword, &QAction::triggered, this, [this] { setToData(4); }); - initAction(&actionSetToDataQword, tr("Qword")); + initAction(&actionSetToDataQword, tr("Qword"), nullptr); setToDataMenu->addAction(&actionSetToDataQword); connect(&actionSetToDataQword, &QAction::triggered, this, [this] { setToData(8); }); initShortcutAction(&actionSetToDataEx, "Disassembly.setToDataEx", - SLOT(on_actionSetToDataEx_triggered())); + &DisassemblyContextMenu::setToDataExTriggered); actionSetToDataEx.setText(tr("Advanced")); setToDataMenu->addAction(&actionSetToDataEx); auto switchAction = new QAction(this); - initShortcutAction(switchAction, "Disassembly.setToData", SLOT(on_actionSetToData_triggered())); + initShortcutAction(switchAction, "Disassembly.setToData", + &DisassemblyContextMenu::setToDataTriggered); setToDataMenu->addAction(switchAction); } @@ -292,17 +294,17 @@ void DisassemblyContextMenu::addEditMenu() editMenu = addMenu(tr("Edit")); initAction(&actionEditInstruction, tr("Instruction"), - SLOT(on_actionEditInstruction_triggered())); + &DisassemblyContextMenu::editInstructionTriggered); editMenu->addAction(&actionEditInstruction); initAction(&actionNopInstruction, tr("Nop Instruction"), - SLOT(on_actionNopInstruction_triggered())); + &DisassemblyContextMenu::nopInstructionTriggered); editMenu->addAction(&actionNopInstruction); - initAction(&actionEditBytes, tr("Bytes"), SLOT(on_actionEditBytes_triggered())); + initAction(&actionEditBytes, tr("Bytes"), &DisassemblyContextMenu::editBytesTriggered); editMenu->addAction(&actionEditBytes); - initAction(&actionJmpReverse, tr("Reverse Jump"), SLOT(on_actionJmpReverse_triggered())); + initAction(&actionJmpReverse, tr("Reverse Jump"), &DisassemblyContextMenu::jmpReverseTriggered); editMenu->addAction(&actionJmpReverse); } @@ -311,10 +313,10 @@ void DisassemblyContextMenu::addBreakpointMenu() breakpointMenu = addMenu(tr("Breakpoint")); initShortcutAction(&actionAddBreakpoint, "Debug.toggleBreakpoint", - SLOT(on_actionAddBreakpoint_triggered())); + &DisassemblyContextMenu::addBreakpointTriggered); breakpointMenu->addAction(&actionAddBreakpoint); initShortcutAction(&actionAdvancedBreakpoint, "Debug.advancedBreakpoint", - SLOT(on_actionAdvancedBreakpoint_triggered())); + &DisassemblyContextMenu::advancedBreakpointTriggered); breakpointMenu->addAction(&actionAdvancedBreakpoint); } @@ -323,10 +325,10 @@ void DisassemblyContextMenu::addDebugMenu() debugMenu = addMenu(tr("Debug")); initAction(&actionContinueUntil, tr("Continue until line"), - SLOT(on_actionContinueUntil_triggered())); + &DisassemblyContextMenu::continueUntilTriggered); debugMenu->addAction(&actionContinueUntil); - initAction(&actionSetPC, "Set PC", SLOT(on_actionSetPC_triggered())); + initAction(&actionSetPC, "Set PC", &DisassemblyContextMenu::setPCTriggered); debugMenu->addAction(&actionSetPC); } @@ -383,8 +385,8 @@ DisassemblyContextMenu::ThingUsedHere DisassemblyContextMenu::getThingAt(ut64 ad { ThingUsedHere tuh; auto core = Core()->lock(); - RzAnalysisFunction *fcn = Core()->functionAt(address); - RzFlagItem *flag = rz_flag_get_i(core->flags, address); + const RzAnalysisFunction *fcn = Core()->functionAt(address); + const RzFlagItem *flag = rz_flag_get_i(core->flags, address); // We will lookup through existing rizin types to find something relevant @@ -421,7 +423,7 @@ void DisassemblyContextMenu::buildRenameMenu(ThingUsedHere *tuh) actionDeleteFlag.setVisible(false); if (tuh->type == ThingUsedHere::Type::Address) { doRenameAction = RENAME_ADD_FLAG; - doRenameInfo.name = RzAddressString(tuh->offset); + doRenameInfo.name = rzAddressString(tuh->offset); doRenameInfo.addr = tuh->offset; actionRename.setText(tr("Add flag at %1 (used here)").arg(doRenameInfo.name)); } else if (tuh->type == ThingUsedHere::Type::Function) { @@ -449,7 +451,7 @@ void DisassemblyContextMenu::buildRenameMenu(ThingUsedHere *tuh) void DisassemblyContextMenu::setupRenaming() { // We parse our highlighted word as an address - ut64 selection = Core()->num(curHighlightedWord); + const ut64 selection = Core()->num(curHighlightedWord); // First, let's try to see if current line (offset) contains a local variable or a function ThingUsedHere *tuh = nullptr; @@ -478,7 +480,7 @@ void DisassemblyContextMenu::setupRenaming() // itself if (thingAt.type == ThingUsedHere::Type::Function) { auto vars = Core()->getVariables(offset); - for (auto v : vars) { + for (const auto &v : std::as_const(vars)) { if (v.name == curHighlightedWord) { // This is a local variable thingAt.type = ThingUsedHere::Type::Var; @@ -495,7 +497,7 @@ void DisassemblyContextMenu::setupRenaming() // Now, build the renaming menu and show it buildRenameMenu(tuh); - auto name = RzAddressString(tuh->offset); + auto name = rzAddressString(tuh->offset); actionGlobalVar.setText(tr("Add or change global variable at %1 (used here)").arg(name)); actionRename.setVisible(true); @@ -507,7 +509,7 @@ void DisassemblyContextMenu::aboutToShowSlot() // check if set immediate base menu makes sense auto cdb = Core()->getRzCoreDecodedBytesSingle(offset); - bool immBase = cdb && (cdb->an_op.val || cdb->an_op.ptr); + const bool immBase = cdb && (cdb->an_op.val || cdb->an_op.ptr); setBaseMenu->menuAction()->setVisible(immBase); setBitsMenu->menuAction()->setVisible(true); @@ -516,11 +518,11 @@ void DisassemblyContextMenu::aboutToShowSlot() st64 memDisp = 0; // Displacement if (cdb) { - CutterJson operands = + const CutterJson operands = Core()->parseJson("opex", rz_structured_data_to_json(cdb->an_op.opex), nullptr); // Loop through both the operands of the instruction - for (const CutterJson operand : operands) { + for (const auto &operand : operands) { if (operand["type"].toString() == "mem" && !operand["base"].toString().contains("bp") && operand["disp"].toSt64() > 0) { @@ -541,7 +543,7 @@ void DisassemblyContextMenu::aboutToShowSlot() structureOffsetMenu->clear(); RzCoreLocked core(Core()); - RzTypeDB *typedb = rz_analysis_get_type_db(core->analysis); + const RzTypeDB *typedb = rz_analysis_get_type_db(core->analysis); RzList *typeoffs = rz_type_db_get_by_offset(typedb, memDisp); if (typeoffs) { for (const auto &ty : CutterRzList(typeoffs)) { @@ -563,10 +565,10 @@ void DisassemblyContextMenu::aboutToShowSlot() actionAnalyzeFunction.setVisible(true); // Show the option to remove a defined string only if a string is defined in this address - QString stringDefinition = Core()->getMetaString(offset); + const QString stringDefinition = Core()->getMetaString(offset); actionSetAsStringRemove.setVisible(!stringDefinition.isEmpty()); - QString comment = Core()->getCommentAt(offset); + const QString comment = Core()->getCommentAt(offset); if (comment.isNull() || comment.isEmpty()) { actionDeleteComment.setVisible(false); @@ -584,12 +586,12 @@ void DisassemblyContextMenu::aboutToShowSlot() setupRenaming(); // Only show retype for local vars if in a function - RzAnalysisFunction *in_fcn = Core()->functionIn(offset); - if (in_fcn) { + const RzAnalysisFunction *inFcn = Core()->functionIn(offset); + if (inFcn) { auto vars = Core()->getVariables(offset); actionSetFunctionVarTypes.setVisible(!vars.empty()); actionEditFunction.setVisible(true); - actionEditFunction.setText(tr("Edit function \"%1\"").arg(in_fcn->name)); + actionEditFunction.setText(tr("Edit function \"%1\"").arg(inFcn->name)); } else { actionSetFunctionVarTypes.setVisible(false); actionEditFunction.setVisible(false); @@ -605,11 +607,11 @@ void DisassemblyContextMenu::aboutToShowSlot() // Only show debug options if we are currently debugging debugMenu->menuAction()->setVisible(Core()->currentlyDebugging); - bool hasBreakpoint = Core()->breakpointIndexAt(offset) > -1; + const bool hasBreakpoint = Core()->breakpointIndexAt(offset) > -1; actionAddBreakpoint.setText(hasBreakpoint ? tr("Remove breakpoint") : tr("Add breakpoint")); actionAdvancedBreakpoint.setText(hasBreakpoint ? tr("Edit breakpoint") : tr("Advanced breakpoint")); - QString progCounterName = Core()->getRegisterName("PC").toUpper(); + const QString progCounterName = Core()->getRegisterName("PC").toUpper(); actionSetPC.setText("Set " + progCounterName + " here"); if (pluginMenu) { @@ -619,7 +621,7 @@ void DisassemblyContextMenu::aboutToShowSlot() } } - bool isLocalVar = isHighlightedWordLocalVar(); + const bool isLocalVar = isHighlightedWordLocalVar(); actionXRefsForVariables.setVisible(isLocalVar); if (isLocalVar) { actionXRefsForVariables.setText(tr("X-Refs for %1").arg(curHighlightedWord)); @@ -633,29 +635,29 @@ void DisassemblyContextMenu::aboutToHideSlot() actionXRefsForVariables.setVisible(true); } -void DisassemblyContextMenu::on_actionEditInstruction_triggered() +void DisassemblyContextMenu::editInstructionTriggered() { if (!ioModesController.prepareForWriting()) { return; } EditInstructionDialog e(EDIT_TEXT, parentForDialog()); - e.setWindowTitle(tr("Edit Instruction at %1").arg(RzAddressString(offset))); + e.setWindowTitle(tr("Edit Instruction at %1").arg(rzAddressString(offset))); - QString oldInstructionOpcode = Core()->getInstructionOpcode(offset); - QString oldInstructionBytes = Core()->getInstructionBytes(offset); + const QString oldInstructionOpcode = Core()->getInstructionOpcode(offset); + const QString oldInstructionBytes = Core()->getInstructionBytes(offset); e.setInstruction(oldInstructionOpcode); if (e.exec()) { - bool fillWithNops = e.needsNops(); - QString userInstructionOpcode = e.getInstruction(); + const bool fillWithNops = e.needsNops(); + const QString userInstructionOpcode = e.getInstruction(); if (userInstructionOpcode != oldInstructionOpcode) { Core()->editInstruction(offset, userInstructionOpcode, fillWithNops); } } } -void DisassemblyContextMenu::on_actionNopInstruction_triggered() +void DisassemblyContextMenu::nopInstructionTriggered() { if (!ioModesController.prepareForWriting()) { return; @@ -675,7 +677,7 @@ void DisassemblyContextMenu::showReverseJmpQuery() } } -void DisassemblyContextMenu::on_actionJmpReverse_triggered() +void DisassemblyContextMenu::jmpReverseTriggered() { if (!ioModesController.prepareForWriting()) { return; @@ -683,50 +685,50 @@ void DisassemblyContextMenu::on_actionJmpReverse_triggered() Core()->jmpReverse(offset); } -void DisassemblyContextMenu::on_actionEditBytes_triggered() +void DisassemblyContextMenu::editBytesTriggered() { if (!ioModesController.prepareForWriting()) { return; } EditInstructionDialog e(EDIT_BYTES, parentForDialog()); - e.setWindowTitle(tr("Edit Bytes at %1").arg(RzAddressString(offset))); + e.setWindowTitle(tr("Edit Bytes at %1").arg(rzAddressString(offset))); - QString oldBytes = Core()->getInstructionBytes(offset); + const QString oldBytes = Core()->getInstructionBytes(offset); e.setInstruction(oldBytes); if (e.exec()) { - QString bytes = e.getInstruction(); + const QString bytes = e.getInstruction(); if (bytes != oldBytes) { Core()->editBytes(offset, bytes); } } } -void DisassemblyContextMenu::on_actionCopy_triggered() +void DisassemblyContextMenu::copyTriggered() { emit copy(); } -void DisassemblyContextMenu::on_actionCopyAddr_triggered() +void DisassemblyContextMenu::copyAddrTriggered() const { QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(RzAddressString(offset)); + clipboard->setText(rzAddressString(offset)); } -void DisassemblyContextMenu::on_actionCopyInstrBytes_triggered() +void DisassemblyContextMenu::copyInstrBytesTriggered() const { QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(Core()->getInstructionBytes(offset)); } -void DisassemblyContextMenu::on_actionAddBreakpoint_triggered() +void DisassemblyContextMenu::addBreakpointTriggered() const { Core()->toggleBreakpoint(offset); } -void DisassemblyContextMenu::on_actionAdvancedBreakpoint_triggered() +void DisassemblyContextMenu::advancedBreakpointTriggered() { - int index = Core()->breakpointIndexAt(offset); + const int index = Core()->breakpointIndexAt(offset); if (index >= 0) { BreakpointsDialog::editBreakpoint(Core()->getBreakpointAt(offset), parentForDialog()); } else { @@ -734,23 +736,23 @@ void DisassemblyContextMenu::on_actionAdvancedBreakpoint_triggered() } } -void DisassemblyContextMenu::on_actionContinueUntil_triggered() +void DisassemblyContextMenu::continueUntilTriggered() const { Core()->continueUntilDebug(offset); } -void DisassemblyContextMenu::on_actionSetPC_triggered() +void DisassemblyContextMenu::setPCTriggered() const { - QString progCounterName = Core()->getRegisterName("PC"); - Core()->setRegister(progCounterName, RzAddressString(offset).toUpper()); + const QString progCounterName = Core()->getRegisterName("PC"); + Core()->setRegister(progCounterName, rzAddressString(offset).toUpper()); } -void DisassemblyContextMenu::on_actionAddComment_triggered() +void DisassemblyContextMenu::addCommentTriggered() { CommentsDialog::addOrEditComment(offset, parentForDialog()); } -void DisassemblyContextMenu::on_actionAnalyzeFunction_triggered() +void DisassemblyContextMenu::analyzeFunctionTriggered() { RVA flagOffset; QString name = Core()->nearestFlag(offset, &flagOffset); @@ -760,13 +762,13 @@ void DisassemblyContextMenu::on_actionAnalyzeFunction_triggered() if (pfx.isEmpty()) { pfx = QString("fcn"); } - name = pfx + QString::asprintf(".%" PFMT64x, offset); + name = pfx + QString::asprintf(".%llx", static_cast(offset)); } // Create dialog QInputDialog inputDialog(parentForDialog()); inputDialog.resize(500, 100); - inputDialog.setWindowTitle(tr("New function at %1").arg(RzAddressString(offset))); + inputDialog.setWindowTitle(tr("New function at %1").arg(rzAddressString(offset))); inputDialog.setLabelText(tr("Function name:")); inputDialog.setTextValue(name); inputDialog.setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint); @@ -775,18 +777,18 @@ void DisassemblyContextMenu::on_actionAnalyzeFunction_triggered() return; } - QString functionName = inputDialog.textValue().trimmed(); + const QString functionName = inputDialog.textValue().trimmed(); if (!functionName.isEmpty()) { Core()->createFunctionAt(offset, functionName); } } -void DisassemblyContextMenu::on_actionRename_triggered() +void DisassemblyContextMenu::renameTriggered() { bool ok = false; if (doRenameAction == RENAME_FUNCTION) { - QString newName = QInputDialog::getText( + const QString newName = QInputDialog::getText( this->mainWindow, tr("Rename function %2").arg(doRenameInfo.name), tr("Function name:"), QLineEdit::Normal, doRenameInfo.name, &ok); if (ok && !newName.isEmpty()) { @@ -796,7 +798,7 @@ void DisassemblyContextMenu::on_actionRename_triggered() FlagDialog dialog(doRenameInfo.addr, parentForDialog()); ok = dialog.exec(); } else if (doRenameAction == RENAME_LOCAL) { - RzAnalysisFunction *fcn = Core()->functionIn(offset); + const RzAnalysisFunction *fcn = Core()->functionIn(offset); if (fcn) { EditVariablesDialog dialog(fcn->addr, curHighlightedWord, parentForDialog()); if (!dialog.empty()) { @@ -817,7 +819,7 @@ void DisassemblyContextMenu::on_actionRename_triggered() } } -void DisassemblyContextMenu::on_actionGlobalVar_triggered() +void DisassemblyContextMenu::globalVarTriggered() { bool ok = false; GlobalVariableDialog dialog(doRenameInfo.addr, parentForDialog()); @@ -829,9 +831,9 @@ void DisassemblyContextMenu::on_actionGlobalVar_triggered() } } -void DisassemblyContextMenu::on_actionSetFunctionVarTypes_triggered() +void DisassemblyContextMenu::setFunctionVarTypesTriggered() { - RzAnalysisFunction *fcn = Core()->functionIn(offset); + const RzAnalysisFunction *fcn = Core()->functionIn(offset); if (!fcn) { QMessageBox::critical(this, tr("Re-type Local Variables"), @@ -846,14 +848,14 @@ void DisassemblyContextMenu::on_actionSetFunctionVarTypes_triggered() dialog.exec(); } -void DisassemblyContextMenu::on_actionXRefs_triggered() +void DisassemblyContextMenu::xRefsTriggered() { XrefsDialog dialog(mainWindow); - dialog.fillRefsForAddress(offset, RzAddressString(offset), false); + dialog.fillRefsForAddress(offset, rzAddressString(offset), false); dialog.exec(); } -void DisassemblyContextMenu::on_actionXRefsForVariables_triggered() +void DisassemblyContextMenu::xRefsForVariablesTriggered() { if (isHighlightedWordLocalVar()) { XrefsDialog dialog(mainWindow); @@ -862,22 +864,22 @@ void DisassemblyContextMenu::on_actionXRefsForVariables_triggered() } } -void DisassemblyContextMenu::on_actionSetToCode_triggered() +void DisassemblyContextMenu::setToCodeTriggered() const { Core()->setToCode(offset); } -void DisassemblyContextMenu::on_actionSetAsString_triggered() +void DisassemblyContextMenu::setAsStringTriggered() const { Core()->setAsString(offset); } -void DisassemblyContextMenu::on_actionSetAsStringRemove_triggered() +void DisassemblyContextMenu::setAsStringRemoveTriggered() const { Core()->removeString(offset); } -void DisassemblyContextMenu::on_actionSetAsStringAdvanced_triggered() +void DisassemblyContextMenu::setAsStringAdvancedTriggered() { EditStringDialog dialog(parentForDialog()); const int predictedStrSize = Core()->getString(offset).size(); @@ -913,7 +915,7 @@ void DisassemblyContextMenu::on_actionSetAsStringAdvanced_triggered() Core()->setAsString(strAddr, strSize, coreStringType); } -void DisassemblyContextMenu::on_actionSetToData_triggered() +void DisassemblyContextMenu::setToDataTriggered() { int size = Core()->sizeofDataMeta(offset); if (size > 8 || (size && (size & (size - 1)))) { @@ -927,7 +929,7 @@ void DisassemblyContextMenu::on_actionSetToData_triggered() setToData(size); } -void DisassemblyContextMenu::on_actionSetToDataEx_triggered() +void DisassemblyContextMenu::setToDataExTriggered() { SetToDataDialog dialog(offset, parentForDialog()); if (!dialog.exec()) { @@ -936,27 +938,27 @@ void DisassemblyContextMenu::on_actionSetToDataEx_triggered() setToData(dialog.getItemSize(), dialog.getItemCount()); } -void DisassemblyContextMenu::on_actionStructureOffsetMenu_triggered(QAction *action) +void DisassemblyContextMenu::structureOffsetMenuTriggered(QAction *action) const { Core()->applyStructureOffset(action->data().toString(), offset); } -void DisassemblyContextMenu::on_actionDeleteComment_triggered() +void DisassemblyContextMenu::deleteCommentTriggered() const { Core()->delComment(offset); } -void DisassemblyContextMenu::on_actionDeleteFlag_triggered() +void DisassemblyContextMenu::deleteFlagTriggered() const { Core()->delFlag(offset); } -void DisassemblyContextMenu::on_actionDeleteFunction_triggered() +void DisassemblyContextMenu::deleteFunctionTriggered() const { Core()->delFunction(offset); } -void DisassemblyContextMenu::on_actionEditFunction_triggered() +void DisassemblyContextMenu::editFunctionTriggered() { auto core = Core()->lock(); EditFunctionDialog dialog(parentForDialog()); @@ -966,7 +968,7 @@ void DisassemblyContextMenu::on_actionEditFunction_triggered() dialog.setWindowTitle(tr("Edit function %1").arg(fcn->name)); dialog.setNameText(fcn->name); - QString startAddrText = "0x" + QString::number(fcn->addr, 16); + const QString startAddrText = "0x" + QString::number(fcn->addr, 16); dialog.setStartAddrText(startAddrText); dialog.setStackSizeText(QString::number(fcn->stack)); @@ -987,14 +989,14 @@ void DisassemblyContextMenu::on_actionEditFunction_triggered() dialog.setCallConSelected(fcn->cc); if (dialog.exec()) { - QString new_name = dialog.getNameText(); - rz_core_analysis_function_rename(core, fcn->addr, new_name.toStdString().c_str()); - QString new_start_addr = dialog.getStartAddrText(); - fcn->addr = Core()->math(new_start_addr); - QString new_stack_size = dialog.getStackSizeText(); - fcn->stack = int(Core()->math(new_stack_size)); + const QString newName = dialog.getNameText(); + rz_core_analysis_function_rename(core, fcn->addr, newName.toStdString().c_str()); + const QString newStartAddr = dialog.getStartAddrText(); + fcn->addr = Core()->math(newStartAddr); + const QString newStackSize = dialog.getStackSizeText(); + fcn->stack = int(Core()->math(newStackSize)); - QByteArray newCC = dialog.getCallConSelected().toUtf8(); + const QByteArray newCC = dialog.getCallConSelected().toUtf8(); if (!newCC.isEmpty() && rz_analysis_cc_exist(core->analysis, newCC.constData())) { fcn->cc = rz_str_constpool_get(rz_analysis_get_const_pool(core->analysis), newCC.constData()); @@ -1005,22 +1007,23 @@ void DisassemblyContextMenu::on_actionEditFunction_triggered() } } -void DisassemblyContextMenu::setBase(QString base) +void DisassemblyContextMenu::setBase(const QString &base) const { Core()->setImmediateBase(base, offset); } -void DisassemblyContextMenu::setBits(int bits) +void DisassemblyContextMenu::setBits(int bits) const { Core()->setCurrentBits(bits, offset); } -void DisassemblyContextMenu::setToData(int size, int repeat) +void DisassemblyContextMenu::setToData(int size, int repeat) const { Core()->setToData(offset, size, repeat); } -QAction *DisassemblyContextMenu::addAnonymousAction(QString name, const char *slot, +template +QAction *DisassemblyContextMenu::addAnonymousAction(QString name, SlotFunc slot, QKeySequence keySequence) { auto action = new QAction(this); @@ -1030,18 +1033,23 @@ QAction *DisassemblyContextMenu::addAnonymousAction(QString name, const char *sl return action; } -void DisassemblyContextMenu::initAction(QAction *action, QString name, const char *slot) +template +void DisassemblyContextMenu::initAction(QAction *action, const QString &name, SlotFunc slot) { action->setParent(this); parentWidget()->addAction(action); action->setText(name); - if (slot) { - connect(action, SIGNAL(triggered(bool)), this, slot); + + if constexpr (!std::is_same_v) { + if (slot != nullptr) { + connect(action, &QAction::triggered, this, slot); + } } } -void DisassemblyContextMenu::initAction(QAction *action, QString name, const char *slot, - QKeySequence keySequence) +template +void DisassemblyContextMenu::initAction(QAction *action, QString name, SlotFunc slot, + const QKeySequence &keySequence) { initAction(action, name, slot); if (keySequence.isEmpty()) { @@ -1051,19 +1059,19 @@ void DisassemblyContextMenu::initAction(QAction *action, QString name, const cha action->setShortcutContext(Qt::WidgetWithChildrenShortcut); } -void DisassemblyContextMenu::initShortcutAction(QAction *action, const QString &id, - const char *slot) +template +void DisassemblyContextMenu::initShortcutAction(QAction *action, const QString &id, SlotFunc slot) { Shortcuts()->setupAction(*action, id); action->setShortcutContext(Qt::WidgetWithChildrenShortcut); - if (slot) { - connect(action, SIGNAL(triggered(bool)), this, slot); + if (slot != nullptr) { + connect(action, &QAction::triggered, this, slot); } } bool DisassemblyContextMenu::isHighlightedWordLocalVar() { - QList variables = Core()->getVariables(offset); + const QList variables = Core()->getVariables(offset); for (const VariableDescription &var : variables) { if (var.name == curHighlightedWord) { return true; diff --git a/src/menus/DisassemblyContextMenu.h b/src/menus/DisassemblyContextMenu.h index 8746d1b7..0560b2fd 100644 --- a/src/menus/DisassemblyContextMenu.h +++ b/src/menus/DisassemblyContextMenu.h @@ -1,13 +1,16 @@ #ifndef DISASSEMBLYCONTEXTMENU_H #define DISASSEMBLYCONTEXTMENU_H -#include "core/Cutter.h" #include "common/IOModesController.h" -#include + #include +#include class MainWindow; +/** + * @brief Context menu for @ref DisassemblyWidget and @ref DisassemblerGraphView + */ class CUTTER_EXPORT DisassemblyContextMenu : public QMenu { Q_OBJECT @@ -33,47 +36,47 @@ private slots: void aboutToShowSlot(); void aboutToHideSlot(); - void on_actionEditFunction_triggered(); - void on_actionEditInstruction_triggered(); - void on_actionNopInstruction_triggered(); - void on_actionJmpReverse_triggered(); - void on_actionEditBytes_triggered(); + void editFunctionTriggered(); + void editInstructionTriggered(); + void nopInstructionTriggered(); + void jmpReverseTriggered(); + void editBytesTriggered(); void showReverseJmpQuery(); - void on_actionCopy_triggered(); - void on_actionCopyAddr_triggered(); - void on_actionCopyInstrBytes_triggered(); - void on_actionAddComment_triggered(); - void on_actionAnalyzeFunction_triggered(); - void on_actionRename_triggered(); - void on_actionGlobalVar_triggered(); - void on_actionSetFunctionVarTypes_triggered(); - void on_actionXRefs_triggered(); - void on_actionXRefsForVariables_triggered(); + void copyTriggered(); + void copyAddrTriggered() const; + void copyInstrBytesTriggered() const; + void addCommentTriggered(); + void analyzeFunctionTriggered(); + void renameTriggered(); + void globalVarTriggered(); + void setFunctionVarTypesTriggered(); + void xRefsTriggered(); + void xRefsForVariablesTriggered(); - void on_actionDeleteComment_triggered(); - void on_actionDeleteFlag_triggered(); - void on_actionDeleteFunction_triggered(); + void deleteCommentTriggered() const; + void deleteFlagTriggered() const; + void deleteFunctionTriggered() const; - void on_actionAddBreakpoint_triggered(); - void on_actionAdvancedBreakpoint_triggered(); - void on_actionContinueUntil_triggered(); - void on_actionSetPC_triggered(); + void addBreakpointTriggered() const; + void advancedBreakpointTriggered(); + void continueUntilTriggered() const; + void setPCTriggered() const; - void on_actionSetToCode_triggered(); - void on_actionSetAsString_triggered(); - void on_actionSetAsStringRemove_triggered(); - void on_actionSetAsStringAdvanced_triggered(); - void on_actionSetToData_triggered(); - void on_actionSetToDataEx_triggered(); + void setToCodeTriggered() const; + void setAsStringTriggered() const; + void setAsStringRemoveTriggered() const; + void setAsStringAdvancedTriggered(); + void setToDataTriggered(); + void setToDataExTriggered(); /** * @brief Executed on selecting an offset from the structureOffsetMenu * Uses the applyStructureOffset() function of CutterCore to apply the * structure offset - * \param action The action which trigered the event + * @param action The action which trigered the event */ - void on_actionStructureOffsetMenu_triggered(QAction *action); + void structureOffsetMenuTriggered(QAction *action) const; private: RVA offset; @@ -154,20 +157,26 @@ private: QAction *pluginActionMenuAction = nullptr; /** - * \return widget that should be used as parent for presenting dialogs + * @return widget that should be used as parent for presenting dialogs */ QWidget *parentForDialog(); // For creating anonymous entries (that are always visible) - QAction *addAnonymousAction(QString name, const char *slot, QKeySequence shortcut); + template + QAction *addAnonymousAction(QString name, SlotFunc slot, QKeySequence keySequence); - void initAction(QAction *action, QString name, const char *slot = nullptr); - void initAction(QAction *action, QString name, const char *slot, QKeySequence keySequence); - void initShortcutAction(QAction *action, const QString &id, const char *slot); + template + void initAction(QAction *action, const QString &name, SlotFunc slot); - void setBase(QString base); - void setToData(int size, int repeat = 1); - void setBits(int bits); + template + void initAction(QAction *action, QString name, SlotFunc slot, const QKeySequence &keySequence); + + template + void initShortcutAction(QAction *action, const QString &id, SlotFunc slot); + + void setBase(const QString &base) const; + void setToData(int size, int repeat = 1) const; + void setBits(int bits) const; void addSetBaseMenu(); void addSetBitsMenu(); @@ -178,7 +187,7 @@ private: void addBreakpointMenu(); void addDebugMenu(); - enum DoRenameAction { + enum DoRenameAction : ut8 { RENAME_FUNCTION, RENAME_FLAG, RENAME_ADD_FLAG, @@ -214,7 +223,7 @@ private: { QString name; RVA offset; - enum class Type { Var, Function, Flag, Address }; + enum class Type : ut8 { Var, Function, Flag, Address }; Type type; }; QVector getThingUsedHere(RVA offset); diff --git a/src/menus/FlirtContextMenu.cpp b/src/menus/FlirtContextMenu.cpp index cd573af0..b2dbec7d 100644 --- a/src/menus/FlirtContextMenu.cpp +++ b/src/menus/FlirtContextMenu.cpp @@ -1,12 +1,13 @@ #include "FlirtContextMenu.h" + #include "MainWindow.h" -#include -#include -#include -#include #include +#include +#include #include +#include +#include FlirtContextMenu::FlirtContextMenu(QWidget *parent, MainWindow *mainWindow) : QMenu(parent), mainWindow(mainWindow) @@ -38,18 +39,18 @@ void FlirtContextMenu::clearTarget() setHasTarget(false); } -void FlirtContextMenu::onActionCopyLine() +void FlirtContextMenu::onActionCopyLine() const { auto clipboard = QApplication::clipboard(); - QString text = entry.bin_name + "\t" + entry.arch_name + "\t" + entry.arch_bits + "\t" - + entry.n_modules + "\t" + entry.base_name + "\t" + entry.details; + const QString text = entry.binName + "\t" + entry.archName + "\t" + entry.archBits + "\t" + + entry.nModules + "\t" + entry.baseName + "\t" + entry.details; clipboard->setText(text); } -void FlirtContextMenu::onActionApplySignature() +void FlirtContextMenu::onActionApplySignature() const { if (this->hasTarget) { - Core()->applySignature(entry.file_path); + Core()->applySignature(entry.filePath); } } diff --git a/src/menus/FlirtContextMenu.h b/src/menus/FlirtContextMenu.h index ec57c7e0..e9dcb47f 100644 --- a/src/menus/FlirtContextMenu.h +++ b/src/menus/FlirtContextMenu.h @@ -1,12 +1,16 @@ #ifndef FLIRT_CONTEXTMENU_H #define FLIRT_CONTEXTMENU_H -#include "core/Cutter.h" -#include +#include "CutterDescriptions.h" + #include +#include class MainWindow; +/** + * @brief Context menu for @ref FlirtWidget + */ class CUTTER_EXPORT FlirtContextMenu : public QMenu { Q_OBJECT @@ -20,8 +24,8 @@ public slots: void clearTarget(); private: - void onActionCopyLine(); - void onActionApplySignature(); + void onActionCopyLine() const; + void onActionApplySignature() const; QMenu *pluginMenu; QAction *pluginMenuAction; diff --git a/src/plugins/CutterPlugin.h b/src/plugins/CutterPlugin.h index dbbe8d47..0cd9f388 100644 --- a/src/plugins/CutterPlugin.h +++ b/src/plugins/CutterPlugin.h @@ -5,6 +5,9 @@ class MainWindow; #include "widgets/CutterDockWidget.h" +/** + * @brief Interface for defining any Cutter plugin + */ class CUTTER_EXPORT CutterPlugin { public: diff --git a/src/plugins/PluginManager.cpp b/src/plugins/PluginManager.cpp index a4a4791f..321d4ee2 100644 --- a/src/plugins/PluginManager.cpp +++ b/src/plugins/PluginManager.cpp @@ -1,23 +1,24 @@ - #include +// clang-format off #ifdef CUTTER_ENABLE_PYTHON_BINDINGS # include # include # include "PythonManager.h" #endif +// clang-format on -#include "PluginManager.h" -#include "CutterPlugin.h" #include "CutterConfig.h" +#include "CutterPlugin.h" +#include "PluginManager.h" #include "common/Helpers.h" #include "common/ResourcePaths.h" -#include #include +#include +#include #include #include -#include Q_GLOBAL_STATIC(PluginManager, uniqueInstance) @@ -39,7 +40,7 @@ void PluginManager::loadPlugins(bool enablePlugins) return; } - QString userPluginDir = getUserPluginsDirectory(); + const QString userPluginDir = getUserPluginsDirectory(); if (!userPluginDir.isEmpty()) { loadPluginsFromDir(QDir(userPluginDir), true); } @@ -98,7 +99,7 @@ void PluginManager::destroyPlugins() QVector PluginManager::getPluginDirectories() const { QVector result; - QStringList locations = Cutter::standardLocations(QStandardPaths::AppDataLocation); + const QStringList locations = Cutter::standardLocations(QStandardPaths::AppDataLocation); for (auto &location : locations) { result.push_back(QDir(location).filePath("plugins")); } @@ -106,10 +107,10 @@ QVector PluginManager::getPluginDirectories() const #if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) && defined(Q_OS_UNIX) QChar listSeparator = ':'; #else - QChar listSeparator = QDir::listSeparator(); + const QChar listSeparator = QDir::listSeparator(); #endif - QString extra_plugin_dirs = CUTTER_EXTRA_PLUGIN_DIRS; - for (auto &path : extra_plugin_dirs.split(listSeparator, CUTTER_QT_SKIP_EMPTY_PARTS)) { + const QString extraPluginDirs = CUTTER_EXTRA_PLUGIN_DIRS; + for (auto &path : extraPluginDirs.split(listSeparator, CUTTER_QT_SKIP_EMPTY_PARTS)) { result.push_back(QDir(path)); } @@ -118,7 +119,7 @@ QVector PluginManager::getPluginDirectories() const QString PluginManager::getUserPluginsDirectory() const { - QString location = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + const QString location = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); if (location.isEmpty()) { return QString(); } diff --git a/src/plugins/PluginManager.h b/src/plugins/PluginManager.h index 9e6996f1..3adedacb 100644 --- a/src/plugins/PluginManager.h +++ b/src/plugins/PluginManager.h @@ -1,14 +1,17 @@ - #ifndef PLUGINMANAGER_H #define PLUGINMANAGER_H -#include +#include "plugins/CutterPlugin.h" + #include +#include + #include #include -#include "plugins/CutterPlugin.h" - +/** + * @brief Main class for managing plugins + */ class PluginManager : public QObject { Q_OBJECT diff --git a/src/plugins/sample-cpp/CutterSamplePlugin.cpp b/src/plugins/sample-cpp/CutterSamplePlugin.cpp index b0b14962..95cec4da 100644 --- a/src/plugins/sample-cpp/CutterSamplePlugin.cpp +++ b/src/plugins/sample-cpp/CutterSamplePlugin.cpp @@ -1,13 +1,13 @@ -#include -#include -#include -#include - #include "CutterSamplePlugin.h" -#include -#include +#include +#include +#include +#include + #include +#include +#include #include void CutterSamplePlugin::setupPlugin() {} diff --git a/src/plugins/sample-cpp/CutterSamplePlugin.h b/src/plugins/sample-cpp/CutterSamplePlugin.h index d0497a0c..545fae19 100644 --- a/src/plugins/sample-cpp/CutterSamplePlugin.h +++ b/src/plugins/sample-cpp/CutterSamplePlugin.h @@ -1,10 +1,10 @@ #ifndef CUTTERSAMPLEPLUGIN_H #define CUTTERSAMPLEPLUGIN_H -#include - #include +#include + class CutterSamplePlugin : public QObject, CutterPlugin { Q_OBJECT diff --git a/src/shortcuts/DefaultShortcuts.h b/src/shortcuts/DefaultShortcuts.h index ff9dba38..7f0bae08 100644 --- a/src/shortcuts/DefaultShortcuts.h +++ b/src/shortcuts/DefaultShortcuts.h @@ -1,10 +1,16 @@ #ifndef DEFAULTSHORTCUTS_H #define DEFAULTSHORTCUTS_H -#include -#include #include +#include #include +#include + +/** + * @file DefaultShortcuts.h + * Contains all of the default shortcuts for Cutter + * Visually shown in @ref ShortcutOptionsWidget + */ struct Shortcut { diff --git a/src/shortcuts/ShortcutManager.cpp b/src/shortcuts/ShortcutManager.cpp index 18961d8f..6e9fa3d2 100644 --- a/src/shortcuts/ShortcutManager.cpp +++ b/src/shortcuts/ShortcutManager.cpp @@ -1,4 +1,5 @@ #include "ShortcutManager.h" + #include #include #include @@ -36,13 +37,14 @@ QKeySequence ShortcutManager::getKeySequence(const QString &id) Qt::KeyboardModifier ShortcutManager::convertKeyToModifer(const QKeySequence &sequence) { - if (sequence.isEmpty()) + if (sequence.isEmpty()) { return Qt::NoModifier; + } #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) Qt::Key key = static_cast(sequence[0] & ~Qt::KeyboardModifierMask); #else - QKeyCombination combo = sequence[0]; - Qt::Key key = combo.key(); + const QKeyCombination combo = sequence[0]; + const Qt::Key key = combo.key(); #endif switch (key) { case Qt::Key_Alt: @@ -74,7 +76,7 @@ Shortcut ShortcutManager::getShortcut(const QString &id) Shortcut result = defaultShortcuts.value(id); - QList customKeySequences = getKeySequences(id); + const QList customKeySequences = getKeySequences(id); if (!customKeySequences.isEmpty()) { result.keySequences = customKeySequences; } @@ -88,8 +90,8 @@ QHash ShortcutManager::getAllShortcuts() shortcuts.reserve(defaultShortcuts.size()); for (auto it = defaultShortcuts.cbegin(); it != defaultShortcuts.cend(); ++it) { - const QString name = it.key(); - Shortcut s = getShortcut(name); + const QString &name = it.key(); + const Shortcut s = getShortcut(name); shortcuts.insert(name, s); } return shortcuts; @@ -98,22 +100,22 @@ QHash ShortcutManager::getAllShortcuts() QAction *ShortcutManager::makeAction(const QString &id, QObject *parent) { - QAction *action = new QAction(parent); + auto *action = new QAction(parent); setupAction(*action, id); return action; } void ShortcutManager::setupAction(QAction &action, const QString &id) { - Shortcut s = getShortcut(id); + const Shortcut s = getShortcut(id); action.setShortcuts(s.keySequences); action.setText(QCoreApplication::translate(s.context, s.text)); } QShortcut *ShortcutManager::makeQShortcut(const QString &id, QWidget *parent) { - QShortcut *shortcut = new QShortcut(parent); - QList keySequences = getKeySequences(id); + auto *shortcut = new QShortcut(parent); + const QList keySequences = getKeySequences(id); if (!keySequences.isEmpty()) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) shortcut->setKeys(keySequences); @@ -135,7 +137,7 @@ bool ShortcutManager::matchesKeySequence(const QString &id, const QKeySequence & return false; } -QList ShortcutManager::getCustomKeySequences(const QString &id) +QList ShortcutManager::getCustomKeySequences(const QString & /*id*/) { return {}; // Custom shortcut support is not implemented yet } diff --git a/src/shortcuts/ShortcutManager.h b/src/shortcuts/ShortcutManager.h index 6cbb0e55..55d8e650 100644 --- a/src/shortcuts/ShortcutManager.h +++ b/src/shortcuts/ShortcutManager.h @@ -1,13 +1,17 @@ #ifndef SHORTCUTMANAGER_H #define SHORTCUTMANAGER_H -#include -#include -#include -#include -#include #include "DefaultShortcuts.h" +#include +#include +#include +#include +#include + +/** + * @brief Singleton class for registering/querying shortcuts + */ class ShortcutManager : public QObject { Q_OBJECT diff --git a/src/tools/basefind/BaseFindDialog.cpp b/src/tools/basefind/BaseFindDialog.cpp index bcd77756..75137b83 100644 --- a/src/tools/basefind/BaseFindDialog.cpp +++ b/src/tools/basefind/BaseFindDialog.cpp @@ -1,7 +1,7 @@ #include "BaseFindDialog.h" -#include "ui_BaseFindDialog.h" #include "BaseFindSearchDialog.h" +#include "ui_BaseFindDialog.h" #include #include @@ -12,10 +12,10 @@ BaseFindDialog::BaseFindDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Ba setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); // Fill in N-thread Combo - RzThreadNCores n_cores = rz_th_physical_core_number(); + const RzThreadNCores nCores = rz_th_physical_core_number(); ui->nCoresCombo->clear(); - for (size_t i = n_cores; i > 0; i--) { - if (n_cores == i) { + for (size_t i = nCores; i > 0; i--) { + if (nCores == i) { ui->nCoresCombo->addItem("All Cores"); continue; } @@ -28,42 +28,45 @@ BaseFindDialog::BaseFindDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Ba ui->minStrLenEdit->setValue(Core()->getConfigut64("basefind.min.string")); ui->minScoreEdit->setValue(Core()->getConfigut64("basefind.min.score")); - size_t selected_n_cores = Core()->getConfigut64("basefind.max.threads"); - if (selected_n_cores < n_cores && selected_n_cores > 0) { - ui->nCoresCombo->setCurrentIndex(n_cores - selected_n_cores); + const size_t selectedNCores = Core()->getConfigut64("basefind.max.threads"); + if (selectedNCores < nCores && selectedNCores > 0) { + ui->nCoresCombo->setCurrentIndex(nCores - selectedNCores); } + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &BaseFindDialog::onButtonBoxAccepted); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &BaseFindDialog::onButtonBoxRejected); } BaseFindDialog::~BaseFindDialog() {} RzThreadNCores BaseFindDialog::getNCores() const { - RzThreadNCores n_cores = rz_th_physical_core_number(); - return static_cast(n_cores - ui->nCoresCombo->currentIndex()); + const RzThreadNCores nCores = rz_th_physical_core_number(); + return static_cast(nCores - ui->nCoresCombo->currentIndex()); } ut32 BaseFindDialog::getPointerSize() const { auto index = ui->pointerSizeCombo->currentIndex(); - QString value = ui->pointerSizeCombo->itemText(index); + const QString value = ui->pointerSizeCombo->itemText(index); return value.toULong(nullptr, 0); } RVA BaseFindDialog::getStartAddress() const { - QString value = ui->startAddressEdit->text(); + const QString value = ui->startAddressEdit->text(); return value.toULongLong(nullptr, 0); } RVA BaseFindDialog::getEndAddress() const { - QString value = ui->endAddressEdit->text(); + const QString value = ui->endAddressEdit->text(); return value.toULongLong(nullptr, 0); } RVA BaseFindDialog::getAlignment() const { - QString value = ui->alignmentEdit->text(); + const QString value = ui->alignmentEdit->text(); return value.toULongLong(nullptr, 0); } @@ -77,7 +80,7 @@ ut32 BaseFindDialog::getMinScore() const return ui->minScoreEdit->value(); } -void BaseFindDialog::on_buttonBox_accepted() +void BaseFindDialog::onButtonBoxAccepted() { RzBaseFindOpt options = {}; options.max_threads = getNCores(); @@ -90,8 +93,8 @@ void BaseFindDialog::on_buttonBox_accepted() options.callback = nullptr; options.user = nullptr; - BaseFindSearchDialog *bfs = new BaseFindSearchDialog(parentWidget()); + auto *bfs = new BaseFindSearchDialog(parentWidget()); bfs->show(&options); } -void BaseFindDialog::on_buttonBox_rejected() {} +void BaseFindDialog::onButtonBoxRejected() {} diff --git a/src/tools/basefind/BaseFindDialog.h b/src/tools/basefind/BaseFindDialog.h index 296b25eb..94e493b7 100644 --- a/src/tools/basefind/BaseFindDialog.h +++ b/src/tools/basefind/BaseFindDialog.h @@ -3,14 +3,17 @@ #include #include -#include #include +#include namespace Ui { class BaseFindDialog; } +/** + * @brief Dialog for configuring and launching the BaseFind analysis + */ class BaseFindDialog : public QDialog { Q_OBJECT @@ -28,8 +31,8 @@ public: ut32 getMinScore() const; private slots: - void on_buttonBox_accepted(); - void on_buttonBox_rejected(); + void onButtonBoxAccepted(); + void onButtonBoxRejected(); private: std::unique_ptr ui; diff --git a/src/tools/basefind/BaseFindResultsDialog.cpp b/src/tools/basefind/BaseFindResultsDialog.cpp index c4c583b1..17e92b15 100644 --- a/src/tools/basefind/BaseFindResultsDialog.cpp +++ b/src/tools/basefind/BaseFindResultsDialog.cpp @@ -1,14 +1,16 @@ #include "BaseFindResultsDialog.h" + #include "ui_BaseFindResultsDialog.h" #include #include -#include #include +#include +#include BaseFindResultsModel::BaseFindResultsModel(QList list, QObject *parent) - : QAbstractListModel(parent), list(list) + : QAbstractListModel(parent), list(std::move(list)) { } @@ -24,8 +26,9 @@ int BaseFindResultsModel::columnCount(const QModelIndex &) const QVariant BaseFindResultsModel::data(const QModelIndex &index, int role) const { - if (index.row() >= list.count()) + if (index.row() >= list.count()) { return QVariant(); + } const BasefindResultDescription &entry = list.at(index.row()); @@ -35,13 +38,13 @@ QVariant BaseFindResultsModel::data(const QModelIndex &index, int role) const case ScoreColumn: return QString::asprintf("%u", entry.score); case CandidateColumn: - return QString::asprintf("%#010" PFMT64x, entry.candidate); + return QString::asprintf("%#010llx", static_cast(entry.candidate)); default: return QVariant(); } case Qt::ToolTipRole: { - return QString::asprintf("%#010" PFMT64x, entry.candidate); + return QString::asprintf("%#010llx", static_cast(entry.candidate)); } default: @@ -68,19 +71,18 @@ QVariant BaseFindResultsModel::headerData(int section, Qt::Orientation, int role BaseFindResultsDialog::BaseFindResultsDialog(QList results, QWidget *parent) - : QDialog(parent), ui(new Ui::BaseFindResultsDialog) + : QDialog(parent), ui(new Ui::BaseFindResultsDialog), blockMenu(new QMenu(this)) { ui->setupUi(this); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); - model = new BaseFindResultsModel(results, this); + model = new BaseFindResultsModel(std::move(results), this); ui->tableView->setModel(model); ui->tableView->sortByColumn(BaseFindResultsModel::ScoreColumn, Qt::AscendingOrder); ui->tableView->verticalHeader()->hide(); ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu); - blockMenu = new QMenu(this); actionCopyCandidate = new QAction(tr("Copy %1"), this); actionSetLoadAddr = new QAction(tr("Reopen Cutter with base address as %1"), this); actionSetMapAddr = new QAction(tr("Reopen Cutter with map address as %1"), this); @@ -93,6 +95,8 @@ BaseFindResultsDialog::BaseFindResultsDialog(QList re &BaseFindResultsDialog::onActionSetLoadAddr); connect(actionSetMapAddr, &QAction::triggered, this, &BaseFindResultsDialog::onActionSetMapAddr); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, + &BaseFindResultsDialog::onButtonBoxRejected); blockMenu->addAction(actionSetLoadAddr); blockMenu->addAction(actionSetMapAddr); @@ -106,7 +110,7 @@ void BaseFindResultsDialog::showItemContextMenu(const QPoint &pt) if (index.isValid()) { const BasefindResultDescription &entry = model->list.at(index.row()); candidate = entry.candidate; - auto addr = QString::asprintf("%#010" PFMT64x, candidate); + auto addr = QString::asprintf("%#010llx", static_cast(candidate)); actionCopyCandidate->setText(tr("Copy %1").arg(addr)); actionSetLoadAddr->setText(tr("Reopen Cutter with base address as %1").arg(addr)); actionSetMapAddr->setText(tr("Reopen Cutter with map address as %1").arg(addr)); @@ -114,13 +118,13 @@ void BaseFindResultsDialog::showItemContextMenu(const QPoint &pt) } } -void BaseFindResultsDialog::onActionCopyLine() +void BaseFindResultsDialog::onActionCopyLine() const { auto clipboard = QApplication::clipboard(); - clipboard->setText(QString::asprintf("%#010" PFMT64x, candidate)); + clipboard->setText(QString::asprintf("%#010llx", static_cast(candidate))); } -void BaseFindResultsDialog::onActionSetLoadAddr() +void BaseFindResultsDialog::onActionSetLoadAddr() const { auto cutter = static_cast(qApp); auto options = cutter->getInitialOptions(); @@ -138,7 +142,7 @@ void BaseFindResultsDialog::onActionSetLoadAddr() cutter->launchNewInstance(args); } -void BaseFindResultsDialog::onActionSetMapAddr() +void BaseFindResultsDialog::onActionSetMapAddr() const { auto cutter = static_cast(qApp); auto options = cutter->getInitialOptions(); @@ -158,4 +162,4 @@ void BaseFindResultsDialog::onActionSetMapAddr() BaseFindResultsDialog::~BaseFindResultsDialog() {} -void BaseFindResultsDialog::on_buttonBox_rejected() {} +void BaseFindResultsDialog::onButtonBoxRejected() {} diff --git a/src/tools/basefind/BaseFindResultsDialog.h b/src/tools/basefind/BaseFindResultsDialog.h index 525e1cdc..23f98a4f 100644 --- a/src/tools/basefind/BaseFindResultsDialog.h +++ b/src/tools/basefind/BaseFindResultsDialog.h @@ -1,12 +1,12 @@ #ifndef BASEFIND_RESULTS_DIALOG_H #define BASEFIND_RESULTS_DIALOG_H -#include #include +#include #include -#include #include +#include class BaseFindResultsDialog; @@ -14,6 +14,9 @@ namespace Ui { class BaseFindResultsDialog; } +/** + * @brief Source model for @ref BaseFindResultsDialog + */ class BaseFindResultsModel : public QAbstractListModel { Q_OBJECT @@ -21,7 +24,7 @@ class BaseFindResultsModel : public QAbstractListModel friend BaseFindResultsDialog; public: - enum Column { ScoreColumn = 0, CandidateColumn, ColumnCount }; + enum Column : ut8 { ScoreColumn = 0, CandidateColumn, ColumnCount }; BaseFindResultsModel(QList list, QObject *parent = nullptr); @@ -35,6 +38,11 @@ private: QList list; }; +/** + * @brief Dialog to display BaseFind results + * + * Contains context menu with options to reopen Cutter with base or map address as selected address + */ class BaseFindResultsDialog : public QDialog { Q_OBJECT @@ -48,12 +56,12 @@ public slots: void showItemContextMenu(const QPoint &pt); private slots: - void on_buttonBox_rejected(); + void onButtonBoxRejected(); private: - void onActionCopyLine(); - void onActionSetLoadAddr(); - void onActionSetMapAddr(); + void onActionCopyLine() const; + void onActionSetLoadAddr() const; + void onActionSetMapAddr() const; std::unique_ptr ui; BaseFindResultsModel *model; diff --git a/src/tools/basefind/BaseFindSearchDialog.cpp b/src/tools/basefind/BaseFindSearchDialog.cpp index 718ec045..5b464511 100644 --- a/src/tools/basefind/BaseFindSearchDialog.cpp +++ b/src/tools/basefind/BaseFindSearchDialog.cpp @@ -1,16 +1,15 @@ #include "BaseFindSearchDialog.h" -#include "ui_BaseFindSearchDialog.h" #include "BaseFindResultsDialog.h" +#include "ui_BaseFindSearchDialog.h" -#include #include +#include -#include #include BaseFindSearchDialog::BaseFindSearchDialog(QWidget *parent) - : QDialog(parent), basefind(new Basefind(Core())), ui(new Ui::BaseFindSearchDialog) + : QDialog(parent), basefind(new Basefind()), ui(new Ui::BaseFindSearchDialog) { ui->setupUi(this); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); @@ -20,16 +19,16 @@ BaseFindSearchDialog::~BaseFindSearchDialog() {} void BaseFindSearchDialog::show(RzBaseFindOpt *opts) { - RzThreadNCores n_cores = rz_th_physical_core_number(); - if (opts->max_threads > n_cores || opts->max_threads < 1) { - opts->max_threads = n_cores; + const RzThreadNCores nCores = rz_th_physical_core_number(); + if (opts->max_threads > nCores || opts->max_threads < 1) { + opts->max_threads = nCores; } - QFormLayout *layout = new QFormLayout(); + auto *layout = new QFormLayout(); ui->scrollAreaWidgetContents->setLayout(layout); for (ut32 i = 0; i < opts->max_threads; ++i) { - QString label = QString::asprintf("Core %u", i); - QProgressBar *pbar = new QProgressBar(nullptr); + const QString label = QString::asprintf("Core %u", i); + auto *pbar = new QProgressBar(nullptr); layout->addRow(label, pbar); pbar->setRange(0, 100); bars.push_back(pbar); @@ -42,6 +41,8 @@ void BaseFindSearchDialog::show(RzBaseFindOpt *opts) connect(this, &BaseFindSearchDialog::cancelSearch, basefind.get(), &Basefind::cancel); connect(basefind.get(), &Basefind::progress, this, &BaseFindSearchDialog::onProgress); connect(basefind.get(), &Basefind::complete, this, &BaseFindSearchDialog::onCompletion); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, + &BaseFindSearchDialog::onButtonBoxRejected); basefind->start(); this->QDialog::show(); @@ -55,12 +56,12 @@ void BaseFindSearchDialog::onProgress(BasefindCoreStatusDescription status) void BaseFindSearchDialog::onCompletion() { auto results = basefind->results(); - BaseFindResultsDialog *table = new BaseFindResultsDialog(results, parentWidget()); + auto *table = new BaseFindResultsDialog(results, parentWidget()); table->show(); this->close(); } -void BaseFindSearchDialog::on_buttonBox_rejected() +void BaseFindSearchDialog::onButtonBoxRejected() { emit cancelSearch(); } diff --git a/src/tools/basefind/BaseFindSearchDialog.h b/src/tools/basefind/BaseFindSearchDialog.h index bd59d6cb..9892dcb8 100644 --- a/src/tools/basefind/BaseFindSearchDialog.h +++ b/src/tools/basefind/BaseFindSearchDialog.h @@ -4,14 +4,19 @@ #include #include #include -#include #include +#include namespace Ui { class BaseFindSearchDialog; } +/** + * @brief Dialog displayed while searching in @ref BaseFindDialog + * + * Shows progress for each CPU core + */ class BaseFindSearchDialog : public QDialog { Q_OBJECT @@ -30,7 +35,7 @@ signals: void cancelSearch(); private slots: - void on_buttonBox_rejected(); + void onButtonBoxRejected(); private: std::vector bars; diff --git a/src/translations b/src/translations index bc5aced4..2e35833f 160000 --- a/src/translations +++ b/src/translations @@ -1 +1 @@ -Subproject commit bc5aced406678ae6f24fa501b53a7ae105c9f119 +Subproject commit 2e35833f7734bd89422ee909d95020955761db52 diff --git a/src/widgets/AbstractFilterView.cpp b/src/widgets/AbstractFilterView.cpp index 072ada6d..497204e1 100644 --- a/src/widgets/AbstractFilterView.cpp +++ b/src/widgets/AbstractFilterView.cpp @@ -1,6 +1,7 @@ #include "AbstractFilterView.h" -#include + #include +#include AbstractFilterView::AbstractFilterView(QWidget *parent) : QWidget(parent) {} @@ -45,7 +46,7 @@ void AbstractFilterView::closeFilter() void AbstractFilterView::showCustomContextMenu(const QPoint &pos) { - QWidget *child = this->childAt(pos); + const QWidget *child = this->childAt(pos); QMenu *menu; QAction *showItemCountAction; diff --git a/src/widgets/AbstractFilterView.h b/src/widgets/AbstractFilterView.h index d863122d..48bfd76f 100644 --- a/src/widgets/AbstractFilterView.h +++ b/src/widgets/AbstractFilterView.h @@ -1,10 +1,15 @@ #ifndef ABSTRACTFILTERVIEW_H #define ABSTRACTFILTERVIEW_H -#include -#include #include "ItemCountLineEdit.h" +#include +#include + +/** + * @brief Base class for filter widgets providing a debounced search interface + * and item count display + */ class AbstractFilterView : public QWidget { Q_OBJECT diff --git a/src/widgets/AddressRangeScrollBar.cpp b/src/widgets/AddressRangeScrollBar.cpp index 8aa9802f..84109b39 100644 --- a/src/widgets/AddressRangeScrollBar.cpp +++ b/src/widgets/AddressRangeScrollBar.cpp @@ -1,4 +1,5 @@ #include "AddressRangeScrollBar.h" + #include "Cutter.h" #include @@ -19,26 +20,30 @@ AddressRangeScrollBar::AddressRangeScrollBar(QWidget *parent) : QScrollBar(paren // for more info. case QAbstractSlider::SliderSingleStepAdd: setSliderPosition(value()); - if (value() == maximum()) + if (value() == maximum()) { return; + } emit scrolled(-singleStep()); return; case QAbstractSlider::SliderPageStepAdd: setSliderPosition(value()); - if (value() == maximum()) + if (value() == maximum()) { return; + } emit scrolled(-pageStep()); return; case QAbstractSlider::SliderSingleStepSub: setSliderPosition(value()); - if (value() == minimum()) + if (value() == minimum()) { return; + } emit scrolled(singleStep()); return; case QAbstractSlider::SliderPageStepSub: setSliderPosition(value()); - if (value() == minimum()) + if (value() == minimum()) { return; + } emit scrolled(pageStep()); return; default: @@ -52,8 +57,8 @@ void AddressRangeScrollBar::refreshRange() beginOffset = RVA_MAX; endOffset = 0; if (!Core()->currentlyEmulating && Core()->currentlyDebugging) { - QString currentlyOpenFile = Core()->getConfig("file.path"); - QList memoryMaps = Core()->getMemoryMap(); + const QString currentlyOpenFile = Core()->getConfig("file.path"); + const QList memoryMaps = Core()->getMemoryMap(); for (const MemoryMapDescription &map : memoryMaps) { if (map.fileName == currentlyOpenFile) { if (map.addrStart < beginOffset) { @@ -66,19 +71,19 @@ void AddressRangeScrollBar::refreshRange() } } else { RzCoreLocked core(Core()); - RzPVector *mapsPtr = rz_io_maps(core->io); + const RzPVector *mapsPtr = rz_io_maps(core->io); if (!mapsPtr) { emit hideScrollBar(); return; } - CutterPVector maps { mapsPtr }; + const CutterPVector maps { mapsPtr }; for (const RzIOMap *const map : maps) { // Skip the ESIL memory stack region if (Core()->currentlyEmulating && std::strncmp(rz_str_get(map->name), "mem.", 4) == 0) { continue; } - ut64 b = rz_itv_begin(map->itv); - ut64 e = rz_itv_end(map->itv); + const ut64 b = rz_itv_begin(map->itv); + const ut64 e = rz_itv_end(map->itv); if (b < beginOffset) { beginOffset = b; } @@ -133,8 +138,8 @@ void AddressRangeScrollBar::setPosition(RVA address) auto offset = address - beginOffset; if ((RVA_MAX / maximum()) < rangeSize()) { // Fallback formula for large files - uint64_t smallBox = rangeSize() / maximum(); - uint64_t extra = rangeSize() % maximum(); + const uint64_t smallBox = rangeSize() / maximum(); + const uint64_t extra = rangeSize() % maximum(); auto bigBoxRange = (smallBox + 1) * extra; if (offset < bigBoxRange) { scrollBarPos = offset / (smallBox + 1); @@ -165,7 +170,7 @@ RVA AddressRangeScrollBar::address() return (value() * rangeSize()) / maximum() + beginOffset; } -RVA AddressRangeScrollBar::clampAddressToRange(RVA address) +RVA AddressRangeScrollBar::clampAddressToRange(RVA address) const { if (address > endOffset) { return endOffset; @@ -176,7 +181,7 @@ RVA AddressRangeScrollBar::clampAddressToRange(RVA address) return address; } -RVA AddressRangeScrollBar::rangeSize() +RVA AddressRangeScrollBar::rangeSize() const { return endOffset - beginOffset; } @@ -204,7 +209,7 @@ void AddressRangeScrollBar::wheelEvent(QWheelEvent *event) // Typical scroll speed is 1 line per 5 degrees const int lineDelta = 5 * 8; if (accumScrollWheelDeltaY >= lineDelta || accumScrollWheelDeltaY <= -lineDelta) { - int lineCount = accumScrollWheelDeltaY / lineDelta; + const int lineCount = accumScrollWheelDeltaY / lineDelta; accumScrollWheelDeltaY -= lineDelta * lineCount; if ((lineCount < 0 && value() == maximum()) || (lineCount > 0 && value() == minimum())) { return; diff --git a/src/widgets/AddressRangeScrollBar.h b/src/widgets/AddressRangeScrollBar.h index 62908f22..2585760e 100644 --- a/src/widgets/AddressRangeScrollBar.h +++ b/src/widgets/AddressRangeScrollBar.h @@ -1,9 +1,14 @@ #ifndef ADDRESS_RANGE_SCROLLBAR_H #define ADDRESS_RANGE_SCROLLBAR_H -#include #include "CutterCommon.h" +#include + +/** + * @brief Generic scrollbar class to be used by memory address based widgets (Disassembly, Hexdump + * etc) + */ class AddressRangeScrollBar : public QScrollBar { Q_OBJECT @@ -13,8 +18,8 @@ public: void setPosition(RVA address); RVA address(); - RVA clampAddressToRange(RVA address); - RVA rangeSize(); + RVA clampAddressToRange(RVA address) const; + RVA rangeSize() const; /** * @brief Sends fake wheelEvent to the parent QScrollBar diff --git a/src/widgets/AddressableDockWidget.cpp b/src/widgets/AddressableDockWidget.cpp index 9713fdc6..c74fd70b 100644 --- a/src/widgets/AddressableDockWidget.cpp +++ b/src/widgets/AddressableDockWidget.cpp @@ -1,21 +1,23 @@ #include "AddressableDockWidget.h" -#include "common/CutterSeekable.h" + #include "MainWindow.h" +#include "common/CutterSeekable.h" + #include +#include #include #include -#include AddressableDockWidget::AddressableDockWidget(MainWindow *parent) : CutterDockWidget(parent), seekable(new CutterSeekable(this)), - syncAction(tr("Sync/unsync offset"), this) + syncAction(tr("Sync/unsync offset"), this), + dockMenu(new QMenu(this)) { connect(seekable, &CutterSeekable::syncChanged, this, &AddressableDockWidget::updateWindowTitle); connect(&syncAction, &QAction::triggered, seekable, &CutterSeekable::toggleSynchronization); - dockMenu = new QMenu(this); dockMenu->addAction(&syncAction); setContextMenuPolicy(Qt::ContextMenuPolicy::DefaultContextMenu); @@ -30,14 +32,14 @@ QVariantMap AddressableDockWidget::serializeViewProprties() void AddressableDockWidget::deserializeViewProperties(const QVariantMap &properties) { - QVariant synchronized = properties.value("synchronized", true); + const QVariant synchronized = properties.value("synchronized", true); seekable->setSynchronization(synchronized.toBool()); } void AddressableDockWidget::updateWindowTitle() { QString name = getWindowTitle(); - QString id = getDockNumber(); + const QString id = getDockNumber(); if (!id.isEmpty()) { name += " " + id; } diff --git a/src/widgets/AddressableDockWidget.h b/src/widgets/AddressableDockWidget.h index dc972116..958750f0 100644 --- a/src/widgets/AddressableDockWidget.h +++ b/src/widgets/AddressableDockWidget.h @@ -2,12 +2,14 @@ #define ADDRESSABLE_DOCK_WIDGET_H #include "CutterDockWidget.h" -#include "core/Cutter.h" #include class CutterSeekable; +/** + * @brief Base class for dock widgets that support synchronization with a specific address/offset + */ class AddressableDockWidget : public CutterDockWidget { Q_OBJECT diff --git a/src/widgets/AddressableItemList.h b/src/widgets/AddressableItemList.h index 5a2b4f06..e306699e 100644 --- a/src/widgets/AddressableItemList.h +++ b/src/widgets/AddressableItemList.h @@ -1,25 +1,31 @@ #ifndef ADDRESSABLE_ITEM_LIST_H #define ADDRESSABLE_ITEM_LIST_H -#include +#include "CutterDockWidget.h" +#include "CutterTreeView.h" +#include "common/AddressableItemModel.h" +#include "core/Cutter.h" +#include "menus/AddressableItemContextMenu.h" + #include -#include #include #include - -#include "core/Cutter.h" -#include "common/AddressableItemModel.h" -#include "CutterDockWidget.h" -#include "menus/AddressableItemContextMenu.h" -#include "CutterTreeView.h" +#include class MainWindow; +/** + * @brief A generic template class for list like widgets whose items correspond to specific memory + * addresses + */ template class AddressableItemList : public BaseListWidget { + // To hide the "hides overloaded virtual function" warning + using BaseListWidget::setModel; + static_assert(std::is_base_of::value, - "ParentModel needs to inherit from QAbstractItemModel"); + "ParentModel needs to inherit from QAbstractItemView"); public: explicit AddressableItemList(QWidget *parent = nullptr) : BaseListWidget(parent) @@ -84,8 +90,9 @@ protected: virtual void onItemActivated(const QModelIndex &index) { - if (!index.isValid()) + if (!index.isValid()) { return; + } auto offset = addressableModel->address(index); Core()->seekAndShow(offset); diff --git a/src/widgets/BacktraceWidget.cpp b/src/widgets/BacktraceWidget.cpp index be86a3f5..e67d1df4 100644 --- a/src/widgets/BacktraceWidget.cpp +++ b/src/widgets/BacktraceWidget.cpp @@ -1,8 +1,8 @@ #include "BacktraceWidget.h" -#include "ui_BacktraceWidget.h" -#include +#include "QHeaderView" #include "core/MainWindow.h" +#include "ui_BacktraceWidget.h" BacktraceModel::BacktraceModel(QObject *parent) : QAbstractListModel(parent) {} @@ -28,9 +28,9 @@ QVariant BacktraceModel::data(const QModelIndex &index, int role) const case Column::Function: return backtraces[index.row()].functionName; case Column::PC: - return RzAddressString(backtraces[index.row()].pc); + return rzAddressString(backtraces[index.row()].pc); case Column::SP: - return RzAddressString(backtraces[index.row()].sp); + return rzAddressString(backtraces[index.row()].sp); case Column::FrameSize: return backtraces[index.row()].frameSize; case Column::Description: diff --git a/src/widgets/BacktraceWidget.h b/src/widgets/BacktraceWidget.h index 4f5d6e5b..2a600ac7 100644 --- a/src/widgets/BacktraceWidget.h +++ b/src/widgets/BacktraceWidget.h @@ -1,12 +1,15 @@ -#pragma once +#ifndef BACKTRACEWIDGET_H +#define BACKTRACEWIDGET_H + +#include "CutterDescriptions.h" +#include "CutterDockWidget.h" #include -#include #include #include +#include -#include "core/Cutter.h" -#include "CutterDockWidget.h" +#include class MainWindow; @@ -19,7 +22,7 @@ class BacktraceModel : public QAbstractListModel public: explicit BacktraceModel(QObject *parent = nullptr); - enum Column { Function = 0, PC, SP, FrameSize, Description, Count }; + enum Column : ut8 { Function = 0, PC, SP, FrameSize, Description, Count }; int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; @@ -52,3 +55,5 @@ private: void adjustFunctionNameCol(); }; + +#endif // BACKTRACEWIDGET_H diff --git a/src/widgets/BoolToggleDelegate.cpp b/src/widgets/BoolToggleDelegate.cpp index 5c80a567..4b345d9b 100644 --- a/src/widgets/BoolToggleDelegate.cpp +++ b/src/widgets/BoolToggleDelegate.cpp @@ -1,24 +1,33 @@ #include "BoolToggleDelegate.h" + #include -BoolTogggleDelegate::BoolTogggleDelegate(QObject *parent) : QStyledItemDelegate(parent) {} +BoolToggleDelegate::BoolToggleDelegate(QObject *parent) : QStyledItemDelegate(parent) {} -QWidget *BoolTogggleDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, - const QModelIndex &index) const +QWidget *BoolToggleDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + if (index.data(Qt::EditRole).typeId() == QMetaType::Bool) { +#else if (index.data(Qt::EditRole).type() == QVariant::Bool) { +#endif return nullptr; } return QStyledItemDelegate::createEditor(parent, option, index); } -bool BoolTogggleDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, const QModelIndex &index) +bool BoolToggleDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, const QModelIndex &index) { if (model->flags(index).testFlag(Qt::ItemFlag::ItemIsEditable)) { if (event->type() == QEvent::MouseButtonDblClick) { auto data = index.data(Qt::EditRole); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + if (data.typeId() == QMetaType::Bool) { +#else if (data.type() == QVariant::Bool) { +#endif model->setData(index, !data.toBool()); return true; } diff --git a/src/widgets/BoolToggleDelegate.h b/src/widgets/BoolToggleDelegate.h index d6c9c40a..a90dc88b 100644 --- a/src/widgets/BoolToggleDelegate.h +++ b/src/widgets/BoolToggleDelegate.h @@ -1,14 +1,18 @@ -#ifndef BOOLTOGGGLEDELEGATE_H -#define BOOLTOGGGLEDELEGATE_H +#ifndef BOOLTOGGLEDELEGATE_H +#define BOOLTOGGLEDELEGATE_H #include "core/CutterCommon.h" #include -class CUTTER_EXPORT BoolTogggleDelegate : public QStyledItemDelegate +/** + * @brief Delegate that toggles boolean model values on double click instead of opening an + * editor + */ +class CUTTER_EXPORT BoolToggleDelegate : public QStyledItemDelegate { public: - BoolTogggleDelegate(QObject *parent = nullptr); + BoolToggleDelegate(QObject *parent = nullptr); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; @@ -17,4 +21,4 @@ public: const QModelIndex &index) override; }; -#endif // BOOLTOGGGLEDELEGATE_H +#endif // BOOLTOGGLEDELEGATE_H diff --git a/src/widgets/BreakpointWidget.cpp b/src/widgets/BreakpointWidget.cpp index c7b8276a..2754fcb5 100644 --- a/src/widgets/BreakpointWidget.cpp +++ b/src/widgets/BreakpointWidget.cpp @@ -1,13 +1,15 @@ #include "BreakpointWidget.h" -#include "ui_BreakpointWidget.h" -#include "dialogs/BreakpointsDialog.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" -#include "widgets/BoolToggleDelegate.h" +#include "core/MainWindow.h" +#include "dialogs/BreakpointsDialog.h" #include "shortcuts/ShortcutManager.h" +#include "ui_BreakpointWidget.h" +#include "widgets/BoolToggleDelegate.h" + +#include #include #include -#include BreakpointModel::BreakpointModel(QObject *parent) : AddressableItemModel(parent) { @@ -47,8 +49,9 @@ static QString formatHwBreakpoint(int permission) QVariant BreakpointModel::data(const QModelIndex &index, int role) const { - if (index.row() >= breakpoints.count()) + if (index.row() >= breakpoints.count()) { return QVariant(); + } const BreakpointDescription &breakpoint = breakpoints.at(index.row()); @@ -56,7 +59,7 @@ QVariant BreakpointModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case AddrColumn: - return RzAddressString(breakpoint.addr); + return rzAddressString(breakpoint.addr); case NameColumn: return breakpoint.name; case TypeColumn: @@ -78,7 +81,7 @@ QVariant BreakpointModel::data(const QModelIndex &index, int role) const case Qt::EditRole: switch (index.column()) { case AddrColumn: - return breakpoint.addr; + return static_cast(breakpoint.addr); case TraceColumn: return breakpoint.trace; case EnabledColumn: @@ -120,8 +123,9 @@ QVariant BreakpointModel::headerData(int section, Qt::Orientation, int role) con bool BreakpointModel::setData(const QModelIndex &index, const QVariant &value, int role) { - if (index.row() >= breakpoints.count()) + if (index.row() >= breakpoints.count()) { return false; + } BreakpointDescription &breakpoint = breakpoints[index.row()]; @@ -179,18 +183,19 @@ BreakpointProxyModel::BreakpointProxyModel(BreakpointModel *sourceModel, QObject } BreakpointWidget::BreakpointWidget(MainWindow *main) - : CutterDockWidget(main), ui(new Ui::BreakpointWidget) + : CutterDockWidget(main), + ui(new Ui::BreakpointWidget), + breakpointModel(new BreakpointModel(this)), + breakpointProxyModel(new BreakpointProxyModel(breakpointModel, this)), + refreshDeferrer(createRefreshDeferrer([this]() { refreshBreakpoint(); })) { ui->setupUi(this); ui->breakpointTreeView->setMainWindow(mainWindow); - breakpointModel = new BreakpointModel(this); - breakpointProxyModel = new BreakpointProxyModel(breakpointModel, this); - ui->breakpointTreeView->setModel(breakpointProxyModel); - ui->breakpointTreeView->sortByColumn(BreakpointModel::AddrColumn, Qt::AscendingOrder); - ui->breakpointTreeView->setItemDelegate(new BoolTogggleDelegate(this)); - refreshDeferrer = createRefreshDeferrer([this]() { refreshBreakpoint(); }); + ui->breakpointTreeView->setModel(static_cast(breakpointProxyModel)); + ui->breakpointTreeView->sortByColumn(BreakpointModel::AddrColumn, Qt::AscendingOrder); + ui->breakpointTreeView->setItemDelegate(new BoolToggleDelegate(this)); setScrollMode(); diff --git a/src/widgets/BreakpointWidget.h b/src/widgets/BreakpointWidget.h index 2a0b027e..de26b76e 100644 --- a/src/widgets/BreakpointWidget.h +++ b/src/widgets/BreakpointWidget.h @@ -1,14 +1,15 @@ -#pragma once +#ifndef BREAKPOINTWIDGET_H +#define BREAKPOINTWIDGET_H -#include - -#include "core/Cutter.h" -#include "CutterDockWidget.h" #include "AddressableItemModel.h" +#include "CutterDockWidget.h" +#include "core/Cutter.h" #include #include +#include + class MainWindow; class QTreeWidget; @@ -65,6 +66,9 @@ public: BreakpointProxyModel(BreakpointModel *sourceModel, QObject *parent = nullptr); }; +/** + * @brief Widget for seeing/editing all breakpoints + */ class BreakpointWidget : public CutterDockWidget { Q_OBJECT @@ -95,3 +99,5 @@ private: RefreshDeferrer *refreshDeferrer; bool editing = false; }; + +#endif // BREAKPOINTWIDGET_H diff --git a/src/widgets/CallGraph.cpp b/src/widgets/CallGraph.cpp index 2a5a516a..f5a9b56e 100644 --- a/src/widgets/CallGraph.cpp +++ b/src/widgets/CallGraph.cpp @@ -2,9 +2,9 @@ #include "MainWindow.h" -#include #include #include +#include CallGraphWidget::CallGraphWidget(MainWindow *main, bool global) : MemoryDockWidget(MemoryWidgetType::CallGraph, main), @@ -54,7 +54,7 @@ void CallGraphView::showExportDialog() if (global) { defaultName = "global_callgraph"; } else { - defaultName = QString("callgraph_%1").arg(RzAddressString(address)); + defaultName = QString("callgraph_%1").arg(rzAddressString(address)); } showExportGraphDialog(defaultName, RZ_CORE_GRAPH_TYPE_FUNCALL, global ? RVA_INVALID : address); } @@ -93,7 +93,7 @@ void CallGraphView::loadCurrentGraph() const bool usenames = Core()->getConfigb("graph.json.usenames"); auto edges = std::unordered_set {}; - auto addFunction = [&](RzAnalysisFunction *fcn) { + auto addFunction = [&](const RzAnalysisFunction *fcn) { GraphLayout::GraphBlock block; block.entry = fcn->addr; @@ -109,7 +109,7 @@ void CallGraphView::loadCurrentGraph() edges.insert(x); } - QString name = usenames ? fcn->name : RzAddressString(fcn->addr); + const QString name = usenames ? fcn->name : rzAddressString(fcn->addr); addBlock(std::move(block), name, fcn->addr); }; @@ -135,14 +135,14 @@ void CallGraphView::loadCurrentGraph() } GraphLayout::GraphBlock block; block.entry = x; - QString flagName = Core()->flagAt(x); - QString name = usenames - ? (!flagName.isEmpty() ? flagName : QString("unk.%0").arg(RzAddressString(x))) - : RzAddressString(x); + const QString flagName = Core()->flagAt(x); + const QString name = usenames + ? (!flagName.isEmpty() ? flagName : QString("unk.%0").arg(rzAddressString(x))) + : rzAddressString(x); addBlock(std::move(block), name, x); } if (blockContent.empty() && !global) { - const auto name = RzAddressString(address); + const auto name = rzAddressString(address); addBlock({}, name, address); } @@ -152,7 +152,7 @@ void CallGraphView::loadCurrentGraph() void CallGraphView::restoreCurrentBlock() { if (!global && lastLoadedAddress != address) { - selectedBlock = NO_BLOCK_SELECTED; + selectedBlock = noBlockSelected; lastLoadedAddress = address; center(); } else { diff --git a/src/widgets/CallGraph.h b/src/widgets/CallGraph.h index 2c6e0a96..88f0efaf 100644 --- a/src/widgets/CallGraph.h +++ b/src/widgets/CallGraph.h @@ -1,10 +1,9 @@ #ifndef CALL_GRAPH_WIDGET_H #define CALL_GRAPH_WIDGET_H -#include "core/Cutter.h" #include "MemoryDockWidget.h" -#include "widgets/SimpleTextGraphView.h" #include "common/RefreshDeferrer.h" +#include "widgets/SimpleTextGraphView.h" class MainWindow; /** diff --git a/src/widgets/ClassesWidget.cpp b/src/widgets/ClassesWidget.cpp index da04744d..5a012eb8 100644 --- a/src/widgets/ClassesWidget.cpp +++ b/src/widgets/ClassesWidget.cpp @@ -1,16 +1,17 @@ #include "ClassesWidget.h" -#include "core/MainWindow.h" -#include "ui_ListDockWidget.h" + #include "common/Helpers.h" #include "common/SvgIconEngine.h" +#include "core/MainWindow.h" #include "dialogs/EditMethodDialog.h" +#include "ui_ListDockWidget.h" +#include +#include #include #include #include -#include #include -#include QVariant ClassesModel::headerData(int section, Qt::Orientation, int role) const { @@ -37,13 +38,13 @@ QVariant ClassesModel::headerData(int section, Qt::Orientation, int role) const RVA ClassesModel::address(const QModelIndex &index) const { - QVariant v = data(index, OffsetRole); + const QVariant v = data(index, offsetRole); return v.isValid() ? v.toULongLong() : RVA_INVALID; } QString ClassesModel::name(const QModelIndex &index) const { - return data(index, NameRole).toString(); + return data(index, nameRole).toString(); } BinClassesModel::BinClassesModel(QObject *parent) : ClassesModel(parent) {} @@ -135,17 +136,17 @@ QVariant BinClassesModel::data(const QModelIndex &index, int role) const case TYPE: return tr("method"); case OFFSET: - return meth->addr == RVA_INVALID ? QString() : RzAddressString(meth->addr); + return meth->addr == RVA_INVALID ? QString() : rzAddressString(meth->addr); case VTABLE: return meth->vtableOffset < 0 ? QString() : QString("+%1").arg(meth->vtableOffset); default: return QVariant(); } - case OffsetRole: + case offsetRole: return QVariant::fromValue(meth->addr); - case NameRole: + case nameRole: return meth->name; - case TypeRole: + case typeRole: return QVariant::fromValue(RowType::Method); default: return QVariant(); @@ -159,15 +160,15 @@ QVariant BinClassesModel::data(const QModelIndex &index, int role) const case TYPE: return tr("field"); case OFFSET: - return field->addr == RVA_INVALID ? QString() : RzAddressString(field->addr); + return field->addr == RVA_INVALID ? QString() : rzAddressString(field->addr); default: return QVariant(); } - case OffsetRole: + case offsetRole: return QVariant::fromValue(field->addr); - case NameRole: + case nameRole: return field->name; - case TypeRole: + case typeRole: return QVariant::fromValue(RowType::Field); default: return QVariant(); @@ -185,9 +186,9 @@ QVariant BinClassesModel::data(const QModelIndex &index, int role) const default: return QVariant(); } - case NameRole: + case nameRole: return base->name; - case TypeRole: + case typeRole: return QVariant::fromValue(RowType::Base); default: return QVariant(); @@ -201,18 +202,18 @@ QVariant BinClassesModel::data(const QModelIndex &index, int role) const case TYPE: return tr("class"); case OFFSET: - return cls->addr == RVA_INVALID ? QString() : RzAddressString(cls->addr); + return cls->addr == RVA_INVALID ? QString() : rzAddressString(cls->addr); case VTABLE: return cls->vtableAddr == RVA_INVALID ? QString() - : RzAddressString(cls->vtableAddr); + : rzAddressString(cls->vtableAddr); default: return QVariant(); } - case OffsetRole: + case offsetRole: return QVariant::fromValue(cls->addr); - case NameRole: + case nameRole: return cls->name; - case TypeRole: + case typeRole: return QVariant::fromValue(RowType::Class); default: return QVariant(); @@ -221,11 +222,12 @@ QVariant BinClassesModel::data(const QModelIndex &index, int role) const } AnalysisClassesModel::AnalysisClassesModel(CutterDockWidget *parent) - : ClassesModel(parent), attrs(new QMap>) + : ClassesModel(parent), + refreshDeferrer(parent->createRefreshDeferrer([this]() { this->refreshAll(); })), + attrs(new QMap>) { // Just use a simple refresh deferrer. If an event was triggered in the background, simply // refresh everything later. - refreshDeferrer = parent->createRefreshDeferrer([this]() { this->refreshAll(); }); connect(Core(), &CutterCore::refreshAll, this, &AnalysisClassesModel::refreshAll); connect(Core(), &CutterCore::codeRebased, this, &AnalysisClassesModel::refreshAll); @@ -257,7 +259,7 @@ void AnalysisClassesModel::classNew(const QString &cls) // find the destination position using binary search and add the row auto it = std::lower_bound(classes.begin(), classes.end(), cls); - int index = it - classes.begin(); + const int index = it - classes.begin(); beginInsertRows(QModelIndex(), index, index); classes.insert(it, cls); endInsertRows(); @@ -274,7 +276,7 @@ void AnalysisClassesModel::classDeleted(const QString &cls) if (it == classes.end() || *it != cls) { return; } - int index = it - classes.begin(); + const int index = it - classes.begin(); beginRemoveRows(QModelIndex(), index, index); classes.erase(it); endRemoveRows(); @@ -291,7 +293,7 @@ void AnalysisClassesModel::classRenamed(const QString &oldName, const QString &n return; } auto newIt = std::lower_bound(classes.begin(), classes.end(), newName); - int oldRow = oldIt - classes.begin(); + const int oldRow = oldIt - classes.begin(); int newRow = newIt - classes.begin(); // oldRow == newRow means the name stayed the same. // oldRow == newRow - 1 means the name changed, but the row stays the same. @@ -322,7 +324,8 @@ void AnalysisClassesModel::classAttrsChanged(const QString &cls) if (it == classes.end() || *it != cls) { return; } - QPersistentModelIndex persistentIndex = QPersistentModelIndex(index(it - classes.begin(), 0)); + const QPersistentModelIndex persistentIndex = + QPersistentModelIndex(index(it - classes.begin(), 0)); layoutAboutToBeChanged({ persistentIndex }); attrs->remove(cls); layoutChanged({ persistentIndex }); @@ -337,9 +340,9 @@ AnalysisClassesModel::getAttrs(const QString &cls) const } QVector clsAttrs; - QList bases = Core()->getAnalysisClassBaseClasses(cls); - QList meths = Core()->getAnalysisClassMethods(cls); - QList vtables = Core()->getAnalysisClassVTables(cls); + const QList bases = Core()->getAnalysisClassBaseClasses(cls); + const QList meths = Core()->getAnalysisClassMethods(cls); + const QList vtables = Core()->getAnalysisClassVTables(cls); clsAttrs.reserve(bases.size() + meths.size() + vtables.size()); for (const AnalysisBaseClassDescription &base : bases) { @@ -410,7 +413,7 @@ QVariant AnalysisClassesModel::data(const QModelIndex &index, int role) const return QVariant(); } - QString cls = classes.at(index.row()); + const QString cls = classes.at(index.row()); switch (role) { case Qt::DisplayRole: switch (index.column()) { @@ -421,20 +424,20 @@ QVariant AnalysisClassesModel::data(const QModelIndex &index, int role) const default: return QVariant(); } - case TypeRole: + case typeRole: return QVariant::fromValue(RowType::Class); - case NameRole: + case nameRole: return cls; default: return QVariant(); } } else { // method/field/base row - QString cls = classes.at(static_cast(index.internalId() - 1)); + const QString cls = classes.at(static_cast(index.internalId() - 1)); const Attribute &attr = getAttrs(cls)[index.row()]; switch (attr.type) { case Attribute::Type::Base: { - AnalysisBaseClassDescription base = attr.data.value(); + const auto base = attr.data.value(); switch (role) { case Qt::DisplayRole: switch (index.column()) { @@ -453,11 +456,11 @@ QVariant AnalysisClassesModel::data(const QModelIndex &index, int role) const QPalette::WindowText)); } return QVariant(); - case VTableRole: + case vTableRole: return -1; - case NameRole: + case nameRole: return base.className; - case TypeRole: + case typeRole: return QVariant::fromValue(RowType::Base); default: return QVariant(); @@ -465,7 +468,7 @@ QVariant AnalysisClassesModel::data(const QModelIndex &index, int role) const break; } case Attribute::Type::Method: { - AnalysisMethodDescription meth = attr.data.value(); + const auto meth = attr.data.value(); switch (role) { case Qt::DisplayRole: switch (index.column()) { @@ -476,7 +479,7 @@ QVariant AnalysisClassesModel::data(const QModelIndex &index, int role) const case TYPE: return tr("method"); case OFFSET: - return meth.addr == RVA_INVALID ? QString() : RzAddressString(meth.addr); + return meth.addr == RVA_INVALID ? QString() : rzAddressString(meth.addr); case VTABLE: return meth.vtableOffset < 0 ? QString() : QString("+%1").arg(meth.vtableOffset); @@ -489,15 +492,15 @@ QVariant AnalysisClassesModel::data(const QModelIndex &index, int role) const QPalette::WindowText)); } return QVariant(); - case VTableRole: + case vTableRole: return QVariant::fromValue(meth.vtableOffset); - case OffsetRole: + case offsetRole: return QVariant::fromValue(meth.addr); - case NameRole: + case nameRole: return meth.name; - case RealNameRole: + case realNameRole: return meth.realName; - case TypeRole: + case typeRole: return QVariant::fromValue(RowType::Method); default: return QVariant(); @@ -505,7 +508,7 @@ QVariant AnalysisClassesModel::data(const QModelIndex &index, int role) const break; } case Attribute::Type::VTable: { - AnalysisVTableDescription vtable = attr.data.value(); + const auto vtable = attr.data.value(); switch (role) { case Qt::DisplayRole: switch (index.column()) { @@ -514,7 +517,7 @@ QVariant AnalysisClassesModel::data(const QModelIndex &index, int role) const case TYPE: return tr("vtable"); case OFFSET: - return RzAddressString(vtable.addr); + return rzAddressString(vtable.addr); default: return QVariant(); } @@ -524,9 +527,9 @@ QVariant AnalysisClassesModel::data(const QModelIndex &index, int role) const QPalette::WindowText)); } return QVariant(); - case OffsetRole: + case offsetRole: return QVariant::fromValue(vtable.addr); - case TypeRole: + case typeRole: return QVariant::fromValue(RowType::VTable); default: return QVariant(); @@ -547,45 +550,46 @@ ClassesSortFilterProxyModel::ClassesSortFilterProxyModel(QObject *parent) bool ClassesSortFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - if (parent.isValid()) + if (parent.isValid()) { return true; + } - QModelIndex index = sourceModel()->index(row, 0, parent); - return qhelpers::filterStringContains(index.data(ClassesModel::NameRole).toString(), this); + const QModelIndex index = sourceModel()->index(row, 0, parent); + return qhelpers::filterStringContains(index.data(ClassesModel::nameRole).toString(), this); } bool ClassesSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { switch (left.column()) { case ClassesModel::OFFSET: { - RVA left_offset = left.data(ClassesModel::OffsetRole).toULongLong(); - RVA right_offset = right.data(ClassesModel::OffsetRole).toULongLong(); - if (left_offset != right_offset) { - return left_offset < right_offset; + const RVA leftOffset = left.data(ClassesModel::offsetRole).toULongLong(); + const RVA rightOffset = right.data(ClassesModel::offsetRole).toULongLong(); + if (leftOffset != rightOffset) { + return leftOffset < rightOffset; } } // fallthrough case ClassesModel::TYPE: { - auto left_type = left.data(ClassesModel::TypeRole).value(); - auto right_type = right.data(ClassesModel::TypeRole).value(); - if (left_type != right_type) { - return left_type < right_type; + auto leftType = left.data(ClassesModel::typeRole).value(); + auto rightType = right.data(ClassesModel::typeRole).value(); + if (leftType != rightType) { + return leftType < rightType; } } // fallthrough case ClassesModel::VTABLE: { - auto left_vtable = left.data(ClassesModel::VTableRole).toLongLong(); - auto right_vtable = right.data(ClassesModel::VTableRole).toLongLong(); - if (left_vtable != right_vtable) { - return left_vtable < right_vtable; + auto leftVtable = left.data(ClassesModel::vTableRole).toLongLong(); + auto rightVtable = right.data(ClassesModel::vTableRole).toLongLong(); + if (leftVtable != rightVtable) { + return leftVtable < rightVtable; } } // fallthrough case ClassesModel::NAME: default: - QString left_name = left.data(ClassesModel::NameRole).toString(); - QString right_name = right.data(ClassesModel::NameRole).toString(); - return QString::compare(left_name, right_name, Qt::CaseInsensitive) < 0; + const QString leftName = left.data(ClassesModel::nameRole).toString(); + const QString rightName = right.data(ClassesModel::nameRole).toString(); + return QString::compare(leftName, rightName, Qt::CaseInsensitive) < 0; } } @@ -596,6 +600,8 @@ bool ClassesSortFilterProxyModel::hasChildren(const QModelIndex &parent) const ClassesWidget::ClassesWidget(MainWindow *main) : ListDockWidget(main), + proxyModel(new ClassesSortFilterProxyModel(this)), + classSourceCombo(new QComboBox(this)), seekToVTableAction(tr("Seek to VTable"), this), editMethodAction(tr("Edit Method"), this), addMethodAction(tr("Add Method"), this), @@ -608,14 +614,12 @@ ClassesWidget::ClassesWidget(MainWindow *main) ui->treeView->setIconSize(QSize(10, 10)); - proxy_model = new ClassesSortFilterProxyModel(this); - setModels(proxy_model); + setModels(proxyModel); - classSourceCombo = new QComboBox(this); // User an intermediate single-child layout to contain the combo box, otherwise // when the combo box is inserted directly, the entire vertical layout gets a // weird horizontal padding on macOS. - QBoxLayout *comboLayout = new QBoxLayout(QBoxLayout::Direction::LeftToRight, nullptr); + auto *comboLayout = new QBoxLayout(QBoxLayout::Direction::LeftToRight, nullptr); comboLayout->addWidget(classSourceCombo); ui->verticalLayout->insertLayout(ui->verticalLayout->indexOf(ui->quickFilterView), comboLayout); classSourceCombo->addItem(tr("Binary Info (Fixed)")); @@ -671,22 +675,22 @@ void ClassesWidget::refreshClasses() { switch (getSource()) { case Source::BIN: - if (!bin_model) { - proxy_model->setSourceModel(static_cast(nullptr)); - delete analysis_model; - analysis_model = nullptr; - bin_model = new BinClassesModel(this); - proxy_model->setSourceModel(static_cast(bin_model)); + if (!binModel) { + proxyModel->setSourceModel(static_cast(nullptr)); + delete analysisModel; + analysisModel = nullptr; + binModel = new BinClassesModel(this); + proxyModel->setSourceModel(static_cast(binModel)); } - bin_model->setClasses(Core()->getAllClassesFromBin()); + binModel->setClasses(Core()->getAllClassesFromBin()); break; case Source::ANALYSIS: - if (!analysis_model) { - proxy_model->setSourceModel(static_cast(nullptr)); - delete bin_model; - bin_model = nullptr; - analysis_model = new AnalysisClassesModel(this); - proxy_model->setSourceModel(static_cast(analysis_model)); + if (!analysisModel) { + proxyModel->setSourceModel(static_cast(nullptr)); + delete binModel; + binModel = nullptr; + analysisModel = new AnalysisClassesModel(this); + proxyModel->setSourceModel(static_cast(analysisModel)); } break; } @@ -694,22 +698,22 @@ void ClassesWidget::refreshClasses() qhelpers::adjustColumns(ui->treeView, 3, 0); // set the initial item count - ui->quickFilterView->setItemCount(proxy_model->rowCount()); + ui->quickFilterView->setItemCount(proxyModel->rowCount()); ui->treeView->setColumnWidth(0, 200); } void ClassesWidget::updateActions() { - bool isAnalysis = !!analysis_model; + const bool isAnalysis = !!analysisModel; newClassAction.setVisible(isAnalysis); addMethodAction.setVisible(isAnalysis); bool rowIsAnalysisClass = false; bool rowIsAnalysisMethod = false; - QModelIndex index = ui->treeView->selectionModel()->currentIndex(); + const QModelIndex index = ui->treeView->selectionModel()->currentIndex(); if (isAnalysis && index.isValid()) { - auto type = static_cast(index.data(ClassesModel::TypeRole).toInt()); + auto type = static_cast(index.data(ClassesModel::typeRole).toInt()); rowIsAnalysisClass = type == ClassesModel::RowType::Class; rowIsAnalysisMethod = type == ClassesModel::RowType::Method; } @@ -722,8 +726,8 @@ void ClassesWidget::updateActions() editMethodAction.setVisible(rowIsAnalysisMethod); bool rowHasVTable = false; if (rowIsAnalysisMethod) { - QString className = index.parent().data(ClassesModel::NameRole).toString(); - QString methodName = index.data(ClassesModel::NameRole).toString(); + const QString className = index.parent().data(ClassesModel::nameRole).toString(); + const QString methodName = index.data(ClassesModel::nameRole).toString(); AnalysisMethodDescription desc; if (Core()->getAnalysisMethod(className, methodName, &desc)) { if (desc.vtableOffset >= 0) { @@ -736,8 +740,8 @@ void ClassesWidget::updateActions() void ClassesWidget::seekToVTableActionTriggered() { - QModelIndex index = ui->treeView->selectionModel()->currentIndex(); - QString className = index.parent().data(ClassesModel::NameRole).toString(); + const QModelIndex index = ui->treeView->selectionModel()->currentIndex(); + const QString className = index.parent().data(ClassesModel::nameRole).toString(); QList vtables = Core()->getAnalysisClassVTables(className); if (vtables.isEmpty()) { @@ -746,7 +750,7 @@ void ClassesWidget::seekToVTableActionTriggered() return; } - QString methodName = index.data(ClassesModel::NameRole).toString(); + const QString methodName = index.data(ClassesModel::nameRole).toString(); AnalysisMethodDescription desc; if (!Core()->getAnalysisMethod(className, methodName, &desc) || desc.vtableOffset < 0) { return; @@ -757,17 +761,17 @@ void ClassesWidget::seekToVTableActionTriggered() void ClassesWidget::addMethodActionTriggered() { - QModelIndex index = ui->treeView->selectionModel()->currentIndex(); + const QModelIndex index = ui->treeView->selectionModel()->currentIndex(); if (!index.isValid()) { return; } QString className; - if (index.data(ClassesModel::TypeRole).toInt() + if (index.data(ClassesModel::typeRole).toInt() == static_cast(ClassesModel::RowType::Class)) { - className = index.data(ClassesModel::NameRole).toString(); + className = index.data(ClassesModel::nameRole).toString(); } else { - className = index.parent().data(ClassesModel::NameRole).toString(); + className = index.parent().data(ClassesModel::nameRole).toString(); } EditMethodDialog::newMethod(className, QString(), this); @@ -775,22 +779,22 @@ void ClassesWidget::addMethodActionTriggered() void ClassesWidget::editMethodActionTriggered() { - QModelIndex index = ui->treeView->selectionModel()->currentIndex(); + const QModelIndex index = ui->treeView->selectionModel()->currentIndex(); if (!index.isValid() - || index.data(ClassesModel::TypeRole).toInt() + || index.data(ClassesModel::typeRole).toInt() != static_cast(ClassesModel::RowType::Method)) { return; } - QString className = index.parent().data(ClassesModel::NameRole).toString(); - QString methName = index.data(ClassesModel::NameRole).toString(); + const QString className = index.parent().data(ClassesModel::nameRole).toString(); + const QString methName = index.data(ClassesModel::nameRole).toString(); EditMethodDialog::editMethod(className, methName, this); } void ClassesWidget::newClassActionTriggered() { bool ok; - QString name = QInputDialog::getText(this, tr("Create new Class"), tr("Class Name:"), - QLineEdit::Normal, QString(), &ok); + const QString name = QInputDialog::getText(this, tr("Create new Class"), tr("Class Name:"), + QLineEdit::Normal, QString(), &ok); if (ok && !name.isEmpty()) { Core()->createNewClass(name); } @@ -798,13 +802,13 @@ void ClassesWidget::newClassActionTriggered() void ClassesWidget::deleteClassActionTriggered() { - QModelIndex index = ui->treeView->selectionModel()->currentIndex(); + const QModelIndex index = ui->treeView->selectionModel()->currentIndex(); if (!index.isValid() - || index.data(ClassesModel::TypeRole).toInt() + || index.data(ClassesModel::typeRole).toInt() != static_cast(ClassesModel::RowType::Class)) { return; } - QString className = index.data(ClassesModel::NameRole).toString(); + const QString className = index.data(ClassesModel::nameRole).toString(); if (QMessageBox::question(this, tr("Delete Class"), tr("Are you sure you want to delete the class %1?").arg(className)) != QMessageBox::StandardButton::Yes) { @@ -815,16 +819,17 @@ void ClassesWidget::deleteClassActionTriggered() void ClassesWidget::renameClassActionTriggered() { - QModelIndex index = ui->treeView->selectionModel()->currentIndex(); + const QModelIndex index = ui->treeView->selectionModel()->currentIndex(); if (!index.isValid() - || index.data(ClassesModel::TypeRole).toInt() + || index.data(ClassesModel::typeRole).toInt() != static_cast(ClassesModel::RowType::Class)) { return; } - QString oldName = index.data(ClassesModel::NameRole).toString(); + const QString oldName = index.data(ClassesModel::nameRole).toString(); bool ok; - QString newName = QInputDialog::getText(this, tr("Rename Class %1").arg(oldName), - tr("Class name:"), QLineEdit::Normal, oldName, &ok); + const QString newName = + QInputDialog::getText(this, tr("Rename Class %1").arg(oldName), tr("Class name:"), + QLineEdit::Normal, oldName, &ok); if (ok && !newName.isEmpty()) { Core()->renameClass(oldName, newName); } diff --git a/src/widgets/ClassesWidget.h b/src/widgets/ClassesWidget.h index 13161ebe..ed6c691d 100644 --- a/src/widgets/ClassesWidget.h +++ b/src/widgets/ClassesWidget.h @@ -1,15 +1,17 @@ #ifndef CLASSESWIDGET_H #define CLASSESWIDGET_H -#include - -#include "core/Cutter.h" +#include "CutterCommon.h" +#include "CutterDescriptions.h" #include "CutterDockWidget.h" #include "widgets/ListDockWidget.h" #include +#include #include +#include + namespace Ui { class ClassesWidget; } @@ -21,24 +23,26 @@ class ClassesWidget; /** * @brief Common abstract base class for Bin and Anal classes models + * + * @see BinClassesModel, AnalysisClassesModel */ class ClassesModel : public AddressableItemModel<> { Q_OBJECT public: - enum Columns { NAME = 0, REAL_NAME, TYPE, OFFSET, VTABLE, COUNT }; + enum Columns : ut8 { NAME = 0, REAL_NAME, TYPE, OFFSET, VTABLE, COUNT }; /** * @brief values for TypeRole data */ - enum class RowType { Class = 0, Base, VTable, Method, Field }; + enum class RowType : ut8 { Class = 0, Base, VTable, Method, Field }; /** * @brief Offset role of data for QModelIndex * * will contain values of type RVA */ - static const int OffsetRole = Qt::UserRole; + static const int offsetRole = Qt::UserRole; /** * @brief Name role of data for QModelIndex @@ -46,14 +50,14 @@ public: * will contain values of QString, used for sorting, * as well as identifying classes and methods */ - static const int NameRole = Qt::UserRole + 1; + static const int nameRole = Qt::UserRole + 1; /** * @brief Type role of data for QModelIndex * * will contain values of RowType */ - static const int TypeRole = Qt::UserRole + 2; + static const int typeRole = Qt::UserRole + 2; /** * @brief VTable role of data for QModelIndex @@ -61,7 +65,7 @@ public: * will contain values of type long long for sorting * by vtable offset */ - static const int VTableRole = Qt::UserRole + 3; + static const int vTableRole = Qt::UserRole + 3; /** * @brief Real Name role of data for QModelIndex @@ -69,7 +73,7 @@ public: * will contain values of QString, used for sorting, * as well as identifying classes and methods */ - static const int RealNameRole = Qt::UserRole + 4; + static const int realNameRole = Qt::UserRole + 4; explicit ClassesModel(QObject *parent = nullptr) : AddressableItemModel(parent) {} @@ -82,6 +86,9 @@ public: Q_DECLARE_METATYPE(ClassesModel::RowType) +/** + * @brief Read-only model for class info found in the binary + */ class BinClassesModel : public ClassesModel { Q_OBJECT @@ -103,6 +110,9 @@ public: void setClasses(const QList &classes); }; +/** + * @brief Editable model for classes created during analysis. + */ class AnalysisClassesModel : public ClassesModel { Q_OBJECT @@ -118,7 +128,7 @@ private: */ struct Attribute { - enum class Type { VTable, Base, Method }; + enum class Type : ut8 { VTable, Base, Method }; Type type; QVariant data; @@ -168,6 +178,9 @@ public slots: void classAttrsChanged(const QString &cls); }; +/** + * @brief Handles sorting and filtering for class lists + */ class ClassesSortFilterProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -181,6 +194,9 @@ protected: bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; }; +/** + * @brief Widget for browsing and managing classes + */ class ClassesWidget : public ListDockWidget { Q_OBJECT @@ -201,13 +217,13 @@ private slots: void updateActions(); private: - enum class Source { BIN, ANALYSIS }; + enum class Source : ut8 { BIN, ANALYSIS }; Source getSource(); - BinClassesModel *bin_model = nullptr; - AnalysisClassesModel *analysis_model = nullptr; - ClassesSortFilterProxyModel *proxy_model; + BinClassesModel *binModel = nullptr; + AnalysisClassesModel *analysisModel = nullptr; + ClassesSortFilterProxyModel *proxyModel; QComboBox *classSourceCombo; diff --git a/src/widgets/ColorPicker.cpp b/src/widgets/ColorPicker.cpp index e16b02aa..7d3d5b05 100644 --- a/src/widgets/ColorPicker.cpp +++ b/src/widgets/ColorPicker.cpp @@ -1,18 +1,19 @@ #include "ColorPicker.h" -#include "ui_ColorPicker.h" -#include "common/Helpers.h" +#include "common/Helpers.h" +#include "ui_ColorPicker.h" + +#include #include #include #include -#include #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) # include #else # include #endif -#include #include +#include #include using namespace ColorPickerHelpers; @@ -38,7 +39,7 @@ void ColorPickArea::paintEvent(QPaintEvent *event) } p.setPen(QPen(Qt::black, 3)); - QPoint curr = colorToPoint(currColor); + const QPoint curr = colorToPoint(currColor); p.drawLine(curr - QPoint(0, 8), curr + QPoint(0, 8)); p.drawLine(curr - QPoint(8, 0), curr + QPoint(8, 0)); @@ -50,8 +51,8 @@ void ColorPickArea::setColor(const QColor &c) if (c == currColor) { return; } - QPoint p1 = colorToPoint(currColor); - QPoint p2 = colorToPoint(c); + const QPoint p1 = colorToPoint(currColor); + const QPoint p2 = colorToPoint(c); currColor = c; repaint(QRect(p2 - QPoint(10, 10), p2 + QPoint(10, 10))); repaint(QRect(p1 - QPoint(10, 10), p1 + QPoint(10, 10))); @@ -133,7 +134,7 @@ void ColorValueBar::paintEvent(QPaintEvent *event) p.drawLine(barRect.x(), y, barRect.right(), y); } - QRectF triangleRect = + const QRectF triangleRect = QRectF(barRect.right(), v * height() - triangleSize / 2, triangleSize, triangleSize); QPainterPath path; @@ -212,12 +213,12 @@ void ColorPicker::setColor(const QColor &color) void ColorPicker::colorChannelChanged() { - QString txt = ui->hexLineEdit->text(); + const QString txt = ui->hexLineEdit->text(); // Regex pattern below mimics the behaviour of former RegExp::exactMatch() if (!QRegularExpression("\\A(?:#[0-9a-fA-F]{6})\\z").match(txt).hasMatch()) { return; } - QColor hexColor = txt; + const QColor hexColor = txt; int h, s, v; h = ui->hueSpinBox->value(); @@ -244,20 +245,20 @@ void ColorPicker::colorChannelChanged() void ColorPicker::updateColor(const QColor &color) { - QSignalBlocker s0(ui->redSpinBox); - QSignalBlocker s1(ui->blueSpinBox); - QSignalBlocker s2(ui->greenSpinBox); + const QSignalBlocker s0(ui->redSpinBox); + const QSignalBlocker s1(ui->blueSpinBox); + const QSignalBlocker s2(ui->greenSpinBox); - QSignalBlocker s3(ui->valSpinBox); - QSignalBlocker s4(ui->satSpinBox); - QSignalBlocker s5(ui->hueSpinBox); + const QSignalBlocker s3(ui->valSpinBox); + const QSignalBlocker s4(ui->satSpinBox); + const QSignalBlocker s5(ui->hueSpinBox); - QSignalBlocker s6(ui->hexLineEdit); + const QSignalBlocker s6(ui->hexLineEdit); - QSignalBlocker s7(ui->alphaChannelBar); - QSignalBlocker s8(ui->colorPickArea); - QSignalBlocker s9(ui->colorShow); - QSignalBlocker s10(ui->valuePickBar); + const QSignalBlocker s7(ui->alphaChannelBar); + const QSignalBlocker s8(ui->colorPickArea); + const QSignalBlocker s9(ui->colorShow); + const QSignalBlocker s10(ui->valuePickBar); currColor = color; @@ -322,7 +323,7 @@ QColor ColorPicker::getColorAtMouse() ->grabWindow(desktop->winId(), QCursor::pos().x(), QCursor::pos().y(), 1, 1); return QColor(pixmap.toImage().pixel(0, 0)); #else - QPoint pos = QCursor::pos(); + const QPoint pos = QCursor::pos(); auto screen = QGuiApplication::screenAt(pos); if (!screen) { screen = QGuiApplication::primaryScreen(); @@ -420,7 +421,7 @@ void AlphaChannelBar::paintEvent(QPaintEvent *event) } } - QRectF triangleRect = + const QRectF triangleRect = QRectF(barRect.right(), a * height() - triangleSize / 2, triangleSize, triangleSize); QPainterPath path; diff --git a/src/widgets/ColorPicker.h b/src/widgets/ColorPicker.h index 8c45ec7c..5a18eaf1 100644 --- a/src/widgets/ColorPicker.h +++ b/src/widgets/ColorPicker.h @@ -3,9 +3,11 @@ #include +#include + /** * @namespace ColorPickerHelpers is a namespace that hides all classes needed for ColorPicker class, - * because classes inherite QObject can not be declared in *.cpp files or inside of another class. + * because classes inherit QObject can not be declared in *.cpp files or inside of another class. */ namespace ColorPickerHelpers { class ColorPickWidgetAbstract : public QWidget @@ -77,7 +79,7 @@ protected: void mouseMoveEvent(QMouseEvent *event) override; private: - Ui::ColorPicker *ui; + std::unique_ptr ui; bool pickingFromScreen; QColor getColorAtMouse(); @@ -116,6 +118,9 @@ protected: virtual QPoint colorToPoint(const QColor &color) const = 0; }; +/** + * @brief Display widget to preview the currently selected color + */ class ColorShowWidget : public ColorPickWidgetAbstract { Q_OBJECT @@ -149,6 +154,9 @@ private: QPoint colorToPoint(const QColor &color) const override; }; +/** + * @brief Slider for adjusting the transparency (alpha) level of a color + */ class AlphaChannelBar : public ColorPickerWidget { Q_OBJECT diff --git a/src/widgets/ColorThemeComboBox.cpp b/src/widgets/ColorThemeComboBox.cpp index 4293895c..5d06dca7 100644 --- a/src/widgets/ColorThemeComboBox.cpp +++ b/src/widgets/ColorThemeComboBox.cpp @@ -1,9 +1,8 @@ #include "ColorThemeComboBox.h" -#include "core/Cutter.h" - #include "common/ColorThemeWorker.h" #include "common/Configuration.h" +#include "core/Cutter.h" ColorThemeComboBox::ColorThemeComboBox(QWidget *parent) : QComboBox(parent), showOnlyCustom(false) { @@ -14,7 +13,7 @@ ColorThemeComboBox::ColorThemeComboBox(QWidget *parent) : QComboBox(parent), sho void ColorThemeComboBox::updateFromConfig(bool interfaceThemeChanged) { - QSignalBlocker signalBlockerColorBox(this); + const QSignalBlocker signalBlockerColorBox(this); const int curInterfaceThemeIndex = Config()->getInterfaceTheme(); const QList themes(showOnlyCustom ? ThemeWorker().customThemes() @@ -41,7 +40,7 @@ void ColorThemeComboBox::updateFromConfig(bool interfaceThemeChanged) } int maxThemeLen = 0; for (const QString &str : themes) { - int strLen = str.length(); + const int strLen = str.length(); if (strLen > maxThemeLen) { maxThemeLen = strLen; } @@ -52,7 +51,7 @@ void ColorThemeComboBox::updateFromConfig(bool interfaceThemeChanged) void ColorThemeComboBox::onCurrentIndexChanged(int index) { - QString theme = itemText(index); + const QString theme = itemText(index); int curQtThemeIndex = Config()->getInterfaceTheme(); if (curQtThemeIndex >= Configuration::cutterInterfaceThemesList().size()) { diff --git a/src/widgets/ColorThemeListView.cpp b/src/widgets/ColorThemeListView.cpp index 4e95c79e..8ed6b24f 100644 --- a/src/widgets/ColorThemeListView.cpp +++ b/src/widgets/ColorThemeListView.cpp @@ -1,22 +1,22 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "widgets/ColorThemeListView.h" -#include "common/Configuration.h" #include "common/ColorThemeWorker.h" +#include "common/Configuration.h" #include "common/Helpers.h" -#include "widgets/ColorThemeListView.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include constexpr int allFieldsRole = Qt::UserRole + 2; @@ -27,32 +27,28 @@ struct OptionInfo }; namespace { -extern const QMap OPTION_INFO_MAP; +extern const QMap optionInfoMap; } ColorOptionDelegate::ColorOptionDelegate(QObject *parent) : QStyledItemDelegate(parent) { resetButtonPixmap = getPixmapFromSvg(":/img/icons/reset.svg", qApp->palette().text().color()); - connect(qApp, &QGuiApplication::paletteChanged, this, [this]() { - resetButtonPixmap = - getPixmapFromSvg(":/img/icons/reset.svg", qApp->palette().text().color()); - }); } void ColorOptionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { - int margin = this->margin; + const int margin = this->margin; painter->save(); painter->setFont(option.font); painter->setRenderHint(QPainter::Antialiasing); - ColorOption currCO = index.data(Qt::UserRole).value(); + const auto currCO = index.data(Qt::UserRole).value(); - QFontMetrics fm = QFontMetrics(painter->font()); - int penWidth = painter->pen().width(); - int fontHeight = fm.height(); - QPoint tl = option.rect.topLeft(); + const QFontMetrics fm = QFontMetrics(painter->font()); + const int penWidth = painter->pen().width(); + const int fontHeight = fm.height(); + const QPoint tl = option.rect.topLeft(); QRect optionNameRect; optionNameRect.setTopLeft(tl + QPoint(margin, penWidth)); @@ -96,7 +92,7 @@ void ColorOptionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o } } else { #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) - QColor placeholderColor = qApp->palette().placeholderText().color(); + const QColor placeholderColor = qApp->palette().placeholderText().color(); #else QColor placeholderColor = qApp->palette().text().color(); placeholderColor.setAlphaF(0.5); @@ -110,9 +106,9 @@ void ColorOptionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o painter->fillRect(option.rect, br); painter->setPen(pen); - int pw = painter->pen().width() / 2; - QPoint top = option.rect.topLeft() + QPoint(pw, pw); - QPoint bottom = option.rect.bottomLeft() - QPoint(-pw, pw - 1); + const int pw = painter->pen().width() / 2; + const QPoint top = option.rect.topLeft() + QPoint(pw, pw); + const QPoint bottom = option.rect.bottomLeft() - QPoint(-pw, pw - 1); painter->drawLine(top, bottom); } @@ -128,10 +124,10 @@ void ColorOptionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o painter->setPen(qApp->palette().text().color()); - QFontMetrics fm2 = QFontMetrics(painter->font()); - auto info = OPTION_INFO_MAP[currCO.optionName]; - QString name = fm2.elidedText(QApplication::translate("ColorTheme", info.displayingtext), - Qt::ElideRight, optionNameRect.width()); + const QFontMetrics fm2 = QFontMetrics(painter->font()); + auto info = optionInfoMap[currCO.optionName]; + const QString name = fm2.elidedText(QApplication::translate("ColorTheme", info.displayingtext), + Qt::ElideRight, optionNameRect.width()); painter->drawText(optionNameRect, name); QPainterPath roundedOptionRect; @@ -158,10 +154,10 @@ void ColorOptionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o painter->setPen(currCO.color); painter->fillPath(roundedColorRect, currCO.color); - QFontMetrics fm3 = QFontMetrics(painter->font()); - QString desc = fm3.elidedText(currCO.optionName + ": " - + QApplication::translate("ColorTheme", info.info), - Qt::ElideRight, descTextRect.width()); + const QFontMetrics fm3 = QFontMetrics(painter->font()); + const QString desc = fm3.elidedText(currCO.optionName + ": " + + QApplication::translate("ColorTheme", info.info), + Qt::ElideRight, descTextRect.width()); painter->setPen(qApp->palette().text().color()); painter->setBrush(qApp->palette().text()); painter->drawText(descTextRect, desc); @@ -172,8 +168,8 @@ void ColorOptionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o QSize ColorOptionDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { - qreal margin = this->margin; - qreal fontHeight = option.fontMetrics.height(); + const qreal margin = this->margin; + const qreal fontHeight = option.fontMetrics.height(); qreal h = QPen().width(); h += fontHeight; // option name h += margin / 2; // margin between option rect and option name @@ -191,6 +187,14 @@ QRect ColorOptionDelegate::getResetButtonRect() const return resetButtonRect; } +void ColorOptionDelegate::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::ApplicationPaletteChange) { + resetButtonPixmap = + getPixmapFromSvg(":/img/icons/reset.svg", qApp->palette().text().color()); + } +} + QPixmap ColorOptionDelegate::getPixmapFromSvg(const QString &fileName, const QColor &after) const { QFile file(fileName); @@ -201,7 +205,7 @@ QPixmap ColorOptionDelegate::getPixmapFromSvg(const QString &fileName, const QCo data.replace(QRegularExpression("#[0-9a-fA-F]{6}"), QString("%1").arg(after.name())); QSvgRenderer svgRenderer(data.toUtf8()); - QFontMetrics fm = QFontMetrics(qApp->font()); + const QFontMetrics fm = QFontMetrics(qApp->font()); QPixmap pix(QSize(fm.height(), fm.height())); pix.fill(Qt::transparent); @@ -213,8 +217,8 @@ QPixmap ColorOptionDelegate::getPixmapFromSvg(const QString &fileName, const QCo ColorThemeListView::ColorThemeListView(QWidget *parent) : QListView(parent) { - QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this); - ColorSettingsModel *model = new ColorSettingsModel(this); + auto *proxy = new QSortFilterProxyModel(this); + auto *model = new ColorSettingsModel(this); proxy->setSourceModel(model); model->updateTheme(); setModel(proxy); @@ -237,9 +241,9 @@ ColorThemeListView::ColorThemeListView(QWidget *parent) : QListView(parent) void ColorThemeListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { - ColorOption prev = previous.data(Qt::UserRole).value(); + const auto prev = previous.data(Qt::UserRole).value(); Config()->setColor(prev.optionName, prev.color); - bool isRizinOption = ThemeWorker().getRizinSpecificOptions().contains(prev.optionName); + const bool isRizinOption = ThemeWorker().getRizinSpecificOptions().contains(prev.optionName); if (isRizinOption) { Core()->setColor(prev.optionName, prev.color.name()); } @@ -257,7 +261,7 @@ void ColorThemeListView::currentChanged(const QModelIndex ¤t, const QModel void ColorThemeListView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) { - ColorOption curr = topLeft.data(Qt::UserRole).value(); + const auto curr = topLeft.data(Qt::UserRole).value(); if (curr.optionName == "gui.background") { backgroundColor = curr.color; } @@ -271,7 +275,7 @@ void ColorThemeListView::mouseReleaseEvent(QMouseEvent *e) if (qobject_cast(itemDelegate()) ->getResetButtonRect() .contains(e->pos())) { - ColorOption co = currentIndex().data(Qt::UserRole).value(); + auto co = currentIndex().data(Qt::UserRole).value(); co.changed = false; co.color = ThemeWorker().getTheme(Config()->getColorTheme())[co.optionName]; model()->setData(currentIndex(), QVariant::fromValue(co)); @@ -304,7 +308,7 @@ ColorSettingsModel *ColorThemeListView::colorSettingsModel() const void ColorThemeListView::blinkTimeout() { - static enum { Normal, Invisible } state = Normal; + static enum : ut8 { Normal, Invisible } state = Normal; state = state == Normal ? Invisible : Normal; backgroundColor.setAlphaF(1); @@ -315,7 +319,7 @@ void ColorThemeListView::blinkTimeout() } }; - ColorOption curr = currentIndex().data(Qt::UserRole).value(); + const auto curr = currentIndex().data(Qt::UserRole).value(); switch (state) { case Normal: updateColor(curr.optionName, curr.color); @@ -340,7 +344,7 @@ QVariant ColorSettingsModel::data(const QModelIndex &index, int role) const } const QString key = theme.at(index.row()).optionName; - auto info = OPTION_INFO_MAP[key]; + auto info = optionInfoMap[key]; if (role == Qt::DisplayRole) { return QVariant::fromValue(QApplication::translate("ColorTheme", info.displayingtext)); @@ -355,7 +359,7 @@ QVariant ColorSettingsModel::data(const QModelIndex &index, int role) const } if (role == allFieldsRole) { - const QString name = key; + const QString &name = key; return QVariant::fromValue(QApplication::translate("ColorTheme", info.displayingtext) + " " + QApplication::translate("ColorTheme", info.info) + " " + name); } @@ -369,7 +373,7 @@ bool ColorSettingsModel::setData(const QModelIndex &index, const QVariant &value return false; } - ColorOption currOpt = value.value(); + const auto currOpt = value.value(); theme[index.row()] = currOpt; emit dataChanged(index, index); return true; @@ -379,16 +383,16 @@ void ColorSettingsModel::updateTheme() { beginResetModel(); theme.clear(); - ColorThemeWorker::Theme obj = ThemeWorker().getTheme(Config()->getColorTheme()); + const ColorThemeWorker::Theme obj = ThemeWorker().getTheme(Config()->getColorTheme()); for (auto it = obj.constBegin(); it != obj.constEnd(); it++) { theme.push_back({ it.key(), it.value(), false }); } std::sort(theme.begin(), theme.end(), [](const ColorOption &f, const ColorOption &s) { - QString s1 = f.optionName; - QString s2 = s.optionName; - int r = s1.compare(s2, Qt::CaseSensitivity::CaseInsensitive); + const QString s1 = f.optionName; + const QString s2 = s.optionName; + const int r = s1.compare(s2, Qt::CaseSensitivity::CaseInsensitive); return r < 0; }); endResetModel(); @@ -403,8 +407,9 @@ ColorThemeWorker::Theme ColorSettingsModel::getTheme() const return th; } +// TODO: these should be queried from rizin namespace { -const QMap OPTION_INFO_MAP = { +const QMap optionInfoMap = { { "comment", { QT_TRANSLATE_NOOP("ColorTheme", "Color for code comments"), QT_TRANSLATE_NOOP("ColorTheme", "Comment") } }, diff --git a/src/widgets/ColorThemeListView.h b/src/widgets/ColorThemeListView.h index f992f2f7..ff08e65a 100644 --- a/src/widgets/ColorThemeListView.h +++ b/src/widgets/ColorThemeListView.h @@ -1,12 +1,12 @@ #ifndef COLORTHEMELISTVIEW_H #define COLORTHEMELISTVIEW_H -#include -#include +#include #include #include -#include +#include #include +#include struct ColorOption { @@ -18,6 +18,9 @@ Q_DECLARE_METATYPE(ColorOption); class ColorSettingsModel; +/** + * @brief Manages the custom rendering of color settings + */ class ColorThemeListView : public QListView { Q_OBJECT @@ -54,6 +57,9 @@ private: //============================================== +/** + * @brief Source model for @ref ColorThemeListView + */ class ColorSettingsModel : public QAbstractListModel { Q_OBJECT @@ -79,6 +85,9 @@ private: QList theme; }; +/** + * @brief Delegate for @ref ColorThemeListView + */ class ColorOptionDelegate : public QStyledItemDelegate { Q_OBJECT @@ -93,6 +102,9 @@ public: QRect getResetButtonRect() const; +protected: + void changeEvent(QEvent *event); + private: const int margin = 12; QPixmap resetButtonPixmap; diff --git a/src/widgets/ComboQuickFilterView.cpp b/src/widgets/ComboQuickFilterView.cpp index e8112bd7..6c24203a 100644 --- a/src/widgets/ComboQuickFilterView.cpp +++ b/src/widgets/ComboQuickFilterView.cpp @@ -1,4 +1,5 @@ #include "ComboQuickFilterView.h" + #include "ui_ComboQuickFilterView.h" ComboQuickFilterView::ComboQuickFilterView(QWidget *parent) diff --git a/src/widgets/ComboQuickFilterView.h b/src/widgets/ComboQuickFilterView.h index 3c69099b..a069ee6b 100644 --- a/src/widgets/ComboQuickFilterView.h +++ b/src/widgets/ComboQuickFilterView.h @@ -2,13 +2,20 @@ #define COMBOQUICKFILTERVIEW_H #include "AbstractFilterView.h" + #include + #include namespace Ui { class ComboQuickFilterView; } +/** + * @brief Quick filter view class containing a combo box + * + * @see QuickFilterView + */ class ComboQuickFilterView : public AbstractFilterView { Q_OBJECT diff --git a/src/widgets/CommentsWidget.cpp b/src/widgets/CommentsWidget.cpp index 8fd20163..b45309e6 100644 --- a/src/widgets/CommentsWidget.cpp +++ b/src/widgets/CommentsWidget.cpp @@ -1,11 +1,12 @@ #include "CommentsWidget.h" -#include "ui_ListDockWidget.h" -#include "core/MainWindow.h" -#include "common/Helpers.h" +#include "common/Helpers.h" +#include "core/MainWindow.h" +#include "ui_ListDockWidget.h" + +#include #include #include -#include CommentsModel::CommentsModel(QObject *parent) : AddressableItemModel<>(parent), nested(false) {} @@ -56,8 +57,9 @@ QModelIndex CommentsModel::parent(const QModelIndex &index) const int CommentsModel::rowCount(const QModelIndex &parent) const { - if (!parent.isValid()) + if (!parent.isValid()) { return (isNested() ? nestedComments.size() : comments.count()); + } if (isNested() && parent.internalId() == 0) { return nestedComments.at(parent.row()).comments.size(); @@ -74,8 +76,9 @@ int CommentsModel::columnCount(const QModelIndex &) const QVariant CommentsModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || (index.internalId() != 0 && !index.parent().isValid())) + if (!index.isValid() || (index.internalId() != 0 && !index.parent().isValid())) { return QVariant(); + } int commentIndex; bool isSubnode; @@ -107,7 +110,7 @@ QVariant CommentsModel::data(const QModelIndex &index, int role) const if (isSubnode) { switch (index.column()) { case OffsetNestedColumn: - return RzAddressString(comment.offset); + return rzAddressString(comment.offset); case CommentNestedColumn: return comment.name; default: @@ -119,7 +122,7 @@ QVariant CommentsModel::data(const QModelIndex &index, int role) const } else { switch (index.column()) { case CommentsModel::OffsetColumn: - return RzAddressString(comment.offset); + return rzAddressString(comment.offset); case CommentsModel::FunctionColumn: return Core()->flagAt(comment.offset); case CommentsModel::CommentColumn: @@ -179,13 +182,13 @@ CommentsProxyModel::CommentsProxyModel(CommentsModel *sourceModel, QObject *pare bool CommentsProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - CommentsModel *srcModel = static_cast(sourceModel()); + const auto *srcModel = static_cast(sourceModel()); if (srcModel->isNested()) { // Disable filtering return true; } - QModelIndex index = sourceModel()->index(row, 0, parent); + const QModelIndex index = sourceModel()->index(row, 0, parent); auto comment = index.data(CommentsModel::CommentDescriptionRole).value(); return qhelpers::filterStringContains(comment.name, this); @@ -193,17 +196,19 @@ bool CommentsProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) co bool CommentsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - CommentsModel *srcModel = static_cast(sourceModel()); + const auto *srcModel = static_cast(sourceModel()); if (srcModel->isNested()) { // Disable sorting return false; } - if (!left.isValid() || !right.isValid()) + if (!left.isValid() || !right.isValid()) { return false; + } - if (left.parent().isValid() || right.parent().isValid()) + if (left.parent().isValid() || right.parent().isValid()) { return false; + } auto leftComment = left.data(CommentsModel::CommentDescriptionRole).value(); auto rightComment = @@ -225,18 +230,18 @@ bool CommentsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &ri CommentsWidget::CommentsWidget(MainWindow *main) : ListDockWidget(main), + commentsModel(new CommentsModel(this)), + commentsProxyModel(new CommentsProxyModel(commentsModel, this)), actionHorizontal(tr("Horizontal"), this), - actionVertical(tr("Vertical"), this) + actionVertical(tr("Vertical"), this), + titleContextMenu(new QMenu(this)) { setWindowTitle(tr("Comments")); setObjectName("CommentsWidget"); - commentsModel = new CommentsModel(this); - commentsProxyModel = new CommentsProxyModel(commentsModel, this); setModels(commentsProxyModel); ui->treeView->sortByColumn(CommentsModel::CommentColumn, Qt::AscendingOrder); - titleContextMenu = new QMenu(this); auto viewTypeGroup = new QActionGroup(titleContextMenu); actionHorizontal.setCheckable(true); actionHorizontal.setActionGroup(viewTypeGroup); @@ -288,7 +293,7 @@ void CommentsWidget::refreshTree() QMap nestedCommentMapping; for (const CommentDescription &comment : commentsModel->comments) { RVA offset = RVA_INVALID; - QString fcnName = Core()->nearestFlag(comment.offset, &offset); + const QString fcnName = Core()->nearestFlag(comment.offset, &offset); auto nestedCommentIt = nestedCommentMapping.find(fcnName); if (nestedCommentIt == nestedCommentMapping.end()) { nestedCommentMapping.insert(fcnName, commentsModel->nestedComments.size()); diff --git a/src/widgets/CommentsWidget.h b/src/widgets/CommentsWidget.h index c8369769..353f352b 100644 --- a/src/widgets/CommentsWidget.h +++ b/src/widgets/CommentsWidget.h @@ -1,15 +1,14 @@ #ifndef COMMENTSWIDGET_H #define COMMENTSWIDGET_H -#include +#include "CutterDescriptions.h" +#include "CutterDockWidget.h" +#include "common/AddressableItemModel.h" +#include "widgets/ListDockWidget.h" + #include #include -#include "core/Cutter.h" -#include "common/AddressableItemModel.h" -#include "CutterDockWidget.h" -#include "widgets/ListDockWidget.h" - class MainWindow; class QTreeWidgetItem; class CommentsWidget; @@ -33,9 +32,9 @@ private: bool nested; public: - enum Column { OffsetColumn = 0, FunctionColumn, CommentColumn, ColumnCount }; - enum NestedColumn { OffsetNestedColumn = 0, CommentNestedColumn, NestedColumnCount }; - enum Role { CommentDescriptionRole = Qt::UserRole, FunctionRole }; + enum Column : ut8 { OffsetColumn = 0, FunctionColumn, CommentColumn, ColumnCount }; + enum NestedColumn : ut8 { OffsetNestedColumn = 0, CommentNestedColumn, NestedColumnCount }; + enum Role : ut16 { CommentDescriptionRole = Qt::UserRole, FunctionRole }; CommentsModel(QObject *parent = nullptr); diff --git a/src/widgets/ConsoleWidget.cpp b/src/widgets/ConsoleWidget.cpp index bb56935a..5c99da79 100644 --- a/src/widgets/ConsoleWidget.cpp +++ b/src/widgets/ConsoleWidget.cpp @@ -1,24 +1,25 @@ -#include -#include -#include +#include "ConsoleWidget.h" + +#include "SearchBarWidget.h" +#include "common/Helpers.h" +#include "core/Cutter.h" +#include "shortcuts/ShortcutManager.h" +#include "ui_ConsoleWidget.h" + #include +#include +#include +#include +#include +#include #include #include #include -#include -#include #include -#include -#include "core/Cutter.h" -#include "ConsoleWidget.h" -#include "ui_ConsoleWidget.h" -#include "common/Helpers.h" -#include "common/SvgIconEngine.h" -#include "shortcuts/ShortcutManager.h" #ifdef Q_OS_WIN -# include # include +# include # define dup2 _dup2 # define dup _dup # define fileno _fileno @@ -32,7 +33,7 @@ # define STDIN_PIPE_NAME "%1/cutter-stdin-%2" #endif -enum InputTarget { RizinConsole = 0, Debugee = 1 }; +enum InputTarget : ut8 { RizinConsole = 0, Debugee = 1 }; static const int invalidHistoryPos = -1; @@ -57,8 +58,8 @@ ConsoleWidget::ConsoleWidget(MainWindow *main) setupFont(); // Adjust text margins of consoleOutputTextEdit - QTextDocument *console_docu = ui->outputTextEdit->document(); - console_docu->setDocumentMargin(10); + QTextDocument *consoleDocu = ui->outputTextEdit->document(); + consoleDocu->setDocumentMargin(10); // Ctrl+` and ';' to toggle console widget QAction *toggleConsole = toggleViewAction(); @@ -73,7 +74,7 @@ ConsoleWidget::ConsoleWidget(MainWindow *main) connect(actionClear, &QAction::triggered, this, [this] { ui->outputTextEdit->clear(); ui->outputTextEdit->setExtraSelections({}); - m_searchBar->clear(); + searchBar->clear(); }); addAction(actionClear); @@ -104,15 +105,15 @@ ConsoleWidget::ConsoleWidget(MainWindow *main) &ConsoleWidget::showCustomContextMenu); // Esc clears rzInputLineEdit and debugeeInputLineEdit (like OmniBar) - QShortcut *rizin_clear_shortcut = + QShortcut *rizinClearShortcut = Shortcuts()->makeQShortcut("Console.clearRzInputLineEdit", ui->rzInputLineEdit); - connect(rizin_clear_shortcut, &QShortcut::activated, this, &ConsoleWidget::clear); - rizin_clear_shortcut->setContext(Qt::WidgetShortcut); + connect(rizinClearShortcut, &QShortcut::activated, this, &ConsoleWidget::clear); + rizinClearShortcut->setContext(Qt::WidgetShortcut); - QShortcut *debugee_clear_shortcut = + QShortcut *debugeeClearShortcut = Shortcuts()->makeQShortcut("Console.clearDebugee", ui->debugeeInputLineEdit); - connect(debugee_clear_shortcut, &QShortcut::activated, this, &ConsoleWidget::clear); - debugee_clear_shortcut->setContext(Qt::WidgetShortcut); + connect(debugeeClearShortcut, &QShortcut::activated, this, &ConsoleWidget::clear); + debugeeClearShortcut->setContext(Qt::WidgetShortcut); // Up and down arrows show history historyUpShortcut = Shortcuts()->makeQShortcut("Console.historyUp", ui->rzInputLineEdit); @@ -123,7 +124,7 @@ ConsoleWidget::ConsoleWidget(MainWindow *main) connect(historyDownShortcut, &QShortcut::activated, this, &ConsoleWidget::historyNext); historyDownShortcut->setContext(Qt::WidgetShortcut); - QShortcut *completionShortcut = + const QShortcut *completionShortcut = Shortcuts()->makeQShortcut("Console.complete", ui->rzInputLineEdit); connect(completionShortcut, &QShortcut::activated, this, &ConsoleWidget::triggerCompletion); @@ -135,7 +136,7 @@ ConsoleWidget::ConsoleWidget(MainWindow *main) connect(ui->inputCombo, static_cast(&QComboBox::currentIndexChanged), this, &ConsoleWidget::onIndexChange); - connect(Core(), &CutterCore::debugTaskStateChanged, this, [=]() { + connect(Core(), &CutterCore::debugTaskStateChanged, this, [=, this]() { if (Core()->isRedirectableDebugee()) { ui->inputCombo->setVisible(true); } else { @@ -153,19 +154,24 @@ ConsoleWidget::ConsoleWidget(MainWindow *main) } connect(ui->outputTextEdit, &SearchableTextEdit::textChanged, this, [this] { - if (m_searchBar && m_searchBar->isVisible()) { - QPair range = - ui->outputTextEdit->search(m_searchBar->text(), m_searchBar->options()); - m_searchBar->setRange(range.first, range.second); + if (searchBar && searchBar->isVisible()) { + const QPair range = + ui->outputTextEdit->search(searchBar->text(), searchBar->options()); + searchBar->setRange(range.first, range.second); } }); connect(ui->outputTextEdit, &SearchableTextEdit::updateRequest, this, [this](const QRect &, int dy) { - if (m_searchBar && m_searchBar->isVisible() && dy != 0) { + if (searchBar && searchBar->isVisible() && dy != 0) { ui->outputTextEdit->highlightMatches(); } }); + connect(ui->rzInputLineEdit, &QLineEdit::returnPressed, this, + &ConsoleWidget::onRzInputLineEditReturnPressed); + connect(ui->debugeeInputLineEdit, &QLineEdit::returnPressed, this, + &ConsoleWidget::onDebugeeInputLineEditReturnPressed); + connect(ui->execButton, &QToolButton::clicked, this, &ConsoleWidget::onExecButtonClicked); } ConsoleWidget::~ConsoleWidget() @@ -194,14 +200,14 @@ bool ConsoleWidget::eventFilter(QObject *obj, QEvent *event) if (completer && obj == completer->popup() && // disable up/down shortcuts if completer is shown (event->type() == QEvent::Type::Show || event->type() == QEvent::Type::Hide)) { - bool enabled = !completer->popup()->isVisible(); + const bool enabled = !completer->popup()->isVisible(); if (historyUpShortcut) { historyUpShortcut->setEnabled(enabled); } if (historyDownShortcut) { historyDownShortcut->setEnabled(enabled); } - } else if (m_searchBar && m_searchBar->isVisible() + } else if (searchBar && searchBar->isVisible() && obj == ui->outputTextEdit->verticalScrollBar()) { if (event->type() == QEvent::Show || event->type() == QEvent::Hide) { this->updateSearchBarPosition(); @@ -242,7 +248,7 @@ void ConsoleWidget::focusInputLineEdit() void ConsoleWidget::removeLastLine() { ui->outputTextEdit->setFocus(); - QTextCursor cur = ui->outputTextEdit->textCursor(); + const QTextCursor cur = ui->outputTextEdit->textCursor(); ui->outputTextEdit->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); ui->outputTextEdit->moveCursor(QTextCursor::StartOfLine, QTextCursor::MoveAnchor); ui->outputTextEdit->moveCursor(QTextCursor::End, QTextCursor::KeepAnchor); @@ -253,23 +259,22 @@ void ConsoleWidget::removeLastLine() void ConsoleWidget::executeCommand(const QString &command) { - if (!commandTask.isNull()) { + if (commandTask) { return; } ui->rzInputLineEdit->setEnabled(false); - QString cmd_line = "[" + RzAddressString(Core()->getOffset()) + "]> " + command; - addOutput(cmd_line); + const QString cmdLine = "[" + rzAddressString(Core()->getOffset()) + "]> " + command; + addOutput(cmdLine); - RVA oldOffset = Core()->getOffset(); - commandTask = - QSharedPointer(new CommandTask(command, CommandTask::ColorMode::MODE_16M)); - connect(commandTask.data(), &CommandTask::finished, this, - [this, cmd_line, command, oldOffset](const QString &result) { + const RVA oldOffset = Core()->getOffset(); + commandTask = std::make_shared(command, CommandTask::ColorMode::MODE_16M); + connect(commandTask.get(), &CommandTask::finished, this, + [this, cmdLine, command, oldOffset](const QString &result) { ui->outputTextEdit->appendHtml(CutterCore::ansiEscapeToHtml(result)); scrollOutputToEnd(); historyAdd(command); - commandTask.clear(); + commandTask.reset(); ui->rzInputLineEdit->setEnabled(true); ui->rzInputLineEdit->setFocus(); @@ -297,7 +302,7 @@ void ConsoleWidget::sendToStdin(const QString &input) void ConsoleWidget::onIndexChange() { - int target = ui->inputCombo->currentIndex(); + const int target = ui->inputCombo->currentIndex(); if (target == InputTarget::Debugee) { ui->rzInputLineEdit->setVisible(false); ui->debugeeInputLineEdit->setVisible(true); @@ -315,19 +320,24 @@ void ConsoleWidget::setWrap(bool wrap) : QPlainTextEdit::NoWrap); } -void ConsoleWidget::on_rzInputLineEdit_returnPressed() +void ConsoleWidget::onRzInputLineEditReturnPressed() { - QString input = ui->rzInputLineEdit->text(); + const QString input = ui->rzInputLineEdit->text(); if (input.isEmpty()) { return; } + if (input == "clear" || input == "cls") { + ui->outputTextEdit->clear(); + ui->rzInputLineEdit->clear(); + return; + } executeCommand(input); ui->rzInputLineEdit->clear(); } -void ConsoleWidget::on_debugeeInputLineEdit_returnPressed() +void ConsoleWidget::onDebugeeInputLineEditReturnPressed() { - QString input = ui->debugeeInputLineEdit->text(); + const QString input = ui->debugeeInputLineEdit->text(); if (input.isEmpty()) { return; } @@ -335,16 +345,16 @@ void ConsoleWidget::on_debugeeInputLineEdit_returnPressed() ui->debugeeInputLineEdit->clear(); } -void ConsoleWidget::on_execButton_clicked() +void ConsoleWidget::onExecButtonClicked() { - on_rzInputLineEdit_returnPressed(); + onRzInputLineEditReturnPressed(); } void ConsoleWidget::showCustomContextMenu(const QPoint &pt) { actionWrapLines->setChecked(ui->outputTextEdit->lineWrapMode() == QPlainTextEdit::WidgetWidth); - QMenu *menu = new QMenu(ui->outputTextEdit); + auto *menu = new QMenu(ui->outputTextEdit); menu->addActions(actions); menu->exec(ui->outputTextEdit->mapToGlobal(pt)); menu->deleteLater(); @@ -409,7 +419,7 @@ void ConsoleWidget::updateCompletion() auto current = ui->rzInputLineEdit->text(); auto completions = Core()->autocomplete(current, RZ_LINE_PROMPT_DEFAULT); - int lastSpace = current.lastIndexOf(' '); + const int lastSpace = current.lastIndexOf(' '); if (lastSpace >= 0) { current = current.left(lastSpace + 1); for (auto &s : completions) { @@ -540,29 +550,29 @@ void ConsoleWidget::searchBarHidden() void ConsoleWidget::searchBarShown() { - searchChanged(m_searchBar->text(), m_searchBar->options()); + searchChanged(searchBar->text(), searchBar->options()); } void ConsoleWidget::findNext() { - int index = ui->outputTextEdit->findNext(); - m_searchBar->setCurrentIndex(index); + const int index = ui->outputTextEdit->findNext(); + searchBar->setCurrentIndex(index); } void ConsoleWidget::findPrev() { - int index = ui->outputTextEdit->findPrev(); - m_searchBar->setCurrentIndex(index); + const int index = ui->outputTextEdit->findPrev(); + searchBar->setCurrentIndex(index); } void ConsoleWidget::findLast() { - int index = ui->outputTextEdit->findLast(); - m_searchBar->setCurrentIndex(index); + const int index = ui->outputTextEdit->findLast(); + searchBar->setCurrentIndex(index); } void ConsoleWidget::searchChanged(const QString &text, int options) { - QPair range = ui->outputTextEdit->search(text, options); - m_searchBar->setRange(range.first, range.second); + const QPair range = ui->outputTextEdit->search(text, options); + searchBar->setRange(range.first, range.second); } diff --git a/src/widgets/ConsoleWidget.h b/src/widgets/ConsoleWidget.h index bf658a21..87692360 100644 --- a/src/widgets/ConsoleWidget.h +++ b/src/widgets/ConsoleWidget.h @@ -1,16 +1,14 @@ #ifndef CONSOLEWIDGET_H #define CONSOLEWIDGET_H -#include "core/MainWindow.h" #include "CutterDockWidget.h" -#include "common/CommandTask.h" -#include "common/DirectionalComboBox.h" -#include "SearchBarWidget.h" #include "SearchableDockWidget.h" +#include "common/CommandTask.h" +#include "core/MainWindow.h" -#include -#include #include +#include +#include #include @@ -21,6 +19,9 @@ namespace Ui { class ConsoleWidget; } +/** + * @brief Widget for console to directly run rizin commands + */ class ConsoleWidget : public SearchableDockWidget { Q_OBJECT @@ -56,11 +57,11 @@ public slots: private slots: void setupFont(); - void on_rzInputLineEdit_returnPressed(); - void on_debugeeInputLineEdit_returnPressed(); + void onRzInputLineEditReturnPressed(); + void onDebugeeInputLineEditReturnPressed(); void onIndexChange(); - void on_execButton_clicked(); + void onExecButtonClicked(); void showCustomContextMenu(const QPoint &pt); @@ -93,7 +94,7 @@ private: */ void redirectOutput(); - QSharedPointer commandTask; + std::shared_ptr commandTask; std::unique_ptr ui; QAction *actionWrapLines; diff --git a/src/widgets/CutterDockWidget.cpp b/src/widgets/CutterDockWidget.cpp index f38cc6e2..9a974afe 100644 --- a/src/widgets/CutterDockWidget.cpp +++ b/src/widgets/CutterDockWidget.cpp @@ -1,9 +1,11 @@ #include "CutterDockWidget.h" -#include "core/MainWindow.h" +#include "core/MainWindow.h" +#include "shortcuts/ShortcutManager.h" + +#include #include #include -#include CutterDockWidget::CutterDockWidget(MainWindow *parent, QAction *) : CutterDockWidget(parent) {} @@ -20,8 +22,8 @@ bool CutterDockWidget::event(QEvent *event) if (event->type() == QEvent::Move || event->type() == QEvent::MouseMove) { - Qt::KeyboardModifiers mods = QApplication::keyboardModifiers(); - Qt::KeyboardModifier mod = + const Qt::KeyboardModifiers mods = QApplication::keyboardModifiers(); + const Qt::KeyboardModifier mod = Shortcuts()->convertKeyToModifer(Shortcuts()->getKeySequence("Docking.toggle")); if (mods & mod) { @@ -83,7 +85,7 @@ QWidget *CutterDockWidget::widgetToFocusOnRaise() void CutterDockWidget::updateIsVisibleToUser() { // Check if the user can actually see the widget. - bool visibleToUser = isVisible() && !visibleRegion().isEmpty() && !ignoreVisibility; + const bool visibleToUser = isVisible() && !visibleRegion().isEmpty() && !ignoreVisibility; if (visibleToUser == isVisibleToUserCurrent) { return; } diff --git a/src/widgets/CutterDockWidget.h b/src/widgets/CutterDockWidget.h index d50fe9a9..70d69c77 100644 --- a/src/widgets/CutterDockWidget.h +++ b/src/widgets/CutterDockWidget.h @@ -1,13 +1,18 @@ #ifndef CUTTERWIDGET_H #define CUTTERWIDGET_H -#include "core/CutterCommon.h" #include "common/RefreshDeferrer.h" -#include "shortcuts/ShortcutManager.h" +#include "core/CutterCommon.h" + #include class MainWindow; +/** + * @brief QDockWidget wrapper for Cutter + * + * This should serve as a base class for all dock widgets in main window + */ class CUTTER_EXPORT CutterDockWidget : public QDockWidget { Q_OBJECT @@ -19,7 +24,7 @@ public: explicit CutterDockWidget(MainWindow *parent); ~CutterDockWidget() override; bool eventFilter(QObject *object, QEvent *event) override; - bool isVisibleToUser() { return isVisibleToUserCurrent; } + bool isVisibleToUser() const { return isVisibleToUserCurrent; } /** * @brief Set whether the Widget should be deleted after it is closed. diff --git a/src/widgets/CutterGraphView.cpp b/src/widgets/CutterGraphView.cpp index 18006fca..34b30862 100644 --- a/src/widgets/CutterGraphView.cpp +++ b/src/widgets/CutterGraphView.cpp @@ -1,17 +1,18 @@ #include "CutterGraphView.h" -#include "core/Cutter.h" #include "common/Configuration.h" +#include "core/Cutter.h" #include "dialogs/MultitypeFileSaveDialog.h" -#include "TempConfig.h" #include "shortcuts/ShortcutManager.h" +#include +#include + #include -#include -#include - -static const uint64_t BITMPA_EXPORT_WARNING_SIZE = 32 * 1024 * 1024; +namespace { +const uint64_t bitmapExportWarningSize = 32 * 1024 * 1024; +} #ifndef NDEBUG # define GRAPH_GRID_DEBUG_MODES true @@ -38,7 +39,7 @@ CutterGraphView::CutterGraphView(QWidget *parent) horizontalLayoutAction = layoutMenu->addAction(tr("Horizontal")); horizontalLayoutAction->setCheckable(true); - static const std::pair LAYOUT_CONFIG[] = { + static const std::pair layoutConfig[] = { { tr("Grid narrow"), GraphView::Layout::GridNarrow }, { tr("Grid medium"), GraphView::Layout::GridMedium }, { tr("Grid wide"), GraphView::Layout::GridWide } @@ -65,11 +66,11 @@ CutterGraphView::CutterGraphView(QWidget *parent) }; layoutMenu->addSeparator(); connect(horizontalLayoutAction, &QAction::toggled, this, &CutterGraphView::updateLayout); - QActionGroup *layoutGroup = new QActionGroup(layoutMenu); - for (auto &item : LAYOUT_CONFIG) { + auto *layoutGroup = new QActionGroup(layoutMenu); + for (auto &item : layoutConfig) { auto action = layoutGroup->addAction(item.first); action->setCheckable(true); - GraphView::Layout layout = item.second; + const GraphView::Layout layout = item.second; if (layout == this->graphLayout) { action->setChecked(true); } @@ -91,14 +92,14 @@ QPoint CutterGraphView::getTextOffset(int line) const void CutterGraphView::initFont() { setFont(Config()->getFont()); - QFontMetricsF metrics(font()); + const QFontMetricsF metrics(font()); baseline = int(metrics.ascent()); #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - ACharWidth = metrics.width('A'); + charWidthA = metrics.width('A'); #else - ACharWidth = metrics.horizontalAdvance('A'); + charWidthA = metrics.horizontalAdvance('A'); #endif - padding = ACharWidth; + padding = charWidthA; charHeight = static_cast(metrics.height()); charOffset = 0; mFontMetrics.reset(new CachedFontMetrics(font())); @@ -106,7 +107,7 @@ void CutterGraphView::initFont() void CutterGraphView::zoom(QPointF mouseRelativePos, double velocity) { - qreal newScale = getViewScale() * std::pow(1.25, velocity); + const qreal newScale = getViewScale() * std::pow(1.25, velocity); setZoom(mouseRelativePos, newScale); } @@ -158,7 +159,7 @@ void CutterGraphView::updateColors() graphNodeColor = ConfigColor("gui.border"); backgroundColor = ConfigColor("gui.background"); disassemblySelectionColor = ConfigColor("lineHighlight"); - PCSelectionColor = ConfigColor("highlightPC"); + pcSelectionColor = ConfigColor("highlightPC"); jmpColor = ConfigColor("graph.trufae"); brtrueColor = ConfigColor("graph.true"); @@ -205,8 +206,8 @@ bool CutterGraphView::event(QEvent *event) { switch (event->type()) { case QEvent::ShortcutOverride: { - QKeyEvent *keyEvent = static_cast(event); - qhelpers::KeyComb key = Qt::Key(keyEvent->key()) | keyEvent->modifiers(); + const auto *keyEvent = static_cast(event); + const qhelpers::KeyComb key = Qt::Key(keyEvent->key()) | keyEvent->modifiers(); if (Shortcuts()->matchesKeySequence("General.zoomOut", key) || Shortcuts()->matchesKeySequence("General.zoomReset", key) || Shortcuts()->matchesKeySequence("General.zoomIn", key)) { @@ -216,8 +217,8 @@ bool CutterGraphView::event(QEvent *event) break; } case QEvent::KeyPress: { - QKeyEvent *keyEvent = static_cast(event); - qhelpers::KeyComb key = Qt::Key(keyEvent->key()) | keyEvent->modifiers(); + const auto *keyEvent = static_cast(event); + const qhelpers::KeyComb key = Qt::Key(keyEvent->key()) | keyEvent->modifiers(); if (Shortcuts()->matchesKeySequence("General.zoomIn", key)) { zoomIn(); return true; @@ -272,7 +273,7 @@ void CutterGraphView::wheelEvent(QWheelEvent *event) if (Qt::ControlModifier == event->modifiers()) { const QPoint numDegrees = event->angleDelta() / 8; if (!numDegrees.isNull()) { - int numSteps = numDegrees.y() / 15; + const int numSteps = numDegrees.y() / 15; #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) QPointF relativeMousePos = event->pos(); @@ -314,11 +315,11 @@ void CutterGraphView::mouseMoveEvent(QMouseEvent *event) emit graphMoved(); } -void CutterGraphView::exportGraph(QString filePath, GraphExportType exportType, +void CutterGraphView::exportGraph(const QString &filePath, GraphExportType exportType, RzCoreGraphType graphType, RVA address) { - bool graphTransparent = Config()->getBitmapTransparentState(); - double graphScaleFactor = Config()->getBitmapExportScaleFactor(); + const bool graphTransparent = Config()->getBitmapTransparentState(); + const double graphScaleFactor = Config()->getBitmapExportScaleFactor(); switch (exportType) { case GraphExportType::Png: this->saveAsBitmap(filePath, "png", graphScaleFactor, graphTransparent); @@ -364,7 +365,7 @@ void CutterGraphView::exportGraph(QString filePath, GraphExportType exportType, } } -void CutterGraphView::exportRzTextGraph(QString filePath, RzCoreGraphType type, +void CutterGraphView::exportRzTextGraph(const QString &filePath, RzCoreGraphType type, RzCoreGraphFormat format, RVA address) { char *string = Core()->getTextualGraphAt(type, format, address); @@ -398,9 +399,10 @@ bool CutterGraphView::graphIsBitamp(CutterGraphView::GraphExportType type) Q_DECLARE_METATYPE(CutterGraphView::GraphExportType); -void CutterGraphView::showExportGraphDialog(QString defaultName, RzCoreGraphType type, RVA address) +void CutterGraphView::showExportGraphDialog(const QString &defaultName, RzCoreGraphType type, + RVA address) { - qWarning() << defaultName << " - " << type << " addr " << RzAddressString(address); + qWarning() << defaultName << " - " << type << " addr " << rzAddressString(address); QVector types = { { tr("PNG (*.png)"), "png", QVariant::fromValue(GraphExportType::Png) }, { tr("JPEG (*.jpg)"), "jpg", QVariant::fromValue(GraphExportType::Jpeg) }, @@ -414,7 +416,7 @@ void CutterGraphView::showExportGraphDialog(QString defaultName, RzCoreGraphType { tr("RZ JSON (*.json)"), "json", QVariant::fromValue(GraphExportType::RzJson) }, }); - bool hasGraphviz = !QStandardPaths::findExecutable("dot").isEmpty() + const bool hasGraphviz = !QStandardPaths::findExecutable("dot").isEmpty() || !QStandardPaths::findExecutable("xdot").isEmpty(); if (hasGraphviz) { types.append({ { tr("Graphviz json (*.json)"), "json", @@ -448,8 +450,8 @@ void CutterGraphView::showExportGraphDialog(QString defaultName, RzCoreGraphType auto exportType = selectedType.data.value(); if (graphIsBitamp(exportType)) { - uint64_t bitmapSize = uint64_t(width) * uint64_t(height); - if (bitmapSize > BITMPA_EXPORT_WARNING_SIZE) { + const uint64_t bitmapSize = uint64_t(width) * uint64_t(height); + if (bitmapSize > bitmapExportWarningSize) { auto answer = QMessageBox::question(this, tr("Graph Export"), tr("Do you really want to export %1 x %2 = %3 pixel " @@ -463,6 +465,6 @@ void CutterGraphView::showExportGraphDialog(QString defaultName, RzCoreGraphType } } - QString filePath = dialog.selectedFiles().first(); + const QString filePath = dialog.selectedFiles().first(); exportGraph(filePath, exportType, type, address); } diff --git a/src/widgets/CutterGraphView.h b/src/widgets/CutterGraphView.h index 36958743..aa7ce0cd 100644 --- a/src/widgets/CutterGraphView.h +++ b/src/widgets/CutterGraphView.h @@ -1,15 +1,14 @@ #ifndef CUTTER_GRAPHVIEW_H #define CUTTER_GRAPHVIEW_H -#include -#include -#include -#include +#include "common/CachedFontMetrics.h" +#include "widgets/GraphView.h" #include - -#include "widgets/GraphView.h" -#include "common/CachedFontMetrics.h" +#include +#include +#include +#include /** * @brief Common Cutter specific graph functionality. @@ -21,7 +20,7 @@ public: CutterGraphView(QWidget *parent); virtual bool event(QEvent *event) override; - enum class GraphExportType { + enum class GraphExportType : ut8 { Png, Jpeg, Svg, @@ -44,7 +43,7 @@ public: * RZ_CORE_GRAPH_TYPE_IMPORT * @param address - object address (if global set it to RVA_INVALID) */ - void exportGraph(QString filePath, GraphExportType exportType, RzCoreGraphType graphType, + void exportGraph(const QString &filePath, GraphExportType exportType, RzCoreGraphType graphType, RVA address = RVA_INVALID); /** @@ -54,7 +53,7 @@ public: * @param format - graph format, example RZ_CORE_GRAPH_FORMAT_DOT or RZ_CORE_GRAPH_FORMAT_GML * @param address - object address (if global set it to RVA_INVALID) */ - void exportRzTextGraph(QString filePath, RzCoreGraphType type, RzCoreGraphFormat format, + void exportRzTextGraph(const QString &filePath, RzCoreGraphType type, RzCoreGraphFormat format, RVA address); static bool graphIsBitamp(GraphExportType type); /** @@ -63,7 +62,7 @@ public: * @param type - graph type, example RZ_CORE_GRAPH_TYPE_FUNCALL or RZ_CORE_GRAPH_TYPE_IMPORT * @param address - object address (if global set it to RVA_INVALID) */ - void showExportGraphDialog(QString defaultName, RzCoreGraphType type, + void showExportGraphDialog(const QString &defaultName, RzCoreGraphType type, RVA address = RVA_INVALID); public slots: @@ -114,7 +113,7 @@ protected: // Font data std::unique_ptr> mFontMetrics; - qreal ACharWidth; // width of character A + qreal charWidthA; // width of character A int charHeight; int charOffset; int baseline; @@ -124,7 +123,7 @@ protected: QColor disassemblyBackgroundColor; QColor disassemblySelectedBackgroundColor; QColor disassemblySelectionColor; - QColor PCSelectionColor; + QColor pcSelectionColor; QColor jmpColor; QColor brtrueColor; QColor brfalseColor; diff --git a/src/widgets/CutterTreeView.cpp b/src/widgets/CutterTreeView.cpp index 233cdd80..3e543ecc 100644 --- a/src/widgets/CutterTreeView.cpp +++ b/src/widgets/CutterTreeView.cpp @@ -1,4 +1,5 @@ #include "CutterTreeView.h" + #include "ui_CutterTreeView.h" CutterTreeView::CutterTreeView(QWidget *parent) : QTreeView(parent), ui(new Ui::CutterTreeView()) diff --git a/src/widgets/CutterTreeView.h b/src/widgets/CutterTreeView.h index 33600bc3..42b36322 100644 --- a/src/widgets/CutterTreeView.h +++ b/src/widgets/CutterTreeView.h @@ -3,14 +3,18 @@ #include "core/CutterCommon.h" -#include #include #include +#include + namespace Ui { class CutterTreeView; } +/** + * @brief QTreeView wrapper for Cutter for default style and functionality + */ class CUTTER_EXPORT CutterTreeView : public QTreeView { Q_OBJECT diff --git a/src/widgets/Dashboard.cpp b/src/widgets/Dashboard.cpp index 95c064b2..7bb11bb9 100644 --- a/src/widgets/Dashboard.cpp +++ b/src/widgets/Dashboard.cpp @@ -1,23 +1,22 @@ #include "Dashboard.h" -#include "ui_Dashboard.h" -#include "common/Helpers.h" -#include "common/JsonModel.h" -#include "common/TempConfig.h" -#include "dialogs/VersionInfoDialog.h" -#include "core/MainWindow.h" #include "CutterTreeView.h" +#include "common/Helpers.h" +#include "common/Json.h" +#include "core/MainWindow.h" +#include "dialogs/VersionInfoDialog.h" +#include "ui_Dashboard.h" #include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include Dashboard::Dashboard(MainWindow *main) : CutterDockWidget(main), ui(new Ui::Dashboard) @@ -25,6 +24,11 @@ Dashboard::Dashboard(MainWindow *main) : CutterDockWidget(main), ui(new Ui::Dash ui->setupUi(this); connect(Core(), &CutterCore::refreshAll, this, &Dashboard::updateContents); + + connect(ui->certificateButton, &QPushButton::clicked, this, + &Dashboard::onCertificateButtonClicked); + connect(ui->versioninfoButton, &QPushButton::clicked, this, + &Dashboard::onVersioninfoButtonClicked); } Dashboard::~Dashboard() {} @@ -32,17 +36,17 @@ Dashboard::~Dashboard() {} void Dashboard::updateContents() { RzCoreLocked core(Core()); - int fd = rz_io_fd_get_current(core->io); - RzIODesc *desc = rz_io_desc_get(core->io, fd); + const int fd = rz_io_fd_get_current(core->io); + const RzIODesc *desc = rz_io_desc_get(core->io, fd); setPlainText(this->ui->modeEdit, desc ? rz_str_rwx_i(desc->perm & RZ_PERM_RWX) : ""); RzBinFile *bf = rz_bin_cur(core->bin); if (bf) { setPlainText(this->ui->compilationDateEdit, rz_core_bin_get_compile_time(bf)); if (bf->o) { - char *relco_buf = sdb_get(bf->o->kv, "elf.relro"); - if (RZ_STR_ISNOTEMPTY(relco_buf)) { - QString relro = QString(relco_buf).section(QLatin1Char(' '), 0, 0); + const char *relcoBuf = sdb_get(bf->o->kv, "elf.relro"); + if (RZ_STR_ISNOTEMPTY(relcoBuf)) { + QString relro = QString(relcoBuf).section(QLatin1Char(' '), 0, 0); relro[0] = relro[0].toUpper(); setPlainText(this->ui->relroEdit, relro); } else { @@ -66,8 +70,8 @@ void Dashboard::updateContents() setPlainText(ui->subsysEdit, binInfo ? binInfo->subsystem : ""); setPlainText(ui->compilerEdit, binInfo ? binInfo->compiler : ""); setPlainText(ui->bitsEdit, binInfo ? QString::number(binInfo->bits) : ""); - setPlainText(ui->baddrEdit, bf ? RzAddressString(rz_bin_file_get_baddr(bf)) : ""); - setPlainText(ui->sizeEdit, bf ? qhelpers::formatBytecount(bf->size) : ""); + setPlainText(ui->baddrEdit, bf ? rzAddressString(rz_bin_file_get_baddr(bf)) : ""); + setPlainText(ui->sizeEdit, bf ? qhelpers::formatByteCount(bf->size) : ""); setPlainText(ui->fdEdit, bf ? QString::number(bf->fd) : ""); // Setting the value of "Endianness" @@ -78,8 +82,8 @@ void Dashboard::updateContents() setRzBinInfo(binInfo); // Setting the value of "static" - int static_value = rz_bin_is_static(core->bin); - setPlainText(ui->staticEdit, setBoolText(static_value)); + const int staticValue = rz_bin_is_static(core->bin); + setPlainText(ui->staticEdit, setBoolText(staticValue)); const RzPVector *hashes = bf ? rz_bin_file_compute_hashes(core->bin, bf, UT64_MAX) : nullptr; @@ -90,7 +94,7 @@ void Dashboard::updateContents() // Define dynamic components to hold the hashes hashesWidget = new QWidget(); - QFormLayout *hashesLayout = new QFormLayout; + auto *hashesLayout = new QFormLayout; hashesWidget->setLayout(hashesLayout); ui->hashesVerticalLayout->addWidget(hashesWidget); @@ -98,10 +102,10 @@ void Dashboard::updateContents() if (hashes != nullptr) { for (const auto &hash : CutterPVector(hashes)) { // Create a bold QString with the hash name uppercased - QString label = QString("%1:").arg(QString(hash->type).toUpper()); + const QString label = QString("%1:").arg(QString(hash->type).toUpper()); // Define a Read-Only line edit to display the hash value - QLineEdit *hashLineEdit = new QLineEdit(); + auto *hashLineEdit = new QLineEdit(); hashLineEdit->setReadOnly(true); hashLineEdit->setText(hash->hex); @@ -114,15 +118,15 @@ void Dashboard::updateContents() } } - st64 fcns = rz_list_length(rz_analysis_function_list(core->analysis)); - st64 strs = rz_flag_count(core->flags, "str.*"); - st64 syms = rz_flag_count(core->flags, "sym.*"); - st64 imps = rz_flag_count(core->flags, "sym.imp.*"); - st64 code = rz_core_analysis_code_count(core); - st64 covr = rz_core_analysis_coverage_count(core); - st64 call = rz_core_analysis_calls_count(core); - ut64 xrfs = rz_analysis_xrefs_count(core->analysis); - double precentage = (code > 0) ? (covr * 100.0 / code) : 0; + const st64 fcns = rz_list_length(rz_analysis_function_list(core->analysis)); + const st64 strs = rz_flag_count(core->flags, "str.*"); + const st64 syms = rz_flag_count(core->flags, "sym.*"); + const st64 imps = rz_flag_count(core->flags, "sym.imp.*"); + const st64 code = rz_core_analysis_code_count(core); + const st64 covr = rz_core_analysis_coverage_count(core); + const st64 call = rz_core_analysis_calls_count(core); + const ut64 xrfs = rz_analysis_xrefs_count(core->analysis); + const double precentage = (code > 0) ? (covr * 100.0 / code) : 0; setPlainText(ui->functionsLineEdit, QString::number(fcns)); setPlainText(ui->xRefsLineEdit, QString::number(xrfs)); @@ -156,7 +160,7 @@ void Dashboard::updateContents() ui->versioninfoButton->setEnabled(Core()->existsFileInfo()); } -void Dashboard::on_certificateButton_clicked() +void Dashboard::onCertificateButtonClicked() { QDialog dialog(this); auto view = new QTreeWidget(&dialog); @@ -178,7 +182,7 @@ void Dashboard::on_certificateButton_clicked() dialog.exec(); } -void Dashboard::on_versioninfoButton_clicked() +void Dashboard::onVersioninfoButtonClicked() { static QDialog *infoDialog = nullptr; @@ -192,11 +196,6 @@ void Dashboard::on_versioninfoButton_clicked() } } -/** - * @brief Set the text of a QLineEdit. If no text, then "N/A" is set. - * @param textBox - * @param text - */ void Dashboard::setPlainText(QLineEdit *textBox, const QString &text) { if (!text.isEmpty()) { @@ -208,10 +207,6 @@ void Dashboard::setPlainText(QLineEdit *textBox, const QString &text) textBox->setCursorPosition(0); } -/** - * @brief Setting boolean values of binary information in dashboard - * @param RzBinInfo - */ void Dashboard::setRzBinInfo(const RzBinInfo *binInfo) { setPlainText(ui->vaEdit, binInfo ? setBoolText(binInfo->has_va) : ""); @@ -224,10 +219,6 @@ void Dashboard::setRzBinInfo(const RzBinInfo *binInfo) setPlainText(ui->relocsEdit, binInfo ? setBoolText(RZ_BIN_DBG_RELOCS & binInfo->dbg_info) : ""); } -/** - * @brief Set the text of a QLineEdit as True, False - * @param boolean value - */ QString Dashboard::setBoolText(bool value) { return value ? tr("True") : tr("False"); diff --git a/src/widgets/Dashboard.h b/src/widgets/Dashboard.h index dbd5a280..5f88f768 100644 --- a/src/widgets/Dashboard.h +++ b/src/widgets/Dashboard.h @@ -1,11 +1,12 @@ #ifndef DASHBOARD_H #define DASHBOARD_H -#include -#include -#include "core/Cutter.h" #include "CutterDockWidget.h" +#include + +#include + QT_BEGIN_NAMESPACE QT_FORWARD_DECLARE_CLASS(QLineEdit) QT_FORWARD_DECLARE_CLASS(QJsonObject) @@ -17,6 +18,9 @@ namespace Ui { class Dashboard; } +/** + * @brief Dock widget that contains info about the loaded binary + */ class Dashboard : public CutterDockWidget { Q_OBJECT @@ -27,16 +31,29 @@ public: private slots: void updateContents(); - void on_certificateButton_clicked(); - void on_versioninfoButton_clicked(); + void onCertificateButtonClicked(); + void onVersioninfoButtonClicked(); private: std::unique_ptr ui; - void setPlainText(QLineEdit *textBox, const QString &text); - void setRzBinInfo(const RzBinInfo *binInfo); - QString setBoolText(bool value); - QWidget *hashesWidget = nullptr; + + /** + * @brief Set the text of a QLineEdit. If no text, then "N/A" is set. + * @param textBox LineEdit to set @p text to + * @param text The text to set to @p textBox + */ + void setPlainText(QLineEdit *textBox, const QString &text); + /** + * @brief Setting boolean values of binary information in dashboard + * @param RzBinInfo + */ + void setRzBinInfo(const RzBinInfo *binInfo); + /** + * @brief Set the text of a QLineEdit as True, False + * @param boolean value + */ + QString setBoolText(bool value); }; #endif // DASHBOARD_H diff --git a/src/widgets/DebugActions.cpp b/src/widgets/DebugActions.cpp index ede38ba0..3ba2b4c7 100644 --- a/src/widgets/DebugActions.cpp +++ b/src/widgets/DebugActions.cpp @@ -1,30 +1,32 @@ #include "DebugActions.h" + +#include "common/Configuration.h" +#include "common/Helpers.h" #include "core/MainWindow.h" #include "dialogs/AttachProcDialog.h" #include "dialogs/NativeDebugDialog.h" -#include "common/Configuration.h" -#include "common/Helpers.h" #include "shortcuts/ShortcutManager.h" -#include -#include -#include #include +#include +#include +#include +#include #include #include -#include -DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) : QObject(main), main(main) +DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) + : QObject(main), continueUntilButton(new QToolButton), main(main) { setObjectName("DebugActions"); // setIconSize(QSize(16, 16)); // define icons - QIcon startEmulIcon = QIcon(":/img/icons/play_light_emul.svg"); - QIcon startAttachIcon = QIcon(":/img/icons/play_light_attach.svg"); - QIcon startRemoteIcon = QIcon(":/img/icons/play_light_remote.svg"); - QIcon continueBackIcon = QIcon(":/img/icons/reverse_continue.svg"); - QIcon stepBackIcon = QIcon(":/img/icons/reverse_step.svg"); + const QIcon startEmulIcon = QIcon(":/img/icons/play_light_emul.svg"); + const QIcon startAttachIcon = QIcon(":/img/icons/play_light_attach.svg"); + const QIcon startRemoteIcon = QIcon(":/img/icons/play_light_remote.svg"); + const QIcon continueBackIcon = QIcon(":/img/icons/reverse_continue.svg"); + const QIcon stepBackIcon = QIcon(":/img/icons/reverse_step.svg"); startTraceIcon = QIcon(":/img/icons/start_trace.svg"); stopTraceIcon = QIcon(":/img/icons/stop_trace.svg"); stopIcon = QIcon(":/img/icons/media-stop_light.svg"); @@ -35,15 +37,15 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) : QObject(main), suspendIcon = QIcon(":/img/icons/media-suspend_light.svg"); // define action labels - QString startEmulLabel = tr("Start emulation"); - QString startAttachLabel = tr("Attach to process"); - QString startRemoteLabel = tr("Connect to a remote debugger"); - QString stopDebugLabel = tr("Stop debug"); - QString stopEmulLabel = tr("Stop emulation"); - QString restartEmulLabel = tr("Restart emulation"); - QString continueUMLabel = tr("Continue until main"); - QString continueUCLabel = tr("Continue until call"); - QString continueUSLabel = tr("Continue until syscall"); + const QString startEmulLabel = tr("Start emulation"); + const QString startAttachLabel = tr("Attach to process"); + const QString startRemoteLabel = tr("Connect to a remote debugger"); + const QString stopDebugLabel = tr("Stop debug"); + const QString stopEmulLabel = tr("Stop emulation"); + const QString restartEmulLabel = tr("Restart emulation"); + const QString continueUMLabel = tr("Continue until main"); + const QString continueUCLabel = tr("Continue until call"); + const QString continueUSLabel = tr("Continue until syscall"); startTraceLabel = tr("Start trace session"); stopTraceLabel = tr("Stop trace session"); suspendLabel = tr("Suspend the process"); @@ -73,10 +75,10 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) : QObject(main), actionContinueUntilSyscall = new QAction(continueUSLabel, this); actionTrace = new QAction(startTraceIcon, startTraceLabel, this); - QToolButton *startButton = new QToolButton; + auto *startButton = new QToolButton; startButton->setPopupMode(QToolButton::MenuButtonPopup); connect(startButton, &QToolButton::triggered, startButton, &QToolButton::setDefaultAction); - QMenu *startMenu = new QMenu(startButton); + auto *startMenu = new QMenu(startButton); startMenu->addAction(actionStart); startMenu->addAction(actionStartEmul); @@ -85,11 +87,10 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) : QObject(main), startButton->setDefaultAction(actionStart); startButton->setMenu(startMenu); - continueUntilButton = new QToolButton; continueUntilButton->setPopupMode(QToolButton::MenuButtonPopup); connect(continueUntilButton, &QToolButton::triggered, continueUntilButton, &QToolButton::setDefaultAction); - QMenu *continueUntilMenu = new QMenu(continueUntilButton); + auto *continueUntilMenu = new QMenu(continueUntilButton); continueUntilMenu->addAction(actionContinueUntilMain); continueUntilMenu->addAction(actionContinueUntilCall); continueUntilMenu->addAction(actionContinueUntilSyscall); @@ -142,10 +143,10 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) : QObject(main), msgBox.exec(); }); - connect(Core(), &CutterCore::debugTaskStateChanged, this, [=]() { - bool disableToolbar = Core()->isDebugTaskInProgress(); + connect(Core(), &CutterCore::debugTaskStateChanged, this, [=, this]() { + const bool disableToolbar = Core()->isDebugTaskInProgress(); if (Core()->currentlyDebugging) { - for (QAction *a : toggleActions) { + for (auto a : std::as_const(toggleActions)) { a->setDisabled(disableToolbar); } // Suspend should only be available when other icons are disabled @@ -156,19 +157,19 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) : QObject(main), actionContinue->setText(continueLabel); actionContinue->setIcon(continueIcon); } - for (QAction *a : reverseActions) { + for (auto a : std::as_const(reverseActions)) { a->setVisible(Core()->currentlyTracing); a->setDisabled(disableToolbar); } } else { - for (QAction *a : toggleConnectionActions) { + for (auto a : std::as_const(toggleConnectionActions)) { a->setDisabled(disableToolbar); } } }); connect(actionStop, &QAction::triggered, Core(), &CutterCore::stopDebug); - connect(actionStop, &QAction::triggered, [=]() { + connect(actionStop, &QAction::triggered, [=, this]() { actionStart->setVisible(true); actionStartEmul->setVisible(true); actionAttach->setVisible(true); @@ -192,7 +193,7 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) : QObject(main), connect(actionStartRemote, &QAction::triggered, this, &DebugActions::attachRemoteDialog); connect(Core(), &CutterCore::attachedRemote, this, &DebugActions::onAttachedRemoteDebugger); connect(actionStartEmul, &QAction::triggered, Core(), &CutterCore::startEmulation); - connect(actionStartEmul, &QAction::triggered, [=]() { + connect(actionStartEmul, &QAction::triggered, [=, this]() { setAllActionsVisible(true); actionStart->setVisible(false); actionAttach->setVisible(false); @@ -204,7 +205,7 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) : QObject(main), actionStartEmul->setIcon(restartIcon); actionStop->setText(stopEmulLabel); // Reverse debug actions aren't visible until we start tracing - for (QAction *a : reverseActions) { + for (auto a : std::as_const(reverseActions)) { a->setVisible(false); } }); @@ -224,7 +225,7 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) : QObject(main), } }); - connect(actionTrace, &QAction::triggered, Core(), [=]() { + connect(actionTrace, &QAction::triggered, Core(), [=, this]() { // Check if a debug session was created to switch between start and stop if (!Core()->currentlyTracing) { Core()->startTraceSession(); @@ -266,20 +267,20 @@ void DebugActions::showDebugWarning() void DebugActions::continueUntilMain() { - RzCoreLocked core(Core()->lock()); - RzFlagItem *main_flag = rz_flag_get(core->flags, "sym.main"); - if (!main_flag) { - main_flag = rz_flag_get(core->flags, "main"); - if (!main_flag) { + auto core = Core()->lock(); + const RzFlagItem *mainFlag = rz_flag_get(core->flags, "sym.main"); + if (!mainFlag) { + mainFlag = rz_flag_get(core->flags, "main"); + if (!mainFlag) { return; } } - Core()->continueUntilDebug(main_flag->offset); + Core()->continueUntilDebug(mainFlag->offset); } void DebugActions::attachRemoteDebugger() { - QString stopAttachLabel = tr("Detach from process"); + const QString stopAttachLabel = tr("Detach from process"); // Hide unwanted buttons setAllActionsVisible(true); actionStart->setVisible(false); @@ -291,8 +292,9 @@ void DebugActions::attachRemoteDebugger() void DebugActions::onAttachedRemoteDebugger(bool successfully) { // TODO(#2829): Investigate why this is happening - if (remoteDialog == nullptr) + if (remoteDialog == nullptr) { return; + } if (!successfully) { QMessageBox msgBox(main); @@ -319,7 +321,7 @@ void DebugActions::attachRemoteDialog() if (!remoteDialog) { remoteDialog = new RemoteDebugDialog(main); } - QMessageBox msgBox(main); + const QMessageBox msgBox(main); bool success = false; while (!success) { success = true; @@ -343,7 +345,7 @@ void DebugActions::attachProcessDialog() while (!success) { success = true; if (dialog.exec()) { - int pid = dialog.getPID(); + const int pid = dialog.getPID(); if (pid >= 0) { attachProcess(pid); } else { @@ -358,7 +360,7 @@ void DebugActions::attachProcessDialog() void DebugActions::attachProcess(int pid) { - QString stopAttachLabel = tr("Detach from process"); + const QString stopAttachLabel = tr("Detach from process"); // hide unwanted buttons setAllActionsVisible(true); actionStart->setVisible(false); @@ -373,9 +375,9 @@ void DebugActions::attachProcess(int pid) void DebugActions::startDebug() { // check if file is executable before starting debug - QString filename = Core()->getConfig("file.path"); + const QString filename = Core()->getConfig("file.path"); - QFileInfo info(filename); + const QFileInfo info(filename); if (!Core()->currentlyDebugging && !info.isExecutable()) { QMessageBox msgBox(main); msgBox.setText(tr("File '%1' does not have executable permissions.").arg(filename)); @@ -419,7 +421,7 @@ void DebugActions::startDebug() setButtonVisibleIfMainExists(); // Reverse debug actions aren't visible until we start tracing - for (QAction *a : reverseActions) { + for (auto a : std::as_const(reverseActions)) { a->setVisible(false); } actionTrace->setText(startTraceLabel); @@ -430,14 +432,11 @@ void DebugActions::startDebug() void DebugActions::setAllActionsVisible(bool visible) { - for (QAction *action : allActions) { + for (auto action : std::as_const(allActions)) { action->setVisible(visible); } } -/** - * @brief When theme changed, change icons which have a special version for the theme. - */ void DebugActions::chooseThemeIcons() { // List of QActions which have alternative icons in different themes diff --git a/src/widgets/DebugActions.h b/src/widgets/DebugActions.h index ac5bc92b..7971627b 100644 --- a/src/widgets/DebugActions.h +++ b/src/widgets/DebugActions.h @@ -1,6 +1,6 @@ -#pragma once +#ifndef DEBUG_ACTIONS_H +#define DEBUG_ACTIONS_H -#include "core/Cutter.h" #include "dialogs/RemoteDebugDialog.h" #include @@ -79,5 +79,11 @@ private slots: void onAttachedRemoteDebugger(bool successfully); void setAllActionsVisible(bool visible); void setButtonVisibleIfMainExists(); + + /** + * @brief When theme changed, change icons which have a special version for the theme. + */ void chooseThemeIcons(); }; + +#endif // DEBUG_ACTIONS_H diff --git a/src/widgets/DecompilerWidget.cpp b/src/widgets/DecompilerWidget.cpp index 69799444..02dc90d8 100644 --- a/src/widgets/DecompilerWidget.cpp +++ b/src/widgets/DecompilerWidget.cpp @@ -1,30 +1,30 @@ #include "DecompilerWidget.h" -#include "ui_DecompilerWidget.h" -#include "menus/DecompilerContextMenu.h" #include "common/Configuration.h" -#include "common/Helpers.h" -#include "common/TempConfig.h" -#include "common/SelectionHighlight.h" -#include "common/Decompiler.h" #include "common/CutterSeekable.h" -#include "core/MainWindow.h" +#include "common/Decompiler.h" #include "common/DecompilerHighlighter.h" +#include "common/Helpers.h" +#include "common/SelectionHighlight.h" +#include "core/MainWindow.h" +#include "menus/DecompilerContextMenu.h" #include "shortcuts/ShortcutManager.h" +#include "ui_DecompilerWidget.h" -#include -#include -#include +#include #include #include -#include +#include #include -#include +#include +#include +#include DecompilerWidget::DecompilerWidget(MainWindow *main) : MemoryDockWidget(MemoryWidgetType::Decompiler, main), mCtxMenu(new DecompilerContextMenu(this, main)), ui(new Ui::DecompilerWidget), + refreshDeferrer(createRefreshDeferrer([this]() { doRefresh(); })), decompilerBusy(false), seekFromCursor(false), historyPos(0), @@ -49,15 +49,13 @@ DecompilerWidget::DecompilerWidget(MainWindow *main) connect(Core(), &CutterCore::registersChanged, this, &DecompilerWidget::highlightPC); connect(mCtxMenu, &DecompilerContextMenu::copy, this, &DecompilerWidget::copy); - refreshDeferrer = createRefreshDeferrer([this]() { doRefresh(); }); - auto decompilers = Core()->getDecompilers(); QString selectedDecompilerId = Config()->getSelectedDecompiler(); if (selectedDecompilerId.isEmpty()) { // If no decompiler was previously chosen. set rz-ghidra as default decompiler selectedDecompilerId = "ghidra"; } - for (Decompiler *dec : decompilers) { + for (const Decompiler *dec : std::as_const(decompilers)) { ui->decompilerComboBox->addItem(dec->getName(), dec->getId()); if (dec->getId() == selectedDecompilerId) { ui->decompilerComboBox->setCurrentIndex(ui->decompilerComboBox->count() - 1); @@ -119,11 +117,9 @@ ut64 DecompilerWidget::findReference(size_t pos) { size_t closestPos = SIZE_MAX; ut64 closestOffset = RVA_INVALID; - void *iter; - rz_vector_foreach(&code->annotations, iter) + RzCodeAnnotation *annotation = nullptr; + CutterRzVectorForeach(&code->annotations, annotation, RzCodeAnnotation) { - RzCodeAnnotation *annotation = (RzCodeAnnotation *)iter; - if (!(annotation->type == RZ_CODE_ANNOTATION_TYPE_GLOBAL_VARIABLE) || annotation->start > pos || annotation->end <= pos) { continue; @@ -141,11 +137,9 @@ ut64 DecompilerWidget::offsetForPosition(size_t pos) { size_t closestPos = SIZE_MAX; ut64 closestOffset = mCtxMenu->getFirstOffsetInLine(); - void *iter; - rz_vector_foreach(&code->annotations, iter) + RzCodeAnnotation *annotation; + CutterRzVectorForeach(&code->annotations, annotation, RzCodeAnnotation) { - RzCodeAnnotation *annotation = (RzCodeAnnotation *)iter; - if (!(annotation->type == RZ_CODE_ANNOTATION_TYPE_OFFSET) || annotation->start > pos || annotation->end <= pos) { continue; @@ -163,10 +157,10 @@ size_t DecompilerWidget::positionForOffset(ut64 offset) { size_t closestPos = SIZE_MAX; ut64 closestOffset = UT64_MAX; - void *iter; - rz_vector_foreach(&code->annotations, iter) + RzCodeAnnotation *annotation = nullptr; + + CutterRzVectorForeach(&code->annotations, annotation, RzCodeAnnotation) { - RzCodeAnnotation *annotation = (RzCodeAnnotation *)iter; if (annotation->type != RZ_CODE_ANNOTATION_TYPE_OFFSET || annotation->offset.offset > offset) { continue; @@ -204,9 +198,9 @@ void DecompilerWidget::setInfoForBreakpoints() // Get the range of the line QTextCursor cursorForLine = ui->textEdit->textCursor(); cursorForLine.movePosition(QTextCursor::StartOfLine); - size_t startPos = cursorForLine.position(); + const size_t startPos = cursorForLine.position(); cursorForLine.movePosition(QTextCursor::EndOfLine); - size_t endPos = cursorForLine.position(); + const size_t endPos = cursorForLine.position(); gatherBreakpointInfo(*code, startPos, endPos); } @@ -214,10 +208,9 @@ void DecompilerWidget::gatherBreakpointInfo(RzAnnotatedCode &codeDecompiled, siz size_t endPos) { RVA firstOffset = RVA_MAX; - void *iter; - rz_vector_foreach(&codeDecompiled.annotations, iter) + RzCodeAnnotation *annotation; + CutterRzVectorForeach(&codeDecompiled.annotations, annotation, RzCodeAnnotation) { - RzCodeAnnotation *annotation = (RzCodeAnnotation *)iter; if (annotation->type != RZ_CODE_ANNOTATION_TYPE_OFFSET) { continue; } @@ -228,10 +221,10 @@ void DecompilerWidget::gatherBreakpointInfo(RzAnnotatedCode &codeDecompiled, siz } } mCtxMenu->setFirstOffsetInLine(firstOffset); - QList functionBreakpoints = Core()->getBreakpointsInFunction(decompiledFunctionAddr); + const QList functionBreakpoints = Core()->getBreakpointsInFunction(decompiledFunctionAddr); QVector offsetList; - for (RVA bpOffset : functionBreakpoints) { - size_t pos = positionForOffset(bpOffset); + for (const RVA bpOffset : functionBreakpoints) { + const size_t pos = positionForOffset(bpOffset); if (startPos <= pos && pos <= endPos) { offsetList.push_back(bpOffset); } @@ -249,7 +242,7 @@ void DecompilerWidget::refreshIfChanged(RVA addr) void DecompilerWidget::doRefresh() { - RVA addr = seekable->getOffset(); + const RVA addr = seekable->getOffset(); if (!refreshDeferrer->attemptRefresh(nullptr)) { return; } @@ -300,7 +293,7 @@ void DecompilerWidget::refreshDecompiler() QTextCursor DecompilerWidget::getCursorForAddress(RVA addr) { - size_t pos = positionForOffset(addr); + const size_t pos = positionForOffset(addr); if (pos == SIZE_MAX || pos == 0) { return QTextCursor(); } @@ -317,7 +310,7 @@ void DecompilerWidget::decompilationFinished(RzAnnotatedCode *codeDecompiled) mCtxMenu->setAnnotationHere(nullptr); setCode(codeDecompiled); - Decompiler *dec = getCurrentDecompiler(); + const Decompiler *dec = getCurrentDecompiler(); QObject::disconnect(dec, &Decompiler::finished, this, &DecompilerWidget::decompilationFinished); decompilerBusy = false; @@ -332,10 +325,9 @@ void DecompilerWidget::decompilationFinished(RzAnnotatedCode *codeDecompiled) highlightBreakpoints(); lowestOffsetInCode = RVA_MAX; highestOffsetInCode = 0; - void *iter; - rz_vector_foreach(&code->annotations, iter) + RzCodeAnnotation *annotation; + CutterRzVectorForeach(&code->annotations, annotation, RzCodeAnnotation) { - RzCodeAnnotation *annotation = (RzCodeAnnotation *)iter; if (annotation->type == RZ_CODE_ANNOTATION_TYPE_OFFSET) { if (lowestOffsetInCode > annotation->offset.offset) { lowestOffsetInCode = annotation->offset.offset; @@ -356,10 +348,9 @@ void DecompilerWidget::decompilationFinished(RzAnnotatedCode *codeDecompiled) void DecompilerWidget::setAnnotationsAtCursor(size_t pos) { RzCodeAnnotation *annotationAtPos = nullptr; - void *iter; - rz_vector_foreach(&this->code->annotations, iter) + RzCodeAnnotation *annotation; + CutterRzVectorForeach(&this->code->annotations, annotation, RzCodeAnnotation) { - RzCodeAnnotation *annotation = (RzCodeAnnotation *)iter; if (annotation->type == RZ_CODE_ANNOTATION_TYPE_OFFSET || annotation->type == RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT || annotation->start > pos || annotation->end <= pos) { @@ -395,11 +386,11 @@ void DecompilerWidget::cursorPositionChanged() return; } - size_t pos = ui->textEdit->textCursor().position(); + const size_t pos = ui->textEdit->textCursor().position(); setAnnotationsAtCursor(pos); setInfoForBreakpoints(); - RVA offset = offsetForPosition(pos); + const RVA offset = offsetForPosition(pos); if (offset != RVA_INVALID && offset != seekable->getOffset()) { seekFromCursor = true; seekable->seek(offset); @@ -431,7 +422,7 @@ void DecompilerWidget::seekChanged(RVA /* addr */, CutterCore::SeekHistoryType t } else if (type == CutterCore::SeekHistoryType::Redo) { ++historyPos; } - RVA fcnAddr = Core()->getFunctionStart(seekable->getOffset()); + const RVA fcnAddr = Core()->getFunctionStart(seekable->getOffset()); if (fcnAddr == RVA_INVALID || fcnAddr != decompiledFunctionAddr) { doRefresh(); return; @@ -441,8 +432,8 @@ void DecompilerWidget::seekChanged(RVA /* addr */, CutterCore::SeekHistoryType t void DecompilerWidget::updateCursorPosition() { - RVA offset = seekable->getOffset(); - size_t pos = positionForOffset(offset); + const RVA offset = seekable->getOffset(); + const size_t pos = positionForOffset(offset); if (pos == SIZE_MAX) { return; } @@ -470,7 +461,7 @@ void DecompilerWidget::updateSelection() // Highlight all the words in the document same as the current one cursor.select(QTextCursor::WordUnderCursor); - QString searchString = cursor.selectedText(); + const QString searchString = cursor.selectedText(); mCtxMenu->setCurHighlightedWord(searchString); extraSelections.append(createSameWordsSelections(ui->textEdit, searchString)); @@ -481,9 +472,9 @@ void DecompilerWidget::updateSelection() QString DecompilerWidget::getWindowTitle() const { - RzAnalysisFunction *fcn = Core()->functionAt(decompiledFunctionAddr); + const RzAnalysisFunction *fcn = Core()->functionAt(decompiledFunctionAddr); QString windowTitle; - if (fcn != NULL) { + if (fcn != nullptr) { windowTitle = tr("Decompiler (%1)").arg(fcn->name); } else { windowTitle = tr("Decompiler (Empty)"); @@ -498,7 +489,7 @@ void DecompilerWidget::fontsUpdatedSlot() void DecompilerWidget::colorsUpdatedSlot() { - bool useAnotationHiglighter = Config()->isDecompilerAnnotationHighlighterEnabled(); + const bool useAnotationHiglighter = Config()->isDecompilerAnnotationHighlighterEnabled(); if (useAnotationHiglighter != usingAnnotationBasedHighlighting) { setHighlighter(useAnotationHiglighter); } @@ -511,8 +502,8 @@ void DecompilerWidget::showDecompilerContextMenu(const QPoint &pt) void DecompilerWidget::seekToReference() { - size_t pos = ui->textEdit->textCursor().position(); - RVA offset = findReference(pos); + const size_t pos = ui->textEdit->textCursor().position(); + const RVA offset = findReference(pos); if (offset != RVA_INVALID) { seekable->seek(offset); } @@ -523,14 +514,14 @@ bool DecompilerWidget::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::MouseButtonDblClick && (obj == ui->textEdit || obj == ui->textEdit->viewport())) { - QMouseEvent *mouseEvent = static_cast(event); + const auto *mouseEvent = static_cast(event); ui->textEdit->setTextCursor(ui->textEdit->cursorForPosition(mouseEvent->pos())); seekToReference(); return true; } if (event->type() == QEvent::MouseButtonPress && (obj == ui->textEdit || obj == ui->textEdit->viewport())) { - QMouseEvent *mouseEvent = static_cast(event); + const auto *mouseEvent = static_cast(event); if (mouseEvent->button() == Qt::RightButton && !ui->textEdit->textCursor().hasSelection()) { ui->textEdit->setTextCursor(ui->textEdit->cursorForPosition(mouseEvent->pos())); return true; @@ -541,13 +532,13 @@ bool DecompilerWidget::eventFilter(QObject *obj, QEvent *event) void DecompilerWidget::highlightPC() { - RVA PCAddress = Core()->getProgramCounterValue(); - if (PCAddress == RVA_INVALID - || (Core()->getFunctionStart(PCAddress) != decompiledFunctionAddr)) { + const RVA pcAddress = Core()->getProgramCounterValue(); + if (pcAddress == RVA_INVALID + || (Core()->getFunctionStart(pcAddress) != decompiledFunctionAddr)) { return; } - QTextCursor cursor = getCursorForAddress(PCAddress); + const QTextCursor cursor = getCursorForAddress(pcAddress); if (!cursor.isNull()) { colorLine(createLineHighlightPC(cursor)); } @@ -556,9 +547,9 @@ void DecompilerWidget::highlightPC() void DecompilerWidget::highlightBreakpoints() { - QList functionBreakpoints = Core()->getBreakpointsInFunction(decompiledFunctionAddr); + const QList functionBreakpoints = Core()->getBreakpointsInFunction(decompiledFunctionAddr); QTextCursor cursor; - for (RVA &bp : functionBreakpoints) { + for (const RVA &bp : functionBreakpoints) { if (bp == RVA_INVALID) { continue; } @@ -573,7 +564,7 @@ void DecompilerWidget::highlightBreakpoints() } } -bool DecompilerWidget::colorLine(QTextEdit::ExtraSelection extraSelection) +bool DecompilerWidget::colorLine(const QTextEdit::ExtraSelection &extraSelection) { QList extraSelections = ui->textEdit->extraSelections(); extraSelections.append(extraSelection); @@ -598,7 +589,7 @@ void DecompilerWidget::copy() } } -bool DecompilerWidget::addressInRange(RVA addr) +bool DecompilerWidget::addressInRange(RVA addr) const { if (lowestOffsetInCode <= addr && addr <= highestOffsetInCode) { return true; @@ -614,7 +605,7 @@ bool DecompilerWidget::addressInRange(RVA addr) */ static QString remapAnnotationOffsetsToQString(RzAnnotatedCode &code) { - QByteArray bytes(code.code); + const QByteArray bytes(code.code); std::vector offsets; offsets.reserve(bytes.size()); char c; @@ -632,10 +623,9 @@ static QString remapAnnotationOffsetsToQString(RzAnnotatedCode &code) return it - offsets.begin(); }; - void *iter; - rz_vector_foreach(&code.annotations, iter) + RzCodeAnnotation *annotation; + CutterRzVectorForeach(&code.annotations, annotation, RzCodeAnnotation) { - RzCodeAnnotation *annotation = (RzCodeAnnotation *)iter; annotation->start = mapPos(annotation->start); annotation->end = mapPos(annotation->end); } @@ -649,7 +639,7 @@ void DecompilerWidget::setCode(RzAnnotatedCode *code) highlighter->setAnnotations(code); } this->code.reset(code); - QString text = remapAnnotationOffsetsToQString(*this->code); + const QString text = remapAnnotationOffsetsToQString(*this->code); this->ui->textEdit->setPlainText(text); connectCursorPositionChanged(true); syntaxHighlighter->rehighlight(); diff --git a/src/widgets/DecompilerWidget.h b/src/widgets/DecompilerWidget.h index ed5c7f0c..198c9592 100644 --- a/src/widgets/DecompilerWidget.h +++ b/src/widgets/DecompilerWidget.h @@ -1,12 +1,13 @@ #ifndef DECOMPILERWIDGET_H #define DECOMPILERWIDGET_H -#include -#include - -#include "core/Cutter.h" -#include "MemoryDockWidget.h" #include "Decompiler.h" +#include "MemoryDockWidget.h" +#include "core/Cutter.h" + +#include + +#include namespace Ui { class DecompilerWidget; @@ -18,6 +19,9 @@ class QTextCursor; class DecompilerContextMenu; struct DecompiledCodeTextLine; +/** + * @brief Widget to display the decompiled output from plugins like RzGhidra, JsDec etc + */ class DecompilerWidget : public MemoryDockWidget { Q_OBJECT @@ -177,7 +181,7 @@ private: * @param extraSelection - an ExtraSelection object colored with the appropriate color * @return True on success, otherwise False */ - bool colorLine(QTextEdit::ExtraSelection extraSelection); + bool colorLine(const QTextEdit::ExtraSelection &extraSelection); /** * @brief This function is responsible for highlighting all the breakpoints in the decompiler @@ -249,7 +253,7 @@ private: * @param addr An offset in the binary. * @return True if the specified is a part of the decompiled function, False otherwise. */ - bool addressInRange(RVA addr); + bool addressInRange(RVA addr) const; void setCode(RzAnnotatedCode *code); diff --git a/src/widgets/DisassemblerGraphView.cpp b/src/widgets/DisassemblerGraphView.cpp index 17822945..cd481f5b 100644 --- a/src/widgets/DisassemblerGraphView.cpp +++ b/src/widgets/DisassemblerGraphView.cpp @@ -1,50 +1,46 @@ - #include "DisassemblerGraphView.h" -#include "common/CutterSeekable.h" -#include "core/Cutter.h" -#include "core/MainWindow.h" -#include "common/Colors.h" -#include "common/Configuration.h" -#include "common/DisassemblyPreview.h" -#include "common/TempConfig.h" -#include "common/SyntaxHighlighter.h" + #include "common/BasicBlockHighlighter.h" #include "common/BasicInstructionHighlighter.h" -#include "common/Helpers.h" -#include "shortcuts/ShortcutManager.h" +#include "common/Configuration.h" +#include "common/CutterSeekable.h" #include "common/DisassemblyHelper.h" +#include "common/DisassemblyPreview.h" +#include "common/Helpers.h" +#include "common/TempConfig.h" +#include "core/Cutter.h" +#include "core/MainWindow.h" +#include "shortcuts/ShortcutManager.h" +#include +#include +#include #include -#include -#include #include +#include #include +#include #include +#include #include -#include #include #include +#include #include -#include -#include -#include -#include - -#include namespace DH = DisassemblyHelper; DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable *seekable, MainWindow *mainWindow, - QList additionalMenuActions) + const QList &additionalMenuActions) : CutterGraphView(parent), + highlightToken(nullptr), blockMenu(new DisassemblyContextMenu(this, mainWindow)), contextMenu(new QMenu(this)), seekable(seekable), actionUnhighlight(this), actionUnhighlightInstruction(this) { - highlight_token = nullptr; auto *layout = new QVBoxLayout(this); setTooltipStylesheet(); @@ -67,28 +63,28 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable *se connectSeekChanged(false); // ESC for previous - QShortcut *shortcut_escape = Shortcuts()->makeQShortcut("General.seekPrev", this); - shortcut_escape->setContext(Qt::WidgetShortcut); - connect(shortcut_escape, &QShortcut::activated, seekable, &CutterSeekable::seekPrev); + QShortcut *shortcutEscape = Shortcuts()->makeQShortcut("General.seekPrev", this); + shortcutEscape->setContext(Qt::WidgetShortcut); + connect(shortcutEscape, &QShortcut::activated, seekable, &CutterSeekable::seekPrev); // Branch shortcuts - QShortcut *shortcut_take_true = Shortcuts()->makeQShortcut("Graph.takeTrue", this); - shortcut_take_true->setContext(Qt::WidgetShortcut); - connect(shortcut_take_true, &QShortcut::activated, this, &DisassemblerGraphView::takeTrue); - QShortcut *shortcut_take_false = Shortcuts()->makeQShortcut("Graph.takeFalse", this); - shortcut_take_false->setContext(Qt::WidgetShortcut); - connect(shortcut_take_false, &QShortcut::activated, this, &DisassemblerGraphView::takeFalse); + QShortcut *shortcutTakeTrue = Shortcuts()->makeQShortcut("Graph.takeTrue", this); + shortcutTakeTrue->setContext(Qt::WidgetShortcut); + connect(shortcutTakeTrue, &QShortcut::activated, this, &DisassemblerGraphView::takeTrue); + QShortcut *shortcutTakeFalse = Shortcuts()->makeQShortcut("Graph.takeFalse", this); + shortcutTakeFalse->setContext(Qt::WidgetShortcut); + connect(shortcutTakeFalse, &QShortcut::activated, this, &DisassemblerGraphView::takeFalse); // Navigation shortcuts - QShortcut *shortcut_next_instr = Shortcuts()->makeQShortcut("Graph.nextInstr", this); - shortcut_next_instr->setContext(Qt::WidgetShortcut); - connect(shortcut_next_instr, &QShortcut::activated, this, &DisassemblerGraphView::nextInstr); - QShortcut *shortcut_prev_instr = Shortcuts()->makeQShortcut("Graph.prevInstr", this); - shortcut_prev_instr->setContext(Qt::WidgetShortcut); - connect(shortcut_prev_instr, &QShortcut::activated, this, &DisassemblerGraphView::prevInstr); - shortcuts.append(shortcut_escape); - shortcuts.append(shortcut_next_instr); - shortcuts.append(shortcut_prev_instr); + QShortcut *shortcutNextInstr = Shortcuts()->makeQShortcut("Graph.nextInstr", this); + shortcutNextInstr->setContext(Qt::WidgetShortcut); + connect(shortcutNextInstr, &QShortcut::activated, this, &DisassemblerGraphView::nextInstr); + QShortcut *shortcutPrevInstr = Shortcuts()->makeQShortcut("Graph.prevInstr", this); + shortcutPrevInstr->setContext(Qt::WidgetShortcut); + connect(shortcutPrevInstr, &QShortcut::activated, this, &DisassemblerGraphView::prevInstr); + shortcuts.append(shortcutEscape); + shortcuts.append(shortcutNextInstr); + shortcuts.append(shortcutPrevInstr); // Context menu that applies to everything contextMenu->addAction(&actionExportGraph); @@ -96,21 +92,21 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable *se contextMenu->addSeparator(); contextMenu->addActions(additionalMenuActions); - QAction *highlightBB = new QAction(this); + auto *highlightBB = new QAction(this); actionUnhighlight.setVisible(false); highlightBB->setText(tr("Highlight block")); connect(highlightBB, &QAction::triggered, this, [this]() { auto bbh = Core()->getBBHighlighter(); - RVA currBlockEntry = blockForAddress(this->seekable->getOffset())->entry; + const RVA currBlockEntry = blockForAddress(this->seekable->getOffset())->entry; QColor background = disassemblyBackgroundColor; if (auto block = bbh->getBasicBlock(currBlockEntry)) { background = block->color; } - QColor c = QColorDialog::getColor(background, this, QString(), - QColorDialog::DontUseNativeDialog); + const QColor c = QColorDialog::getColor(background, this, QString(), + QColorDialog::DontUseNativeDialog); if (c.isValid()) { bbh->highlight(currBlockEntry, c); } @@ -124,7 +120,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable *se emit Config()->colorsUpdated(); }); - QAction *highlightBI = new QAction(this); + auto *highlightBI = new QAction(this); actionUnhighlightInstruction.setVisible(false); highlightBI->setText(tr("Highlight instruction")); @@ -152,7 +148,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable *se layout->setContentsMargins(0, 0, 0, 0); layout->setAlignment(Qt::AlignTop); - this->scale_thickness_multiplier = true; + this->scaleThicknessMultiplier = true; installEventFilter(this); } @@ -171,7 +167,7 @@ DisassemblerGraphView::~DisassemblerGraphView() { qDeleteAll(shortcuts); shortcuts.clear(); - delete highlight_token; + delete highlightToken; } void DisassemblerGraphView::refreshView() @@ -190,15 +186,15 @@ void DisassemblerGraphView::loadCurrentGraph() .set("asm.lines", false) .set("asm.lines.fcn", false); - disassembly_blocks.clear(); + disassemblyBlocks.clear(); blocks.clear(); - if (highlight_token) { - delete highlight_token; - highlight_token = nullptr; + if (highlightToken) { + delete highlightToken; + highlightToken = nullptr; } - RzAnalysisFunction *fcn = Core()->functionIn(seekable->getOffset()); + const RzAnalysisFunction *fcn = Core()->functionIn(seekable->getOffset()); windowTitle = tr("Graph"); if (fcn && RZ_STR_ISNOTEMPTY(fcn->name)) { @@ -233,8 +229,8 @@ void DisassemblerGraphView::loadCurrentGraph() } for (const auto &bbi : CutterPVector(fcn->bbs)) { - RVA bbiFail = bbi->fail; - RVA bbiJump = bbi->jump; + const RVA bbiFail = bbi->fail; + const RVA bbiJump = bbi->jump; DisassemblyBlock db; GraphBlock gb; @@ -242,23 +238,23 @@ void DisassemblerGraphView::loadCurrentGraph() db.entry = bbi->addr; if (Config()->getGraphBlockEntryOffset()) { // QColor(0,0,0,0) is transparent - db.header_text = Text("[" + RzAddressString(db.entry) + "]", ConfigColor("offset"), - QColor(0, 0, 0, 0)); + db.headerText = Text("[" + rzAddressString(db.entry) + "]", ConfigColor("offset"), + QColor(0, 0, 0, 0)); } - db.true_path = RVA_INVALID; - db.false_path = RVA_INVALID; + db.truePath = RVA_INVALID; + db.falsePath = RVA_INVALID; if (bbiFail) { - db.false_path = bbiFail; + db.falsePath = bbiFail; gb.edges.emplace_back(bbiFail); } if (bbiJump) { if (bbiFail) { - db.true_path = bbiJump; + db.truePath = bbiJump; } gb.edges.emplace_back(bbiJump); } - RzAnalysisSwitchOp *switchOp = bbi->switch_op; + const RzAnalysisSwitchOp *switchOp = bbi->switch_op; if (switchOp) { for (const auto &caseOp : CutterRzList(switchOp->cases)) { if (caseOp->jump == RVA_INVALID) { @@ -269,7 +265,7 @@ void DisassemblerGraphView::loadCurrentGraph() } RzCoreLocked core(Core()); - std::unique_ptr buf { new ut8[bbi->size] }; + const std::unique_ptr buf { new ut8[bbi->size] }; if (!buf) { break; } @@ -285,20 +281,20 @@ void DisassemblerGraphView::loadCurrentGraph() options.vec = vec.get(); options.cbytes = 1; - rz_core_print_disasm(core, bbi->addr, buf.get(), (int)bbi->size, (int)bbi->size, NULL, + rz_core_print_disasm(core, bbi->addr, buf.get(), (int)bbi->size, (int)bbi->size, nullptr, &options); auto vecVisitor = CutterPVector(vec.get()); auto iter = vecVisitor.begin(); while (iter != vecVisitor.end()) { - RzAnalysisDisasmText *op = *iter; + const RzAnalysisDisasmText *op = *iter; Instr instr; instr.addr = op->offset; ++iter; if (iter != vecVisitor.end()) { // get instruction size from distance to next instruction ... - RVA nextOffset = (*iter)->offset; + const RVA nextOffset = (*iter)->offset; instr.size = nextOffset - instr.addr; } else { // or to the end of the block. @@ -310,20 +306,21 @@ void DisassemblerGraphView::loadCurrentGraph() instr.plainText = textDoc.toPlainText(); - RichTextPainter::List richText = RichTextPainter::fromTextDocument(textDoc); + const RichTextPainter::List richText = RichTextPainter::fromTextDocument(textDoc); // Colors::colorizeAssembly(richText, textDoc.toPlainText(), 0); bool cropped; - int blockLength = Config()->getGraphBlockMaxChars() + const int blockLength = Config()->getGraphBlockMaxChars() + Core()->getConfigb("asm.bytes") * 24 + Core()->getConfigb("asm.emu") * 10; instr.text = Text(RichTextPainter::cropped(richText, blockLength, "...", &cropped)); - if (cropped) + if (cropped) { instr.fullText = richText; - else + } else { instr.fullText = Text(); + } db.instrs.push_back(instr); } - disassembly_blocks[db.entry] = db; + disassemblyBlocks[db.entry] = db; prepareGraphNode(gb); addBlock(gb); } @@ -345,36 +342,40 @@ DisassemblerGraphView::EdgeConfigurationMapping DisassemblerGraphView::getEdgeCo void DisassemblerGraphView::prepareGraphNode(GraphBlock &block) { - DisassemblyBlock &db = disassembly_blocks[block.entry]; + const DisassemblyBlock &db = disassemblyBlocks[block.entry]; int width = 0; int height = 0; - for (auto &line : db.header_text.lines) { + for (auto &line : db.headerText.lines) { int lw = 0; - for (auto &part : line) + for (auto &part : line) { lw += mFontMetrics->width(part.text); - if (lw > width) + } + if (lw > width) { width = lw; + } height += 1; } - for (Instr &instr : db.instrs) { + for (const Instr &instr : db.instrs) { for (auto &line : instr.text.lines) { int lw = 0; - for (auto &part : line) + for (auto &part : line) { lw += mFontMetrics->width(part.text); - if (lw > width) + } + if (lw > width) { width = lw; + } height += 1; } } - int extra = static_cast(2 * padding + 4); - qreal indent = ACharWidth; + const int extra = static_cast(2 * padding + 4); + const qreal indent = charWidthA; block.width = static_cast(width + extra + indent); block.height = (height * charHeight) + extra; } void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, bool interactive) { - QRectF blockRect(block.x, block.y, block.width, block.height); + const QRectF blockRect(block.x, block.y, block.width, block.height); p.setPen(Qt::black); p.setBrush(Qt::gray); @@ -382,17 +383,17 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, p.drawRect(blockRect); // Render node - DisassemblyBlock &db = disassembly_blocks[block.entry]; - bool block_selected = false; - RVA selected_instruction = RVA_INVALID; + const DisassemblyBlock &db = disassemblyBlocks[block.entry]; + bool blockSelected = false; + RVA selectedInstruction = RVA_INVALID; // Figure out if the current block is selected - RVA addr = seekable->getOffset(); - RVA PCAddr = Core()->getProgramCounterValue(); + const RVA addr = seekable->getOffset(); + const RVA pcAddr = Core()->getProgramCounterValue(); for (const Instr &instr : db.instrs) { if (instr.contains(addr) && interactive) { - block_selected = true; - selected_instruction = instr.addr; + blockSelected = true; + selectedInstruction = instr.addr; } // TODO: L219 @@ -409,7 +410,7 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, p.setPen(QPen(graphNodeColor, 1)); - if (block_selected) { + if (blockSelected) { p.setBrush(disassemblySelectedBackgroundColor); } else { p.setBrush(disassemblyBackgroundColor); @@ -419,32 +420,32 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, p.drawRect(blockRect); auto bb = Core()->getBBHighlighter()->getBasicBlock(block.entry); if (bb) { - QColor color(bb->color); + const QColor color(bb->color); p.setBrush(color); p.drawRect(blockRect); } // Stop rendering text when it's too small auto transform = p.combinedTransform(); - QRect screenChar = transform.mapRect(QRect(0, 0, ACharWidth, charHeight)); + const QRect screenChar = transform.mapRect(QRect(0, 0, charWidthA, charHeight)); if (screenChar.width() < Config()->getGraphMinFontSize()) { return; } - qreal indent = ACharWidth; + const qreal indent = charWidthA; // Render node text auto x = block.x + padding; int y = block.y + getTextOffset(0).y(); - for (auto &line : db.header_text.lines) { + for (auto &line : db.headerText.lines) { RichTextPainter::paintRichText(&p, x, y, block.width, charHeight, 0, line, mFontMetrics.get()); y += charHeight; } auto bih = Core()->getBIHighlighter(); - QColor selectionColor = ConfigColor("wordHighlight"); + const QColor selectionColor = ConfigColor("wordHighlight"); for (const Instr &instr : db.instrs) { const QRect instrRect = QRect(static_cast(block.x + indent), y, @@ -454,8 +455,8 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, QColor instrColor; if (Core()->isBreakpoint(breakpoints, instr.addr)) { instrColor = ConfigColor("gui.breakpoint_background"); - } else if (instr.addr == PCAddr) { - instrColor = PCSelectionColor; + } else if (instr.addr == pcAddr) { + instrColor = pcSelectionColor; } else if (auto background = bih->getBasicInstruction(instr.addr)) { instrColor = background->color; } @@ -464,16 +465,16 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, p.fillRect(instrRect, instrColor); } - if (selected_instruction != RVA_INVALID && selected_instruction == instr.addr) { + if (selectedInstruction != RVA_INVALID && selectedInstruction == instr.addr) { p.fillRect(instrRect, disassemblySelectionColor); } // Highlight selected tokens - if (interactive && highlight_token != nullptr) { + if (interactive && highlightToken != nullptr) { int pos = -1; - qreal tokenWidth = mFontMetrics->width(highlight_token->content); - while ((pos = instr.plainText.indexOf(highlight_token->content, pos + 1)) != -1) { - int tokenEnd = pos + highlight_token->content.length(); + const qreal tokenWidth = mFontMetrics->width(highlightToken->content); + while ((pos = instr.plainText.indexOf(highlightToken->content, pos + 1)) != -1) { + const int tokenEnd = pos + highlightToken->content.length(); if ((pos > 0 && instr.plainText[pos - 1].isLetterOrNumber()) || (tokenEnd < instr.plainText.length() @@ -481,8 +482,8 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, continue; } - qreal widthBefore = mFontMetrics->width(instr.plainText.left(pos)); - qreal textOffset = padding + indent; + const qreal widthBefore = mFontMetrics->width(instr.plainText.left(pos)); + const qreal textOffset = padding + indent; if (textOffset + widthBefore > block.width - (10 + padding)) { continue; @@ -512,21 +513,21 @@ GraphView::EdgeConfiguration DisassemblerGraphView::edgeConfiguration(GraphView: bool interactive) { EdgeConfiguration ec; - DisassemblyBlock &db = disassembly_blocks[from.entry]; - if (to->entry == db.true_path) { + const DisassemblyBlock &db = disassemblyBlocks[from.entry]; + if (to->entry == db.truePath) { ec.color = brtrueColor; - } else if (to->entry == db.false_path) { + } else if (to->entry == db.falsePath) { ec.color = brfalseColor; } else { ec.color = jmpColor; } - ec.start_arrow = false; - ec.end_arrow = true; + ec.startArrow = false; + ec.endArrow = true; if (interactive) { if (from.entry == currentBlockAddress) { - ec.width_scale = 2.0; + ec.widthScale = 2.0; } else if (to->entry == currentBlockAddress) { - ec.width_scale = 2.0; + ec.widthScale = 2.0; } } return ec; @@ -537,8 +538,8 @@ bool DisassemblerGraphView::eventFilter(QObject *obj, QEvent *event) if ((Config()->getGraphPreview() || Config()->getShowVarTooltips()) && event->type() == QEvent::Type::ToolTip) { - QHelpEvent *helpEvent = static_cast(event); - QPoint point = viewToLogicalCoordinates(helpEvent->pos()); + const auto *helpEvent = static_cast(event); + const QPoint point = viewToLogicalCoordinates(helpEvent->pos()); if (auto block = getBlockContaining(point)) { // Get pos relative to start of block @@ -586,9 +587,9 @@ bool DisassemblerGraphView::eventFilter(QObject *obj, QEvent *event) void DisassemblerGraphView::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Return && seekable) { - RVA offset = seekable->getOffset(); + const RVA offset = seekable->getOffset(); // pressing enter at last instruction of the block seeks to true path if valid - RVA truePath = getTruePathForOffset(offset); + const RVA truePath = getTruePathForOffset(offset); if (truePath != RVA_INVALID) { seekable->seek(truePath); } else { @@ -601,21 +602,21 @@ void DisassemblerGraphView::keyPressEvent(QKeyEvent *event) RVA DisassemblerGraphView::getAddrForMouseEvent(GraphBlock &block, QPoint *point) { - DisassemblyBlock &db = disassembly_blocks[block.entry]; + const DisassemblyBlock &db = disassemblyBlocks[block.entry]; // Remove header and margin - int off_y = getInstructionOffset(db, 0).y(); + const int offY = getInstructionOffset(db, 0).y(); // Get mouse coordinate over the actual text - int text_point_y = point->y() - off_y; - int mouse_row = text_point_y / charHeight; + const int textPointY = point->y() - offY; + const int mouseRow = textPointY / charHeight; // If mouse coordinate is in header region or margin above - if (mouse_row < 0) { + if (mouseRow < 0) { return db.entry; } - Instr *instr = getInstrForMouseEvent(block, point); + const Instr *instr = getInstrForMouseEvent(block, point); if (instr) { return instr->addr; } @@ -627,26 +628,26 @@ DisassemblerGraphView::Instr * DisassemblerGraphView::getInstrForMouseEvent(GraphView::GraphBlock &block, QPoint *point, bool force) { - DisassemblyBlock &db = disassembly_blocks[block.entry]; + DisassemblyBlock &db = disassemblyBlocks[block.entry]; // Remove header and margin - int off_y = getInstructionOffset(db, 0).y(); + const int offY = getInstructionOffset(db, 0).y(); // Get mouse coordinate over the actual text - int text_point_y = point->y() - off_y; - int mouse_row = text_point_y / charHeight; + const int textPointY = point->y() - offY; + const int mouseRow = textPointY / charHeight; // Row in actual text - int cur_row = 0; + int curRow = 0; for (Instr &instr : db.instrs) { - if (mouse_row < cur_row + (int)instr.text.lines.size()) { + if (mouseRow < curRow + (int)instr.text.lines.size()) { return &instr; } - cur_row += instr.text.lines.size(); + curRow += instr.text.lines.size(); } if (force && !db.instrs.empty()) { - if (mouse_row <= 0) { + if (mouseRow <= 0) { return &db.instrs.front(); } else { return &db.instrs.back(); @@ -658,8 +659,8 @@ DisassemblerGraphView::getInstrForMouseEvent(GraphView::GraphBlock &block, QPoin QRectF DisassemblerGraphView::getInstrRect(GraphView::GraphBlock &block, RVA addr) const { - auto blockIt = disassembly_blocks.find(block.entry); - if (blockIt == disassembly_blocks.end()) { + auto blockIt = disassemblyBlocks.find(block.entry); + if (blockIt == disassemblyBlocks.end()) { return QRectF(); } auto &db = blockIt->second; @@ -681,7 +682,7 @@ QRectF DisassemblerGraphView::getInstrRect(GraphView::GraphBlock &block, RVA add currentLine += db.instrs[i].text.lines.size(); i++; } - QPointF topLeft = getInstructionOffset(db, static_cast(firstLineWithAddr)); + const QPointF topLeft = getInstructionOffset(db, static_cast(firstLineWithAddr)); return QRectF(topLeft, QSizeF(block.width - 2 * padding, charHeight * int(currentLine - firstLineWithAddr))); @@ -695,9 +696,9 @@ RVA DisassemblerGraphView::getTruePathForOffset(RVA offset) { DisassemblyBlock *db = blockForAddress(offset); if (db && !db->instrs.empty()) { - Instr lastInstruction = db->instrs.back(); + const Instr lastInstruction = db->instrs.back(); if (lastInstruction.addr == offset) { - return db->true_path; + return db->truePath; } } return RVA_INVALID; @@ -712,7 +713,7 @@ void DisassemblerGraphView::showInstruction(GraphView::GraphBlock &block, RVA ad DisassemblerGraphView::DisassemblyBlock *DisassemblerGraphView::blockForAddress(RVA addr) { - for (auto &blockIt : disassembly_blocks) { + for (auto &blockIt : disassemblyBlocks) { DisassemblyBlock &db = blockIt.second; for (const Instr &i : db.instrs) { if (i.addr == RVA_INVALID || i.size == RVA_INVALID) { @@ -729,7 +730,7 @@ DisassemblerGraphView::DisassemblyBlock *DisassemblerGraphView::blockForAddress( const DisassemblerGraphView::Instr *DisassemblerGraphView::instrForAddress(RVA addr) { - DisassemblyBlock *block = blockForAddress(addr); + const DisassemblyBlock *block = blockForAddress(addr); for (const Instr &i : block->instrs) { if (i.addr == RVA_INVALID || i.size == RVA_INVALID) { continue; @@ -745,7 +746,7 @@ const DisassemblerGraphView::Instr *DisassemblerGraphView::instrForAddress(RVA a void DisassemblerGraphView::onSeekChanged(RVA addr) { blockMenu->setOffset(addr); - DisassemblyBlock *db = blockForAddress(addr); + const DisassemblyBlock *db = blockForAddress(addr); bool switchFunction = false; if (!db) { // not in this function, try refreshing @@ -755,7 +756,7 @@ void DisassemblerGraphView::onSeekChanged(RVA addr) } if (db) { // This is a local address! We animated to it. - transition_dont_seek = true; + transitionDontSeek = true; showBlock(blocks[db->entry], !switchFunction); showInstruction(blocks[db->entry], addr); } @@ -763,13 +764,13 @@ void DisassemblerGraphView::onSeekChanged(RVA addr) void DisassemblerGraphView::takeTrue() { - DisassemblyBlock *db = blockForAddress(seekable->getOffset()); + const DisassemblyBlock *db = blockForAddress(seekable->getOffset()); if (!db) { return; } - if (db->true_path != RVA_INVALID) { - seekable->seek(db->true_path); + if (db->truePath != RVA_INVALID) { + seekable->seek(db->truePath); } else if (!blocks[db->entry].edges.empty()) { seekable->seek(blocks[db->entry].edges[0].target); } @@ -777,13 +778,13 @@ void DisassemblerGraphView::takeTrue() void DisassemblerGraphView::takeFalse() { - DisassemblyBlock *db = blockForAddress(seekable->getOffset()); + const DisassemblyBlock *db = blockForAddress(seekable->getOffset()); if (!db) { return; } - if (db->false_path != RVA_INVALID) { - seekable->seek(db->false_path); + if (db->falsePath != RVA_INVALID) { + seekable->seek(db->falsePath); } else if (!blocks[db->entry].edges.empty()) { seekable->seek(blocks[db->entry].edges[0].target); } @@ -796,14 +797,14 @@ void DisassemblerGraphView::setTooltipStylesheet() void DisassemblerGraphView::seekInstruction(bool previous_instr) { - RVA addr = seekable->getOffset(); + const RVA addr = seekable->getOffset(); DisassemblyBlock *db = blockForAddress(addr); if (!db) { return; } for (size_t i = 0; i < db->instrs.size(); i++) { - Instr &instr = db->instrs[i]; + const Instr &instr = db->instrs[i]; if (!instr.contains(addr)) { continue; } @@ -833,7 +834,7 @@ void DisassemblerGraphView::prevInstr() void DisassemblerGraphView::seekLocal(RVA addr, bool update_viewport) { - RVA curAddr = seekable->getOffset(); + const RVA curAddr = seekable->getOffset(); if (addr == curAddr) { return; } @@ -847,21 +848,22 @@ void DisassemblerGraphView::seekLocal(RVA addr, bool update_viewport) void DisassemblerGraphView::copySelection() { - if (!highlight_token) + if (!highlightToken) { return; + } QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(highlight_token->content); + clipboard->setText(highlightToken->content); } DisassemblerGraphView::Token *DisassemblerGraphView::getToken(Instr *instr, int x) { - x -= (int)(padding + ACharWidth); // Ignore left margin + x -= static_cast(padding + charWidthA); // Ignore left margin if (x < 0) { return nullptr; } - int clickedCharPos = mFontMetrics->position(instr->plainText, x); + const int clickedCharPos = mFontMetrics->position(instr->plainText, x); if (clickedCharPos > instr->plainText.length()) { return nullptr; } @@ -870,7 +872,7 @@ DisassemblerGraphView::Token *DisassemblerGraphView::getToken(Instr *instr, int QRegularExpressionMatchIterator i = tokenRegExp.globalMatch(instr->plainText); while (i.hasNext()) { - QRegularExpressionMatch match = i.next(); + const QRegularExpressionMatch match = i.next(); if (match.capturedStart() <= clickedCharPos && match.capturedEnd() > clickedCharPos) { auto t = new Token; @@ -888,7 +890,7 @@ DisassemblerGraphView::Token *DisassemblerGraphView::getToken(Instr *instr, int QPoint DisassemblerGraphView::getInstructionOffset(const DisassemblyBlock &block, int line) const { - return getTextOffset(line + static_cast(block.header_text.lines.size())); + return getTextOffset(line + static_cast(block.headerText.lines.size())); } void DisassemblerGraphView::blockClicked(GraphView::GraphBlock &block, QMouseEvent *event, @@ -901,16 +903,16 @@ void DisassemblerGraphView::blockClicked(GraphView::GraphBlock &block, QMouseEve currentBlockAddress = block.entry; - delete highlight_token; - highlight_token = getToken(instr, pos.x()); + delete highlightToken; + highlightToken = getToken(instr, pos.x()); - RVA addr = instr->addr; + const RVA addr = instr->addr; seekLocal(addr); blockMenu->setOffset(addr); - blockMenu->setCanCopy(highlight_token); - if (highlight_token) { - blockMenu->setCurHighlightedWord(highlight_token->content); + blockMenu->setCanCopy(highlightToken); + if (highlightToken) { + blockMenu->setCurHighlightedWord(highlightToken->content); } viewport()->update(); } @@ -969,7 +971,7 @@ void DisassemblerGraphView::blockDoubleClicked(GraphView::GraphBlock &block, QMo { Q_UNUSED(event); - Instr *instr = getInstrForMouseEvent(block, &pos); + const Instr *instr = getInstrForMouseEvent(block, &pos); if (!instr) { return; } @@ -979,8 +981,8 @@ void DisassemblerGraphView::blockDoubleClicked(GraphView::GraphBlock &block, QMo if (bracketValue.found) { ctx.word = bracketValue.content; - } else if (highlight_token) { - ctx.word = highlight_token->content; + } else if (highlightToken) { + ctx.word = highlightToken->content; } else { ctx.word = QString(); } @@ -988,7 +990,7 @@ void DisassemblerGraphView::blockDoubleClicked(GraphView::GraphBlock &block, QMo ctx.offset = getAddrForMouseEvent(block, &pos); ctx.arrow = getTruePathForOffset(ctx.offset); - DH::TargetAction ta = DH::resolveTarget(ctx, DH::TargetFilter::Standard); + const DH::TargetAction ta = DH::resolveTarget(ctx, DH::TargetFilter::Standard); switch (ta.type) { case DH::TargetType::TypeName: Core()->showTypeInTypesWidget(ctx.word); @@ -1011,14 +1013,14 @@ void DisassemblerGraphView::blockDoubleClicked(GraphView::GraphBlock &block, QMo void DisassemblerGraphView::blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event, QPoint pos) { - Instr *instr = getInstrForMouseEvent(block, &pos); + const Instr *instr = getInstrForMouseEvent(block, &pos); if (!instr || instr->fullText.lines.empty()) { QToolTip::hideText(); event->ignore(); return; } - QToolTip::showText(event->globalPos(), instr->fullText.ToQString()); + QToolTip::showText(event->globalPos(), instr->fullText.toQString()); } bool DisassemblerGraphView::helpEvent(QHelpEvent *event) @@ -1034,8 +1036,8 @@ bool DisassemblerGraphView::helpEvent(QHelpEvent *event) void DisassemblerGraphView::blockTransitionedTo(GraphView::GraphBlock *to) { currentBlockAddress = to->entry; - if (transition_dont_seek) { - transition_dont_seek = false; + if (transitionDontSeek) { + transitionDontSeek = false; return; } seekLocal(to->entry); @@ -1056,7 +1058,7 @@ void DisassemblerGraphView::onActionHighlightBITriggered() background = currentColor->color; } - QColor c = + const QColor c = QColorDialog::getColor(background, this, QString(), QColorDialog::DontUseNativeDialog); if (c.isValid()) { bih->highlight(instr->addr, instr->size, c); diff --git a/src/widgets/DisassemblerGraphView.h b/src/widgets/DisassemblerGraphView.h index b41b8f9e..c0bdd579 100644 --- a/src/widgets/DisassemblerGraphView.h +++ b/src/widgets/DisassemblerGraphView.h @@ -3,19 +3,22 @@ // Based on the DisassemblerGraphView from x64dbg -#include +#include "common/CutterSeekable.h" +#include "common/RichTextPainter.h" +#include "menus/DisassemblyContextMenu.h" +#include "widgets/CutterGraphView.h" + +#include #include #include -#include - -#include "widgets/CutterGraphView.h" -#include "menus/DisassemblyContextMenu.h" -#include "common/RichTextPainter.h" -#include "common/CutterSeekable.h" +#include class QTextEdit; class FallbackSyntaxHighlighter; +/** + * @brief Graph View widget for disassembly + */ class DisassemblerGraphView : public CutterGraphView { Q_OBJECT @@ -29,7 +32,7 @@ class DisassemblerGraphView : public CutterGraphView Text(const QString &text, QColor color, QColor background) { RichTextPainter::List richText; - RichTextPainter::CustomRichText_t rt; + RichTextPainter::CustomRichText rt; rt.highlight = false; rt.text = text; rt.textColor = color; @@ -42,7 +45,7 @@ class DisassemblerGraphView : public CutterGraphView Text(const RichTextPainter::List &richText) { lines.push_back(richText); } - QString ToQString() const + QString toQString() const { QString result; for (const auto &line : lines) { @@ -79,20 +82,20 @@ class DisassemblerGraphView : public CutterGraphView struct DisassemblyBlock { - Text header_text; + Text headerText; std::vector instrs; ut64 entry = 0; - ut64 true_path = 0; - ut64 false_path = 0; + ut64 truePath = 0; + ut64 falsePath = 0; bool terminal = false; bool indirectcall = false; }; public: DisassemblerGraphView(QWidget *parent, CutterSeekable *seekable, MainWindow *mainWindow, - QList additionalMenuAction); + const QList &additionalMenuAction); ~DisassemblerGraphView() override; - std::unordered_map disassembly_blocks; + std::unordered_map disassemblyBlocks; virtual void drawBlock(QPainter &p, GraphView::GraphBlock &block, bool interactive) override; virtual void blockClicked(GraphView::GraphBlock &block, QMouseEvent *event, QPoint pos) override; @@ -149,9 +152,9 @@ private slots: void setTooltipStylesheet(); private: - bool transition_dont_seek = false; + bool transitionDontSeek = false; - Token *highlight_token; + Token *highlightToken; bool emptyGraph; ut64 currentBlockAddress = RVA_INVALID; @@ -199,7 +202,7 @@ signals: void nameChanged(const QString &name); public: - bool isGraphEmpty() { return emptyGraph; } + bool isGraphEmpty() const { return emptyGraph; } }; #endif // DISASSEMBLERGRAPHVIEW_H diff --git a/src/widgets/DisassemblyWidget.cpp b/src/widgets/DisassemblyWidget.cpp index e10a9ec8..df363db7 100644 --- a/src/widgets/DisassemblyWidget.cpp +++ b/src/widgets/DisassemblyWidget.cpp @@ -1,27 +1,28 @@ #include "DisassemblyWidget.h" -#include "menus/DisassemblyContextMenu.h" + +#include "DisassemblyHelper.h" +#include "common/BinaryTrees.h" #include "common/Configuration.h" #include "common/DisassemblyPreview.h" #include "common/Helpers.h" -#include "common/TempConfig.h" #include "common/SelectionHighlight.h" -#include "common/BinaryTrees.h" +#include "common/TempConfig.h" #include "core/MainWindow.h" -#include "widgets/AddressRangeScrollBar.h" +#include "menus/DisassemblyContextMenu.h" #include "shortcuts/ShortcutManager.h" -#include "DisassemblyHelper.h" +#include "widgets/AddressRangeScrollBar.h" #include -#include #include #include -#include -#include -#include -#include #include #include +#include +#include #include +#include +#include +#include #include #include @@ -33,21 +34,25 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main) : MemoryDockWidget(MemoryWidgetType::Disassembly, main), mCtxMenu(new DisassemblyContextMenu(this, main)), mDisasScrollArea(new DisassemblyScrollArea(this)), - mDisasTextEdit(new DisassemblyTextEdit(this)) + mDisasTextEdit(new DisassemblyTextEdit(this)), + leftPanel(new DisassemblyLeftPanel(this)), + maxLines(0), + cursorLineOffset(0), + cursorCharOffset(0), + seekFromCursor(false), + disasmRefresh(createReplacingRefreshDeferrer( + false, [this](const RVA *offset) { refreshDisasm(offset ? *offset : RVA_INVALID); })) { setObjectName(main ? main->getUniqueObjectName(getWidgetType()) : getWidgetType()); updateWindowTitle(); topOffset = bottomOffset = RVA_INVALID; - cursorLineOffset = 0; - cursorCharOffset = 0; - seekFromCursor = false; // Instantiate the window layout auto *splitter = new QSplitter; // Setup the left frame that contains breakpoints and jumps - leftPanel = new DisassemblyLeftPanel(this); + splitter->addWidget(leftPanel); // Setup the disassembly content @@ -71,8 +76,8 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main) // Behave like all widgets: highlight on focus and hover connect(qApp, &QApplication::focusChanged, this, [this](QWidget *, QWidget *now) { - QColor borderColor = this == now ? palette().color(QPalette::Highlight) - : palette().color(QPalette::WindowText).darker(); + const QColor borderColor = this == now ? palette().color(QPalette::Highlight) + : palette().color(QPalette::WindowText).darker(); widget()->setStyleSheet(QString("QSplitter { border: %1px solid %2 } \n" "QSplitter:hover { border: %1px solid %3 } \n") .arg(devicePixelRatio()) @@ -95,10 +100,6 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main) setupFonts(); setupColors(); - disasmRefresh = createReplacingRefreshDeferrer( - false, [this](const RVA *offset) { refreshDisasm(offset ? *offset : RVA_INVALID); }); - - maxLines = 0; updateMaxLines(); mDisasTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -109,8 +110,8 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main) mDisasTextEdit->setWordWrapMode(QTextOption::NoWrap); // Increase asm text edit margin - QTextDocument *asm_docu = mDisasTextEdit->document(); - asm_docu->setDocumentMargin(10); + QTextDocument *asmDocu = mDisasTextEdit->document(); + asmDocu->setDocumentMargin(10); // Event filter to intercept double clicks in the textbox // and showing tooltips when hovering above those offsets @@ -130,16 +131,18 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main) connectCursorPositionChanged(false); - connect(Core(), &CutterCore::commentsChanged, this, [this]() { refreshDisasm(); }); - connect(Core(), SIGNAL(flagsChanged()), this, SLOT(refreshDisasm())); - connect(Core(), SIGNAL(globalVarsChanged()), this, SLOT(refreshDisasm())); - connect(Core(), SIGNAL(functionsChanged()), this, SLOT(refreshDisasm())); - connect(Core(), &CutterCore::functionRenamed, this, [this]() { refreshDisasm(); }); - connect(Core(), SIGNAL(varsChanged()), this, SLOT(refreshDisasm())); - connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(refreshDisasm())); + // Avoids the "The slot requires more arguments than the signal provides" error + auto refresh = [this]() { refreshDisasm(); }; + connect(Core(), &CutterCore::commentsChanged, this, refresh); + connect(Core(), &CutterCore::flagsChanged, this, refresh); + connect(Core(), &CutterCore::globalVarsChanged, this, refresh); + connect(Core(), &CutterCore::functionsChanged, this, refresh); + connect(Core(), &CutterCore::functionRenamed, this, refresh); + connect(Core(), &CutterCore::varsChanged, this, refresh); + connect(Core(), &CutterCore::asmOptionsChanged, this, refresh); + connect(Core(), &CutterCore::refreshCodeViews, this, refresh); connect(Core(), &CutterCore::instructionChanged, this, &DisassemblyWidget::instructionChanged); connect(Core(), &CutterCore::breakpointsChanged, this, &DisassemblyWidget::refreshIfInRange); - connect(Core(), SIGNAL(refreshCodeViews()), this, SLOT(refreshDisasm())); connect(Config(), &Configuration::fontsUpdated, this, &DisassemblyWidget::fontsUpdatedSlot); connect(Config(), &Configuration::colorsUpdated, this, &DisassemblyWidget::colorsUpdatedSlot); @@ -153,7 +156,7 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main) mCtxMenu->addSeparator(); mCtxMenu->addAction(&syncAction); connect(seekable, &CutterSeekable::seekableSeekChanged, this, - &DisassemblyWidget::on_seekChanged); + &DisassemblyWidget::onSeekChanged); addActions(mCtxMenu->actions()); @@ -259,7 +262,7 @@ void DisassemblyWidget::refreshDisasm(RVA offset) } breakpoints = Core()->getBreakpointsAddresses(); - int horizontalScrollValue = mDisasTextEdit->horizontalScrollBar()->value(); + const int horizontalScrollValue = mDisasTextEdit->horizontalScrollBar()->value(); mDisasTextEdit->setLockScroll(true); // avoid flicker // Retrieve disassembly lines @@ -273,7 +276,7 @@ void DisassemblyWidget::refreshDisasm(RVA offset) mDisasTextEdit->document()->clear(); QTextCursor cursor(mDisasTextEdit->document()); - QTextBlockFormat regular = cursor.blockFormat(); + const QTextBlockFormat regular = cursor.blockFormat(); for (const DisassemblyLine &line : lines) { if (line.offset < topOffset) { // overflow break; @@ -348,7 +351,7 @@ void DisassemblyWidget::scrollInstructions(int count, bool clampToScrollBarRange bool DisassemblyWidget::updateMaxLines() { - int currentMaxLines = qhelpers::getMaxFullyDisplayedLines(mDisasTextEdit); + const int currentMaxLines = qhelpers::getMaxFullyDisplayedLines(mDisasTextEdit); if (currentMaxLines != maxLines) { maxLines = currentMaxLines; @@ -362,7 +365,7 @@ bool DisassemblyWidget::updateMaxLines() void DisassemblyWidget::highlightCurrentLine() { QList extraSelections; - QColor highlightColor = ConfigColor("lineHighlight"); + const QColor highlightColor = ConfigColor("lineHighlight"); // Highlight the current word QTextCursor cursor = mDisasTextEdit->textCursor(); @@ -370,12 +373,12 @@ void DisassemblyWidget::highlightCurrentLine() // Select the line (BlockUnderCursor matches a line with current implementation) cursor.select(QTextCursor::BlockUnderCursor); // Remove any non-breakable space from the current line - QString searchString = cursor.selectedText().replace("\xc2\xa0", " "); + const QString searchString = cursor.selectedText().replace("\xc2\xa0", " "); // Cut the line in "tokens" that can be highlighted static const QRegularExpression tokenRegExp(R"(\b(? clickedCharPos) { curHighlightedWord = match.captured(); @@ -388,7 +391,7 @@ void DisassemblyWidget::highlightCurrentLine() highlightSelection.cursor = cursor; highlightSelection.cursor.movePosition(QTextCursor::Start); while (true) { - RVA lineOffset = DH::readDisassemblyOffset(highlightSelection.cursor); + const RVA lineOffset = DH::readDisassemblyOffset(highlightSelection.cursor); if (lineOffset == seekable->getOffset()) { highlightSelection.format.setBackground(highlightColor); highlightSelection.format.setProperty(QTextFormat::FullWidthSelection, true); @@ -413,23 +416,23 @@ void DisassemblyWidget::highlightCurrentLine() void DisassemblyWidget::highlightPCLine() { - RVA PCAddr = Core()->getProgramCounterValue(); + const RVA pcAddr = Core()->getProgramCounterValue(); - QColor highlightPCColor = ConfigColor("highlightPC"); + const QColor highlightPCColor = ConfigColor("highlightPC"); QList pcSelections; QTextEdit::ExtraSelection highlightSelection; highlightSelection.cursor = mDisasTextEdit->textCursor(); highlightSelection.cursor.movePosition(QTextCursor::Start); - if (PCAddr != RVA_INVALID) { + if (pcAddr != RVA_INVALID) { while (true) { - RVA lineOffset = DH::readDisassemblyOffset(highlightSelection.cursor); - if (lineOffset == PCAddr) { + const RVA lineOffset = DH::readDisassemblyOffset(highlightSelection.cursor); + if (lineOffset == pcAddr) { highlightSelection.format.setBackground(highlightPCColor); highlightSelection.format.setProperty(QTextFormat::FullWidthSelection, true); highlightSelection.cursor.clearSelection(); pcSelections.append(highlightSelection); - } else if (lineOffset != RVA_INVALID && lineOffset > PCAddr) { + } else if (lineOffset != RVA_INVALID && lineOffset > pcAddr) { break; } highlightSelection.cursor.movePosition(QTextCursor::EndOfLine); @@ -455,16 +458,16 @@ void DisassemblyWidget::showDisasContextMenu(const QPoint &pt) RVA DisassemblyWidget::readCurrentDisassemblyOffset() { - QTextCursor tc = mDisasTextEdit->textCursor(); + const QTextCursor tc = mDisasTextEdit->textCursor(); return DH::readDisassemblyOffset(tc); } void DisassemblyWidget::updateCursorPosition() { - RVA offset = seekable->getOffset(); + const RVA offset = seekable->getOffset(); // already fine where it is? - RVA currentLineOffset = readCurrentDisassemblyOffset(); + const RVA currentLineOffset = readCurrentDisassemblyOffset(); if (currentLineOffset == offset) { return; } @@ -476,14 +479,14 @@ void DisassemblyWidget::updateCursorPosition() mDisasTextEdit->setExtraSelections( createSameWordsSelections(mDisasTextEdit, curHighlightedWord)); } else { - RVA currentCursorOffset = readCurrentDisassemblyOffset(); - QTextCursor originalCursor = mDisasTextEdit->textCursor(); + const RVA currentCursorOffset = readCurrentDisassemblyOffset(); + const QTextCursor originalCursor = mDisasTextEdit->textCursor(); QTextCursor cursor = originalCursor; cursor.movePosition(QTextCursor::Start); while (true) { - RVA lineOffset = DH::readDisassemblyOffset(cursor); + const RVA lineOffset = DH::readDisassemblyOffset(cursor); if (lineOffset == offset) { if (cursorLineOffset > 0) { cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, @@ -537,7 +540,7 @@ void DisassemblyWidget::connectCursorPositionChanged(bool disconnect) void DisassemblyWidget::cursorPositionChanged() { - RVA offset = readCurrentDisassemblyOffset(); + const RVA offset = readCurrentDisassemblyOffset(); cursorLineOffset = 0; QTextCursor c = mDisasTextEdit->textCursor(); @@ -603,12 +606,12 @@ void DisassemblyWidget::moveCursorRelative(bool up, bool page) } refreshDisasm(offset); } else { // normal arrow keys - int blockCount = mDisasTextEdit->blockCount(); + const int blockCount = mDisasTextEdit->blockCount(); if (blockCount < 1) { return; } - int blockNumber = mDisasTextEdit->textCursor().blockNumber(); + const int blockNumber = mDisasTextEdit->textCursor().blockNumber(); if (blockNumber == blockCount - 1 && !up) { scrollInstructions(1); @@ -619,7 +622,7 @@ void DisassemblyWidget::moveCursorRelative(bool up, bool page) mDisasTextEdit->moveCursor(up ? QTextCursor::Up : QTextCursor::Down); // handle cases where top instruction offsets change - RVA offset = readCurrentDisassemblyOffset(); + const RVA offset = readCurrentDisassemblyOffset(); if (offset != seekable->getOffset()) { seekable->seek(offset); highlightCurrentLine(); @@ -630,7 +633,7 @@ void DisassemblyWidget::moveCursorRelative(bool up, bool page) void DisassemblyWidget::jumpToOffsetUnderCursor(const QTextCursor &cursor) { - RVA offset = DH::readDisassemblyOffset(cursor); + const RVA offset = DH::readDisassemblyOffset(cursor); seekable->seekToReference(offset); } @@ -638,13 +641,14 @@ bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::MouseButtonDblClick && (obj == mDisasTextEdit || obj == mDisasTextEdit->viewport())) { - QMouseEvent *mouseEvent = static_cast(event); + const auto *mouseEvent = static_cast(event); if (mouseEvent->button() == Qt::LeftButton) { auto ctx = DH::getContextFromCursor(mDisasTextEdit->cursorForPosition(mouseEvent->pos())); - DH::TargetAction ta = DH::resolveTarget(ctx, DisassemblyHelper::TargetFilter::Standard); + const DH::TargetAction ta = + DH::resolveTarget(ctx, DisassemblyHelper::TargetFilter::Standard); switch (ta.type) { case DH::TargetType::TypeName: Core()->showTypeInTypesWidget(ctx.word); @@ -666,7 +670,7 @@ bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event) } } else if ((Config()->getPreviewValue() || Config()->getShowVarTooltips()) && event->type() == QEvent::ToolTip && obj == mDisasTextEdit->viewport()) { - QHelpEvent *helpEvent = static_cast(event); + const auto *helpEvent = static_cast(event); auto ctx = DH::getContextFromCursor(mDisasTextEdit->cursorForPosition(helpEvent->pos())); @@ -708,7 +712,7 @@ QString DisassemblyWidget::getWindowTitle() const return tr("Disassembly"); } -void DisassemblyWidget::on_seekChanged(RVA offset, CutterCore::SeekHistoryType type) +void DisassemblyWidget::onSeekChanged(RVA offset, CutterCore::SeekHistoryType type) { if (type == CutterCore::SeekHistoryType::New) { // Erase previous history past this point. @@ -772,11 +776,14 @@ void DisassemblyWidget::setupColors() setStyleSheet(DisassemblyPreview::getToolTipStyleSheet()); } -DisassemblyScrollArea::DisassemblyScrollArea(QWidget *parent) : QAbstractScrollArea(parent) +DisassemblyScrollArea::DisassemblyScrollArea(QWidget *parent) + : QAbstractScrollArea(parent), + vScrollBar(new AddressRangeScrollBar(this)), + accumScrollWheelDeltaY(0) { - vScrollBar = new AddressRangeScrollBar(this); + setVerticalScrollBar(vScrollBar); - accumScrollWheelDeltaY = 0; + vScrollBar->setPageStep(40); vScrollBar->setSingleStep(1); connect(vScrollBar, &AddressRangeScrollBar::scrolled, this, @@ -815,7 +822,7 @@ void DisassemblyScrollArea::wheelEvent(QWheelEvent *event) // Typical scroll speed is 1 line per 5 degrees const int lineDelta = 5 * 8; if (accumScrollWheelDeltaY >= lineDelta || accumScrollWheelDeltaY <= -lineDelta) { - int lineCount = accumScrollWheelDeltaY / lineDelta; + const int lineCount = accumScrollWheelDeltaY / lineDelta; accumScrollWheelDeltaY -= lineDelta * lineCount; emit scrollLines(-lineCount); } @@ -868,9 +875,9 @@ void DisassemblyWidget::seekPrev() * Left panel *********************/ -DisassemblyLeftPanel::DisassemblyLeftPanel(DisassemblyWidget *disas) +DisassemblyLeftPanel::DisassemblyLeftPanel(DisassemblyWidget *disas) : disas(disas) { - this->disas = disas; + arrows.reserve((arrowsSize * 3) / 2); } @@ -891,14 +898,14 @@ void DisassemblyLeftPanel::paintEvent(QPaintEvent *event) constexpr int penSizePix = 1; constexpr int distanceBetweenLines = 10; constexpr int arrowWidth = 5; - int rightOffset = size().rwidth(); + const int rightOffset = size().rwidth(); auto tEdit = qobject_cast(disas->getTextWidget()); int lineHeight = qCeil(disas->getFontMetrics().lineSpacing()); - QColor arrowColorDown = ConfigColor("flow"); - QColor arrowColorUp = ConfigColor("cflow"); + const QColor arrowColorDown = ConfigColor("flow"); + const QColor arrowColorUp = ConfigColor("cflow"); QPainter p(this); - QPen penDown(arrowColorDown, penSizePix, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin); - QPen penUp(arrowColorUp, penSizePix, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin); + const QPen penDown(arrowColorDown, penSizePix, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin); + const QPen penUp(arrowColorUp, penSizePix, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin); // Fill background p.fillRect(event->rect(), Config()->getColor("gui.background").darker(115)); @@ -929,10 +936,10 @@ void DisassemblyLeftPanel::paintEvent(QPaintEvent *event) maxViewOffset = std::max(maxViewOffset, lines[i].offset); if (lines[i].arrow != RVA_INVALID) { Arrow a { lines[i].offset, lines[i].arrow }; - bool contains = std::find_if(std::begin(arrows), std::end(arrows), - [&](const Arrow &it) { - return it.min == a.min && it.max == a.max; - }) + const bool contains = std::find_if(std::begin(arrows), std::end(arrows), + [&](const Arrow &it) { + return it.min == a.min && it.max == a.max; + }) != std::end(arrows); if (!contains) { arrows.emplace_back(lines[i].offset, lines[i].arrow); @@ -955,14 +962,15 @@ void DisassemblyLeftPanel::paintEvent(QPaintEvent *event) } std::sort(lineOffsets.begin(), lineOffsets.end()); lineOffsets.erase(std::unique(lineOffsets.begin(), lineOffsets.end()), lineOffsets.end()); - size_t firstVisibleLine = std::find_if(lineOffsets.begin(), lineOffsets.end(), - [](const LineInfo &line) { return line.second == 0; }) + const size_t firstVisibleLine = + std::find_if(lineOffsets.begin(), lineOffsets.end(), + [](const LineInfo &line) { return line.second == 0; }) - lineOffsets.begin(); for (int i = int(firstVisibleLine) - 1; i >= 0; i--) { // -1 to ensure end of arrrow is drawn outside screen lineOffsets[i].second = i - firstVisibleLine - 1; } - size_t firstLineAfter = + const size_t firstLineAfter = std::find_if(lineOffsets.begin(), lineOffsets.end(), [&](const LineInfo &line) { return line.first > maxViewOffset; }) - lineOffsets.begin(); @@ -990,7 +998,7 @@ void DisassemblyLeftPanel::paintEvent(QPaintEvent *event) auto fitsInScreen = [&](const Arrow &a) { return maxViewOffset - minViewOffset < a.length(); }; std::sort(std::begin(arrows), std::end(arrows), [&](const Arrow &l, const Arrow &r) { - int lScreen = fitsInScreen(l), rScreen = fitsInScreen(r); + const int lScreen = fitsInScreen(l), rScreen = fitsInScreen(r); if (lScreen != rScreen) { return lScreen < rScreen; } @@ -1004,16 +1012,16 @@ void DisassemblyLeftPanel::paintEvent(QPaintEvent *event) it.level = 0; } - const int MAX_ARROW_LINES = 1 << 18; + const int maxArrowLines = 1 << 18; uint32_t maxLevel = 0; - if (!arrows.empty() && maxLine - minLine < MAX_ARROW_LINES) { + if (!arrows.empty() && maxLine - minLine < maxArrowLines) { // Limit maximum tree range to MAX_ARROW_LINES as sanity check, since the tree is designed // for dense ranges. Under normal conditions due to amount lines fitting screen and number // of arrows remembered should be few hundreds at most. MinMaxAccumulateTree maxLevelTree(maxLine - minLine + 2); for (Arrow &arrow : arrows) { - int top = offsetToLine(arrow.min) - minLine; - int bottom = offsetToLine(arrow.max) - minLine + 1; + const int top = offsetToLine(arrow.min) - minLine; + const int bottom = offsetToLine(arrow.max) - minLine + 1; auto minMax = maxLevelTree.rangeMinMax(top, bottom); if (minMax.first > 1) { arrow.level = 1; // place below existing lines @@ -1033,7 +1041,7 @@ void DisassemblyLeftPanel::paintEvent(QPaintEvent *event) if (!visibleRange.intersects(arrow)) { continue; } - int lineOffset = + const int lineOffset = int((distanceBetweenLines * arrow.level + distanceBetweenLines) * pixelRatio); p.setPen(arrow.up ? penUp : penDown); @@ -1044,8 +1052,8 @@ void DisassemblyLeftPanel::paintEvent(QPaintEvent *event) } auto lineToPixels = [&](int i) { - int offset = int(arrow.up ? std::floor(pixelRatio) : -std::floor(pixelRatio)); - int clampedLine = std::max(0, std::min(i, ((int)lineY.size()) - 1)); + const int offset = int(arrow.up ? std::floor(pixelRatio) : -std::floor(pixelRatio)); + const int clampedLine = std::max(0, std::min(i, ((int)lineY.size()) - 1)); int pos0 = 0; if (lineY.size() > 0) { pos0 = lineY[clampedLine]; @@ -1053,10 +1061,10 @@ void DisassemblyLeftPanel::paintEvent(QPaintEvent *event) return pos0 + (i - clampedLine) * lineHeight + lineHeight / 2 + offset; }; - int lineStartNumber = offsetToLine(arrow.jmpFromOffset()); + const int lineStartNumber = offsetToLine(arrow.jmpFromOffset()); int currentLineYPos = lineToPixels(lineStartNumber); - int arrowLineNumber = offsetToLine(arrow.jmpToffset()); + const int arrowLineNumber = offsetToLine(arrow.jmpToffset()); int lineArrowY = lineToPixels(arrowLineNumber); if (lineStartNumber == arrowLineNumber) { diff --git a/src/widgets/DisassemblyWidget.h b/src/widgets/DisassemblyWidget.h index 131cf877..abd6d99b 100644 --- a/src/widgets/DisassemblyWidget.h +++ b/src/widgets/DisassemblyWidget.h @@ -1,16 +1,15 @@ #ifndef DISASSEMBLYWIDGET_H #define DISASSEMBLYWIDGET_H -#include "core/Cutter.h" #include "MemoryDockWidget.h" #include "common/CutterSeekable.h" #include "common/RefreshDeferrer.h" -#include "common/CachedFontMetrics.h" +#include "core/Cutter.h" -#include +#include #include #include -#include +#include #include @@ -20,6 +19,11 @@ class DisassemblyContextMenu; class DisassemblyLeftPanel; class AddressRangeScrollBar; +/** + * @brief Main widget for showing disassembly of a binary + * + * @see DisassemblerGraphView + */ class DisassemblyWidget : public MemoryDockWidget { Q_OBJECT @@ -56,7 +60,7 @@ public slots: */ void showTransientScrollBar(); protected slots: - void on_seekChanged(RVA offset, CutterCore::SeekHistoryType type); + void onSeekChanged(RVA offset, CutterCore::SeekHistoryType type); void refreshIfInRange(RVA offset); void instructionChanged(RVA offset); void refreshDisasm(RVA offset = RVA_INVALID); diff --git a/src/widgets/EntrypointWidget.cpp b/src/widgets/EntrypointWidget.cpp index 5c78a371..6c59d107 100644 --- a/src/widgets/EntrypointWidget.cpp +++ b/src/widgets/EntrypointWidget.cpp @@ -1,15 +1,11 @@ #include "EntrypointWidget.h" + +#include "common/Helpers.h" +#include "core/MainWindow.h" #include "ui_EntrypointWidget.h" -#include "core/MainWindow.h" -#include "common/Helpers.h" - -#include #include - -/* - * Entrypoint Widget - */ +#include EntrypointWidget::EntrypointWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui::EntrypointWidget) @@ -20,6 +16,8 @@ EntrypointWidget::EntrypointWidget(MainWindow *main) connect(Core(), &CutterCore::codeRebased, this, &EntrypointWidget::fillEntrypoint); connect(Core(), &CutterCore::refreshAll, this, &EntrypointWidget::fillEntrypoint); + connect(ui->entrypointTreeWidget, &QTreeWidget::itemDoubleClicked, this, + &EntrypointWidget::onEntrypointTreeWidgetItemDoubleClicked); } EntrypointWidget::~EntrypointWidget() {} @@ -28,8 +26,8 @@ void EntrypointWidget::fillEntrypoint() { ui->entrypointTreeWidget->clear(); for (const EntrypointDescription &i : Core()->getAllEntrypoint()) { - QTreeWidgetItem *item = new QTreeWidgetItem(); - item->setText(0, RzAddressString(i.vaddr)); + auto *item = new QTreeWidgetItem(); + item->setText(0, rzAddressString(i.vaddr)); item->setText(1, i.type); item->setData(0, Qt::UserRole, QVariant::fromValue(i)); ui->entrypointTreeWidget->addTopLevelItem(item); @@ -43,11 +41,12 @@ void EntrypointWidget::setScrollMode() qhelpers::setVerticalScrollMode(ui->entrypointTreeWidget); } -void EntrypointWidget::on_entrypointTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column) +void EntrypointWidget::onEntrypointTreeWidgetItemDoubleClicked(QTreeWidgetItem *item, int column) { - if (column < 0) + if (column < 0) { return; + } - EntrypointDescription ep = item->data(0, Qt::UserRole).value(); + const auto ep = item->data(0, Qt::UserRole).value(); Core()->seekAndShow(ep.vaddr); } diff --git a/src/widgets/EntrypointWidget.h b/src/widgets/EntrypointWidget.h index 157245e2..10c4b264 100644 --- a/src/widgets/EntrypointWidget.h +++ b/src/widgets/EntrypointWidget.h @@ -1,11 +1,12 @@ #ifndef ENTRYPOINTWIDGET_H #define ENTRYPOINTWIDGET_H -#include +#include "CutterDockWidget.h" + #include #include -#include "CutterDockWidget.h" +#include class MainWindow; class QTreeWidget; @@ -14,6 +15,9 @@ namespace Ui { class EntrypointWidget; } +/** + * @brief Widget that displays all entry points + */ class EntrypointWidget : public CutterDockWidget { Q_OBJECT @@ -23,7 +27,7 @@ public: ~EntrypointWidget(); private slots: - void on_entrypointTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column); + void onEntrypointTreeWidgetItemDoubleClicked(QTreeWidgetItem *item, int column); void fillEntrypoint(); diff --git a/src/widgets/ExportsWidget.cpp b/src/widgets/ExportsWidget.cpp index af73f90c..9bf9455a 100644 --- a/src/widgets/ExportsWidget.cpp +++ b/src/widgets/ExportsWidget.cpp @@ -1,8 +1,9 @@ #include "ExportsWidget.h" -#include "ui_ListDockWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" #include "shortcuts/ShortcutManager.h" +#include "ui_ListDockWidget.h" #include @@ -20,8 +21,9 @@ int ExportsModel::columnCount(const QModelIndex &) const QVariant ExportsModel::data(const QModelIndex &index, int role) const { - if (index.row() >= exports.count()) + if (index.row() >= exports.count()) { return QVariant(); + } const ExportDescription &exp = exports.at(index.row()); @@ -29,9 +31,9 @@ QVariant ExportsModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case ExportsModel::OffsetColumn: - return RzAddressString(exp.vaddr); + return rzAddressString(exp.vaddr); case ExportsModel::SizeColumn: - return RzSizeString(exp.size); + return rzSizeString(exp.size); case ExportsModel::TypeColumn: return exp.type; case ExportsModel::NameColumn: @@ -92,7 +94,7 @@ ExportsProxyModel::ExportsProxyModel(ExportsModel *source_model, QObject *parent bool ExportsProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); + const QModelIndex index = sourceModel()->index(row, 0, parent); auto exp = index.data(ExportsModel::ExportDescriptionRole).value(); return qhelpers::filterStringContains(exp.name, this); @@ -105,20 +107,24 @@ bool ExportsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &rig switch (left.column()) { case ExportsModel::SizeColumn: - if (leftExp.size != rightExp.size) + if (leftExp.size != rightExp.size) { return leftExp.size < rightExp.size; + } // fallthrough case ExportsModel::OffsetColumn: - if (leftExp.vaddr != rightExp.vaddr) + if (leftExp.vaddr != rightExp.vaddr) { return leftExp.vaddr < rightExp.vaddr; + } // fallthrough case ExportsModel::NameColumn: - if (leftExp.name != rightExp.name) + if (leftExp.name != rightExp.name) { return leftExp.name < rightExp.name; + } // fallthrough case ExportsModel::TypeColumn: - if (leftExp.type != rightExp.type) + if (leftExp.type != rightExp.type) { return leftExp.type < rightExp.type; + } // fallthrough case ExportsModel::CommentColumn: return Core()->getCommentAt(leftExp.vaddr) < Core()->getCommentAt(rightExp.vaddr); @@ -130,21 +136,23 @@ bool ExportsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &rig return leftExp.vaddr < rightExp.vaddr; } -ExportsWidget::ExportsWidget(MainWindow *main) : ListDockWidget(main) +ExportsWidget::ExportsWidget(MainWindow *main) + : ListDockWidget(main), + exportsModel(new ExportsModel(this)), + exportsProxyModel(new ExportsProxyModel(exportsModel, this)) { setWindowTitle(tr("Exports")); setObjectName("ExportsWidget"); - exportsModel = new ExportsModel(this); - exportsProxyModel = new ExportsProxyModel(exportsModel, this); setModels(exportsProxyModel); ui->treeView->sortByColumn(ExportsModel::OffsetColumn, Qt::AscendingOrder); connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this]() { AddressableItemContextMenu *contextMenu = ui->treeView->getItemContextMenu(); - QModelIndex index = ui->treeView->selectionModel()->currentIndex(); + const QModelIndex index = ui->treeView->selectionModel()->currentIndex(); if (index.isValid()) { - QVariant variant = exportsProxyModel->data(index, ExportsModel::ExportDescriptionRole); + const QVariant variant = + exportsProxyModel->data(index, ExportsModel::ExportDescriptionRole); if (variant.canConvert()) { auto exp = variant.value(); contextMenu->toggleBreakpointAction(exp.type == "FUNC"); @@ -154,8 +162,8 @@ ExportsWidget::ExportsWidget(MainWindow *main) : ListDockWidget(main) contextMenu->toggleBreakpointAction(false); }); - QShortcut *toggle_shortcut = Shortcuts()->makeQShortcut("Exports.toggle", main); - connect(toggle_shortcut, &QShortcut::activated, this, [=]() { toggleDockWidget(true); }); + const QShortcut *toggleShortcut = Shortcuts()->makeQShortcut("Exports.toggle", main); + connect(toggleShortcut, &QShortcut::activated, this, [=, this]() { toggleDockWidget(true); }); connect(Core(), &CutterCore::codeRebased, this, &ExportsWidget::refreshExports); connect(Core(), &CutterCore::refreshAll, this, &ExportsWidget::refreshExports); diff --git a/src/widgets/ExportsWidget.h b/src/widgets/ExportsWidget.h index f0871a07..e356321d 100644 --- a/src/widgets/ExportsWidget.h +++ b/src/widgets/ExportsWidget.h @@ -1,9 +1,7 @@ #ifndef EXPORTSWIDGET_H #define EXPORTSWIDGET_H -#include - -#include "core/Cutter.h" +#include "CutterDescriptions.h" #include "CutterDockWidget.h" #include "widgets/ListDockWidget.h" @@ -18,6 +16,9 @@ namespace Ui { class ExportsWidget; } +/** + * @brief Source model for @ref ExportsWidget + */ class ExportsModel : public AddressableItemModel { Q_OBJECT @@ -28,7 +29,7 @@ private: QList exports; public: - enum Column { + enum Column : ut8 { OffsetColumn = 0, SizeColumn, TypeColumn, @@ -36,7 +37,7 @@ public: CommentColumn, ColumnCount }; - enum Role { ExportDescriptionRole = Qt::UserRole }; + enum Role : ut16 { ExportDescriptionRole = Qt::UserRole }; ExportsModel(QObject *parent = nullptr); @@ -63,6 +64,9 @@ protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; +/** + * @brief Widget listing all exports inside the binary + */ class ExportsWidget : public ListDockWidget { Q_OBJECT diff --git a/src/widgets/FlagsWidget.cpp b/src/widgets/FlagsWidget.cpp index 2eb4f0f1..69f48ae3 100644 --- a/src/widgets/FlagsWidget.cpp +++ b/src/widgets/FlagsWidget.cpp @@ -1,15 +1,16 @@ #include "FlagsWidget.h" -#include "ui_FlagsWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" #include "shortcuts/ShortcutManager.h" +#include "ui_FlagsWidget.h" #include +#include #include #include -#include #include -#include +#include FlagsModel::FlagsModel(QObject *parent) : AddressableItemModel(parent) {} @@ -25,8 +26,9 @@ int FlagsModel::columnCount(const QModelIndex &) const QVariant FlagsModel::data(const QModelIndex &index, int role) const { - if (index.row() >= flags.count()) + if (index.row() >= flags.count()) { return QVariant(); + } const FlagDescription &flag = flags.at(index.row()); @@ -34,9 +36,9 @@ QVariant FlagsModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case SIZE: - return RzSizeString(flag.size); + return rzSizeString(flag.size); case OFFSET: - return RzAddressString(flag.offset); + return rzAddressString(flag.offset); case NAME: return flag.name; case REALNAME: @@ -46,7 +48,7 @@ QVariant FlagsModel::data(const QModelIndex &index, int role) const default: return QVariant(); } - case FlagDescriptionRole: + case flagDescriptionRole: return QVariant::fromValue(flag); default: return QVariant(); @@ -103,54 +105,58 @@ FlagsSortFilterProxyModel::FlagsSortFilterProxyModel(FlagsModel *source_model, Q bool FlagsSortFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); - FlagDescription flag = index.data(FlagsModel::FlagDescriptionRole).value(); + const QModelIndex index = sourceModel()->index(row, 0, parent); + const auto flag = index.data(FlagsModel::flagDescriptionRole).value(); return qhelpers::filterStringContains(flag.name, this); } bool FlagsSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { auto source = static_cast(sourceModel()); - auto left_flag = source->description(left); - auto right_flag = source->description(right); + auto leftFlag = source->description(left); + auto rightFlag = source->description(right); switch (left.column()) { case FlagsModel::SIZE: - if (left_flag->size != right_flag->size) - return left_flag->size < right_flag->size; + if (leftFlag->size != rightFlag->size) { + return leftFlag->size < rightFlag->size; + } // fallthrough case FlagsModel::OFFSET: - if (left_flag->offset != right_flag->offset) - return left_flag->offset < right_flag->offset; + if (leftFlag->offset != rightFlag->offset) { + return leftFlag->offset < rightFlag->offset; + } // fallthrough case FlagsModel::NAME: - return left_flag->name < right_flag->name; + return leftFlag->name < rightFlag->name; case FlagsModel::REALNAME: - return left_flag->realname < right_flag->realname; + return leftFlag->realname < rightFlag->realname; case FlagsModel::COMMENT: - return Core()->getCommentAt(left_flag->offset) < Core()->getCommentAt(right_flag->offset); + return Core()->getCommentAt(leftFlag->offset) < Core()->getCommentAt(rightFlag->offset); default: break; } // fallback - return left_flag->offset < right_flag->offset; + return leftFlag->offset < rightFlag->offset; } FlagsWidget::FlagsWidget(MainWindow *main) - : CutterDockWidget(main), ui(new Ui::FlagsWidget), main(main) + : CutterDockWidget(main), + ui(new Ui::FlagsWidget), + main(main), + flagsModel(new FlagsModel(this)), + flagsProxyModel(new FlagsSortFilterProxyModel(flagsModel, this)) { ui->setupUi(this); - flags_model = new FlagsModel(this); - flags_proxy_model = new FlagsSortFilterProxyModel(flags_model, this); - connect(ui->filterLineEdit, &QLineEdit::textChanged, flags_proxy_model, + connect(ui->filterLineEdit, &QLineEdit::textChanged, flagsProxyModel, &QSortFilterProxyModel::setFilterWildcard); ui->flagsTreeView->setMainWindow(mainWindow); - ui->flagsTreeView->setModel(flags_proxy_model); + ui->flagsTreeView->setModel(static_cast(flagsProxyModel)); ui->flagsTreeView->sortByColumn(FlagsModel::OFFSET, Qt::AscendingOrder); // Ctrl-F to move the focus to the Filter search box @@ -171,7 +177,7 @@ FlagsWidget::FlagsWidget(MainWindow *main) clearShortcut->setContext(Qt::WidgetWithChildrenShortcut); connect(ui->filterLineEdit, &QLineEdit::textChanged, this, - [this] { ui->filterLineEdit->setItemCount(flags_proxy_model->rowCount()); }); + [this] { ui->filterLineEdit->setItemCount(flagsProxyModel->rowCount()); }); setScrollMode(); @@ -179,7 +185,7 @@ FlagsWidget::FlagsWidget(MainWindow *main) connect(Core(), &CutterCore::codeRebased, this, &FlagsWidget::flagsChanged); connect(Core(), &CutterCore::refreshAll, this, &FlagsWidget::refreshFlagspaces); connect(Core(), &CutterCore::commentsChanged, this, - [this]() { qhelpers::emitColumnChanged(flags_model, FlagsModel::COMMENT); }); + [this]() { qhelpers::emitColumnChanged(flagsModel, FlagsModel::COMMENT); }); auto menu = ui->flagsTreeView->getItemContextMenu(); menu->addSeparator(); @@ -187,38 +193,44 @@ FlagsWidget::FlagsWidget(MainWindow *main) menu->addAction(ui->actionDelete); addAction(ui->actionRename); addAction(ui->actionDelete); + + connect(ui->flagspaceCombo, &QComboBox::currentTextChanged, this, + &FlagsWidget::onFlagspaceComboCurrentTextChanged); + connect(ui->actionRename, &QAction::triggered, this, &FlagsWidget::onActionRenameTriggered); + connect(ui->actionDelete, &QAction::triggered, this, &FlagsWidget::onActionDeleteTriggered); } FlagsWidget::~FlagsWidget() {} -void FlagsWidget::on_flagspaceCombo_currentTextChanged(const QString &arg1) +void FlagsWidget::onFlagspaceComboCurrentTextChanged(const QString &arg1) { Q_UNUSED(arg1); refreshFlags(); } -void FlagsWidget::on_actionRename_triggered() +void FlagsWidget::onActionRenameTriggered() { - FlagDescription flag = ui->flagsTreeView->selectionModel() - ->currentIndex() - .data(FlagsModel::FlagDescriptionRole) - .value(); + const auto flag = ui->flagsTreeView->selectionModel() + ->currentIndex() + .data(FlagsModel::flagDescriptionRole) + .value(); bool ok; - QString newName = QInputDialog::getText(this, tr("Rename flag %1").arg(flag.name), - tr("Flag name:"), QLineEdit::Normal, flag.name, &ok); + const QString newName = + QInputDialog::getText(this, tr("Rename flag %1").arg(flag.name), tr("Flag name:"), + QLineEdit::Normal, flag.name, &ok); if (ok && !newName.isEmpty()) { Core()->renameFlag(flag.name, newName); } } -void FlagsWidget::on_actionDelete_triggered() +void FlagsWidget::onActionDeleteTriggered() { - FlagDescription flag = ui->flagsTreeView->selectionModel() - ->currentIndex() - .data(FlagsModel::FlagDescriptionRole) - .value(); + const auto flag = ui->flagsTreeView->selectionModel() + ->currentIndex() + .data(FlagsModel::flagDescriptionRole) + .value(); Core()->delFlag(flag.name); } @@ -229,9 +241,10 @@ void FlagsWidget::flagsChanged() void FlagsWidget::refreshFlagspaces() { - int cur_idx = ui->flagspaceCombo->currentIndex(); - if (cur_idx < 0) - cur_idx = 0; + int curIdx = ui->flagspaceCombo->currentIndex(); + if (curIdx < 0) { + curIdx = 0; + } disableFlagRefresh = true; // prevent duplicate flag refresh caused by flagspaceCombo modifications @@ -242,8 +255,9 @@ void FlagsWidget::refreshFlagspaces() ui->flagspaceCombo->addItem(i.name, QVariant::fromValue(i)); } - if (cur_idx > 0) - ui->flagspaceCombo->setCurrentIndex(cur_idx); + if (curIdx > 0) { + ui->flagspaceCombo->setCurrentIndex(curIdx); + } disableFlagRefresh = false; refreshFlags(); @@ -256,16 +270,17 @@ void FlagsWidget::refreshFlags() } QString flagspace; - QVariant flagspace_data = ui->flagspaceCombo->currentData(); - if (flagspace_data.isValid()) - flagspace = flagspace_data.value().name; + const QVariant flagspaceData = ui->flagspaceCombo->currentData(); + if (flagspaceData.isValid()) { + flagspace = flagspaceData.value().name; + } - flags_model->beginResetModel(); - flags_model->flags = Core()->getAllFlags(flagspace); - flags_model->endResetModel(); + flagsModel->beginResetModel(); + flagsModel->flags = Core()->getAllFlags(flagspace); + flagsModel->endResetModel(); // set the initial item count - ui->filterLineEdit->setItemCount(flags_proxy_model->rowCount()); + ui->filterLineEdit->setItemCount(flagsProxyModel->rowCount()); } void FlagsWidget::setScrollMode() diff --git a/src/widgets/FlagsWidget.h b/src/widgets/FlagsWidget.h index f5ef90fc..f9c69356 100644 --- a/src/widgets/FlagsWidget.h +++ b/src/widgets/FlagsWidget.h @@ -1,21 +1,24 @@ #ifndef FLAGSWIDGET_H #define FLAGSWIDGET_H -#include +#include "AddressableItemList.h" +#include "AddressableItemModel.h" +#include "CutterDescriptions.h" +#include "CutterDockWidget.h" #include #include #include -#include "core/Cutter.h" -#include "CutterDockWidget.h" -#include "AddressableItemList.h" -#include "AddressableItemModel.h" +#include class MainWindow; class QTreeWidgetItem; class FlagsWidget; +/** + * @brief Source model for @ref FlagsWidget + */ class FlagsModel : public AddressableItemModel { Q_OBJECT @@ -25,8 +28,8 @@ private: QList flags; public: - enum Columns { OFFSET = 0, SIZE, NAME, REALNAME, COMMENT, COUNT }; - static const int FlagDescriptionRole = Qt::UserRole; + enum Columns : ut8 { OFFSET = 0, SIZE, NAME, REALNAME, COMMENT, COUNT }; + static const int flagDescriptionRole = Qt::UserRole; FlagsModel(QObject *parent = nullptr); @@ -43,6 +46,9 @@ public: const FlagDescription *description(QModelIndex index) const; }; +/** + * @brief Sort and filter proxy model for @ref FlagsWidget + */ class FlagsSortFilterProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -59,6 +65,9 @@ namespace Ui { class FlagsWidget; } +/** + * @brief Widget for listing and modifying all flags + */ class FlagsWidget : public CutterDockWidget { Q_OBJECT @@ -68,10 +77,10 @@ public: ~FlagsWidget(); private slots: - void on_flagspaceCombo_currentTextChanged(const QString &arg1); + void onFlagspaceComboCurrentTextChanged(const QString &arg1); - void on_actionRename_triggered(); - void on_actionDelete_triggered(); + void onActionRenameTriggered(); + void onActionDeleteTriggered(); void flagsChanged(); void refreshFlagspaces(); @@ -81,8 +90,8 @@ private: MainWindow *main; bool disableFlagRefresh = false; - FlagsModel *flags_model; - FlagsSortFilterProxyModel *flags_proxy_model; + FlagsModel *flagsModel; + FlagsSortFilterProxyModel *flagsProxyModel; void refreshFlags(); void setScrollMode(); diff --git a/src/widgets/FlirtWidget.cpp b/src/widgets/FlirtWidget.cpp index 26dc9cbe..c5d6ccbc 100644 --- a/src/widgets/FlirtWidget.cpp +++ b/src/widgets/FlirtWidget.cpp @@ -1,7 +1,8 @@ #include "FlirtWidget.h" -#include "ui_FlirtWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" +#include "ui_FlirtWidget.h" FlirtModel::FlirtModel(QObject *parent) : QAbstractListModel(parent) {} @@ -17,8 +18,9 @@ int FlirtModel::columnCount(const QModelIndex &) const QVariant FlirtModel::data(const QModelIndex &index, int role) const { - if (index.row() >= sigdb.count()) + if (index.row() >= sigdb.count()) { return QVariant(); + } const FlirtDescription &entry = sigdb.at(index.row()); @@ -26,15 +28,15 @@ QVariant FlirtModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case BinTypeColumn: - return entry.bin_name; + return entry.binName; case ArchNameColumn: - return entry.arch_name; + return entry.archName; case ArchBitsColumn: - return entry.arch_bits; + return entry.archBits; case NumModulesColumn: - return entry.n_modules; + return entry.nModules; case NameColumn: - return entry.base_name; + return entry.baseName; case DetailsColumn: return entry.details; default: @@ -45,7 +47,7 @@ QVariant FlirtModel::data(const QModelIndex &index, int role) const return QVariant::fromValue(entry); case Qt::ToolTipRole: { - return entry.short_path; + return entry.shortPath; } default: @@ -86,47 +88,45 @@ FlirtProxyModel::FlirtProxyModel(FlirtModel *sourceModel, QObject *parent) bool FlirtProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); - FlirtDescription entry = index.data(FlirtModel::FlirtDescriptionRole).value(); - return qhelpers::filterStringContains(entry.base_name, this); + const QModelIndex index = sourceModel()->index(row, 0, parent); + const auto entry = index.data(FlirtModel::FlirtDescriptionRole).value(); + return qhelpers::filterStringContains(entry.baseName, this); } bool FlirtProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - FlirtDescription leftEntry = - left.data(FlirtModel::FlirtDescriptionRole).value(); - FlirtDescription rightEntry = - right.data(FlirtModel::FlirtDescriptionRole).value(); + const auto leftEntry = left.data(FlirtModel::FlirtDescriptionRole).value(); + const auto rightEntry = right.data(FlirtModel::FlirtDescriptionRole).value(); switch (left.column()) { case FlirtModel::BinTypeColumn: - return leftEntry.bin_name < rightEntry.bin_name; + return leftEntry.binName < rightEntry.binName; case FlirtModel::ArchNameColumn: - return leftEntry.arch_name < rightEntry.arch_name; + return leftEntry.archName < rightEntry.archName; case FlirtModel::ArchBitsColumn: - return leftEntry.arch_bits.toULongLong() < rightEntry.arch_bits.toULongLong(); + return leftEntry.archBits.toULongLong() < rightEntry.archBits.toULongLong(); case FlirtModel::NumModulesColumn: - return leftEntry.n_modules.toULongLong() < rightEntry.n_modules.toULongLong(); + return leftEntry.nModules.toULongLong() < rightEntry.nModules.toULongLong(); case FlirtModel::NameColumn: - return leftEntry.base_name < rightEntry.base_name; + return leftEntry.baseName < rightEntry.baseName; case FlirtModel::DetailsColumn: return leftEntry.details < rightEntry.details; default: break; } - return leftEntry.bin_name < rightEntry.bin_name; + return leftEntry.binName < rightEntry.binName; } FlirtWidget::FlirtWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui::FlirtWidget), + model(new FlirtModel(this)), + proxyModel(new FlirtProxyModel(model, this)), blockMenu(new FlirtContextMenu(this, mainWindow)) { ui->setupUi(this); - model = new FlirtModel(this); - proxyModel = new FlirtProxyModel(model, this); ui->flirtTreeView->setModel(proxyModel); ui->flirtTreeView->sortByColumn(FlirtModel::BinTypeColumn, Qt::AscendingOrder); diff --git a/src/widgets/FlirtWidget.h b/src/widgets/FlirtWidget.h index a10f23ce..5222a663 100644 --- a/src/widgets/FlirtWidget.h +++ b/src/widgets/FlirtWidget.h @@ -1,15 +1,14 @@ #ifndef FLIRT_WIDGET_H #define FLIRT_WIDGET_H -#include - -#include "core/Cutter.h" #include "CutterDockWidget.h" #include "menus/FlirtContextMenu.h" #include #include +#include + class MainWindow; class QTreeWidget; class QTreeWidgetItem; @@ -19,6 +18,9 @@ namespace Ui { class FlirtWidget; } +/** + * @brief Source model for @ref FlirtWidget + */ class FlirtModel : public QAbstractListModel { Q_OBJECT @@ -26,7 +28,7 @@ class FlirtModel : public QAbstractListModel friend FlirtWidget; public: - enum Column { + enum Column : ut8 { BinTypeColumn = 0, ArchNameColumn, ArchBitsColumn, @@ -35,9 +37,9 @@ public: DetailsColumn, ColumnCount }; - enum Role { FlirtDescriptionRole = Qt::UserRole }; + enum Role : ut16 { FlirtDescriptionRole = Qt::UserRole }; - FlirtModel(QObject *parent = 0); + FlirtModel(QObject *parent = nullptr); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; @@ -49,6 +51,9 @@ private: QList sigdb; }; +/** + * @brief Proxy model for @ref FlirtWidget + */ class FlirtProxyModel : public QSortFilterProxyModel { Q_OBJECT @@ -61,6 +66,9 @@ protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; +/** + * @brief Widget for browsing and applying FLIRT signatures to identify library functions + */ class FlirtWidget : public CutterDockWidget { Q_OBJECT diff --git a/src/widgets/FunctionsWidget.cpp b/src/widgets/FunctionsWidget.cpp index c4240482..2b6881ff 100644 --- a/src/widgets/FunctionsWidget.cpp +++ b/src/widgets/FunctionsWidget.cpp @@ -1,26 +1,24 @@ #include "FunctionsWidget.h" -#include "ui_ListDockWidget.h" -#include "core/MainWindow.h" #include "common/DisassemblyPreview.h" -#include "common/Helpers.h" #include "common/FunctionsTask.h" -#include "common/TempConfig.h" +#include "common/Helpers.h" +#include "core/MainWindow.h" #include "menus/AddressableItemContextMenu.h" #include "shortcuts/ShortcutManager.h" +#include "ui_ListDockWidget.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include #include +#include +#include +#include namespace { @@ -30,7 +28,8 @@ static const int kMaxTooltipHighlightsLines = 5; } -FunctionModel::FunctionModel(bool nested, QFont default_font, QFont highlight_font, QObject *parent) +FunctionModel::FunctionModel(bool nested, const QFont &default_font, const QFont &highlight_font, + QObject *parent) : AddressableItemModel<>(parent), highlightFont(highlight_font), defaultFont(default_font), @@ -50,8 +49,9 @@ FunctionModel::FunctionModel(bool nested, QFont default_font, QFont highlight_fo QModelIndex FunctionModel::index(int row, int column, const QModelIndex &parent) const { - if (!parent.isValid()) + if (!parent.isValid()) { return createIndex(row, column, (quintptr)0); // root function nodes have id = 0 + } return createIndex(row, column, (quintptr)(parent.row() + 1)); // sub-nodes have id = function index + 1 @@ -59,34 +59,40 @@ QModelIndex FunctionModel::index(int row, int column, const QModelIndex &parent) QModelIndex FunctionModel::parent(const QModelIndex &index) const { - if (!index.isValid() || index.column() != 0) + if (!index.isValid() || index.column() != 0) { return QModelIndex(); + } - if (index.internalId() == 0) // root function node + if (index.internalId() == 0) { // root function node return QModelIndex(); - else // sub-node + } else { // sub-node return this->index((int)(index.internalId() - 1), 0); + } } int FunctionModel::rowCount(const QModelIndex &parent) const { - if (!parent.isValid()) + if (!parent.isValid()) { return functions.count(); + } if (nested) { - if (parent.internalId() == 0) + if (parent.internalId() == 0) { return ColumnCount - 1; // sub-nodes for nested functions + } return 0; - } else + } else { return 0; + } } int FunctionModel::columnCount(const QModelIndex & /*parent*/) const { - if (nested) + if (nested) { return 1; - else + } else { return ColumnCount; + } } bool FunctionModel::functionIsImport(ut64 addr) const @@ -101,25 +107,27 @@ bool FunctionModel::functionIsMain(ut64 addr) const QVariant FunctionModel::data(const QModelIndex &index, int role) const { - if (!index.isValid()) + if (!index.isValid()) { return QVariant(); + } - int function_index; + int functionIndex; bool subnode; - bool is_dark; + bool isDark; if (index.internalId() != 0) { // sub-node - function_index = index.parent().row(); + functionIndex = index.parent().row(); subnode = true; } else { // root function node - function_index = index.row(); + functionIndex = index.row(); subnode = false; } - const FunctionDescription &function = functions.at(function_index); + const FunctionDescription &function = functions.at(functionIndex); - if (function_index >= functions.count()) + if (functionIndex >= functions.count()) { return QVariant(); + } switch (role) { case Qt::DisplayRole: @@ -127,18 +135,18 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const if (subnode) { switch (index.row()) { case 0: - return tr("Offset: %1").arg(RzAddressString(function.offset)); + return tr("Offset: %1").arg(rzAddressString(function.offset)); case 1: - return tr("Size: %1").arg(RzSizeString(function.linearSize)); + return tr("Size: %1").arg(rzSizeString(function.linearSize)); case 2: return tr("Import: %1") .arg(functionIsImport(function.offset) ? tr("true") : tr("false")); case 3: - return tr("Nargs: %1").arg(RzSizeString(function.nargs)); + return tr("Nargs: %1").arg(rzSizeString(function.nargs)); case 4: - return tr("Nbbs: %1").arg(RzSizeString(function.nbbs)); + return tr("Nbbs: %1").arg(rzSizeString(function.nbbs)); case 5: - return tr("Nlocals: %1").arg(RzSizeString(function.nlocals)); + return tr("Nlocals: %1").arg(rzSizeString(function.nlocals)); case 6: return tr("Call type: %1").arg(function.calltype); case 7: @@ -150,8 +158,9 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const default: return QVariant(); } - } else + } else { return function.name; + } } else { switch (index.column()) { case NameColumn: @@ -161,7 +170,7 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const case ImportColumn: return functionIsImport(function.offset) ? tr("true") : tr("false"); case OffsetColumn: - return RzAddressString(function.offset); + return rzAddressString(function.offset); case NargsColumn: return QString::number(function.nargs); case NlocalsColumn: @@ -189,22 +198,22 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const } if (index.column() == NameColumn) { - is_dark = Config()->windowColorIsDark(); + isDark = Config()->windowColorIsDark(); if (functionIsImport(function.offset)) { - if (is_dark) { + if (isDark) { return iconFuncImpDark; } return iconFuncImpLight; } else if (functionIsMain(function.offset)) { - if (is_dark) { + if (isDark) { return iconFuncMainDark; } return iconFuncMainLight; } - if (is_dark) { + if (isDark) { return iconFuncDark; } return iconFuncLight; @@ -214,42 +223,45 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const } case Qt::FontRole: - if (currentIndex == function_index) + if (currentIndex == functionIndex) { return highlightFont; + } return defaultFont; case Qt::TextAlignmentRole: - if (index.column() == 1) + if (index.column() == 1) { return static_cast(Qt::AlignRight | Qt::AlignVCenter); + } return static_cast(Qt::AlignLeft | Qt::AlignVCenter); case Qt::ToolTipRole: { - QStringList disasmPreview = + const QStringList disasmPreview = Core()->getDisassemblyPreview(function.offset, kMaxTooltipDisasmPreviewLines); QStringList summary {}; { auto core = Core()->lock(); auto seeker = Core()->seekTemp(function.offset); auto strings = fromOwnedCharPtr(rz_core_print_disasm_strings( - core, RZ_CORE_DISASM_STRINGS_MODE_FUNCTION, 0, NULL)); + core, RZ_CORE_DISASM_STRINGS_MODE_FUNCTION, 0, nullptr)); summary = strings.split('\n', CUTTER_QT_SKIP_EMPTY_PARTS); } const QFont &fnt = Config()->getFont(); - QFontMetrics fm { fnt }; + const QFontMetrics fm { fnt }; // elide long strings using current disasm font metrics QStringList highlights; - for (const QString &s : summary) { + for (const QString &s : std::as_const(summary)) { highlights << fm.elidedText(s, Qt::ElideRight, kMaxTooltipWidth); if (highlights.length() > kMaxTooltipHighlightsLines) { highlights << "..."; break; } } - if (disasmPreview.isEmpty() && highlights.isEmpty()) + if (disasmPreview.isEmpty() && highlights.isEmpty()) { return {}; + } QString toolTipContent = QString("
Disassembly " "preview:
%1
") .arg(disasmPreview.join("
")); + } if (!highlights.isEmpty()) { toolTipContent += tr("
Highlights:
%1
") @@ -284,10 +297,10 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const return QVariant(this->property("color")); - case FunctionDescriptionRole: + case functionDescriptionRole: return QVariant::fromValue(function); - case IsImportRole: + case isImportRole: return importAddresses.contains(function.offset); default: @@ -343,19 +356,19 @@ void FunctionModel::setNested(bool nested) RVA FunctionModel::address(const QModelIndex &index) const { - auto function = data(index, FunctionDescriptionRole).value(); + auto function = data(index, functionDescriptionRole).value(); return function.offset; } QString FunctionModel::name(const QModelIndex &index) const { - auto function = data(index, FunctionDescriptionRole).value(); + auto function = data(index, functionDescriptionRole).value(); return function.name; } void FunctionModel::seekChanged(RVA) { - int previousIndex = currentIndex; + const int previousIndex = currentIndex; if (updateCurrentIndex()) { if (previousIndex >= 0) { emit dataChanged(index(previousIndex, 0), index(previousIndex, columnCount() - 1)); @@ -371,7 +384,7 @@ bool FunctionModel::updateCurrentIndex() int index = -1; RVA offset = 0; - RVA seek = Core()->getOffset(); + const RVA seek = Core()->getOffset(); for (int i = 0; i < functions.count(); i++) { const FunctionDescription &function = functions.at(i); @@ -382,7 +395,7 @@ bool FunctionModel::updateCurrentIndex() } } - bool changed = currentIndex != index; + const bool changed = currentIndex != index; currentIndex = index; @@ -410,80 +423,90 @@ FunctionSortFilterProxyModel::FunctionSortFilterProxyModel(FunctionModel *source bool FunctionSortFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); - FunctionDescription function = - index.data(FunctionModel::FunctionDescriptionRole).value(); + const QModelIndex index = sourceModel()->index(row, 0, parent); + const auto function = + index.data(FunctionModel::functionDescriptionRole).value(); return qhelpers::filterStringContains(function.name, this); } bool FunctionSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - if (!left.isValid() || !right.isValid()) + if (!left.isValid() || !right.isValid()) { return false; + } - if (left.parent().isValid() || right.parent().isValid()) + if (left.parent().isValid() || right.parent().isValid()) { return false; + } - FunctionDescription left_function = - left.data(FunctionModel::FunctionDescriptionRole).value(); - FunctionDescription right_function = - right.data(FunctionModel::FunctionDescriptionRole).value(); + const auto leftFunction = + left.data(FunctionModel::functionDescriptionRole).value(); + const auto rightFunction = + right.data(FunctionModel::functionDescriptionRole).value(); if (static_cast(sourceModel())->isNested()) { - return left_function.name < right_function.name; + return leftFunction.name < rightFunction.name; } else { switch (left.column()) { case FunctionModel::OffsetColumn: - return left_function.offset < right_function.offset; + return leftFunction.offset < rightFunction.offset; case FunctionModel::SizeColumn: - if (left_function.linearSize != right_function.linearSize) - return left_function.linearSize < right_function.linearSize; + if (leftFunction.linearSize != rightFunction.linearSize) { + return leftFunction.linearSize < rightFunction.linearSize; + } break; case FunctionModel::ImportColumn: { - bool left_is_import = left.data(FunctionModel::IsImportRole).toBool(); - bool right_is_import = right.data(FunctionModel::IsImportRole).toBool(); - if (!left_is_import && right_is_import) + const bool leftIsImport = left.data(FunctionModel::isImportRole).toBool(); + const bool rightIsImport = right.data(FunctionModel::isImportRole).toBool(); + if (!leftIsImport && rightIsImport) { return true; + } break; } case FunctionModel::NameColumn: - return left_function.name < right_function.name; + return leftFunction.name < rightFunction.name; case FunctionModel::NargsColumn: - if (left_function.nargs != right_function.nargs) - return left_function.nargs < right_function.nargs; + if (leftFunction.nargs != rightFunction.nargs) { + return leftFunction.nargs < rightFunction.nargs; + } break; case FunctionModel::NlocalsColumn: - if (left_function.nlocals != right_function.nlocals) - return left_function.nlocals < right_function.nlocals; + if (leftFunction.nlocals != rightFunction.nlocals) { + return leftFunction.nlocals < rightFunction.nlocals; + } break; case FunctionModel::NbbsColumn: - if (left_function.nbbs != right_function.nbbs) - return left_function.nbbs < right_function.nbbs; + if (leftFunction.nbbs != rightFunction.nbbs) { + return leftFunction.nbbs < rightFunction.nbbs; + } break; case FunctionModel::CalltypeColumn: - return left_function.calltype < right_function.calltype; + return leftFunction.calltype < rightFunction.calltype; case FunctionModel::EdgesColumn: - if (left_function.edges != right_function.edges) - return left_function.edges < right_function.edges; + if (leftFunction.edges != rightFunction.edges) { + return leftFunction.edges < rightFunction.edges; + } break; case FunctionModel::FrameColumn: - if (left_function.stackframe != right_function.stackframe) - return left_function.stackframe < right_function.stackframe; + if (leftFunction.stackframe != rightFunction.stackframe) { + return leftFunction.stackframe < rightFunction.stackframe; + } break; case FunctionModel::CommentColumn: - return Core()->getCommentAt(left_function.offset) - < Core()->getCommentAt(right_function.offset); + return Core()->getCommentAt(leftFunction.offset) + < Core()->getCommentAt(rightFunction.offset); default: return false; } - return left_function.offset < right_function.offset; + return leftFunction.offset < rightFunction.offset; } } FunctionsWidget::FunctionsWidget(MainWindow *main) : ListDockWidget(main), + titleContextMenu(new QMenu(this)), actionRename(tr("Rename"), this), actionUndefine(tr("Undefine"), this), actionHorizontal(tr("Horizontal"), this), @@ -495,17 +518,17 @@ FunctionsWidget::FunctionsWidget(MainWindow *main) setTooltipStylesheet(); connect(Config(), &Configuration::colorsUpdated, this, &FunctionsWidget::setTooltipStylesheet); - QFontInfo font_info = ui->treeView->fontInfo(); - QFont default_font = QFont(font_info.family(), font_info.pointSize()); - QFont highlight_font = QFont(font_info.family(), font_info.pointSize(), QFont::Bold); + const QFontInfo fontInfo = ui->treeView->fontInfo(); + const QFont defaultFont = QFont(fontInfo.family(), fontInfo.pointSize()); + const QFont highlightFont = QFont(fontInfo.family(), fontInfo.pointSize(), QFont::Bold); - functionModel = new FunctionModel(false, default_font, highlight_font, this); + functionModel = new FunctionModel(false, defaultFont, highlightFont, this); functionProxyModel = new FunctionSortFilterProxyModel(functionModel, this); + setModels(functionProxyModel); ui->treeView->sortByColumn(FunctionModel::NameColumn, Qt::AscendingOrder); ui->treeView->setExpandsOnDoubleClick(false); - titleContextMenu = new QMenu(this); auto viewTypeGroup = new QActionGroup(titleContextMenu); actionHorizontal.setCheckable(true); actionHorizontal.setActionGroup(viewTypeGroup); @@ -558,7 +581,7 @@ FunctionsWidget::FunctionsWidget(MainWindow *main) }); auto updateNameColumnWidth = [this] { - bool truncate = Config()->getTruncateFunctionNameCol(); + const bool truncate = Config()->getTruncateFunctionNameCol(); if (truncate) { maxFunctionNameWidth = Config()->getFunctionNameColWidth(); } @@ -578,8 +601,8 @@ void FunctionsWidget::refreshTree() task->wait(); } - task = QSharedPointer(new FunctionsTask()); - connect(task.data(), &FunctionsTask::fetchFinished, this, + task = std::shared_ptr(new FunctionsTask()); + connect(task.get(), &FunctionsTask::fetchFinished, this, [this](const QList &functions) { functionModel->beginResetModel(); @@ -592,12 +615,12 @@ void FunctionsWidget::refreshTree() functionModel->mainAdress = RVA_INVALID; RzCoreLocked core(Core()); - RzBinFile *bf = rz_bin_cur(core->bin); + const RzBinFile *bf = rz_bin_cur(core->bin); if (bf) { const RzBinAddr *binmain = rz_bin_object_get_special_symbol(bf->o, RZ_BIN_SPECIAL_SYMBOL_MAIN); if (binmain) { - int va = core->io->va || core->bin->is_debugger; + const int va = core->io->va || core->bin->is_debugger; functionModel->mainAdress = va ? rz_bin_object_addr_with_base(bf->o, binmain->vaddr) : binmain->paddr; @@ -629,14 +652,14 @@ void FunctionsWidget::changeSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Pol void FunctionsWidget::onActionFunctionsRenameTriggered() { // Get selected item in functions tree view - FunctionDescription function = ui->treeView->selectionModel() - ->currentIndex() - .data(FunctionModel::FunctionDescriptionRole) - .value(); + const auto function = ui->treeView->selectionModel() + ->currentIndex() + .data(FunctionModel::functionDescriptionRole) + .value(); bool ok; // Create dialog - QString newName = + const QString newName = QInputDialog::getText(this, tr("Rename function %1").arg(function.name), tr("Function name:"), QLineEdit::Normal, function.name, &ok); // If user accepted @@ -656,7 +679,7 @@ void FunctionsWidget::onActionFunctionsUndefineTriggered() for (const auto &index : selection) { offsets.insert(functionProxyModel->address(index)); } - for (RVA offset : offsets) { + for (const RVA &offset : offsets) { Core()->delFunction(offset); } } @@ -689,9 +712,6 @@ void FunctionsWidget::onActionVerticalToggled(bool enable) } } -/** - * @brief a SLOT to set the stylesheet for a tooltip - */ void FunctionsWidget::setTooltipStylesheet() { setStyleSheet(DisassemblyPreview::getToolTipStyleSheet()); diff --git a/src/widgets/FunctionsWidget.h b/src/widgets/FunctionsWidget.h index 231e9bc9..ca83ff3f 100644 --- a/src/widgets/FunctionsWidget.h +++ b/src/widgets/FunctionsWidget.h @@ -1,16 +1,21 @@ #ifndef FUNCTIONSWIDGET_H #define FUNCTIONSWIDGET_H -#include - -#include "core/Cutter.h" +#include "CutterDescriptions.h" #include "CutterDockWidget.h" #include "widgets/ListDockWidget.h" +#include + +#include + class MainWindow; class FunctionsTask; class FunctionsWidget; +/** + * @brief Source model for @ref FunctionsWidget + */ class FunctionModel : public AddressableItemModel<> { Q_OBJECT @@ -40,10 +45,10 @@ private: bool functionIsMain(ut64 addr) const; public: - static const int FunctionDescriptionRole = Qt::UserRole; - static const int IsImportRole = Qt::UserRole + 1; + static const int functionDescriptionRole = Qt::UserRole; + static const int isImportRole = Qt::UserRole + 1; - enum Column { + enum Column : ut8 { NameColumn = 0, SizeColumn, ImportColumn, @@ -58,7 +63,8 @@ public: ColumnCount }; - FunctionModel(bool nested, QFont defaultFont, QFont highlightFont, QObject *parent = nullptr); + FunctionModel(bool nested, const QFont &defaultFont, const QFont &highlightFont, + QObject *parent = nullptr); QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; @@ -77,7 +83,7 @@ public: bool updateCurrentIndex(); void setNested(bool nested); - bool isNested() { return nested; } + bool isNested() const { return nested; } RVA address(const QModelIndex &index) const override; QString name(const QModelIndex &index) const override; @@ -86,6 +92,9 @@ private slots: void functionRenamed(const RVA offset, const QString &new_name); }; +/** + * @brief Sort filter proxy model for @ref FunctionsWidget + */ class FunctionSortFilterProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -98,6 +107,9 @@ protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; +/** + * @brief Widget for displaying all functions + */ class FunctionsWidget : public ListDockWidget { Q_OBJECT @@ -113,11 +125,14 @@ private slots: void onActionHorizontalToggled(bool enable); void onActionVerticalToggled(bool enable); void showTitleContextMenu(const QPoint &pt); + /** + * @brief a SLOT to set the stylesheet for a tooltip + */ void setTooltipStylesheet(); void refreshTree(); private: - QSharedPointer task; + std::shared_ptr task; FunctionModel *functionModel; FunctionSortFilterProxyModel *functionProxyModel; diff --git a/src/widgets/GlibcHeapWidget.cpp b/src/widgets/GlibcHeapWidget.cpp index a06f6a77..d2a2cbdb 100644 --- a/src/widgets/GlibcHeapWidget.cpp +++ b/src/widgets/GlibcHeapWidget.cpp @@ -1,10 +1,12 @@ -#include -#include #include "GlibcHeapWidget.h" -#include "ui_GlibcHeapWidget.h" -#include "core/MainWindow.h" + #include "QHeaderView" +#include "core/MainWindow.h" #include "dialogs/GlibcHeapInfoDialog.h" +#include "ui_GlibcHeapWidget.h" + +#include +#include GlibcHeapWidget::GlibcHeapWidget(MainWindow *main, QWidget *parent) : QWidget(parent), @@ -49,10 +51,7 @@ GlibcHeapWidget::GlibcHeapWidget(MainWindow *main, QWidget *parent) [this]() { updateContents(); }); } -GlibcHeapWidget::~GlibcHeapWidget() -{ - delete ui; -} +GlibcHeapWidget::~GlibcHeapWidget() {} GlibcHeapModel::GlibcHeapModel(QObject *parent) : QAbstractTableModel(parent) {} @@ -66,7 +65,7 @@ void GlibcHeapWidget::updateArenas() // add the new arenas to the arena selector for (auto &arena : arenas) { - arenaSelectorView->addItem(RzAddressString(arena.offset) + arenaSelectorView->addItem(rzAddressString(arena.offset) + QString(" (" + arena.type + " Arena)")); } @@ -80,9 +79,9 @@ void GlibcHeapWidget::updateArenas() void GlibcHeapWidget::onArenaSelected(int index) { if (index == -1) { - modelHeap->arena_addr = 0; + modelHeap->arenaAddr = 0; } else { - modelHeap->arena_addr = arenas[index].offset; + modelHeap->arenaAddr = arenas[index].offset; } updateChunks(); @@ -113,7 +112,7 @@ void GlibcHeapModel::reload() { beginResetModel(); values.clear(); - values = Core()->getHeapChunks(arena_addr); + values = Core()->getHeapChunks(arenaAddr); endResetModel(); } @@ -129,8 +128,9 @@ int GlibcHeapModel::rowCount(const QModelIndex &) const QVariant GlibcHeapModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= values.count()) + if (!index.isValid() || index.row() >= values.count()) { return QVariant(); + } const auto &item = values.at(index.row()); @@ -138,9 +138,9 @@ QVariant GlibcHeapModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case OffsetColumn: - return RzAddressString(item.offset); + return rzAddressString(item.offset); case SizeColumn: - return RzHexString(item.size); + return rzHexString(item.size); case StatusColumn: return item.status; default: @@ -177,9 +177,9 @@ void GlibcHeapWidget::onDoubleClicked(const QModelIndex &index) return; } - int column = index.column(); + const int column = index.column(); if (column == GlibcHeapModel::OffsetColumn) { - QString item = index.data().toString(); + const QString item = index.data().toString(); Core()->seek(item); main->showMemoryWidget(MemoryWidgetType::Hexdump); } @@ -191,21 +191,23 @@ void GlibcHeapWidget::onCurrentChanged(const QModelIndex ¤t, const QModelI Q_UNUSED(prev) auto currentIndex = viewHeap->selectionModel()->currentIndex(); - QString offsetString = currentIndex.sibling(currentIndex.row(), GlibcHeapModel::OffsetColumn) - .data() - .toString(); + const QString offsetString = + currentIndex.sibling(currentIndex.row(), GlibcHeapModel::OffsetColumn) + .data() + .toString(); addressableItemContextMenu.setTarget(Core()->math(offsetString)); } void GlibcHeapWidget::viewChunkInfo() { auto currentIndex = viewHeap->selectionModel()->currentIndex(); - QString offsetString = currentIndex.sibling(currentIndex.row(), GlibcHeapModel::OffsetColumn) + const QString offsetString = + currentIndex.sibling(currentIndex.row(), GlibcHeapModel::OffsetColumn) + .data() + .toString(); + const QString status = currentIndex.sibling(currentIndex.row(), GlibcHeapModel::StatusColumn) .data() .toString(); - QString status = currentIndex.sibling(currentIndex.row(), GlibcHeapModel::StatusColumn) - .data() - .toString(); GlibcHeapInfoDialog heapInfoDialog(Core()->math(offsetString), status, this); heapInfoDialog.exec(); @@ -213,7 +215,7 @@ void GlibcHeapWidget::viewChunkInfo() void GlibcHeapWidget::viewBinInfo() { - GlibcHeapBinsDialog heapBinsDialog(modelHeap->arena_addr, main, this); + GlibcHeapBinsDialog heapBinsDialog(modelHeap->arenaAddr, main, this); heapBinsDialog.exec(); } @@ -222,7 +224,7 @@ void GlibcHeapWidget::viewArenaInfo() // find the active arena Arena currentArena; for (auto &arena : arenas) { - if (arena.offset == modelHeap->arena_addr) { + if (arena.offset == modelHeap->arenaAddr) { currentArena = arena; break; } @@ -230,4 +232,4 @@ void GlibcHeapWidget::viewArenaInfo() ArenaInfoDialog arenaInfoDialog(currentArena, this); arenaInfoDialog.exec(); -} \ No newline at end of file +} diff --git a/src/widgets/GlibcHeapWidget.h b/src/widgets/GlibcHeapWidget.h index 23a4d7bd..eb4acf18 100644 --- a/src/widgets/GlibcHeapWidget.h +++ b/src/widgets/GlibcHeapWidget.h @@ -1,34 +1,43 @@ #ifndef GLIBCHEAPWIDGET_H #define GLIBCHEAPWIDGET_H -#include +#include "CutterDescriptions.h" #include "CutterDockWidget.h" -#include "core/Cutter.h" -#include + #include +#include +#include + #include +#include namespace Ui { class GlibcHeapWidget; } +/** + * @brief Source model for @ref GlibcHeapWidget + */ class GlibcHeapModel : public QAbstractTableModel { Q_OBJECT public: explicit GlibcHeapModel(QObject *parent = nullptr); - enum Column { OffsetColumn = 0, SizeColumn, StatusColumn, ColumnCount }; + enum Column : ut8 { OffsetColumn = 0, SizeColumn, StatusColumn, ColumnCount }; void reload(); int rowCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex &parent) const override; QVariant data(const QModelIndex &index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - RVA arena_addr = 0; + RVA arenaAddr = 0; private: QVector values; }; +/** + * @brief Widget listing glibc heap during debugging/emulation + */ class GlibcHeapWidget : public QWidget { Q_OBJECT @@ -49,7 +58,7 @@ private slots: private: void updateArenas(); void updateChunks(); - Ui::GlibcHeapWidget *ui; + std::unique_ptr ui; QTableView *viewHeap; QComboBox *arenaSelectorView; GlibcHeapModel *modelHeap = new GlibcHeapModel(this); diff --git a/src/widgets/GlobalsWidget.cpp b/src/widgets/GlobalsWidget.cpp index 37957db2..03896e27 100644 --- a/src/widgets/GlobalsWidget.cpp +++ b/src/widgets/GlobalsWidget.cpp @@ -1,9 +1,10 @@ #include "GlobalsWidget.h" -#include "ui_GlobalsWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" #include "dialogs/GlobalVariableDialog.h" #include "shortcuts/ShortcutManager.h" +#include "ui_GlobalsWidget.h" #include #include @@ -32,7 +33,7 @@ QVariant GlobalsModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case GlobalsModel::AddressColumn: - return RzAddressString(global.addr); + return rzAddressString(global.addr); case GlobalsModel::TypeColumn: return QString(global.type).trimmed(); case GlobalsModel::NameColumn: @@ -91,7 +92,7 @@ GlobalsProxyModel::GlobalsProxyModel(GlobalsModel *sourceModel, QObject *parent) bool GlobalsProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); + const QModelIndex index = sourceModel()->index(row, 0, parent); auto global = index.data(GlobalsModel::GlobalDescriptionRole).value(); return qhelpers::filterStringContains(global.name, this); @@ -120,13 +121,13 @@ bool GlobalsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &rig void GlobalsWidget::editGlobal() { - QModelIndex index = ui->treeView->currentIndex(); + const QModelIndex index = ui->treeView->currentIndex(); if (!index.isValid()) { return; } - RVA globalVariableAddress = globalsProxyModel->address(index); + const RVA globalVariableAddress = globalsProxyModel->address(index); GlobalVariableDialog dialog(globalVariableAddress, parentWidget()); dialog.exec(); @@ -134,17 +135,21 @@ void GlobalsWidget::editGlobal() void GlobalsWidget::deleteGlobal() { - QModelIndex index = ui->treeView->currentIndex(); + const QModelIndex index = ui->treeView->currentIndex(); if (!index.isValid()) { return; } - RVA globalVariableAddress = globalsProxyModel->address(index); + const RVA globalVariableAddress = globalsProxyModel->address(index); Core()->delGlobalVariable(globalVariableAddress); } -GlobalsWidget::GlobalsWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui::GlobalsWidget) +GlobalsWidget::GlobalsWidget(MainWindow *main) + : CutterDockWidget(main), + ui(new Ui::GlobalsWidget), + globalsModel(new GlobalsModel(this)), + globalsProxyModel(new GlobalsProxyModel(globalsModel, this)) { ui->setupUi(this); ui->quickFilterView->setLabelText(tr("Category")); @@ -158,9 +163,8 @@ GlobalsWidget::GlobalsWidget(MainWindow *main) : CutterDockWidget(main), ui(new ui->treeView->setMainWindow(mainWindow); // Setup up the model and the proxy model - globalsModel = new GlobalsModel(this); - globalsProxyModel = new GlobalsProxyModel(globalsModel, this); - ui->treeView->setModel(globalsProxyModel); + + ui->treeView->setModel(static_cast(globalsProxyModel)); ui->treeView->sortByColumn(GlobalsModel::AddressColumn, Qt::AscendingOrder); // Setup custom context menu diff --git a/src/widgets/GlobalsWidget.h b/src/widgets/GlobalsWidget.h index 0e282ab1..de185a42 100644 --- a/src/widgets/GlobalsWidget.h +++ b/src/widgets/GlobalsWidget.h @@ -1,13 +1,14 @@ #ifndef GLOBALSWIDGET_H #define GLOBALSWIDGET_H -#include +#include "CutterDescriptions.h" +#include "CutterDockWidget.h" +#include "widgets/ListDockWidget.h" + #include #include -#include "core/Cutter.h" -#include "CutterDockWidget.h" -#include "widgets/ListDockWidget.h" +#include class MainWindow; class QTreeWidget; @@ -20,6 +21,9 @@ class GlobalsWidget; class MainWindow; class QTreeWidgetItem; +/** + * @brief Source model for @ref GlobalsWidget + */ class GlobalsModel : public AddressableItemModel { Q_OBJECT @@ -30,8 +34,8 @@ private: QList globals; public: - enum Column { AddressColumn = 0, TypeColumn, NameColumn, CommentColumn, ColumnCount }; - enum Role { GlobalDescriptionRole = Qt::UserRole }; + enum Column : ut8 { AddressColumn = 0, TypeColumn, NameColumn, CommentColumn, ColumnCount }; + enum Role : ut16 { GlobalDescriptionRole = Qt::UserRole }; GlobalsModel(QObject *parent = nullptr); @@ -46,6 +50,9 @@ public: QString name(const QModelIndex &index) const override; }; +/** + * @brief Proxy model for @ref GlobalsWidget + */ class GlobalsProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -58,6 +65,9 @@ protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; +/** + * @brief Widget for listing and editing info about global objects + */ class GlobalsWidget : public CutterDockWidget { Q_OBJECT diff --git a/src/widgets/GraphGridLayout.cpp b/src/widgets/GraphGridLayout.cpp index 0f85702f..91e4da24 100644 --- a/src/widgets/GraphGridLayout.cpp +++ b/src/widgets/GraphGridLayout.cpp @@ -1,13 +1,13 @@ #include "GraphGridLayout.h" -#include -#include -#include -#include -#include +#include "common/BinaryTrees.h" + #include -#include "common/BinaryTrees.h" +#include +#include +#include +#include /** @class GraphGridLayout @@ -56,7 +56,7 @@ be interpreted as every second row and column being reserved for edges. The row using the first interpretation. To allow better centering of nodes one above other, each node is 2 columns wide and 1 row high. -\image html graph_grid.svg +@image html graph_grid.svg # 1-2 Cycle removal and toposort @@ -95,7 +95,7 @@ In compact mode two subtrees are placed side by side accounting for their shape. mode the bounding box of the shorter subtree is used instead of its exact shape. This gives slightly sparser layout without being too wide. -\image html graph_parent_placement.svg +@image html graph_parent_placement.svg # Edge routing Edge routing can be split into: main column selection, rough routing, and segment offset @@ -150,7 +150,7 @@ tallest block within a row. One common case is a function-entry block being wide function name, causing wide horizontal space between branching blocks. Another case is rows in two parallel columns being aligned. -\image html layout_compacting.svg +@image html layout_compacting.svg Both problems are mitigated by squishing the graph. Compressing in each of the two direction is done separately. The process is defined as liner program. Each variable represents a position of edge @@ -218,18 +218,18 @@ std::vector GraphGridLayout::topoSort(LayoutState &state, ut64 entry) stack.push({ first, 0 }); while (!stack.empty()) { auto v = stack.top().first; - auto edge_index = stack.top().second; + auto edgeIndex = stack.top().second; const auto &block = blocks[v]; - if (edge_index < block.edges.size()) { + if (edgeIndex < block.edges.size()) { ++stack.top().second; - auto target = block.edges[edge_index].target; + auto target = block.edges[edgeIndex].target; auto &targetState = visited[target]; if (targetState == State::NotVisited) { targetState = State::InStack; stack.push({ target, 0 }); - state.grid_blocks[v].dag_edge.push_back(target); + state.gridBlocks[v].dagEdge.push_back(target); } else if (targetState == State::Visited) { - state.grid_blocks[v].dag_edge.push_back(target); + state.gridBlocks[v].dagEdge.push_back(target); } // else { targetState == 1 in stack, loop edge } } else { stack.pop(); @@ -255,11 +255,11 @@ std::vector GraphGridLayout::topoSort(LayoutState &state, ut64 entry) void GraphGridLayout::assignRows(GraphGridLayout::LayoutState &state, const std::vector &blockOrder) { - for (auto it = blockOrder.rbegin(), end = blockOrder.rend(); it != end; it++) { - auto &block = state.grid_blocks[*it]; - int nextLevel = block.row + 1; - for (auto target : block.dag_edge) { - auto &targetBlock = state.grid_blocks[target]; + for (auto it = blockOrder.rbegin(), end = blockOrder.rend(); it != end; it++) { // NOLINT + auto &block = state.gridBlocks[*it]; + const int nextLevel = block.row + 1; + for (auto target : block.dagEdge) { + auto &targetBlock = state.gridBlocks[target]; targetBlock.row = std::max(targetBlock.row, nextLevel); } } @@ -267,19 +267,19 @@ void GraphGridLayout::assignRows(GraphGridLayout::LayoutState &state, void GraphGridLayout::selectTree(GraphGridLayout::LayoutState &state) { - for (auto &blockIt : state.grid_blocks) { + for (auto &blockIt : state.gridBlocks) { auto &block = blockIt.second; - for (auto targetId : block.dag_edge) { - auto &targetBlock = state.grid_blocks[targetId]; - if (!targetBlock.has_parent && targetBlock.row == block.row + 1) { - block.tree_edge.push_back(targetId); - targetBlock.has_parent = true; + for (auto targetId : block.dagEdge) { + auto &targetBlock = state.gridBlocks[targetId]; + if (!targetBlock.hasParent && targetBlock.row == block.row + 1) { + block.treeEdge.push_back(targetId); + targetBlock.hasParent = true; } } } } -void GraphGridLayout::CalculateLayout(GraphLayout::Graph &blocks, ut64 entry, int &width, +void GraphGridLayout::calculateLayout(GraphLayout::Graph &blocks, ut64 entry, int &width, int &height) const { LayoutState layoutState; @@ -294,7 +294,7 @@ void GraphGridLayout::CalculateLayout(GraphLayout::Graph &blocks, ut64 entry, in for (auto &it : blocks) { GridBlock block; block.id = it.first; - layoutState.grid_blocks[it.first] = block; + layoutState.gridBlocks[it.first] = block; } auto blockOrder = topoSort(layoutState, entry); @@ -308,17 +308,17 @@ void GraphGridLayout::CalculateLayout(GraphLayout::Graph &blocks, ut64 entry, in } } for (const auto &edgeList : layoutState.edge) { - auto &startBlock = layoutState.grid_blocks[edgeList.first]; + auto &startBlock = layoutState.gridBlocks[edgeList.first]; startBlock.outputCount = edgeList.second.size(); for (auto &edge : edgeList.second) { - auto &targetBlock = layoutState.grid_blocks[edge.dest]; + auto &targetBlock = layoutState.gridBlocks[edge.dest]; targetBlock.inputCount++; } } layoutState.columns = 1; layoutState.rows = 1; - for (auto &node : layoutState.grid_blocks) { + for (auto &node : layoutState.gridBlocks) { // count is at least index + 1 layoutState.rows = std::max(layoutState.rows, size_t(node.second.row) + 1); // block is 2 column wide @@ -327,7 +327,7 @@ void GraphGridLayout::CalculateLayout(GraphLayout::Graph &blocks, ut64 entry, in layoutState.rowHeight.assign(layoutState.rows, 0); layoutState.columnWidth.assign(layoutState.columns, 0); - for (auto &node : layoutState.grid_blocks) { + for (auto &node : layoutState.gridBlocks) { const auto &inputBlock = blocks[node.first]; layoutState.rowHeight[node.second.row] = std::max(inputBlock.height, layoutState.rowHeight[node.second.row]); @@ -348,33 +348,33 @@ void GraphGridLayout::CalculateLayout(GraphLayout::Graph &blocks, ut64 entry, in void GraphGridLayout::findMergePoints(GraphGridLayout::LayoutState &state) const { - for (auto &blockIt : state.grid_blocks) { + for (auto &blockIt : state.gridBlocks) { auto &block = blockIt.second; - GridBlock *mergeBlock = nullptr; + const GridBlock *mergeBlock = nullptr; int grandChildCount = 0; - for (auto edge : block.tree_edge) { - auto &targetBlock = state.grid_blocks[edge]; - if (targetBlock.tree_edge.size()) { - mergeBlock = &state.grid_blocks[targetBlock.tree_edge[0]]; + for (auto edge : block.treeEdge) { + auto &targetBlock = state.gridBlocks[edge]; + if (targetBlock.treeEdge.size()) { + mergeBlock = &state.gridBlocks[targetBlock.treeEdge[0]]; } - grandChildCount += targetBlock.tree_edge.size(); + grandChildCount += targetBlock.treeEdge.size(); } if (!mergeBlock || grandChildCount != 1) { continue; } int blocksGoingToMerge = 0; int blockWithTreeEdge = 0; - for (auto edge : block.tree_edge) { - auto &targetBlock = state.grid_blocks[edge]; + for (auto edge : block.treeEdge) { + auto &targetBlock = state.gridBlocks[edge]; bool goesToMerge = false; - for (auto secondEdgeTarget : targetBlock.dag_edge) { + for (auto secondEdgeTarget : targetBlock.dagEdge) { if (secondEdgeTarget == mergeBlock->id) { goesToMerge = true; break; } } if (goesToMerge) { - if (targetBlock.tree_edge.size() == 1) { + if (targetBlock.treeEdge.size() == 1) { blockWithTreeEdge = blocksGoingToMerge; } blocksGoingToMerge++; @@ -384,7 +384,7 @@ void GraphGridLayout::findMergePoints(GraphGridLayout::LayoutState &state) const } if (blocksGoingToMerge) { block.mergeBlock = mergeBlock->id; - state.grid_blocks[block.tree_edge[blockWithTreeEdge]].col = + state.gridBlocks[block.treeEdge[blockWithTreeEdge]].col = blockWithTreeEdge * 2 - (blocksGoingToMerge - 1); } } @@ -405,9 +405,9 @@ void GraphGridLayout::computeAllBlockPlacement(const std::vector &blockOrd // Process nodes in the order from bottom to top. Ensures that all subtrees are processed before // parent node. for (auto blockId : blockOrder) { - auto &block = layoutState.grid_blocks[blockId]; - if (block.tree_edge.size() == 0) { - block.row_count = 1; + auto &block = layoutState.gridBlocks[blockId]; + if (block.treeEdge.size() == 0) { + block.rowCount = 1; block.col = 0; block.lastRowRight = 2; block.lastRowLeft = 0; @@ -417,19 +417,19 @@ void GraphGridLayout::computeAllBlockPlacement(const std::vector &blockOrd block.leftSideShape = sides.makeList(0); block.rightSideShape = sides.makeList(2); } else { - auto &firstChild = layoutState.grid_blocks[block.tree_edge[0]]; + auto &firstChild = layoutState.gridBlocks[block.treeEdge[0]]; auto leftSide = firstChild .leftSideShape; // left side of block children subtrees processed so far auto rightSide = firstChild.rightSideShape; - block.row_count = firstChild.row_count; + block.rowCount = firstChild.rowCount; block.lastRowRight = firstChild.lastRowRight; block.lastRowLeft = firstChild.lastRowLeft; block.leftPosition = firstChild.leftPosition; block.rightPosition = firstChild.rightPosition; // Place children subtrees side by side - for (size_t i = 1; i < block.tree_edge.size(); i++) { - auto &child = layoutState.grid_blocks[block.tree_edge[i]]; + for (size_t i = 1; i < block.treeEdge.size(); i++) { + auto &child = layoutState.gridBlocks[block.treeEdge[i]]; int minPos = INT_MIN; int leftPos = 0; int rightPos = 0; @@ -477,7 +477,7 @@ void GraphGridLayout::computeAllBlockPlacement(const std::vector &blockOrd rightSide = child.rightSideShape; } *sides.head(rightSide) += rightTreeOffset; - block.row_count = std::max(block.row_count, child.row_count); + block.rowCount = std::max(block.rowCount, child.rowCount); block.leftPosition = std::min(block.leftPosition, child.leftPosition + rightTreeOffset); block.rightPosition = @@ -488,20 +488,20 @@ void GraphGridLayout::computeAllBlockPlacement(const std::vector &blockOrd // Calculate parent position if (parentBetweenDirectChild) { // mode a) keep one child to the left, other to the right - for (auto target : block.tree_edge) { - col += layoutState.grid_blocks[target].col; + for (auto target : block.treeEdge) { + col += layoutState.gridBlocks[target].col; } - col /= block.tree_edge.size(); + col /= block.treeEdge.size(); } else { // mode b) somewhere between left most direct child and right most, preferably in // the middle of horizontal dimensions. Results layout looks more like single // vertical line. col = (block.rightPosition + block.leftPosition) / 2 - 1; - col = std::max(col, layoutState.grid_blocks[block.tree_edge.front()].col - 1); - col = std::min(col, layoutState.grid_blocks[block.tree_edge.back()].col + 1); + col = std::max(col, layoutState.gridBlocks[block.treeEdge.front()].col - 1); + col = std::min(col, layoutState.gridBlocks[block.treeEdge.back()].col + 1); } block.col += col; // += instead of = to keep offset calculated in previous steps - block.row_count += 1; + block.rowCount += 1; block.leftPosition = std::min(block.leftPosition, block.col); block.rightPosition = std::max(block.rightPosition, block.col + 2); @@ -512,8 +512,8 @@ void GraphGridLayout::computeAllBlockPlacement(const std::vector &blockOrd block.rightSideShape = sides.append(sides.makeList(block.col + 2), rightSide); // Keep children positions relative to parent so that moving parent moves whole subtree - for (auto target : block.tree_edge) { - auto &targetBlock = layoutState.grid_blocks[target]; + for (auto target : block.treeEdge) { + auto &targetBlock = layoutState.gridBlocks[target]; targetBlock.col -= block.col; } } @@ -523,7 +523,7 @@ void GraphGridLayout::computeAllBlockPlacement(const std::vector &blockOrd // entrypoint. There can be more of them in case of switch statement analysis failure, // unreahable basic blocks or using the algorithm for non control flow graphs. int nextEmptyColumn = 0; - for (auto &blockIt : layoutState.grid_blocks) { + for (auto &blockIt : layoutState.gridBlocks) { auto &block = blockIt.second; if (block.row == 0) { // place all the roots first auto offset = -block.leftPosition; @@ -532,11 +532,11 @@ void GraphGridLayout::computeAllBlockPlacement(const std::vector &blockOrd } } // Visit all nodes top to bottom, converting relative positions to absolute. - for (auto it = blockOrder.rbegin(), end = blockOrder.rend(); it != end; it++) { - auto &block = layoutState.grid_blocks[*it]; + for (auto it = blockOrder.rbegin(), end = blockOrder.rend(); it != end; it++) { // NOLINT + auto &block = layoutState.gridBlocks[*it]; assert(block.col >= 0); - for (auto childId : block.tree_edge) { - auto &childBlock = layoutState.grid_blocks[childId]; + for (auto childId : block.treeEdge) { + auto &childBlock = layoutState.gridBlocks[childId]; childBlock.col += block.col; } } @@ -561,23 +561,23 @@ void GraphGridLayout::calculateEdgeMainColumn(GraphGridLayout::LayoutState &stat ut64 blockId; size_t edgeId; int row; - enum Type { Edge = 0, Block = 1 } type; + enum Type : ut8 { Edge = 0, Block = 1 } type; }; // create events std::vector events; - events.reserve(state.grid_blocks.size() * 2); - for (const auto &it : state.grid_blocks) { + events.reserve(state.gridBlocks.size() * 2); + for (const auto &it : state.gridBlocks) { events.push_back({ it.first, 0, it.second.row, Event::Block }); const auto &inputBlock = (*state.blocks)[it.first]; - int startRow = it.second.row + 1; + const int startRow = it.second.row + 1; auto gridEdges = state.edge[it.first]; gridEdges.resize(inputBlock.edges.size()); for (size_t i = 0; i < inputBlock.edges.size(); i++) { auto targetId = inputBlock.edges[i].target; gridEdges[i].dest = targetId; - const auto &targetGridBlock = state.grid_blocks[targetId]; - int endRow = targetGridBlock.row; + const auto &targetGridBlock = state.gridBlocks[targetId]; + const int endRow = targetGridBlock.row; events.push_back({ it.first, i, std::max(startRow, endRow), Event::Edge }); } } @@ -592,13 +592,13 @@ void GraphGridLayout::calculateEdgeMainColumn(GraphGridLayout::LayoutState &stat PointSetMinTree blockedColumns(state.columns + 1, -1); for (const auto &event : events) { if (event.type == Event::Block) { - auto block = state.grid_blocks[event.blockId]; + auto block = state.gridBlocks[event.blockId]; blockedColumns.set(block.col + 1, event.row); } else { - auto block = state.grid_blocks[event.blockId]; - int column = block.col + 1; + auto block = state.gridBlocks[event.blockId]; + const int column = block.col + 1; auto &edge = state.edge[event.blockId][event.edgeId]; - const auto &targetBlock = state.grid_blocks[edge.dest]; + const auto &targetBlock = state.gridBlocks[edge.dest]; auto topRow = std::min(block.row + 1, targetBlock.row); auto targetColumn = targetBlock.col + 1; @@ -654,19 +654,18 @@ void GraphGridLayout::roughRouting(GraphGridLayout::LayoutState &state) const if (edgeCount == 0) { return 0; } - int maxSpacing = blockWidth / edgeCount; + const int maxSpacing = blockWidth / edgeCount; if (maxSpacing < layoutConfig.edgeHorizontalSpacing) { return std::max(maxSpacing, 1); } return 0; }; - for (auto &blockIt : state.grid_blocks) { + for (auto &blockIt : state.gridBlocks) { auto &blockEdges = state.edge[blockIt.first]; - for (size_t i = 0; i < blockEdges.size(); i++) { - auto &edge = blockEdges[i]; + for (auto &edge : blockEdges) { const auto &start = blockIt.second; - const auto &target = state.grid_blocks[edge.dest]; + const auto &target = state.gridBlocks[edge.dest]; edge.addPoint(start.row + 1, start.col + 1); if (edge.mainColumn != start.col + 1) { @@ -759,11 +758,11 @@ struct NodeSide * @param segmentSpacing The expected spacing between two segments in the same column. Actual * spacing may be smaller for nodes with many edges. */ -void calculateSegmentOffsets(std::vector &segments, std::vector &edgeOffsets, - std::vector &edgeColumnWidth, - std::vector &nodeRightSide, - std::vector &nodeLeftSide, - const std::vector &columnWidth, size_t H, int segmentSpacing) +static void +calculateSegmentOffsets(std::vector &segments, std::vector &edgeOffsets, + std::vector &edgeColumnWidth, std::vector &nodeRightSide, + std::vector &nodeLeftSide, const std::vector &columnWidth, + size_t H, int segmentSpacing) { for (auto &segment : segments) { if (segment.y0 > segment.y1) { @@ -772,10 +771,12 @@ void calculateSegmentOffsets(std::vector &segments, std::vector &segments, std::vectorx; + const int x = nextSegmentIt->x; int leftColumWidth = 0; if (x > 0) { @@ -899,10 +900,12 @@ static void centerEdges(std::vector &segmentOffsets, const std::vector } } std::sort(events.begin(), events.end(), [](const Event &a, const Event &b) { - if (a.x != b.x) + if (a.x != b.x) { return a.x < b.x; - if (a.y != b.y) + } + if (a.y != b.y) { return a.y < b.y; + } // Process segment start events before end to ensure that activeSegmentCount doesn't go // negative and only reaches 0 at the end of chunk. return int(a.start) > int(b.start); @@ -917,12 +920,12 @@ static void centerEdges(std::vector &segmentOffsets, const std::vector while (activeSegmentCount > 0) { activeSegmentCount += it->start ? 1 : -1; - int offset = segmentOffsets[it->index]; + const int offset = segmentOffsets[it->index]; left = std::min(left, offset); right = std::max(right, offset); it++; } - int spacing = (edgeColumnWidth[chunkStart->x] - (right - left)) / 2 - left; + const int spacing = (edgeColumnWidth[chunkStart->x] - (right - left)) / 2 - left; for (auto segment = chunkStart; segment != it; segment++) { if (segment->start) { segmentOffsets[segment->index] += spacing; @@ -958,7 +961,7 @@ static int compressCoordinates(std::vector &segments, std::vectorwidth; - int edgeColumWidth = state.edgeColumnWidth[edge.points[j].col]; + const int blockWidth = block->width; + const int edgeColumWidth = state.edgeColumnWidth[edge.points[j].col]; offset = std::max(-blockWidth / 2 + edgeColumWidth / 2, offset); offset = std::min(edgeColumWidth / 2 + std::min(blockWidth, edgeColumWidth) / 2, @@ -1080,23 +1083,25 @@ void GraphGridLayout::elaborateEdgePlacement(GraphGridLayout::LayoutState &state for (auto &edgeListIt : state.edge) { for (const auto &edge : edgeListIt.second) { for (size_t j = 2; j < edge.points.size(); j += 2) { - int y0 = state.edgeColumnOffset[edge.points[j - 1].col] + edge.points[j - 1].offset; - int y1 = state.edgeColumnOffset[edge.points[j + 1].col] + edge.points[j + 1].offset; + const int y0 = + state.edgeColumnOffset[edge.points[j - 1].col] + edge.points[j - 1].offset; + const int y1 = + state.edgeColumnOffset[edge.points[j + 1].col] + edge.points[j + 1].offset; segments.push_back( segmentFromPoint(edge.points[j], edge, y0, y1, edge.points[j].row)); } } } edgeOffsets.resize(edgeIndex); - for (auto &blockIt : state.grid_blocks) { + for (auto &blockIt : state.gridBlocks) { auto &node = blockIt.second; auto blockWidth = (*state.blocks)[node.id].width; - int leftSide = state.edgeColumnOffset[node.col + 1] + const int leftSide = state.edgeColumnOffset[node.col + 1] + state.edgeColumnWidth[node.col + 1] / 2 - blockWidth / 2; - int rightSide = leftSide + blockWidth; + const int rightSide = leftSide + blockWidth; - int h = (*state.blocks)[blockIt.first].height; - int freeSpace = state.rowHeight[node.row] - h; + const int h = (*state.blocks)[blockIt.first].height; + const int freeSpace = state.rowHeight[node.row] - h; int topProfile = state.rowHeight[node.row]; int bottomProfile = h; if (verticalBlockAlignmentMiddle) { @@ -1120,12 +1125,12 @@ void GraphGridLayout::adjustColumnWidths(GraphGridLayout::LayoutState &state) co { state.rowHeight.assign(state.rows, 0); state.columnWidth.assign(state.columns, 0); - for (auto &node : state.grid_blocks) { + for (auto &node : state.gridBlocks) { const auto &inputBlock = (*state.blocks)[node.first]; state.rowHeight[node.second.row] = std::max(inputBlock.height, state.rowHeight[node.second.row]); - int edgeWidth = state.edgeColumnWidth[node.second.col + 1]; - int columnWidth = (inputBlock.width - edgeWidth) / 2; + const int edgeWidth = state.edgeColumnWidth[node.second.col + 1]; + const int columnWidth = (inputBlock.width - edgeWidth) / 2; state.columnWidth[node.second.col] = std::max(columnWidth, state.columnWidth[node.second.col]); state.columnWidth[node.second.col + 1] = @@ -1164,7 +1169,7 @@ void GraphGridLayout::convertToPixelCoordinates(GraphGridLayout::LayoutState &st // block pixel positions for (auto &block : (*state.blocks)) { - const auto &gridBlock = state.grid_blocks[block.first]; + const auto &gridBlock = state.gridBlocks[block.first]; block.second.x = state.edgeColumnOffset[gridBlock.col + 1] + state.edgeColumnWidth[gridBlock.col + 1] / 2 - block.second.width / 2; @@ -1184,13 +1189,13 @@ void GraphGridLayout::convertToPixelCoordinates(GraphGridLayout::LayoutState &st const auto &edge = state.edge[it.first][i]; for (size_t j = 1; j < edge.points.size(); j++) { if (j & 1) { // vertical segment - int column = edge.points[j].col; - int x = state.edgeColumnOffset[column] + edge.points[j].offset; + const int column = edge.points[j].col; + const int x = state.edgeColumnOffset[column] + edge.points[j].offset; resultEdge.polyline.back().setX(x); resultEdge.polyline.push_back(QPointF(x, 0)); } else { // horizontal segment - int row = edge.points[j].row; - int y = state.edgeRowOffset[row] + edge.points[j].offset; + const int row = edge.points[j].row; + const int y = state.edgeRowOffset[row] + edge.points[j].offset; resultEdge.polyline.back().setY(y); resultEdge.polyline.push_back(QPointF(0, y)); } @@ -1298,9 +1303,9 @@ static void optimizeLinearProgramPass(size_t n, std::vector objectiveFuncti auto joinGroup = [&](int a, int b) { group[getGroup(b)] = getGroup(a); }; for (auto &constraint : inequalities) { - int a = constraint.first.first; - int b = constraint.first.second; - size_t index = &constraint - &inequalities.front(); + const int a = constraint.first.first; + const int b = constraint.first.second; + const size_t index = &constraint - &inequalities.front(); edges[a] = edgePool.append(edges[a], edgePool.makeList(index)); edges[b] = edgePool.append(edges[b], edgePool.makeList(index)); edgeCount[a]++; @@ -1323,7 +1328,7 @@ static void optimizeLinearProgramPass(size_t n, std::vector objectiveFuncti // grouped for (auto it = edgePool.head(edges[b]); it; ++it) { auto &constraint = inequalities[*it]; - int other = constraint.first.first + constraint.first.second - b; + const int other = constraint.first.first + constraint.first.second - b; if (getGroup(other) == a) { // skip inequalities where both variables are now in the same group internalEdgeCount++; @@ -1332,7 +1337,7 @@ static void optimizeLinearProgramPass(size_t n, std::vector objectiveFuncti *writeIt++ = *it; // Modify the inequalities for the group being attached relative to the main variable in // the group to which it is being attached. - int diff = solution[a] - solution[b]; + const int diff = solution[a] - solution[b]; if (b == constraint.first.first) { constraint.first.first = a; constraint.second += diff; @@ -1382,13 +1387,13 @@ static void optimizeLinearProgramPass(size_t n, std::vector objectiveFuncti } } while (!queue.empty()) { - int g = queue.top().second; - int size = queue.top().first; + const int g = queue.top().second; + const int size = queue.top().first; queue.pop(); if ((size_t)size != edgeCount[g] || processed[g]) { continue; } - int direction = objectiveFunction[g]; + const int direction = objectiveFunction[g]; if (direction == 0) { continue; } @@ -1403,11 +1408,11 @@ static void optimizeLinearProgramPass(size_t n, std::vector objectiveFuncti if (g == inequality.first.second) { continue; } - int other = inequality.first.second; + const int other = inequality.first.second; if (getGroup(other) == g) { continue; } - int move = solution[other] + inequality.second - solution[g]; + const int move = solution[other] + inequality.second - solution[g]; if (move < smallestMove) { smallestMove = move; limitingGroup = other; @@ -1420,11 +1425,11 @@ static void optimizeLinearProgramPass(size_t n, std::vector objectiveFuncti if (g == inequality.first.first) { continue; } - int other = inequality.first.first; + const int other = inequality.first.first; if (getGroup(other) == g) { continue; } - int move = solution[other] - inequality.second - solution[g]; + const int move = solution[other] - inequality.second - solution[g]; if (move > smallestMove) { smallestMove = move; limitingGroup = other; @@ -1450,7 +1455,7 @@ static void optimizeLinearProgramPass(size_t n, std::vector objectiveFuncti equalities.push_back({ { g, limitingGroup }, solution[g] - solution[limitingGroup] }); } // else do nothing if limited by variable >= 0 } - for (auto it = equalities.rbegin(), end = equalities.rend(); it != end; ++it) { + for (auto it = equalities.rbegin(), end = equalities.rend(); it != end; ++it) { // NOLINT solution[it->first.first] = solution[it->first.second] + it->second; } } @@ -1477,8 +1482,8 @@ static void optimizeLinearProgram(size_t n, const std::vector &objectiveFun [](const Constraint &a, const Constraint &b) { return a.first == b.first; }); inequalities.erase(uniqueEnd, inequalities.end()); - static const int ITERATIONS = 1; - for (int i = 0; i < ITERATIONS; i++) { + static const int iterations = 1; + for (int i = 0; i < iterations; i++) { optimizeLinearProgramPass(n, objectiveFunction, inequalities, equalities, solution, true); // optimizeLinearProgramPass(n, objectiveFunction, inequalities, equalities, solution, // false); @@ -1537,8 +1542,8 @@ static void createInequalitiesFromSegments(std::vector segments, auto lastSegment = startPos->second; auto it = startPos; while (it != lastSegments.end() && it->first <= segment.y1) { - int prevSegmentVariable = it->second.first; - int prevSegmentPos = it->second.second; + const int prevSegmentVariable = it->second.first; + const int prevSegmentPos = it->second.second; if (prevSegmentVariable != -1) { int minSpacing = segmentSpacing; if (prevSegmentVariable < blockCount && segment.variableId < blockCount) { @@ -1601,8 +1606,8 @@ void GraphGridLayout::optimizeLayout(GraphGridLayout::LayoutState &state) const inequalities.push_back(createInequality(a, posA, b, posB, minSpacing, solution)); }; auto addBlockSegmentEquality = [&](ut64 blockId, int edgeVariable, int edgeVariablePos) { - int blockPos = (*state.blocks)[blockId].x; - int blockVariable = blockMapping[blockId]; + const int blockPos = (*state.blocks)[blockId].x; + const int blockVariable = blockMapping[blockId]; equalities.push_back({ { blockVariable, edgeVariable }, blockPos - edgeVariablePos }); }; auto setFeasibleSolution = [&](size_t variable, int value) { @@ -1621,7 +1626,7 @@ void GraphGridLayout::optimizeLayout(GraphGridLayout::LayoutState &state) const auto &block = blockIt.second; for (auto &edge : blockIt.second.edges) { for (int i = 1 + int(horizontal); i < edge.polyline.size(); i += 2) { - int x = solution[variableIndex++]; + const int x = solution[variableIndex++]; if (horizontal) { edge.polyline[i].ry() = x; edge.polyline[i - 1].ry() = x; @@ -1631,7 +1636,7 @@ void GraphGridLayout::optimizeLayout(GraphGridLayout::LayoutState &state) const } } } - int blockVariable = blockMapping[blockIt.first]; + const int blockVariable = blockMapping[blockIt.first]; (horizontal ? block.y : block.x) = solution[blockVariable]; } }; @@ -1645,11 +1650,11 @@ void GraphGridLayout::optimizeLayout(GraphGridLayout::LayoutState &state) const objectiveFunction.assign(blockMapping.size(), 1); for (auto &blockIt : *state.blocks) { auto &block = blockIt.second; - int blockVariable = blockMapping[blockIt.first]; + const int blockVariable = blockMapping[blockIt.first]; for (auto &edge : block.edges) { auto &targetBlock = (*state.blocks)[edge.target]; if (block.y < targetBlock.y) { - int spacing = block.height + layoutConfig.blockVerticalSpacing; + const int spacing = block.height + layoutConfig.blockVerticalSpacing; inequalities.push_back({ { blockVariable, blockMapping[edge.target] }, -spacing }); } if (edge.polyline.size() < 3) { @@ -1661,12 +1666,12 @@ void GraphGridLayout::optimizeLayout(GraphGridLayout::LayoutState &state) const if (y0 > y1) { std::swap(y0, y1); } - int x = edge.polyline[i].y(); + const int x = edge.polyline[i].y(); segments.push_back({ x, int(variableIndex), y0, y1 }); variableGroups.push_back(blockMapping.size() + edgeIndex); setFeasibleSolution(variableIndex, x); if (i > 2) { - int prevX = edge.polyline[i - 2].y(); + const int prevX = edge.polyline[i - 2].y(); addObjective(variableIndex, x, variableIndex - 1, prevX); } variableIndex++; @@ -1703,29 +1708,29 @@ void GraphGridLayout::optimizeLayout(GraphGridLayout::LayoutState &state) const if (edge.polyline.size() < 2) { continue; } - size_t firstEdgeVariable = variableIndex; + const size_t firstEdgeVariable = variableIndex; for (int i = 1; i < edge.polyline.size(); i += 2) { int y0 = edge.polyline[i - 1].y(); int y1 = edge.polyline[i].y(); if (y0 > y1) { std::swap(y0, y1); } - int x = edge.polyline[i].x(); + const int x = edge.polyline[i].x(); segments.push_back({ x, int(variableIndex), y0, y1 }); variableGroups.push_back(blockMapping.size() + edgeIndex); setFeasibleSolution(variableIndex, x); if (i > 2) { - int prevX = edge.polyline[i - 2].x(); + const int prevX = edge.polyline[i - 2].x(); addObjective(variableIndex, x, variableIndex - 1, prevX); } variableIndex++; } - size_t lastEdgeVariableIndex = variableIndex - 1; + const size_t lastEdgeVariableIndex = variableIndex - 1; addBlockSegmentEquality(blockIt.first, firstEdgeVariable, edge.polyline[1].x()); addBlockSegmentEquality(edge.target, lastEdgeVariableIndex, segments.back().x); edgeIndex++; } - int blockVariable = blockMapping[blockIt.first]; + const int blockVariable = blockMapping[blockIt.first]; segments.push_back({ block.x, blockVariable, block.y, block.y + block.height }); segments.push_back( { block.x + block.width, blockVariable, block.y, block.y + block.height }); @@ -1740,7 +1745,7 @@ void GraphGridLayout::optimizeLayout(GraphGridLayout::LayoutState &state) const // horizontal centering constraints for (auto &blockIt : *state.blocks) { auto &block = blockIt.second; - int blockVariable = blockMapping[blockIt.first]; + const int blockVariable = blockMapping[blockIt.first]; if (block.edges.size() == 2) { auto &blockLeft = (*state.blocks)[block.edges[0].target]; auto &blockRight = (*state.blocks)[block.edges[1].target]; @@ -1750,7 +1755,7 @@ void GraphGridLayout::optimizeLayout(GraphGridLayout::LayoutState &state) const blockVariable, middle, layoutConfig.blockHorizontalSpacing / 2); addInequality(blockVariable, middle, blockMapping[block.edges[1].target], blockRight.x, layoutConfig.blockHorizontalSpacing / 2); - auto &gridBlock = state.grid_blocks[blockIt.first]; + auto &gridBlock = state.gridBlocks[blockIt.first]; if (gridBlock.mergeBlock) { auto &mergeBlock = (*state.blocks)[gridBlock.mergeBlock]; if (mergeBlock.x + mergeBlock.width / 2 == middle) { diff --git a/src/widgets/GraphGridLayout.h b/src/widgets/GraphGridLayout.h index 84654e96..74a6fb49 100644 --- a/src/widgets/GraphGridLayout.h +++ b/src/widgets/GraphGridLayout.h @@ -1,7 +1,6 @@ #ifndef GRAPHGRIDLAYOUT_H #define GRAPHGRIDLAYOUT_H -#include "core/Cutter.h" #include "GraphLayout.h" #include "common/LinkedListPool.h" @@ -12,14 +11,14 @@ class GraphGridLayout : public GraphLayout { public: - enum class LayoutType { + enum class LayoutType : ut8 { Medium, Wide, Narrow, }; GraphGridLayout(LayoutType layoutType = LayoutType::Medium); - virtual void CalculateLayout(Graph &blocks, ut64 entry, int &width, int &height) const override; + virtual void calculateLayout(Graph &blocks, ut64 entry, int &width, int &height) const override; void setTightSubtreePlacement(bool enabled) { tightSubtreePlacement = enabled; } void setParentBetweenDirectChild(bool enabled) { parentBetweenDirectChild = enabled; } void setverticalBlockAlignmentMiddle(bool enabled) { verticalBlockAlignmentMiddle = enabled; } @@ -37,14 +36,14 @@ private: struct GridBlock { ut64 id; - std::vector tree_edge; //!< subset of outgoing edges that form a tree - std::vector dag_edge; //!< subset of outgoing edges that form a dag - std::size_t has_parent = false; + std::vector treeEdge; //!< subset of outgoing edges that form a tree + std::vector dagEdge; //!< subset of outgoing edges that form a dag + std::size_t hasParent = false; int inputCount = 0; int outputCount = 0; /// Number of rows in subtree - int row_count = 0; + int rowCount = 0; /// Column in which the block is int col = 0; /// Row in which the block is @@ -84,7 +83,7 @@ private: struct LayoutState { - std::unordered_map grid_blocks; + std::unordered_map gridBlocks; std::unordered_map *blocks = nullptr; std::unordered_map> edge; size_t rows = -1; diff --git a/src/widgets/GraphHorizontalAdapter.cpp b/src/widgets/GraphHorizontalAdapter.cpp index d50cefd9..74306e53 100644 --- a/src/widgets/GraphHorizontalAdapter.cpp +++ b/src/widgets/GraphHorizontalAdapter.cpp @@ -6,13 +6,13 @@ GraphHorizontalAdapter::GraphHorizontalAdapter(std::unique_ptr layo swapLayoutConfigDirection(); } -void GraphHorizontalAdapter::CalculateLayout(GraphLayout::Graph &blocks, ut64 entry, int &width, +void GraphHorizontalAdapter::calculateLayout(GraphLayout::Graph &blocks, ut64 entry, int &width, int &height) const { for (auto &block : blocks) { std::swap(block.second.width, block.second.height); } - layout->CalculateLayout(blocks, entry, height, + layout->calculateLayout(blocks, entry, height, width); // intentionally swapping height and width for (auto &block : blocks) { std::swap(block.second.width, block.second.height); diff --git a/src/widgets/GraphHorizontalAdapter.h b/src/widgets/GraphHorizontalAdapter.h index 4052c9cc..c6ff0949 100644 --- a/src/widgets/GraphHorizontalAdapter.h +++ b/src/widgets/GraphHorizontalAdapter.h @@ -1,7 +1,6 @@ #ifndef GRAPH_HORIZONTAL_ADAPTER_H #define GRAPH_HORIZONTAL_ADAPTER_H -#include "core/Cutter.h" #include "GraphLayout.h" #include @@ -13,7 +12,7 @@ class GraphHorizontalAdapter : public GraphLayout { public: GraphHorizontalAdapter(std::unique_ptr layout); - virtual void CalculateLayout(GraphLayout::Graph &blocks, ut64 entry, int &width, + virtual void calculateLayout(GraphLayout::Graph &blocks, ut64 entry, int &width, int &height) const override; void setLayoutConfig(const LayoutConfig &config) override; diff --git a/src/widgets/GraphLayout.h b/src/widgets/GraphLayout.h index 4e1caa5c..9c75d0a2 100644 --- a/src/widgets/GraphLayout.h +++ b/src/widgets/GraphLayout.h @@ -1,7 +1,9 @@ #ifndef GRAPHLAYOUT_H #define GRAPHLAYOUT_H -#include "core/Cutter.h" +#include "CutterCommon.h" // IWYU pragma: keep + +#include #include @@ -12,7 +14,7 @@ public: { ut64 target; QPolygonF polyline; - enum ArrowDirection { Down, Left, Up, Right, None }; + enum ArrowDirection : ut8 { Down, Left, Up, Right, None }; ArrowDirection arrow = ArrowDirection::Down; explicit GraphEdge(ut64 target) : target(target) {} @@ -41,7 +43,7 @@ public: GraphLayout(const LayoutConfig &layout_config) : layoutConfig(layout_config) {} virtual ~GraphLayout() {} - virtual void CalculateLayout(Graph &blocks, ut64 entry, int &width, int &height) const = 0; + virtual void calculateLayout(Graph &blocks, ut64 entry, int &width, int &height) const = 0; virtual void setLayoutConfig(const LayoutConfig &config) { this->layoutConfig = config; }; protected: diff --git a/src/widgets/GraphView.cpp b/src/widgets/GraphView.cpp index a5e276ed..2aa66a9f 100644 --- a/src/widgets/GraphView.cpp +++ b/src/widgets/GraphView.cpp @@ -7,18 +7,19 @@ #include "GraphHorizontalAdapter.h" #include "Helpers.h" -#include -#include -#include #include +#include +#include #include #include +#include + #ifndef CUTTER_NO_OPENGL_GRAPH # include -# include -# include # include +# include +# include #endif GraphView::GraphView(QWidget *parent) @@ -120,7 +121,7 @@ void GraphView::contextMenuEvent(QContextMenuEvent *event) { event->ignore(); if (event->reason() == QContextMenuEvent::Mouse) { - QPoint p = viewToLogicalCoordinates(event->pos()); + const QPoint p = viewToLogicalCoordinates(event->pos()); if (auto block = getBlockContaining(p)) { blockContextMenuRequested(*block, event, p); } @@ -129,7 +130,7 @@ void GraphView::contextMenuEvent(QContextMenuEvent *event) void GraphView::computeGraphPlacement() { - graphLayoutSystem->CalculateLayout(blocks, entry, width, height); + graphLayoutSystem->calculateLayout(blocks, entry, width, height); setCacheDirty(); clampViewOffset(); viewport()->update(); @@ -141,13 +142,13 @@ void GraphView::cleanupEdges(GraphLayout::Graph &graph) auto &block = blockIt.second; auto outIt = block.edges.begin(); std::unordered_set seenEdges; - for (auto it = block.edges.begin(), end = block.edges.end(); it != end; ++it) { + for (auto &edge : block.edges) { // remove edges going to different functions // and remove duplicate edges, common in switch statements - if (graph.find(it->target) != graph.end() - && seenEdges.find(it->target) == seenEdges.end()) { - *outIt++ = *it; - seenEdges.insert(it->target); + if (graph.find(edge.target) != graph.end() + && seenEdges.find(edge.target) == seenEdges.end()) { + *outIt++ = edge; + seenEdges.insert(edge.target); } } block.edges.erase(outIt, block.edges.end()); @@ -157,7 +158,7 @@ void GraphView::cleanupEdges(GraphLayout::Graph &graph) void GraphView::beginMouseDrag(QMouseEvent *event) { scrollBase = event->pos(); - scroll_mode = true; + scrollMode = true; setCursor(Qt::ClosedHandCursor); } @@ -168,7 +169,7 @@ void GraphView::setViewOffset(QPoint offset) void GraphView::setViewScale(qreal scale) { - this->current_scale = scale; + this->currentScale = scale; emit viewScaleChanged(scale); } @@ -242,20 +243,21 @@ void GraphView::paintEvent(QPaintEvent *) void GraphView::clampViewOffset() { const qreal edgeFraction = 0.25; - qreal edgeX = edgeFraction * (viewport()->width() / current_scale); - qreal edgeY = edgeFraction * (viewport()->height() / current_scale); + const qreal edgeX = edgeFraction * (viewport()->width() / currentScale); + const qreal edgeY = edgeFraction * (viewport()->height() / currentScale); offset.rx() = std::max(std::min(qreal(offset.x()), width - edgeX), - -viewport()->width() / current_scale + edgeX); + -viewport()->width() / currentScale + edgeX); offset.ry() = std::max(std::min(qreal(offset.y()), height - edgeY), - -viewport()->height() / current_scale + edgeY); + -viewport()->height() / currentScale + edgeY); } void GraphView::setViewOffsetInternal(QPoint pos, bool emitSignal) { offset = pos; clampViewOffset(); - if (emitSignal) + if (emitSignal) { emit viewOffsetChanged(offset); + } } void GraphView::addViewOffset(QPoint move, bool emitSignal) @@ -274,7 +276,7 @@ void GraphView::paintGraphCache() auto gl = QOpenGLContext::currentContext()->functions(); bool resizeTex = false; - QSize sizeNeed = getRequiredCacheSize(); + const QSize sizeNeed = getRequiredCacheSize(); if (!cacheTexture) { gl->glGenTextures(1, &cacheTexture); gl->glBindTexture(GL_TEXTURE_2D, cacheTexture); @@ -316,29 +318,29 @@ void GraphView::paintGraphCache() p.setRenderHint(QPainter::Antialiasing); p.setViewport(this->viewport()->rect()); } - paint(p, offset, this->viewport()->rect(), current_scale); + paint(p, offset, this->viewport()->rect(), currentScale); p.end(); } void GraphView::paint(QPainter &p, QPoint offset, QRect viewport, qreal scale, bool interactive) { - QPointF offsetF(offset.x(), offset.y()); + const QPointF offsetF(offset.x(), offset.y()); p.setBrush(Qt::black); - int render_width = viewport.width(); - int render_height = viewport.height(); + const int renderWidth = viewport.width(); + const int renderHeight = viewport.height(); // window - rectangle in logical coordinates - QRect window = - QRect(offset, QSize(qRound(render_width / scale), qRound(render_height / scale))); + const QRect window = + QRect(offset, QSize(qRound(renderWidth / scale), qRound(renderHeight / scale))); p.setWindow(window); - QRectF windowF(window.x(), window.y(), window.width(), window.height()); + const QRectF windowF(window.x(), window.y(), window.width(), window.height()); for (auto &blockIt : blocks) { GraphBlock &block = blockIt.second; - QRectF blockRect(block.x, block.y, block.width, block.height); + const QRectF blockRect(block.x, block.y, block.width, block.height); // Check if block is visible by checking if block intersects with view area if (blockRect.intersects(windowF)) { @@ -354,13 +356,14 @@ void GraphView::paint(QPainter &p, QPoint offset, QRect viewport, qreal scale, b if (edge.polyline.empty()) { continue; } - QPolygonF polyline = edge.polyline; - EdgeConfiguration ec = edgeConfiguration(block, &blocks[edge.target], interactive); + const QPolygonF polyline = edge.polyline; + const EdgeConfiguration ec = + edgeConfiguration(block, &blocks[edge.target], interactive); QPen pen(ec.color); pen.setStyle(ec.lineStyle); - pen.setWidthF(pen.width() * ec.width_scale); - if (scale_thickness_multiplier && ec.width_scale > 1.01 && pen.widthF() * scale < 2) { - pen.setWidthF(ec.width_scale / scale); + pen.setWidthF(pen.width() * ec.widthScale); + if (scaleThicknessMultiplier && ec.widthScale > 1.01 && pen.widthF() * scale < 2) { + pen.setWidthF(ec.widthScale / scale); } if (pen.widthF() * scale < 2) { pen.setWidth(0); @@ -376,19 +379,19 @@ void GraphView::paint(QPainter &p, QPoint offset, QRect viewport, qreal scale, b p.setPen(pen); QPolygonF arrow; arrow << tip; - QPointF dy(-dir.y(), dir.x()); - QPointF base = tip - dir * 6; + const QPointF dy(-dir.y(), dir.x()); + const QPointF base = tip - dir * 6; arrow << base + 3 * dy; arrow << base - 3 * dy; p.drawConvexPolygon(arrow); }; if (!polyline.empty()) { - if (ec.start_arrow) { + if (ec.startArrow) { auto firstPt = edge.polyline.first(); drawArrow(firstPt, QPointF(0, 1)); } - if (ec.end_arrow) { + if (ec.endArrow) { auto lastPt = edge.polyline.last(); QPointF dir(0, -1); switch (edge.arrow) { @@ -414,7 +417,8 @@ void GraphView::paint(QPainter &p, QPoint offset, QRect viewport, qreal scale, b } } -void GraphView::saveAsBitmap(QString path, const char *format, double scaler, bool transparent) +void GraphView::saveAsBitmap(const QString &path, const char *format, double scaler, + bool transparent) { QImage image(width * scaler, height * scaler, QImage::Format_ARGB32); if (transparent) { @@ -431,7 +435,7 @@ void GraphView::saveAsBitmap(QString path, const char *format, double scaler, bo } } -void GraphView::saveAsSvg(QString path) +void GraphView::saveAsSvg(const QString &path) { QSvgGenerator generator; generator.setFileName(path); @@ -453,8 +457,8 @@ void GraphView::center() void GraphView::centerX(bool emitSignal) { - offset.rx() = -((viewport()->width() - width * current_scale) / 2); - offset.rx() /= current_scale; + offset.rx() = -((viewport()->width() - width * currentScale) / 2); + offset.rx() /= currentScale; clampViewOffset(); if (emitSignal) { emit viewOffsetChanged(offset); @@ -463,8 +467,8 @@ void GraphView::centerX(bool emitSignal) void GraphView::centerY(bool emitSignal) { - offset.ry() = -((viewport()->height() - height * current_scale) / 2); - offset.ry() /= current_scale; + offset.ry() = -((viewport()->height() - height * currentScale) / 2); + offset.ry() /= currentScale; clampViewOffset(); if (emitSignal) { emit viewOffsetChanged(offset); @@ -479,8 +483,8 @@ void GraphView::showBlock(GraphBlock &block, bool anywhere) void GraphView::showRectangle(const QRect &block, bool anywhere) { - QSizeF renderSize = QSizeF(viewport()->size()) / current_scale; - if (width * current_scale <= viewport()->width()) { + const QSizeF renderSize = QSizeF(viewport()->size()) / currentScale; + if (width * currentScale <= viewport()->width()) { centerX(false); } else { if (!anywhere || block.x() < offset.x() @@ -488,14 +492,14 @@ void GraphView::showRectangle(const QRect &block, bool anywhere) offset.rx() = block.x() - ((renderSize.width() - block.width()) / 2); } } - if (height * current_scale <= viewport()->height()) { + if (height * currentScale <= viewport()->height()) { centerY(false); } else { if (!anywhere || block.y() < offset.y() || block.bottom() > offset.y() + renderSize.height()) { offset.ry() = block.y(); // Leave some space at top if possible - const qreal topPadding = 10 / current_scale; + const qreal topPadding = 10 / currentScale; if (block.height() + topPadding < renderSize.height()) { offset.ry() -= topPadding; } @@ -512,7 +516,7 @@ GraphView::GraphBlock *GraphView::getBlockContaining(QPoint p) for (auto &blockIt : blocks) { GraphBlock &block = blockIt.second; - QRect rec(block.x, block.y, block.width, block.height); + const QRect rec(block.x, block.y, block.width, block.height); if (rec.contains(p)) { return █ } @@ -522,12 +526,12 @@ GraphView::GraphBlock *GraphView::getBlockContaining(QPoint p) QPoint GraphView::viewToLogicalCoordinates(QPoint p) { - return p / current_scale + offset; + return p / currentScale + offset; } QPoint GraphView::logicalToViewCoordinates(QPoint p) { - return (p - offset) * current_scale; + return (p - offset) * currentScale; } void GraphView::setGraphLayout(std::unique_ptr layout) @@ -546,7 +550,7 @@ void GraphView::setLayoutConfig(const GraphLayout::LayoutConfig &config) std::unique_ptr GraphView::makeGraphLayout(GraphView::Layout layout, bool horizontal) { std::unique_ptr result; - bool needAdapter = true; + bool needAdapter = true; // NOLINT #ifdef CUTTER_ENABLE_GRAPHVIZ auto makeGraphvizLayout = [&](GraphvizLayout::LayoutType type) { @@ -574,7 +578,7 @@ std::unique_ptr GraphView::makeGraphLayout(GraphView::Layout layout case Layout::GridBAB: case Layout::GridBBA: case Layout::GridBBB: { - int options = static_cast(layout) - static_cast(Layout::GridAAA); + const int options = static_cast(layout) - static_cast(Layout::GridAAA); std::unique_ptr gridLayout(new GraphGridLayout()); gridLayout->setTightSubtreePlacement((options & 1) == 0); gridLayout->setParentBetweenDirectChild((options & 2)); @@ -609,7 +613,7 @@ std::unique_ptr GraphView::makeGraphLayout(GraphView::Layout layout return result; } -void GraphView::addBlock(GraphView::GraphBlock block) +void GraphView::addBlock(const GraphView::GraphBlock &block) { blocks[block.entry] = block; } @@ -621,11 +625,10 @@ void GraphView::setEntry(ut64 e) bool GraphView::checkPointClicked(QPointF &point, int x, int y, bool above_y) { - int half_target_size = 5; - if ((point.x() - half_target_size < x) - && (point.y() - (above_y ? (2 * half_target_size) : 0) < y) - && (x < point.x() + half_target_size) - && (y < point.y() + (above_y ? 0 : (3 * half_target_size)))) { + const int halfTargetSize = 5; + if ((point.x() - halfTargetSize < x) && (point.y() - (above_y ? (2 * halfTargetSize) : 0) < y) + && (x < point.x() + halfTargetSize) + && (y < point.y() + (above_y ? 0 : (3 * halfTargetSize)))) { return true; } return false; @@ -639,7 +642,7 @@ void GraphView::mousePressEvent(QMouseEvent *event) return; } - QPoint pos = viewToLogicalCoordinates(event->pos()); + const QPoint pos = viewToLogicalCoordinates(event->pos()); // Check if a block was clicked if (auto block = getBlockContaining(pos)) { @@ -685,8 +688,8 @@ void GraphView::mousePressEvent(QMouseEvent *event) void GraphView::mouseMoveEvent(QMouseEvent *event) { - if (scroll_mode) { - addViewOffset((scrollBase - event->pos()) / current_scale); + if (scrollMode) { + addViewOffset((scrollBase - event->pos()) / currentScale); scrollBase = event->pos(); viewport()->update(); } @@ -703,9 +706,9 @@ void GraphView::mouseDoubleClickEvent(QMouseEvent *event) void GraphView::keyPressEvent(QKeyEvent *event) { // for scrolling with arrow keys - const int delta = static_cast(30.0 / current_scale); + const int delta = static_cast(30.0 / currentScale); // for scrolling with pgup/pgdown keys - const int delta2 = static_cast(100.0 / current_scale); + const int delta2 = static_cast(100.0 / currentScale); int dx = 0, dy = 0; switch (event->key()) { case Qt::Key_Up: @@ -737,21 +740,21 @@ void GraphView::keyPressEvent(QKeyEvent *event) void GraphView::mouseReleaseEvent(QMouseEvent *event) { - if (scroll_mode && (event->buttons() & (Qt::LeftButton | Qt::MiddleButton)) == 0) { - scroll_mode = false; + if (scrollMode && (event->buttons() & (Qt::LeftButton | Qt::MiddleButton)) == 0) { + scrollMode = false; setCursor(Qt::ArrowCursor); } } void GraphView::wheelEvent(QWheelEvent *event) { - if (scroll_mode) { + if (scrollMode) { // With some mice it's easy to hit sideway scroll button while holding middle mouse. // That would result in unwanted scrolling while panning. return; } QPoint delta = -event->angleDelta(); - delta /= current_scale; + delta /= currentScale; addViewOffset(delta); viewport()->update(); event->accept(); diff --git a/src/widgets/GraphView.h b/src/widgets/GraphView.h index 6756aa90..6f624aa2 100644 --- a/src/widgets/GraphView.h +++ b/src/widgets/GraphView.h @@ -1,23 +1,23 @@ #ifndef GRAPHVIEW_H #define GRAPHVIEW_H -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - #include "core/Cutter.h" #include "widgets/GraphLayout.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + #if defined(QT_NO_OPENGL) || QT_VERSION < QT_VERSION_CHECK(5, 6, 0) // QOpenGLExtraFunctions were introduced in 5.6 # define CUTTER_NO_OPENGL_GRAPH @@ -27,6 +27,11 @@ class QOpenGLWidget; #endif +/** + * @brief Base class for rendering and interacting with control-flow graphs + * + * Supports both QPainter and OpenGL rendering + */ class GraphView : public QAbstractScrollArea { Q_OBJECT @@ -39,7 +44,7 @@ public: using GraphBlock = GraphLayout::GraphBlock; using GraphEdge = GraphLayout::GraphEdge; - enum class Layout { + enum class Layout : ut8 { GridNarrow, GridMedium, GridWide, @@ -66,9 +71,9 @@ public: struct EdgeConfiguration { QColor color = QColor(128, 128, 128); - bool start_arrow = false; - bool end_arrow = true; - qreal width_scale = 1.0; + bool startArrow = false; + bool endArrow = true; + qreal widthScale = 1.0; Qt::PenStyle lineStyle = Qt::PenStyle::SolidLine; }; @@ -97,9 +102,9 @@ public: void paint(QPainter &p, QPoint offset, QRect area, qreal scale = 1.0, bool interactive = true); - void saveAsBitmap(QString path, const char *format = nullptr, double scaler = 1.0, + void saveAsBitmap(const QString &path, const char *format = nullptr, double scaler = 1.0, bool transparent = false); - void saveAsSvg(QString path); + void saveAsSvg(const QString &path); void computeGraphPlacement(); @@ -115,11 +120,11 @@ protected: QColor backgroundColor = QColor(Qt::white); // Padding inside the block - int block_padding = 16; + int blockPadding = 16; void setCacheDirty() { cacheDirty = true; } - void addBlock(GraphView::GraphBlock block); + void addBlock(const GraphView::GraphBlock &block); void setEntry(ut64 e); // Callbacks that should be overridden @@ -166,7 +171,7 @@ protected: int width = 0; int height = 0; - bool scale_thickness_multiplier = false; + bool scaleThicknessMultiplier = false; void clampViewOffset(); void setViewOffsetInternal(QPoint pos, bool emitSignal = true); @@ -181,7 +186,7 @@ private: bool checkPointClicked(QPointF &point, int x, int y, bool above_y = false); // Zoom data - qreal current_scale = 1.0; + qreal currentScale = 1.0; QPoint offset = QPoint(0, 0); @@ -190,7 +195,7 @@ private: std::unique_ptr graphLayoutSystem; QPoint scrollBase; - bool scroll_mode = false; + bool scrollMode = false; bool useGL; @@ -220,7 +225,7 @@ private: public: QPoint getViewOffset() const { return offset; } void setViewOffset(QPoint offset); - qreal getViewScale() const { return current_scale; } + qreal getViewScale() const { return currentScale; } void setViewScale(qreal scale); void center(); diff --git a/src/widgets/GraphWidget.cpp b/src/widgets/GraphWidget.cpp index 11a3f2f6..a1e6f525 100644 --- a/src/widgets/GraphWidget.cpp +++ b/src/widgets/GraphWidget.cpp @@ -1,10 +1,13 @@ -#include "core/MainWindow.h" #include "GraphWidget.h" + #include "DisassemblerGraphView.h" +#include "core/MainWindow.h" #include "shortcuts/ShortcutManager.h" + #include -GraphWidget::GraphWidget(MainWindow *main) : MemoryDockWidget(MemoryWidgetType::Graph, main) +GraphWidget::GraphWidget(MainWindow *main) + : MemoryDockWidget(MemoryWidgetType::Graph, main), header(new QLineEdit(this)) { setObjectName(main ? main->getUniqueObjectName(getWidgetType()) : getWidgetType()); @@ -16,7 +19,6 @@ GraphWidget::GraphWidget(MainWindow *main) : MemoryDockWidget(MemoryWidgetType:: layout->setContentsMargins(0, 0, 0, 0); layoutWidget->setLayout(layout); - header = new QLineEdit(this); header->setReadOnly(true); layout->addWidget(header); @@ -29,13 +31,13 @@ GraphWidget::GraphWidget(MainWindow *main) : MemoryDockWidget(MemoryWidgetType:: // getting the name of the class is implementation defined, and cannot be // used reliably across different compilers. // QShortcut *toggle_shortcut = new QShortcut(widgetShortcuts[typeid(this).name()], main); - QShortcut *toggle_shortcut = Shortcuts()->makeQShortcut("Graph.toggle", main); - connect(toggle_shortcut, &QShortcut::activated, this, [=]() { toggleDockWidget(true); }); + const QShortcut *toggleShortcut = Shortcuts()->makeQShortcut("Graph.toggle", main); + connect(toggleShortcut, &QShortcut::activated, this, [=, this]() { toggleDockWidget(true); }); connect(graphView, &DisassemblerGraphView::nameChanged, this, &MemoryDockWidget::updateWindowTitle); - connect(this, &QDockWidget::visibilityChanged, this, [=](bool visibility) { + connect(this, &QDockWidget::visibilityChanged, this, [=, this](bool visibility) { main->toggleOverview(visibility, this); if (visibility) { graphView->onSeekChanged(Core()->getOffset()); @@ -49,7 +51,7 @@ GraphWidget::GraphWidget(MainWindow *main) : MemoryDockWidget(MemoryWidgetType:: [this] { mainWindow->showMemoryWidget(MemoryWidgetType::Disassembly); }); connect(graphView, &DisassemblerGraphView::graphMoved, this, - [=]() { main->toggleOverview(true, this); }); + [=, this]() { main->toggleOverview(true, this); }); connect(seekable, &CutterSeekable::seekableSeekChanged, this, &GraphWidget::prepareHeader); connect(Core(), &CutterCore::functionRenamed, this, &GraphWidget::prepareHeader); graphView->installEventFilter(this); diff --git a/src/widgets/GraphWidget.h b/src/widgets/GraphWidget.h index ee44ad5b..e0d5e3b1 100644 --- a/src/widgets/GraphWidget.h +++ b/src/widgets/GraphWidget.h @@ -2,11 +2,15 @@ #define GRAPHWIDGET_H #include "MemoryDockWidget.h" + #include class MainWindow; class DisassemblerGraphView; +/** + * @brief Widget holding the main @ref DisassemblerGraphView + */ class GraphWidget : public MemoryDockWidget { Q_OBJECT diff --git a/src/widgets/GraphvizLayout.cpp b/src/widgets/GraphvizLayout.cpp index e7770dc1..4c7d6719 100644 --- a/src/widgets/GraphvizLayout.cpp +++ b/src/widgets/GraphvizLayout.cpp @@ -1,15 +1,15 @@ #include "GraphvizLayout.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include +#include +#include +#include +#include +#include +#include GraphvizLayout::GraphvizLayout(LayoutType lineType, Direction direction) : GraphLayout({}), direction(direction), layoutType(lineType) @@ -34,7 +34,7 @@ static GraphLayout::GraphEdge::ArrowDirection getArrowDirection(QPointF directio } } -static std::set> SelectLoopEdges(const GraphLayout::Graph &graph, ut64 entry) +static std::set> selectLoopEdges(const GraphLayout::Graph &graph, ut64 entry) { std::set> result; // Run DFS to select backwards/loop edges @@ -49,15 +49,15 @@ static std::set> SelectLoopEdges(const GraphLayout::Graph stack.push({ first, 0 }); while (!stack.empty()) { auto v = stack.top().first; - auto edge_index = stack.top().second; + auto edgeIndex = stack.top().second; auto blockIt = graph.find(v); if (blockIt == graph.end()) { continue; } const auto &block = blockIt->second; - if (edge_index < block.edges.size()) { + if (edgeIndex < block.edges.size()) { ++stack.top().second; - auto target = block.edges[edge_index].target; + auto target = block.edges[edgeIndex].target; auto &targetState = visited[target]; if (targetState == 0) { targetState = 1; @@ -82,7 +82,7 @@ static std::set> SelectLoopEdges(const GraphLayout::Graph return result; } -void GraphvizLayout::CalculateLayout(std::unordered_map &blocks, ut64 entry, +void GraphvizLayout::calculateLayout(std::unordered_map &blocks, ut64 entry, int &width, int &height) const { // https://gitlab.com/graphviz/graphviz/issues/1441 @@ -132,7 +132,7 @@ void GraphvizLayout::CalculateLayout(std::unordered_map &block agxset(obj, sym, STR(str.c_str())); }; - std::set> loopEdges = SelectLoopEdges(blocks, entry); + std::set> loopEdges = selectLoopEdges(blocks, entry); for (const auto &blockIt : blocks) { auto u = nodes[blockIt.first]; @@ -205,7 +205,7 @@ void GraphvizLayout::CalculateLayout(std::unordered_map &block last = edge.polyline.back(); } if (bz.eflag) { - QPointF tip = QPointF(bz.ep.x, bz.ep.y); + const QPointF tip = QPointF(bz.ep.x, bz.ep.y); edge.polyline.push_back(tip); } diff --git a/src/widgets/GraphvizLayout.h b/src/widgets/GraphvizLayout.h index 88c02627..808c99e2 100644 --- a/src/widgets/GraphvizLayout.h +++ b/src/widgets/GraphvizLayout.h @@ -1,13 +1,12 @@ #ifndef GRAPHVIZLAYOUT_H #define GRAPHVIZLAYOUT_H -#include "core/Cutter.h" #include "GraphLayout.h" class GraphvizLayout : public GraphLayout { public: - enum class LayoutType { + enum class LayoutType : ut8 { DotOrtho, DotPolyline, Sfdp, @@ -15,9 +14,9 @@ public: TwoPi, Circo, }; - enum class Direction { TB, LR }; + enum class Direction : ut8 { TB, LR }; GraphvizLayout(LayoutType layoutType, Direction direction = Direction::TB); - virtual void CalculateLayout(std::unordered_map &blocks, ut64 entry, + virtual void calculateLayout(std::unordered_map &blocks, ut64 entry, int &width, int &height) const override; private: diff --git a/src/widgets/HeadersWidget.cpp b/src/widgets/HeadersWidget.cpp index c4462369..6f48c340 100644 --- a/src/widgets/HeadersWidget.cpp +++ b/src/widgets/HeadersWidget.cpp @@ -1,7 +1,8 @@ #include "HeadersWidget.h" -#include "ui_ListDockWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" +#include "ui_ListDockWidget.h" HeadersModel::HeadersModel(QObject *parent) : AddressableItemModel(parent) {} @@ -17,8 +18,9 @@ int HeadersModel::columnCount(const QModelIndex &) const QVariant HeadersModel::data(const QModelIndex &index, int role) const { - if (index.row() >= headers.count()) + if (index.row() >= headers.count()) { return QVariant(); + } const HeaderDescription &header = headers.at(index.row()); @@ -26,7 +28,7 @@ QVariant HeadersModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case OffsetColumn: - return RzAddressString(header.vaddr); + return rzAddressString(header.vaddr); case NameColumn: return header.name; case ValueColumn: @@ -83,17 +85,16 @@ HeadersProxyModel::HeadersProxyModel(HeadersModel *sourceModel, QObject *parent) bool HeadersProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); - HeaderDescription item = - index.data(HeadersModel::HeaderDescriptionRole).value(); + const QModelIndex index = sourceModel()->index(row, 0, parent); + const auto item = index.data(HeadersModel::HeaderDescriptionRole).value(); return qhelpers::filterStringContains(item.name, this); } bool HeadersProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - HeaderDescription leftHeader = + const auto leftHeader = left.data(HeadersModel::HeaderDescriptionRole).value(); - HeaderDescription rightHeader = + const auto rightHeader = right.data(HeadersModel::HeaderDescriptionRole).value(); switch (left.column()) { @@ -112,13 +113,14 @@ bool HeadersProxyModel::lessThan(const QModelIndex &left, const QModelIndex &rig return leftHeader.vaddr < rightHeader.vaddr; } -HeadersWidget::HeadersWidget(MainWindow *main) : ListDockWidget(main) +HeadersWidget::HeadersWidget(MainWindow *main) + : ListDockWidget(main), + headersModel(new HeadersModel(this)), + headersProxyModel(new HeadersProxyModel(headersModel, this)) { setWindowTitle(tr("Headers")); setObjectName("HeadersWidget"); - headersModel = new HeadersModel(this); - headersProxyModel = new HeadersProxyModel(headersModel, this); setModels(headersProxyModel); ui->treeView->sortByColumn(HeadersModel::OffsetColumn, Qt::AscendingOrder); diff --git a/src/widgets/HeadersWidget.h b/src/widgets/HeadersWidget.h index ba9d9735..01c7be08 100644 --- a/src/widgets/HeadersWidget.h +++ b/src/widgets/HeadersWidget.h @@ -1,9 +1,7 @@ #ifndef HEADERSWIDGET_H #define HEADERSWIDGET_H -#include - -#include "core/Cutter.h" +#include "CutterDescriptions.h" #include "ListDockWidget.h" #include @@ -20,6 +18,9 @@ class MainWindow; class QTreeWidgetItem; class HeadersWidget; +/** + * @brief Source model for @ref HeadersWidget + */ class HeadersModel : public AddressableItemModel { Q_OBJECT @@ -30,8 +31,8 @@ private: QList headers; public: - enum Column { OffsetColumn = 0, NameColumn, ValueColumn, CommentColumn, ColumnCount }; - enum Role { HeaderDescriptionRole = Qt::UserRole }; + enum Column : ut8 { OffsetColumn = 0, NameColumn, ValueColumn, CommentColumn, ColumnCount }; + enum Role : ut16 { HeaderDescriptionRole = Qt::UserRole }; HeadersModel(QObject *parent = nullptr); @@ -46,6 +47,9 @@ public: QString name(const QModelIndex &index) const override; }; +/** + * @brief Proxy model for @ref HeadersWidget + */ class HeadersProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -58,6 +62,10 @@ protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; +/** + * @brief A dock widget that displays binary header information (e.g., ELF or PE fields) in a + * searchable list, allowing users to inspect offsets, names, and values + */ class HeadersWidget : public ListDockWidget { Q_OBJECT diff --git a/src/widgets/HeapBinsGraphView.cpp b/src/widgets/HeapBinsGraphView.cpp index c81c7ae3..9d77894e 100644 --- a/src/widgets/HeapBinsGraphView.cpp +++ b/src/widgets/HeapBinsGraphView.cpp @@ -1,9 +1,10 @@ -#include -#include #include "HeapBinsGraphView.h" +#include +#include + HeapBinsGraphView::HeapBinsGraphView(QWidget *parent, RzHeapBin *bin, MainWindow *main) - : SimpleTextGraphView(parent, main), heapBin(bin) + : SimpleTextGraphView(parent, main), heapBin(bin), bits(Core()->getArchBits()) { chunkInfoAction = new QAction(tr("Detailed Chunk Info"), this); addressableItemContextMenu.addAction(chunkInfoAction); @@ -11,8 +12,6 @@ HeapBinsGraphView::HeapBinsGraphView(QWidget *parent, RzHeapBin *bin, MainWindow connect(chunkInfoAction, &QAction::triggered, this, &HeapBinsGraphView::viewChunkInfo); - bits = Core()->getArchBits(); - enableAddresses(true); } @@ -32,7 +31,7 @@ void HeapBinsGraphView::loadCurrentGraph() QVector chunks; // if the bin is a fastbin or not - bool singleLinkedBin = QString(heapBin->type) == QString("Fast") + const bool singleLinkedBin = QString(heapBin->type) == QString("Fast") || QString(heapBin->type) == QString("Tcache"); // store info about the chunks in a vector for easy access @@ -43,12 +42,12 @@ void HeapBinsGraphView::loadCurrentGraph() if (!chunkInfo) { break; } - QString content = "Chunk @ " + RzAddressString(chunkInfo->addr) + "\nSize: " - + RzHexString(chunkInfo->size) + "\nFd: " + RzAddressString(chunkInfo->fd); + QString content = "Chunk @ " + rzAddressString(chunkInfo->addr) + "\nSize: " + + rzHexString(chunkInfo->size) + "\nFd: " + rzAddressString(chunkInfo->fd); // fastbins lack bk pointer if (!singleLinkedBin) { - content += "\nBk: " + RzAddressString(chunkInfo->bk); + content += "\nBk: " + rzAddressString(chunkInfo->bk); } graphHeapChunk.fd = chunkInfo->fd; graphHeapChunk.bk = chunkInfo->bk; @@ -59,28 +58,28 @@ void HeapBinsGraphView::loadCurrentGraph() // fast and tcache bins have single linked list and other bins have double linked list if (singleLinkedBin) { - display_single_linked_list(chunks); + displaySingleLinkedList(chunks); } else { - display_double_linked_list(chunks); + displayDoubleLinkedList(chunks); } cleanupEdges(blocks); computeGraphPlacement(); } -void HeapBinsGraphView::display_single_linked_list(QVector chunks) +void HeapBinsGraphView::displaySingleLinkedList(QVector chunks) { - bool tcache = QString(heapBin->type) == QString("Tcache"); - int ptrSize = bits; + const bool tcache = QString(heapBin->type) == QString("Tcache"); + const int ptrSize = bits; // add the graph block for the bin GraphLayout::GraphBlock gbBin; gbBin.entry = 1; gbBin.edges.emplace_back(heapBin->fd); QString content = tr(heapBin->type) + tr("bin ") + QString::number(heapBin->bin_num); if (tcache) { - content += "\nEntry: " + RzAddressString(heapBin->fd); + content += "\nEntry: " + rzAddressString(heapBin->fd); } else { - content += "\nFd: " + RzAddressString(heapBin->fd); + content += "\nFd: " + rzAddressString(heapBin->fd); } addBlock(gbBin, content); @@ -111,7 +110,7 @@ void HeapBinsGraphView::display_single_linked_list(QVector chunk } } -void HeapBinsGraphView::display_double_linked_list(QVector chunks) +void HeapBinsGraphView::displayDoubleLinkedList(QVector chunks) { // add the graph block for the bin GraphLayout::GraphBlock gbBin; @@ -119,9 +118,9 @@ void HeapBinsGraphView::display_double_linked_list(QVector chunk gbBin.edges.emplace_back(heapBin->fd); gbBin.edges.emplace_back(heapBin->bk); QString content = tr(heapBin->type) + tr("bin ") + QString::number(heapBin->bin_num) + tr(" @ ") - + RzAddressString(heapBin->addr); - content += "\nFd: " + RzAddressString(heapBin->fd); - content += "\nBk: " + RzAddressString(heapBin->bk); + + rzAddressString(heapBin->addr); + content += "\nFd: " + rzAddressString(heapBin->fd); + content += "\nBk: " + rzAddressString(heapBin->bk); addBlock(gbBin, content, heapBin->addr); @@ -145,7 +144,7 @@ void HeapBinsGraphView::display_double_linked_list(QVector chunk // most code is shared from that implementation void HeapBinsGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, bool interactive) { - QRectF blockRect(block.x, block.y, block.width, block.height); + const QRectF blockRect(block.x, block.y, block.width, block.height); p.setPen(Qt::black); p.setBrush(Qt::gray); @@ -159,7 +158,7 @@ void HeapBinsGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, boo p.setBrush(QColor(0, 0, 0, 100)); p.setPen(QPen(graphNodeColor, 1)); - bool blockSelected = interactive && (block.entry == selectedBlock); + const bool blockSelected = interactive && (block.entry == selectedBlock); if (blockSelected) { p.setBrush(disassemblySelectedBackgroundColor); } else { @@ -170,7 +169,7 @@ void HeapBinsGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, boo // Stop rendering text when it's too small auto transform = p.combinedTransform(); - QRect screenChar = transform.mapRect(QRect(0, 0, ACharWidth, charHeight)); + const QRect screenChar = transform.mapRect(QRect(0, 0, charWidthA, charHeight)); if (screenChar.width() < Config()->getGraphMinFontSize()) { return; @@ -190,19 +189,19 @@ void HeapBinsGraphView::addBlock(GraphLayout::GraphBlock block, const QString &t content.text = text; content.address = address; - int height = 1; + const int height = 1; double width = 0; // split text into different lines auto lines = text.split("\n", CUTTER_QT_SKIP_EMPTY_PARTS); // width of the block is the maximum width of a line - for (QString &line : lines) { + for (const QString &line : std::as_const(lines)) { width = std::max(mFontMetrics->width(line), width); } block.width = static_cast(width + padding); block.height = (height * charHeight) * lines.length() + padding; - GraphView::addBlock(std::move(block)); + GraphView::addBlock(block); } // overriding to support detailed heap info action in context menu diff --git a/src/widgets/HeapBinsGraphView.h b/src/widgets/HeapBinsGraphView.h index 1f3e6f6e..a516b33a 100644 --- a/src/widgets/HeapBinsGraphView.h +++ b/src/widgets/HeapBinsGraphView.h @@ -2,6 +2,9 @@ #define CUTTER_HEAPBINSGRAPHVIEW_H #include "SimpleTextGraphView.h" +/** + * @brief Dock widget providing a container to switch between different heap allocator views + */ class HeapBinsGraphView : public SimpleTextGraphView { Q_OBJECT @@ -29,8 +32,8 @@ private slots: private: RzHeapBin *heapBin; - void display_single_linked_list(QVector); - void display_double_linked_list(QVector); + void displaySingleLinkedList(QVector); + void displayDoubleLinkedList(QVector); QAction *chunkInfoAction; RVA selectedBlock; int bits; diff --git a/src/widgets/HeapDockWidget.cpp b/src/widgets/HeapDockWidget.cpp index d30ca0b5..30492d99 100644 --- a/src/widgets/HeapDockWidget.cpp +++ b/src/widgets/HeapDockWidget.cpp @@ -1,4 +1,5 @@ #include "HeapDockWidget.h" + #include "ui_HeapDockWidget.h" #include "widgets/GlibcHeapWidget.h" @@ -17,15 +18,13 @@ HeapDockWidget::HeapDockWidget(MainWindow *main) onAllocatorSelected(0); } -HeapDockWidget::~HeapDockWidget() -{ - delete ui; -} +HeapDockWidget::~HeapDockWidget() {} void HeapDockWidget::onAllocatorSelected(int index) { - if (index >= AllocatorCount) + if (index >= AllocatorCount) { return; + } // remove the current heap widget from layout if (currentHeapWidget) { diff --git a/src/widgets/HeapDockWidget.h b/src/widgets/HeapDockWidget.h index a8a324cb..74c80a5c 100644 --- a/src/widgets/HeapDockWidget.h +++ b/src/widgets/HeapDockWidget.h @@ -1,13 +1,19 @@ #ifndef HEAPDOCKWIDGET_H #define HEAPDOCKWIDGET_H -#include #include "CutterDockWidget.h" +#include + +#include + namespace Ui { class HeapDockWidget; } +/** + * @brief A container widget that serves as the primary interface for heap analysis + */ class HeapDockWidget : public CutterDockWidget { Q_OBJECT @@ -19,8 +25,8 @@ private slots: void onAllocatorSelected(int index); private: - enum Allocator { Glibc = 0, AllocatorCount }; - Ui::HeapDockWidget *ui; + enum Allocator : ut8 { Glibc = 0, AllocatorCount }; + std::unique_ptr ui; MainWindow *main; QWidget *currentHeapWidget = nullptr; }; diff --git a/src/widgets/HexWidget.cpp b/src/widgets/HexWidget.cpp index 7cf54ca2..dbb39d3b 100644 --- a/src/widgets/HexWidget.cpp +++ b/src/widgets/HexWidget.cpp @@ -1,36 +1,39 @@ #include "HexWidget.h" -#include "Cutter.h" + #include "Configuration.h" -#include "dialogs/MarkDialog.h" -#include "dialogs/WriteCommandsDialogs.h" +#include "Cutter.h" #include "dialogs/CommentsDialog.h" #include "dialogs/FlagDialog.h" -#include "widgets/AddressRangeScrollBar.h" +#include "dialogs/MarkDialog.h" +#include "dialogs/WriteCommandsDialogs.h" #include "shortcuts/ShortcutManager.h" +#include "widgets/AddressRangeScrollBar.h" -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -static constexpr uint64_t MAX_COPY_SIZE = 128 * 1024 * 1024; -static constexpr int MAX_LINE_WIDTH_PRESET = 32; -static constexpr int MAX_LINE_WIDTH_BYTES = 128 * 1024; -static constexpr int WARNING_TIME_MS = 500; +namespace { +constexpr uint64_t maxCopySize = 128 * 1024 * 1024; +constexpr int maxLineWidthPreset = 32; +constexpr int maxLineWidthBytes = 128 * 1024; +constexpr int warningTimeMs = 500; +} HexWidget::HexWidget(QWidget *parent) : QScrollArea(parent), @@ -49,7 +52,8 @@ HexWidget::HexWidget(QWidget *parent) showExHex(true), showExAddr(true), ioModesController(parent), - warningTimer(this) + warningTimer(this), + vScrollBar(new AddressRangeScrollBar(this)) { setMouseTracking(true); setFocusPolicy(Qt::FocusPolicy::StrongFocus); @@ -59,7 +63,6 @@ HexWidget::HexWidget(QWidget *parent) connect(Config(), &Configuration::fontsUpdated, this, [this]() { setMonospaceFont(Config()->getFont()); }); - vScrollBar = new AddressRangeScrollBar(this); setVerticalScrollBar(vScrollBar); vScrollBar->setPageStep(10); vScrollBar->setSingleStep(1); @@ -75,10 +78,10 @@ HexWidget::HexWidget(QWidget *parent) auto sizeActionGroup = new QActionGroup(this); for (int i = 1; i <= 8; i *= 2) { - QAction *action = new QAction(QString::number(i), this); + auto *action = new QAction(QString::number(i), this); action->setCheckable(true); action->setActionGroup(sizeActionGroup); - connect(action, &QAction::triggered, this, [=]() { setItemSize(i); }); + connect(action, &QAction::triggered, this, [=, this]() { setItemSize(i); }); actionsItemSize.append(action); } actionsItemSize.at(0)->setChecked(true); @@ -93,11 +96,11 @@ HexWidget::HexWidget(QWidget *parent) auto formatActionGroup = new QActionGroup(this); for (int i = 0; i < names.length(); ++i) { - QAction *action = new QAction(names.at(i), this); + auto *action = new QAction(names.at(i), this); action->setCheckable(true); action->setActionGroup(formatActionGroup); connect(action, &QAction::triggered, this, - [=]() { setItemFormat(static_cast(i)); }); + [=, this]() { setItemFormat(static_cast(i)); }); actionsItemFormat.append(action); } actionsItemFormat.at(0)->setChecked(true); @@ -105,11 +108,11 @@ HexWidget::HexWidget(QWidget *parent) rowSizeMenu = new QMenu(tr("Bytes per row"), this); auto columnsActionGroup = new QActionGroup(this); - for (int i = 1; i <= MAX_LINE_WIDTH_PRESET; i *= 2) { - QAction *action = new QAction(QString::number(i), rowSizeMenu); + for (int i = 1; i <= maxLineWidthPreset; i *= 2) { + auto *action = new QAction(QString::number(i), rowSizeMenu); action->setCheckable(true); action->setActionGroup(columnsActionGroup); - connect(action, &QAction::triggered, this, [=]() { setFixedLineSize(i); }); + connect(action, &QAction::triggered, this, [=, this]() { setFixedLineSize(i); }); rowSizeMenu->addAction(action); } rowSizeMenu->addSeparator(); @@ -117,7 +120,7 @@ HexWidget::HexWidget(QWidget *parent) actionRowSizePowerOf2->setCheckable(true); actionRowSizePowerOf2->setActionGroup(columnsActionGroup); connect(actionRowSizePowerOf2, &QAction::triggered, this, - [=]() { setColumnMode(ColumnMode::PowerOf2); }); + [=, this]() { setColumnMode(ColumnMode::PowerOf2); }); rowSizeMenu->addAction(actionRowSizePowerOf2); actionItemBigEndian = new QAction(tr("Big Endian"), this); @@ -147,11 +150,11 @@ HexWidget::HexWidget(QWidget *parent) // Add flag option actionAddFlag = Shortcuts()->makeAction("Hex.addFlag", this); - actionAddFlag->setText(tr("Add flag at %1").arg(RzAddressString(getLocationAddress()))); + actionAddFlag->setText(tr("Add flag at %1").arg(rzAddressString(getLocationAddress()))); actionAddFlag->setShortcutContext(Qt::ShortcutContext::WidgetWithChildrenShortcut); connect(actionAddFlag, &QAction::triggered, this, &HexWidget::onActionAddFlagTriggered); connect(this, &HexWidget::positionChanged, this, [this](RVA pos) { - RzAnalysisFunction *fcn = Core()->functionAt(pos); + const RzAnalysisFunction *fcn = Core()->functionAt(pos); if (fcn) { actionAddFlag->setVisible(false); } else { @@ -169,50 +172,50 @@ HexWidget::HexWidget(QWidget *parent) actionSelectRange = new QAction(tr("Select range"), this); connect(actionSelectRange, &QAction::triggered, this, - [this]() { rangeDialog.open(cursor.address); }); + [this]() { rangeDialog.openAt(cursor.address); }); addAction(actionSelectRange); connect(&rangeDialog, &QDialog::accepted, this, &HexWidget::onRangeDialogAccepted); actionsWriteString.reserve(5); - QAction *actionWriteString = new QAction(tr("Write string"), this); - connect(actionWriteString, &QAction::triggered, this, &HexWidget::w_writeString); + auto *actionWriteString = new QAction(tr("Write string"), this); + connect(actionWriteString, &QAction::triggered, this, &HexWidget::wWriteString); actionsWriteString.append(actionWriteString); - QAction *actionWriteLenString = new QAction(tr("Write length and string"), this); - connect(actionWriteLenString, &QAction::triggered, this, &HexWidget::w_writePascalString); + auto *actionWriteLenString = new QAction(tr("Write length and string"), this); + connect(actionWriteLenString, &QAction::triggered, this, &HexWidget::wWritePascalString); actionsWriteString.append(actionWriteLenString); - QAction *actionWriteWideString = new QAction(tr("Write wide string"), this); - connect(actionWriteWideString, &QAction::triggered, this, &HexWidget::w_writeWideString); + auto *actionWriteWideString = new QAction(tr("Write wide string"), this); + connect(actionWriteWideString, &QAction::triggered, this, &HexWidget::wWriteWideString); actionsWriteString.append(actionWriteWideString); - QAction *actionWriteCString = new QAction(tr("Write zero terminated string"), this); - connect(actionWriteCString, &QAction::triggered, this, &HexWidget::w_writeCString); + auto *actionWriteCString = new QAction(tr("Write zero terminated string"), this); + connect(actionWriteCString, &QAction::triggered, this, &HexWidget::wWriteCString); actionsWriteString.append(actionWriteCString); - QAction *actionWrite64 = new QAction(tr("Write a decoded or encoded Base64 string"), this); - connect(actionWrite64, &QAction::triggered, this, &HexWidget::w_write64); + auto *actionWrite64 = new QAction(tr("Write a decoded or encoded Base64 string"), this); + connect(actionWrite64, &QAction::triggered, this, &HexWidget::wWrite64); actionsWriteString.append(actionWrite64); actionsWriteOther.reserve(5); - QAction *actionWriteBytes = new QAction(tr("Write hex bytes"), this); - connect(actionWriteBytes, &QAction::triggered, this, &HexWidget::w_writeBytes); + auto *actionWriteBytes = new QAction(tr("Write hex bytes"), this); + connect(actionWriteBytes, &QAction::triggered, this, &HexWidget::wWriteBytes); actionsWriteOther.append(actionWriteBytes); - QAction *actionWriteZeros = new QAction(tr("Write zeros"), this); - connect(actionWriteZeros, &QAction::triggered, this, &HexWidget::w_writeZeros); + auto *actionWriteZeros = new QAction(tr("Write zeros"), this); + connect(actionWriteZeros, &QAction::triggered, this, &HexWidget::wWriteZeros); actionsWriteOther.append(actionWriteZeros); - QAction *actionWriteRandom = new QAction(tr("Write random bytes"), this); - connect(actionWriteRandom, &QAction::triggered, this, &HexWidget::w_writeRandom); + auto *actionWriteRandom = new QAction(tr("Write random bytes"), this); + connect(actionWriteRandom, &QAction::triggered, this, &HexWidget::wWriteRandom); actionsWriteOther.append(actionWriteRandom); - QAction *actionDuplicateFromOffset = new QAction(tr("Duplicate from offset"), this); - connect(actionDuplicateFromOffset, &QAction::triggered, this, &HexWidget::w_duplFromOffset); + auto *actionDuplicateFromOffset = new QAction(tr("Duplicate from offset"), this); + connect(actionDuplicateFromOffset, &QAction::triggered, this, &HexWidget::wDuplFromOffset); actionsWriteOther.append(actionDuplicateFromOffset); - QAction *actionIncDec = new QAction(tr("Increment/Decrement"), this); - connect(actionIncDec, &QAction::triggered, this, &HexWidget::w_increaseDecrease); + auto *actionIncDec = new QAction(tr("Increment/Decrement"), this); + connect(actionIncDec, &QAction::triggered, this, &HexWidget::wIncreaseDecrease); actionsWriteOther.append(actionIncDec); actionKeyboardEdit = new QAction(tr("Edit with keyboard"), this); @@ -267,8 +270,9 @@ void HexWidget::setItemSize(int nbytes) { static const QVector values({ 1, 2, 4, 8 }); - if (!values.contains(nbytes)) + if (!values.contains(nbytes)) { return; + } finishEditingWord(); @@ -299,8 +303,9 @@ void HexWidget::setItemFormat(ItemFormat format) itemFormat = format; bool sizeEnabled = true; - if (format == ItemFormatFloat) + if (format == ItemFormatFloat) { sizeEnabled = false; + } actionsItemSize.at(0)->setEnabled(sizeEnabled); actionsItemSize.at(1)->setEnabled(sizeEnabled); @@ -357,18 +362,18 @@ void HexWidget::updateCounts() } if (columnMode == ColumnMode::PowerOf2) { - int last_good_size = itemGroupByteLen(); - for (int i = itemGroupByteLen(); i <= MAX_LINE_WIDTH_BYTES; i *= 2) { + int lastGoodSize = itemGroupByteLen(); + for (int i = itemGroupByteLen(); i <= maxLineWidthBytes; i *= 2) { rowSizeBytes = i; itemColumns = rowSizeBytes / itemGroupByteLen(); updateAreasPosition(); if (horizontalScrollBar()->maximum() == 0) { - last_good_size = rowSizeBytes; + lastGoodSize = rowSizeBytes; } else { break; } } - rowSizeBytes = last_good_size; + rowSizeBytes = lastGoodSize; } itemColumns = rowSizeBytes / itemGroupByteLen(); @@ -381,7 +386,7 @@ void HexWidget::updateCounts() action->setChecked(false); } for (auto action : actions) { - if (w > MAX_LINE_WIDTH_PRESET) { + if (w > maxLineWidthPreset) { break; } if (rowSizeBytes == w) { @@ -496,9 +501,10 @@ void HexWidget::paintEvent(QPaintEvent *event) QPainter painter(viewport()); painter.setFont(monospaceFont); - int xOffset = horizontalScrollBar()->value(); - if (xOffset > 0) + const int xOffset = horizontalScrollBar()->value(); + if (xOffset > 0) { painter.translate(QPoint(-xOffset, 0)); + } if (event->rect() == cursor.screenPos.toAlignedRect()) { /* Cursor blink */ @@ -519,8 +525,9 @@ void HexWidget::paintEvent(QPaintEvent *event) painter.drawRect(warningRect); } - if (!cursorEnabled) + if (!cursorEnabled) { return; + } drawCursor(painter, true); } @@ -528,10 +535,11 @@ void HexWidget::paintEvent(QPaintEvent *event) void HexWidget::updateWidth() { int max = (showAscii ? asciiArea.right() : itemArea.right()) - viewport()->width(); - if (max < 0) + if (max < 0) { max = 0; - else + } else { max += charWidth; + } horizontalScrollBar()->setMaximum(max); horizontalScrollBar()->setSingleStep(charWidth); } @@ -543,11 +551,12 @@ bool HexWidget::isFixedWidth() const void HexWidget::resizeEvent(QResizeEvent *event) { - int oldByteCount = bytesPerScreen(); + const int oldByteCount = bytesPerScreen(); updateCounts(); - if (event->oldSize().height() == event->size().height() && oldByteCount == bytesPerScreen()) + if (event->oldSize().height() == event->size().height() && oldByteCount == bytesPerScreen()) { return; + } updateAreasHeight(); fetchData(); // rowCount was changed @@ -578,13 +587,13 @@ void HexWidget::mouseMoveEvent(QMouseEvent *event) if (!infoText.isEmpty()) { infoText += "
"; } - QColor c = mark.color; + const QColor c = mark.color; infoText += QString("● " " %5") .arg(c.red()) .arg(c.green()) .arg(c.blue()) - .arg(MARK_ALPHA_F) + .arg(markAlphaF) .arg(mark.realname.toHtmlEscaped()); } if (!infoText.isEmpty()) { @@ -600,18 +609,20 @@ void HexWidget::mouseMoveEvent(QMouseEvent *event) } if (!updatingSelection) { - if (itemArea.contains(pos) || asciiArea.contains(pos)) + if (itemArea.contains(pos) || asciiArea.contains(pos)) { setCursor(Qt::IBeamCursor); - else + } else { setCursor(Qt::ArrowCursor); + } return; } auto &area = currentArea(); - if (pos.x() < area.left()) + if (pos.x() < area.left()) { pos.setX(area.left()); - else if (pos.x() > area.right()) + } else if (pos.x() > area.right()) { pos.setX(area.right()); + } auto addr = currentAreaPosToAddr(pos, true); setCursorAddr(addr, true); @@ -627,9 +638,9 @@ void HexWidget::mousePressEvent(QMouseEvent *event) pos.rx() += horizontalScrollBar()->value(); if (event->button() == Qt::LeftButton) { - bool selectingData = itemArea.contains(pos); - bool selecting = selectingData || asciiArea.contains(pos); - bool holdingShift = event->modifiers() == Qt::ShiftModifier; + const bool selectingData = itemArea.contains(pos); + const bool selecting = selectingData || asciiArea.contains(pos); + const bool holdingShift = event->modifiers() == Qt::ShiftModifier; // move cursor within actively edited item if (selectingData && !holdingShift && editWordState >= EditWordState::WriteNotEdited) { @@ -708,7 +719,7 @@ void HexWidget::mouseDoubleClickEvent(QMouseEvent *event) auto cursorPosition = screenPosToAddr(pos, false, &wordOffset); setCursorAddr(cursorPosition, false); startEditWord(); - int padding = std::max(0, itemCharLen - editWord.length()); + const int padding = std::max(0, itemCharLen - editWord.length()); editWordPos = std::max(0, wordOffset - padding); editWordPos = std::min(editWordPos, editWord.length()); } @@ -730,7 +741,7 @@ void HexWidget::wheelEvent(QWheelEvent *event) { // according to Qt doc 1 row per 5 degrees, angle measured in 1/8 of degree - int dy = event->angleDelta().y() / (8 * 5); + const int dy = event->angleDelta().y() / (8 * 5); scrollLines(dy); vScrollBar->showTransientScrollBar(); } @@ -745,8 +756,8 @@ bool HexWidget::validCharForEdit(QChar digit) if (editWordPos > 0) { return (digit >= '0' && digit <= '7'); } else { - int bitsInMSD = (itemByteLen * 8) % 3; - int biggestDigit = (1 << bitsInMSD) - 1; + const int bitsInMSD = (itemByteLen * 8) % 3; + const int biggestDigit = (1 << bitsInMSD) - 1; return digit >= '0' && digit <= char('0' + biggestDigit); } } @@ -790,7 +801,7 @@ void HexWidget::typeOverwriteModeChar(QChar c) editWordState = EditWordState::WriteEdited; if (editWordPos >= editWord.length()) { finishEditingWord(); - bool moved = moveCursor(itemByteLen, false, OverflowMove::Ignore); + const bool moved = moveCursor(itemByteLen, false, OverflowMove::Ignore); startEditWord(); if (!moved) { editWordPos = editWord.length() - 1; @@ -851,7 +862,7 @@ bool HexWidget::handleAsciiWrite(QKeyEvent *event) if (text.length() <= 0) { return false; } - QChar c = text[0]; + const QChar c = text[0]; if (c <= '\x1f' || c == '\x7f') { return false; } @@ -871,9 +882,9 @@ bool HexWidget::handleNumberWrite(QKeyEvent *event) if (editWordState < EditWordState::WriteNotStarted) { return false; } - bool overwrite = isFixedWidth(); + const bool overwrite = isFixedWidth(); auto keyText = event->text(); - bool editingWord = editWordState >= EditWordState::WriteNotEdited; + const bool editingWord = editWordState >= EditWordState::WriteNotEdited; if (keyText.length() > 0 && validCharForEdit(keyText[0])) { if (!selection.isEmpty()) { setCursorAddr(BasicCursor(selection.start())); @@ -896,11 +907,11 @@ bool HexWidget::handleNumberWrite(QKeyEvent *event) return true; } if (event->matches(QKeySequence::Paste) && (editingWord || overwrite)) { - QString text = QApplication::clipboard()->text(); + const QString text = QApplication::clipboard()->text(); if (text.length() > 0) { if (overwrite) { startEditWord(); - for (QChar c : text) { + for (const QChar c : text) { if (validCharForEdit(c)) { typeOverwriteModeChar(c); } @@ -919,7 +930,7 @@ bool HexWidget::handleNumberWrite(QKeyEvent *event) cancelEditedWord(); return true; } else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { - bool needToAdvance = + const bool needToAdvance = !(editWordPos == 0 && overwrite && editWordState < EditWordState::WriteEdited); if (finishEditingWord(false) && needToAdvance) { moveCursor(itemByteLen); @@ -1069,11 +1080,11 @@ void HexWidget::keyPressEvent(QKeyEvent *event) QKeySequence::SelectPreviousPage)) { moveCursor(-bytesPerScreen(), select); } else if (moveOrSelect(QKeySequence::MoveToStartOfLine, QKeySequence::SelectStartOfLine)) { - int linePos = + const int linePos = int((cursor.address % itemRowByteLen()) - (startAddress % itemRowByteLen())); moveCursor(-linePos, select); } else if (moveOrSelect(QKeySequence::MoveToEndOfLine, QKeySequence::SelectEndOfLine)) { - int linePos = + const int linePos = int((cursor.address % itemRowByteLen()) - (startAddress % itemRowByteLen())); moveCursor(itemRowByteLen() - linePos, select); } @@ -1111,7 +1122,7 @@ void HexWidget::keyPressEvent(QKeyEvent *event) } editWordPos += 1; if (editWordPos >= editWord.length()) { - bool moved = moveCursor(itemByteLen, false, OverflowMove::Ignore); + const bool moved = moveCursor(itemByteLen, false, OverflowMove::Ignore); startEditWord(); if (!moved) { editWordPos = editWord.length() - 1; @@ -1171,7 +1182,7 @@ void HexWidget::keyPressEvent(QKeyEvent *event) void HexWidget::contextMenuEvent(QContextMenuEvent *event) { - QPoint pt = event->pos(); + const QPoint pt = event->pos(); bool mouseOutsideSelection = false; if (event->reason() == QContextMenuEvent::Mouse) { auto mouseAddr = mousePosToAddr(pt).address; @@ -1191,7 +1202,7 @@ void HexWidget::contextMenuEvent(QContextMenuEvent *event) actionCopyAddress->setDisabled(disable); }; - QString comment = Core()->getCommentAt(cursor.address); + const QString comment = Core()->getCommentAt(cursor.address); if (comment.isEmpty()) { actionDeleteComment->setVisible(false); @@ -1201,11 +1212,11 @@ void HexWidget::contextMenuEvent(QContextMenuEvent *event) actionComment->setText(tr("Edit Comment")); } - QString flag = Core()->flagAt(cursor.address, false); + const QString flag = Core()->flagAt(cursor.address, false); actionAddFlag->setData(flag); if (flag.isEmpty()) { - actionAddFlag->setText(tr("Add flag at %1").arg(RzAddressString(cursor.address))); + actionAddFlag->setText(tr("Add flag at %1").arg(rzAddressString(cursor.address))); } else { actionAddFlag->setText(tr("Rename flag \"%1\"").arg(flag)); } @@ -1242,9 +1253,9 @@ void HexWidget::contextMenuEvent(QContextMenuEvent *event) if (marks.size() == 1) { // Add direct actions if only one mark contains this address const auto &mark = marks.front(); - QAction *editAction = menu->addAction(tr("Edit Mark")); - QAction *removeAction = menu->addAction(tr("Remove Mark")); - QString markName = mark.name; + const QAction *editAction = menu->addAction(tr("Edit Mark")); + const QAction *removeAction = menu->addAction(tr("Remove Mark")); + const QString markName = mark.name; connect(removeAction, &QAction::triggered, this, [this, markName]() { onActionDeleteMarkTriggered(markName); }); connect(editAction, &QAction::triggered, this, @@ -1254,9 +1265,9 @@ void HexWidget::contextMenuEvent(QContextMenuEvent *event) QMenu *editMarkMenu = menu->addMenu(tr("Edit Mark")); QMenu *removeMarkMenu = menu->addMenu(tr("Remove Mark")); for (const auto &mark : marks) { - QAction *subActionRename = removeMarkMenu->addAction(mark.realname); - QAction *subActionEdit = editMarkMenu->addAction(mark.realname); - QString markName = mark.name; + const QAction *subActionRename = removeMarkMenu->addAction(mark.realname); + const QAction *subActionEdit = editMarkMenu->addAction(mark.realname); + const QString markName = mark.name; connect(subActionRename, &QAction::triggered, this, [this, markName]() { onActionDeleteMarkTriggered(markName); }); connect(subActionEdit, &QAction::triggered, this, @@ -1272,10 +1283,11 @@ void HexWidget::contextMenuEvent(QContextMenuEvent *event) void HexWidget::onCursorBlinked() { - if (!cursorEnabled) + if (!cursorEnabled) { return; + } cursor.blink(); - QRect cursorRect = cursor.screenPos.toAlignedRect(); + const QRect cursorRect = cursor.screenPos.toAlignedRect(); viewport()->update(cursorRect.translated(-horizontalScrollBar()->value(), 0)); } @@ -1292,8 +1304,9 @@ void HexWidget::onHexPairsModeEnabled(bool enable) void HexWidget::copy() { - if (selection.isEmpty() || selection.size() > MAX_COPY_SIZE) + if (selection.isEmpty() || selection.size() > maxCopySize) { return; + } auto x = cursorOnAscii ? Core()->getString(selection.start(), selection.size(), RZ_STRING_ENC_8BIT, true) @@ -1303,15 +1316,15 @@ void HexWidget::copy() void HexWidget::copyAddress() { - uint64_t addr = getLocationAddress(); + const uint64_t addr = getLocationAddress(); QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(RzAddressString(addr)); + clipboard->setText(rzAddressString(addr)); } // slot for add comment action void HexWidget::onActionAddCommentTriggered() { - uint64_t addr = cursor.address; + const uint64_t addr = cursor.address; CommentsDialog::addOrEditComment(addr, this); refresh(); } @@ -1319,14 +1332,14 @@ void HexWidget::onActionAddCommentTriggered() // slot for deleting comment action void HexWidget::onActionDeleteCommentTriggered() { - uint64_t addr = cursor.address; + const uint64_t addr = cursor.address; Core()->delComment(addr); refresh(); } void HexWidget::onActionAddFlagTriggered() { - QString flagNameHint = actionAddFlag->data().toString(); + const QString flagNameHint = actionAddFlag->data().toString(); if (FlagDialog(cursor.address, this, flagNameHint).exec()) { refresh(); } @@ -1362,7 +1375,7 @@ void HexWidget::onActionDeleteMarkTriggered(const QString &name) void HexWidget::onActionEditMarkTriggered(const QString &name) { - RVA addr = cursor.address; + const RVA addr = cursor.address; if (MarkDialog(addr, addr, this, name).exec()) { refresh(); } @@ -1370,8 +1383,8 @@ void HexWidget::onActionEditMarkTriggered(const QString &name) void HexWidget::writeZeros(uint64_t address, uint64_t length) { - const uint64_t MAX_BUFFER = 1024; - std::vector zeroes(std::min(MAX_BUFFER, length), 0); + const uint64_t maxBuffer = 1024; + std::vector zeroes(std::min(maxBuffer, length), 0); while (length > zeroes.size()) { data->write(zeroes.data(), address, zeroes.size()); address += zeroes.size(); @@ -1382,14 +1395,14 @@ void HexWidget::writeZeros(uint64_t address, uint64_t length) } } -void HexWidget::w_writeString() +void HexWidget::wWriteString() { if (!ioModesController.prepareForWriting()) { return; } bool ok = false; - QString str = QInputDialog::getText(this, tr("Write string"), tr("String:"), QLineEdit::Normal, - "", &ok); + const QString str = QInputDialog::getText(this, tr("Write string"), tr("String:"), + QLineEdit::Normal, "", &ok); if (!ok || str.isEmpty()) { return; } @@ -1400,18 +1413,18 @@ void HexWidget::w_writeString() refresh(); } -void HexWidget::w_increaseDecrease() +void HexWidget::wIncreaseDecrease() { if (!ioModesController.prepareForWriting()) { return; } IncrementDecrementDialog d; - int ret = d.exec(); + const int ret = d.exec(); if (ret == QDialog::Rejected) { return; } - int64_t value = (int64_t)d.getValue(); - uint8_t sz = d.getNBytes(); + auto value = (int64_t)d.getValue(); + const uint8_t sz = d.getNBytes(); if (d.getMode() == IncrementDecrementDialog::Decrease) { value *= -1; } @@ -1422,7 +1435,7 @@ void HexWidget::w_increaseDecrease() refresh(); } -void HexWidget::w_writeBytes() +void HexWidget::wWriteBytes() { if (!ioModesController.prepareForWriting()) { return; @@ -1434,17 +1447,18 @@ void HexWidget::w_writeBytes() size = static_cast(selection.size()); } - QByteArray bytes = QInputDialog::getText(this, tr("Write hex bytes"), tr("Hex byte string:"), - QLineEdit::Normal, "", &ok) - .toUtf8(); + const QByteArray bytes = + QInputDialog::getText(this, tr("Write hex bytes"), tr("Hex byte string:"), + QLineEdit::Normal, "", &ok) + .toUtf8(); const int offset = bytes.startsWith("\\x") ? 2 : 0; const int incr = offset + 2; - const int bytes_size = qMin(bytes.size() / incr, size); - if (!ok || !bytes_size) { + const int bytesSize = qMin(bytes.size() / incr, size); + if (!ok || !bytesSize) { return; } { - auto *buf = (uint8_t *)malloc(static_cast(bytes_size)); + auto *buf = static_cast(malloc(static_cast(bytesSize))); if (!buf) { return; } @@ -1452,13 +1466,13 @@ void HexWidget::w_writeBytes() buf[j] = static_cast(bytes.mid(i + offset, 2).toInt(nullptr, 16)); } RzCoreLocked core(Core()); - rz_core_write_at(core, getLocationAddress(), buf, bytes_size); + rz_core_write_at(core, getLocationAddress(), buf, bytesSize); free(buf); } refresh(); } -void HexWidget::w_writeZeros() +void HexWidget::wWriteZeros() { if (!ioModesController.prepareForWriting()) { return; @@ -1470,8 +1484,8 @@ void HexWidget::w_writeZeros() } bool ok = false; - int len = QInputDialog::getInt(this, tr("Write zeros"), tr("Number of zeros:"), size, 1, - 0x7FFFFFFF, 1, &ok); + const int len = QInputDialog::getInt(this, tr("Write zeros"), tr("Number of zeros:"), size, 1, + 0x7FFFFFFF, 1, &ok); if (!ok) { return; } @@ -1481,17 +1495,17 @@ void HexWidget::w_writeZeros() refresh(); } -void HexWidget::w_write64() +void HexWidget::wWrite64() { if (!ioModesController.prepareForWriting()) { return; } Base64EnDecodedWriteDialog d; - int ret = d.exec(); + const int ret = d.exec(); if (ret == QDialog::Rejected) { return; } - QByteArray str = d.getData(); + const QByteArray str = d.getData(); if (d.getMode() == Base64EnDecodedWriteDialog::Decode && (QString(str).contains(QRegularExpression("[^a-zA-Z0-9+/=]")) || str.length() % 4 != 0 @@ -1514,7 +1528,7 @@ void HexWidget::w_write64() refresh(); } -void HexWidget::w_writeRandom() +void HexWidget::wWriteRandom() { if (!ioModesController.prepareForWriting()) { return; @@ -1526,8 +1540,8 @@ void HexWidget::w_writeRandom() } bool ok = false; - int nbytes = QInputDialog::getInt(this, tr("Write random bytes"), tr("Number of bytes:"), size, - 1, 0x7FFFFFFF, 1, &ok); + const int nbytes = QInputDialog::getInt(this, tr("Write random bytes"), tr("Number of bytes:"), + size, 1, 0x7FFFFFFF, 1, &ok); if (!ok) { return; } @@ -1539,18 +1553,18 @@ void HexWidget::w_writeRandom() refresh(); } -void HexWidget::w_duplFromOffset() +void HexWidget::wDuplFromOffset() { if (!ioModesController.prepareForWriting()) { return; } DuplicateFromOffsetDialog d; - int ret = d.exec(); + const int ret = d.exec(); if (ret == QDialog::Rejected) { return; } - RVA src = d.getOffset(); - int len = (int)d.getNBytes(); + const RVA src = d.getOffset(); + const int len = (int)d.getNBytes(); { RzCoreLocked core(Core()); rz_core_write_duplicate_at(core, getLocationAddress(), src, len); @@ -1558,14 +1572,14 @@ void HexWidget::w_duplFromOffset() refresh(); } -void HexWidget::w_writePascalString() +void HexWidget::wWritePascalString() { if (!ioModesController.prepareForWriting()) { return; } bool ok = false; - QString str = QInputDialog::getText(this, tr("Write Pascal string"), tr("String:"), - QLineEdit::Normal, "", &ok); + const QString str = QInputDialog::getText(this, tr("Write Pascal string"), tr("String:"), + QLineEdit::Normal, "", &ok); if (!ok || str.isEmpty()) { return; } @@ -1576,14 +1590,14 @@ void HexWidget::w_writePascalString() refresh(); } -void HexWidget::w_writeWideString() +void HexWidget::wWriteWideString() { if (!ioModesController.prepareForWriting()) { return; } bool ok = false; - QString str = QInputDialog::getText(this, tr("Write wide string"), tr("String:"), - QLineEdit::Normal, "", &ok); + const QString str = QInputDialog::getText(this, tr("Write wide string"), tr("String:"), + QLineEdit::Normal, "", &ok); if (!ok || str.isEmpty()) { return; } @@ -1594,14 +1608,14 @@ void HexWidget::w_writeWideString() refresh(); } -void HexWidget::w_writeCString() +void HexWidget::wWriteCString() { if (!ioModesController.prepareForWriting()) { return; } bool ok = false; - QString str = QInputDialog::getText(this, tr("Write zero-terminated string"), tr("String:"), - QLineEdit::Normal, "", &ok); + const QString str = QInputDialog::getText(this, tr("Write zero-terminated string"), + tr("String:"), QLineEdit::Normal, "", &ok); if (!ok || str.isEmpty()) { return; } @@ -1685,8 +1699,9 @@ void HexWidget::updateItemLength() } break; case ItemFormatFloat: - if (itemByteLen < 4) + if (itemByteLen < 4) { itemByteLen = 4; + } // FIXME itemCharLen = 3 * itemByteLen; break; @@ -1699,8 +1714,9 @@ void HexWidget::updateItemLength() void HexWidget::drawHeader(QPainter &painter) { - if (!showHeader) + if (!showHeader) { return; + } int offset = 0; QRectF rect(itemArea.left(), 0, itemWidth(), lineHeight); @@ -1746,7 +1762,7 @@ void HexWidget::drawCursor(QPainter &painter, bool shadow) QRectF charRect(cursor.screenPos); charRect.setWidth(charWidth); painter.fillRect(charRect, backgroundColor); - QColor markColor = Core()->getBlendedMarksColorAt(cursor.address); + const QColor markColor = Core()->getBlendedMarksColorAt(cursor.address); if (markColor.isValid()) { painter.fillRect(charRect, markColor); } @@ -1761,21 +1777,22 @@ void HexWidget::drawAddrArea(QPainter &painter) { uint64_t offset = startAddress; QString addrString; - QSizeF areaSize((addrCharLen + (showExAddr ? 2 : 0)) * charWidth, lineHeight); + const QSizeF areaSize((addrCharLen + (showExAddr ? 2 : 0)) * charWidth, lineHeight); QRectF strRect(addrArea.topLeft(), areaSize); painter.setPen(addrColor); for (int line = 0; line < visibleLines && offset <= data->maxIndex(); ++line, strRect.translate(0, lineHeight), offset += itemRowByteLen()) { addrString = QString("%1").arg(offset, addrCharLen, 16, QLatin1Char('0')); - if (showExAddr) + if (showExAddr) { addrString.prepend(hexPrefix); + } painter.drawText(strRect, Qt::AlignVCenter, addrString); } painter.setPen(borderColor); - qreal vLineOffset = itemArea.left() - charWidth; + const qreal vLineOffset = itemArea.left() - charWidth; painter.drawLine(QLineF(vLineOffset, 0, vLineOffset, viewport()->height())); } @@ -1785,8 +1802,8 @@ void HexWidget::fillMarks(QPainter &painter, bool ascii) endAddress = std::min(endAddress, data->maxIndex()); const auto marks = Core()->getMarks(); for (const auto &mark : marks) { - ut64 from = mark.from; - ut64 to = mark.to; + const ut64 from = mark.from; + const ut64 to = mark.to; // Skip marks not visible in current viewport if (to < startAddress || from > endAddress) { @@ -1799,7 +1816,7 @@ void HexWidget::fillMarks(QPainter &painter, bool ascii) if (!color.isValid()) { continue; } - color.setAlphaF(MARK_ALPHA_F); + color.setAlphaF(markAlphaF); painter.setBrush(color); painter.setPen(Qt::NoPen); @@ -1895,7 +1912,7 @@ void HexWidget::drawItemArea(QPainter &painter) painter.setPen(borderColor); - qreal vLineOffset = asciiArea.left() - charWidth; + const qreal vLineOffset = asciiArea.left() - charWidth; painter.drawLine(QLineF(vLineOffset, 0, vLineOffset, viewport()->height())); } @@ -1923,7 +1940,7 @@ void HexWidget::drawAsciiArea(QPainter &painter) painter.setPen(color); /* Dots look ugly. Use fillRect() instead of drawText(). */ if (ascii == '.') { - qreal a = cursor.screenPos.width(); + const qreal a = cursor.screenPos.width(); QPointF p = charRect.bottomLeft(); p.rx() += (charWidth - a) / 2 + 1; p.ry() += -2 * a; @@ -1948,7 +1965,7 @@ void HexWidget::fillSelectionBackground(QPainter &painter, bool ascii) } const auto parts = rangePolygons(selection.start(), selection.end(), ascii); for (const auto &shape : parts) { - QColor highlightColor = palette().color(QPalette::Highlight); + const QColor highlightColor = palette().color(QPalette::Highlight); if (ascii == cursorOnAscii) { painter.setBrush(highlightColor); painter.drawPolygon(shape); @@ -1969,8 +1986,8 @@ QVector HexWidget::rangePolygons(RVA start, RVA last, bool ascii) const QRectF area = QRectF(ascii ? asciiArea : itemArea); /* Convert absolute values to relative */ - int startOffset = std::max(uint64_t(start), startAddress) - startAddress; - int endOffset = std::min(uint64_t(last), lastVisibleAddr()) - startAddress; + const int startOffset = std::max(uint64_t(start), startAddress) - startAddress; + const int endOffset = std::min(uint64_t(last), lastVisibleAddr()) - startAddress; QVector parts; @@ -1983,11 +2000,11 @@ QVector HexWidget::rangePolygons(RVA start, RVA last, bool ascii) bool startJagged = false; bool endJagged = false; if (!ascii) { - if (int startFraction = startOffset % itemByteLen) { + if (const int startFraction = startOffset % itemByteLen) { startRect.setLeft(startRect.left() + startFraction * startRect.width() / itemByteLen); startJagged = true; } - if (int endFraction = itemByteLen - 1 - (endOffset % itemByteLen)) { + if (const int endFraction = itemByteLen - 1 - (endOffset % itemByteLen)) { endRect.setRight(endRect.right() - endFraction * endRect.width() / itemByteLen); endJagged = true; } @@ -2037,7 +2054,7 @@ QVector HexWidget::rangePolygons(RVA start, RVA last, bool ascii) // small adjustment to make sure that edges don't overlap with rect edges, QPolygonF doesn't // handle it properly - QPointF adjustment(charWidth / 16, 0); + const QPointF adjustment(charWidth / 16, 0); top.translate(-adjustment); bottom.translate(adjustment); @@ -2057,7 +2074,7 @@ QVector HexWidget::rangePolygons(RVA start, RVA last, bool ascii) void HexWidget::updateMetrics() { - QFontMetricsF fontMetrics(this->monospaceFont); + const QFontMetricsF fontMetrics(this->monospaceFont); lineHeight = fontMetrics.height(); #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) charWidth = fontMetrics.width('A'); @@ -2068,7 +2085,7 @@ void HexWidget::updateMetrics() updateCounts(); updateAreasHeight(); - qreal cursorWidth = std::max(charWidth / 3, 1.); + const qreal cursorWidth = std::max(charWidth / 3, 1.); cursor.screenPos.setHeight(lineHeight); shadowCursor.screenPos.setHeight(lineHeight); @@ -2089,7 +2106,7 @@ void HexWidget::updateAreasPosition() { const qreal spacingWidth = areaSpacingWidth(); - qreal yOffset = showHeader ? lineHeight : 0; + const qreal yOffset = showHeader ? lineHeight : 0; addrArea.setTopLeft(QPointF(0, yOffset)); addrArea.setWidth((addrCharLen + (showExAddr ? 2 : 0)) * charWidth); @@ -2107,7 +2124,7 @@ void HexWidget::updateAreasHeight() { visibleLines = static_cast((viewport()->height() - itemArea.top()) / lineHeight); - qreal height = visibleLines * lineHeight; + const qreal height = visibleLines * lineHeight; addrArea.setHeight(height); itemArea.setHeight(height); asciiArea.setHeight(height); @@ -2138,7 +2155,7 @@ bool HexWidget::moveCursor(int offset, bool select, OverflowMove overflowMove) void HexWidget::moveCursorKeepEditOffset(int byteOffset, bool select, OverflowMove overflowMove) { - int wordOffset = editWordPos; + const int wordOffset = editWordPos; moveCursor(byteOffset, select, overflowMove); // preserve position within word when moving vertically in hex or oct modes if (!cursorOnAscii && !select && wordOffset > 0 && navigationMode == HexNavigationMode::AnyChar @@ -2152,10 +2169,11 @@ void HexWidget::setCursorAddr(BasicCursor addr, bool select) { finishEditingWord(); if (!select) { - bool clearingSelection = !selection.isEmpty(); + const bool clearingSelection = !selection.isEmpty(); selection.init(addr); - if (clearingSelection) + if (clearingSelection) { emit selectionChanged(getSelection()); + } } emit positionChanged(addr.address); @@ -2179,7 +2197,7 @@ void HexWidget::setCursorAddr(BasicCursor addr, bool select) addressValue -= (addressValue % itemRowByteLen()); /* FIXME: handling Page Up/Down */ - uint64_t rowAfterVisibleAddress = startAddress + bytesPerScreen(); + const uint64_t rowAfterVisibleAddress = startAddress + bytesPerScreen(); if (addressValue == rowAfterVisibleAddress && addressValue > startAddress) { // when pressing down add only one new row startAddress += itemRowByteLen(); @@ -2209,7 +2227,7 @@ void HexWidget::updateCursorMeta() QPointF point; QPointF pointAscii; - int offset = cursor.address - startAddress; + const int offset = cursor.address - startAddress; int itemOffset = offset; int asciiOffset; @@ -2247,13 +2265,13 @@ QColor HexWidget::itemColor(uint8_t byte) { QColor color(defColor); - if (byte == 0x00) + if (byte == 0x00) { color = b0x00Color; - else if (byte == 0x7f) + } else if (byte == 0x7f) { color = b0x7fColor; - else if (byte == 0xff) + } else if (byte == 0xff) { color = b0xffColor; - else if (IS_PRINTABLE(byte)) { + } else if (IS_PRINTABLE(byte)) { color = printableColor; } @@ -2304,44 +2322,52 @@ QVariant HexWidget::readItem(int offset, QColor *color) switch (itemByteLen) { case 1: byte = bytes[0]; - if (color) + if (color) { *color = itemColor(byte); - if (!signedItem) + } + if (!signedItem) { return QVariant(static_cast(byte)); + } return QVariant(static_cast(static_cast(byte))); case 2: - if (itemBigEndian) + if (itemBigEndian) { word = fromBigEndian(bytes); - else + } else { word = fromLittleEndian(bytes); + } - if (!signedItem) + if (!signedItem) { return QVariant(static_cast(word)); + } return QVariant(static_cast(static_cast(word))); case 4: - if (itemBigEndian) + if (itemBigEndian) { dword = fromBigEndian(bytes); - else + } else { dword = fromLittleEndian(bytes); + } if (itemFormat == ItemFormatFloat) { memcpy(&float32, &dword, sizeof(float32)); return QVariant(float32); } - if (!signedItem) + if (!signedItem) { return QVariant(static_cast(dword)); + } return QVariant(static_cast(static_cast(dword))); case 8: - if (itemBigEndian) + if (itemBigEndian) { qword = fromBigEndian(bytes); - else + } else { qword = fromLittleEndian(bytes); + } if (itemFormat == ItemFormatFloat) { memcpy(&float64, &qword, sizeof(float64)); return QVariant(float64); } - if (!signedItem) + if (!signedItem) { return QVariant(qword); + } return QVariant(static_cast(qword)); } @@ -2351,15 +2377,16 @@ QVariant HexWidget::readItem(int offset, QColor *color) QString HexWidget::renderItem(int offset, QColor *color) { QString item; - QVariant itemVal = readItem(offset, color); - int itemLen = itemCharLen - itemPrefixLen; /* Reserve space for prefix */ + const QVariant itemVal = readItem(offset, color); + const int itemLen = itemCharLen - itemPrefixLen; /* Reserve space for prefix */ // FIXME: handle broken itemVal ( QVariant() ) switch (itemFormat) { case ItemFormatHex: item = QString("%1").arg(itemVal.toULongLong(), itemLen, 16, QLatin1Char('0')); - if (itemByteLen > 1 && showExHex) + if (itemByteLen > 1 && showExHex) { item.prepend(hexPrefix); + } break; case ItemFormatOct: item = QString("%1").arg(itemVal.toULongLong(), itemLen, 8, QLatin1Char('0')); @@ -2398,10 +2425,10 @@ QChar HexWidget::renderAscii(int offset, QColor *color) */ QString HexWidget::getFlagsAndComment(uint64_t address) { - QString flagNames = Core()->listFlagsAsStringAt(address); + const QString flagNames = Core()->listFlagsAsStringAt(address); QString metaData = flagNames.isEmpty() ? "" : "Flags: " + flagNames.trimmed(); - QString comment = Core()->getCommentAt(address); + const QString comment = Core()->getCommentAt(address); if (!comment.isEmpty()) { if (!metaData.isEmpty()) { metaData.append("\n"); @@ -2448,7 +2475,7 @@ static bool checkAndWriteWithSign(const QVariant &value, uint8_t *buf, bool isSi } } -bool HexWidget::parseWord(QString word, uint8_t *buf, size_t bufferSize) const +bool HexWidget::parseWord(const QString &word, uint8_t *buf, size_t bufferSize) const { bool parseOk = false; if (bufferSize < size_t(itemByteLen)) { @@ -2456,7 +2483,7 @@ bool HexWidget::parseWord(QString word, uint8_t *buf, size_t bufferSize) const } if (itemFormat == ItemFormatFloat) { if (itemByteLen == 4) { - float value = word.toFloat(&parseOk); + const float value = word.toFloat(&parseOk); if (!parseOk) { return false; } @@ -2467,7 +2494,7 @@ bool HexWidget::parseWord(QString word, uint8_t *buf, size_t bufferSize) const } return true; } else if (itemByteLen == 8) { - double value = word.toDouble(&parseOk); + const double value = word.toDouble(&parseOk); if (!parseOk) { return false; } @@ -2601,9 +2628,9 @@ BasicCursor HexWidget::screenPosToAddr(const QPoint &point, bool middle, int *wo QPointF pt = point - itemArea.topLeft(); int relativeAddress = 0; - int line = static_cast(pt.y() / lineHeight); + const int line = static_cast(pt.y() / lineHeight); relativeAddress += line * itemRowByteLen(); - int column = static_cast(pt.x() / columnExWidth()); + const int column = static_cast(pt.x() / columnExWidth()); relativeAddress += column * itemGroupByteLen(); pt.rx() -= column * columnExWidth(); auto roundingOffset = middle ? itemWidth() / 2 : 0; @@ -2627,7 +2654,7 @@ BasicCursor HexWidget::screenPosToAddr(const QPoint &point, bool middle, int *wo BasicCursor HexWidget::asciiPosToAddr(const QPoint &point, bool middle) const { - QPointF pt = point - asciiArea.topLeft(); + const QPointF pt = point - asciiArea.topLeft(); int relativeAddress = 0; relativeAddress += static_cast(pt.y() / lineHeight) * itemRowByteLen(); @@ -2704,7 +2731,7 @@ void HexWidget::showWarningRect(QRectF rect) { warningRect = rect; warningRectVisible = true; - warningTimer.start(WARNING_TIME_MS); + warningTimer.start(warningTimeMs); updateViewport(); } @@ -2716,7 +2743,7 @@ void HexWidget::updateViewport() void HexWidget::scrollLines(int lines, bool clampToScrollBarRange) { - int64_t delta = -lines * itemRowByteLen(); + const int64_t delta = -lines * itemRowByteLen(); if (lines == 0) { return; @@ -2746,8 +2773,8 @@ void HexWidget::setStartAddress(RVA address) { RVA aligned = address - (address % itemRowByteLen()); - uint64_t maxIdx = data->maxIndex(); - uint64_t screenBytes = bytesPerScreen(); + const uint64_t maxIdx = data->maxIndex(); + const uint64_t screenBytes = bytesPerScreen(); if (maxIdx > screenBytes) { RVA maxStart = (maxIdx - screenBytes + 1); maxStart -= (maxStart % itemRowByteLen()); diff --git a/src/widgets/HexWidget.h b/src/widgets/HexWidget.h index fd2217c6..5a730296 100644 --- a/src/widgets/HexWidget.h +++ b/src/widgets/HexWidget.h @@ -2,14 +2,18 @@ #define HEXWIDGET_H #include "Cutter.h" -#include "dialogs/HexdumpRangeDialog.h" #include "common/IOModesController.h" +#include "dialogs/HexdumpRangeDialog.h" +#include #include #include -#include + #include +/** + * @brief Tracks memory addresses while preventing 64-bit overflow + */ struct BasicCursor { uint64_t address; @@ -60,13 +64,12 @@ struct BasicCursor } }; +/** + * @brief Controls the cursor's visual blinking and screen location + */ struct HexCursor { - HexCursor() - { - isVisible = false; - onAsciiArea = false; - } + HexCursor() : isVisible(false), onAsciiArea(false) {} bool isVisible; bool onAsciiArea; @@ -82,6 +85,9 @@ struct HexCursor void stopBlinking() { blinkTimer.stop(); } }; +/** + * @brief A blueprint for how the widget reads and writes memory data. + */ class AbstractData { public: @@ -93,17 +99,20 @@ public: virtual uint64_t minIndex() = 0; }; +/** + * @brief Handles memory operations for simple, local byte arrays + */ class BufferData : public AbstractData { public: - BufferData() { m_buffer.fill(0, 1); } + BufferData() { mBuffer.fill(0, 1); } explicit BufferData(const QByteArray &buffer) { if (buffer.isEmpty()) { - m_buffer.fill(0, 1); + mBuffer.fill(0, 1); } else { - m_buffer = buffer; + mBuffer = buffer; } } @@ -113,9 +122,9 @@ public: bool copy(void *out, uint64_t addr, size_t len) override { - if (addr < static_cast(m_buffer.size()) - && (static_cast(m_buffer.size()) - addr) < len) { - memcpy(out, m_buffer.constData() + addr, len); + if (addr < static_cast(mBuffer.size()) + && (static_cast(mBuffer.size()) - addr) < len) { + memcpy(out, mBuffer.constData() + addr, len); return true; } return false; @@ -123,75 +132,78 @@ public: bool write(const uint8_t *in, uint64_t addr, size_t len) override { - if (addr < static_cast(m_buffer.size()) - && (static_cast(m_buffer.size()) - addr) < len) { - memcpy(m_buffer.data() + addr, in, len); + if (addr < static_cast(mBuffer.size()) + && (static_cast(mBuffer.size()) - addr) < len) { + memcpy(mBuffer.data() + addr, in, len); return true; } return false; } - uint64_t maxIndex() override { return m_buffer.size() - 1; } + uint64_t maxIndex() override { return mBuffer.size() - 1; } private: - QByteArray m_buffer; + QByteArray mBuffer; }; +/** + * @brief Manages live binary data using a fast block-based cache + */ class MemoryData : public AbstractData { public: MemoryData() = default; ~MemoryData() override = default; - static constexpr size_t BLOCK_SIZE = 4096; + static constexpr size_t blockSize = 4096; void fetch(uint64_t address, int length) override { // FIXME: reuse data if possible const uint64_t blockSize = 0x1000ULL; - uint64_t alignedAddr = address & ~(blockSize - 1); - int offset = address - alignedAddr; + const uint64_t alignedAddr = address & ~(blockSize - 1); + const int offset = address - alignedAddr; int len = (offset + length + (blockSize - 1)) & ~(blockSize - 1); - m_firstBlockAddr = alignedAddr; - m_lastValidAddr = length ? alignedAddr + len - 1 : 0; - if (m_lastValidAddr < m_firstBlockAddr) { - m_lastValidAddr = -1; - len = m_lastValidAddr - m_firstBlockAddr + 1; + mFirstBlockAddr = alignedAddr; + mLastValidAddr = length ? alignedAddr + len - 1 : 0; + if (mLastValidAddr < mFirstBlockAddr) { + mLastValidAddr = -1; + len = mLastValidAddr - mFirstBlockAddr + 1; } - m_blocks.clear(); + mBlocks.clear(); uint64_t addr = alignedAddr; for (ut64 i = 0; i < len / blockSize; ++i, addr += blockSize) { - m_blocks.append(Core()->ioRead(addr, blockSize)); + mBlocks.append(Core()->ioRead(addr, blockSize)); } } bool copy(void *out, uint64_t addr, size_t len) override { - if (addr < m_firstBlockAddr - || addr > m_lastValidAddr + if (addr < mFirstBlockAddr + || addr > mLastValidAddr /* do not merge with previous check to handle overflows */ - || (m_lastValidAddr - addr + 1) < len || m_blocks.isEmpty()) { + || (mLastValidAddr - addr + 1) < len || mBlocks.isEmpty()) { memset(out, 0xff, len); return false; } - int totalOffset = addr - m_firstBlockAddr; - int blockId = totalOffset / BLOCK_SIZE; - int blockOffset = totalOffset % BLOCK_SIZE; - size_t first_part = BLOCK_SIZE - blockOffset; - if (first_part >= len) { - memcpy(out, m_blocks.at(blockId).constData() + blockOffset, len); + const int totalOffset = addr - mFirstBlockAddr; + const int blockId = totalOffset / blockSize; + const int blockOffset = totalOffset % blockSize; + const size_t firstPart = blockSize - blockOffset; + if (firstPart >= len) { + memcpy(out, mBlocks.at(blockId).constData() + blockOffset, len); } else { - memcpy(out, m_blocks.at(blockId).constData() + blockOffset, first_part); - memcpy(static_cast(out) + first_part, m_blocks.at(blockId + 1).constData(), - len - first_part); + memcpy(out, mBlocks.at(blockId).constData() + blockOffset, firstPart); + memcpy(static_cast(out) + firstPart, mBlocks.at(blockId + 1).constData(), + len - firstPart); } return true; } void writeToCache(const uint8_t *in, uint64_t adr, size_t len) { - if (adr < m_firstBlockAddr) { - uint64_t prefix = m_firstBlockAddr - adr; + if (adr < mFirstBlockAddr) { + const uint64_t prefix = mFirstBlockAddr - adr; if (prefix <= len) { return; } @@ -199,16 +211,16 @@ public: adr += prefix; len -= prefix; } - if (adr > m_lastValidAddr) { + if (adr > mLastValidAddr) { return; } - int offset = (int)(adr - m_firstBlockAddr); - int blockId = offset / BLOCK_SIZE; - int blockOffset = offset % BLOCK_SIZE; - while (len > 0 && blockId < m_blocks.size()) { - size_t l = BLOCK_SIZE - blockOffset; + const int offset = (int)(adr - mFirstBlockAddr); + int blockId = offset / blockSize; + int blockOffset = offset % blockSize; + while (len > 0 && blockId < mBlocks.size()) { + size_t l = blockSize - blockOffset; l = std::min(l, len); - memcpy(m_blocks[blockId].data() + blockOffset, in, l); + memcpy(mBlocks[blockId].data() + blockOffset, in, l); len -= l; blockOffset = 0; adr += l; @@ -228,84 +240,86 @@ public: uint64_t maxIndex() override { return std::numeric_limits::max(); } - uint64_t minIndex() override { return m_firstBlockAddr; } + uint64_t minIndex() override { return mFirstBlockAddr; } private: - QVector m_blocks; - uint64_t m_firstBlockAddr = 0; - uint64_t m_lastValidAddr = 0; + QVector mBlocks; + uint64_t mFirstBlockAddr = 0; + uint64_t mLastValidAddr = 0; }; class HexSelection { public: - HexSelection() - { - m_empty = true; - m_start = m_end = 0; - } + HexSelection() : empty(true) { mStart = mEnd = 0; } inline void init(BasicCursor addr) { - m_empty = true; - m_init = addr; + empty = true; + mInit = addr; } void set(uint64_t start, uint64_t end) { - m_empty = false; - m_init = BasicCursor(start); - m_start = start; - m_end = end; + empty = false; + mInit = BasicCursor(start); + mStart = start; + mEnd = end; } void update(BasicCursor addr) { - m_empty = false; - if (m_init < addr) { - m_start = m_init.address; - m_end = addr.address; - if (!addr.pastEnd) - m_end -= 1; - } else if (addr < m_init) { - m_start = addr.address; - m_end = m_init.address; - if (!m_init.pastEnd) - m_end -= 1; + empty = false; + if (mInit < addr) { + mStart = mInit.address; + mEnd = addr.address; + if (!addr.pastEnd) { + mEnd -= 1; + } + } else if (addr < mInit) { + mStart = addr.address; + mEnd = mInit.address; + if (!mInit.pastEnd) { + mEnd -= 1; + } } else { - m_start = m_end = m_init.address; - m_empty = true; + mStart = mEnd = mInit.address; + empty = true; } } - bool intersects(uint64_t start, uint64_t end) + bool intersects(uint64_t start, uint64_t end) const { - return !m_empty && m_end >= start && m_start <= end; + return !empty && mEnd >= start && mStart <= end; } - bool contains(uint64_t pos) const { return !m_empty && m_start <= pos && pos <= m_end; } + bool contains(uint64_t pos) const { return !empty && mStart <= pos && pos <= mEnd; } uint64_t size() const { uint64_t size = 0; - if (!isEmpty()) - size = m_end - m_start + 1; + if (!isEmpty()) { + size = mEnd - mStart + 1; + } return size; } - inline bool isEmpty() const { return m_empty; } - inline uint64_t start() const { return m_start; } - inline uint64_t end() const { return m_end; } + inline bool isEmpty() const { return empty; } + inline uint64_t start() const { return mStart; } + inline uint64_t end() const { return mEnd; } private: - BasicCursor m_init; - uint64_t m_start; - uint64_t m_end; - bool m_empty; + BasicCursor mInit; + uint64_t mStart; + uint64_t mEnd; + bool empty; }; class AddressRangeScrollBar; +/** + * @brief Widget for rendering and editing of hex and ASCII memory data + */ class HexWidget : public QScrollArea { Q_OBJECT @@ -316,18 +330,23 @@ public: void setMonospaceFont(const QFont &font); - enum AddrWidth { AddrWidth32 = 8, AddrWidth64 = 16 }; - enum ItemSize { ItemSizeByte = 1, ItemSizeWord = 2, ItemSizeDword = 4, ItemSizeQword = 8 }; - enum ItemFormat { + enum AddrWidth : ut8 { AddrWidth32 = 8, AddrWidth64 = 16 }; + enum ItemSize : ut8 { + ItemSizeByte = 1, + ItemSizeWord = 2, + ItemSizeDword = 4, + ItemSizeQword = 8 + }; + enum ItemFormat : ut8 { ItemFormatHex, ItemFormatOct, ItemFormatDec, ItemFormatSignedDec, ItemFormatFloat }; - enum class ColumnMode { Fixed, PowerOf2 }; - enum class EditWordState { Read, WriteNotStarted, WriteNotEdited, WriteEdited }; - enum class HexNavigationMode { Words, WordChar, AnyChar }; + enum class ColumnMode : ut8 { Fixed, PowerOf2 }; + enum class EditWordState : ut8 { Read, WriteNotStarted, WriteNotEdited, WriteEdited }; + enum class HexNavigationMode : ut8 { Words, WordChar, AnyChar }; void setItemSize(int nbytes); void setItemFormat(ItemFormat format); @@ -391,16 +410,16 @@ private slots: void onActionEditMarkTriggered(const QString &name); // Write command slots - void w_writeString(); - void w_increaseDecrease(); - void w_writeBytes(); - void w_writeZeros(); - void w_write64(); - void w_writeRandom(); - void w_duplFromOffset(); - void w_writePascalString(); - void w_writeWideString(); - void w_writeCString(); + void wWriteString(); + void wIncreaseDecrease(); + void wWriteBytes(); + void wWriteZeros(); + void wWrite64(); + void wWriteRandom(); + void wDuplFromOffset(); + void wWritePascalString(); + void wWriteWideString(); + void wWriteCString(); void onKeyboardEditTriggered(bool enabled); void onKeyboardEditChanged(bool enabled); @@ -418,7 +437,7 @@ private: void updateMetrics(); void updateAreasPosition(); void updateAreasHeight(); - enum class OverflowMove { Clamp, Ignore }; + enum class OverflowMove : ut8 { Clamp, Ignore }; bool moveCursor(int offset, bool select = false, OverflowMove overflowMove = OverflowMove::Clamp); void moveCursorKeepEditOffset(int byteOffset, bool select, OverflowMove overflowMove); @@ -509,7 +528,7 @@ private: void typeOverwriteModeChar(QChar c); HexNavigationMode defaultNavigationMode(); void refreshWordEditState(); - bool parseWord(QString word, uint8_t *buf, size_t bufferSize) const; + bool parseWord(const QString &word, uint8_t *buf, size_t bufferSize) const; bool handleAsciiWrite(QKeyEvent *event); bool handleNumberWrite(QKeyEvent *event); @@ -614,7 +633,7 @@ private: QString editWord; EditWordState editWordState = EditWordState::Read; HexNavigationMode navigationMode = HexNavigationMode::Words; - enum class EarlyEditFlush { + enum class EarlyEditFlush : ut8 { OnFinish, EditNibble, EditFixedWidthChar, diff --git a/src/widgets/HexdumpWidget.cpp b/src/widgets/HexdumpWidget.cpp index 306582d9..309f1927 100644 --- a/src/widgets/HexdumpWidget.cpp +++ b/src/widgets/HexdumpWidget.cpp @@ -1,21 +1,20 @@ #include "HexdumpWidget.h" + +#include "common/Configuration.h" +#include "common/Helpers.h" +#include "common/TempConfig.h" +#include "core/MainWindow.h" #include "ui_HexdumpWidget.h" -#include "common/Helpers.h" -#include "common/Configuration.h" -#include "common/TempConfig.h" -#include "common/SyntaxHighlighter.h" -#include "core/MainWindow.h" - -#include -#include -#include -#include -#include #include -#include +#include #include +#include +#include +#include +#include #include +#include HexdumpWidget::HexdumpWidget(MainWindow *main) : MemoryDockWidget(MemoryWidgetType::Hexdump, main), ui(new Ui::HexdumpWidget) @@ -32,12 +31,12 @@ HexdumpWidget::HexdumpWidget(MainWindow *main) ui->splitter->setChildrenCollapsible(false); - QToolButton *closeButton = new QToolButton; - QIcon closeIcon = QIcon(":/img/icons/delete.svg"); + auto *closeButton = new QToolButton; + const QIcon closeIcon = QIcon(":/img/icons/delete.svg"); closeButton->setIcon(closeIcon); closeButton->setAutoRaise(true); - ui->hexSideTab_2->setCornerWidget(closeButton); + ui->hexSideTab2->setCornerWidget(closeButton); syntaxHighLighter = Config()->createSyntaxHighlighter(ui->hexDisasTextEdit->document()); ui->openSideViewB->hide(); // hide button at startup since side view is visible @@ -47,7 +46,7 @@ HexdumpWidget::HexdumpWidget(MainWindow *main) connect(ui->openSideViewB, &QToolButton::clicked, this, [this] { showSidePanel(true); }); // Set placeholders for the line-edit components - QString placeholder = tr("Select bytes to display information"); + const QString placeholder = tr("Select bytes to display information"); ui->bytesMD5->setPlaceholderText(placeholder); ui->bytesEntropy->setPlaceholderText(placeholder); ui->bytesSHA1->setPlaceholderText(placeholder); @@ -83,28 +82,44 @@ HexdumpWidget::HexdumpWidget(MainWindow *main) connect(seekable, &CutterSeekable::seekableSeekChanged, this, &HexdumpWidget::onSeekChanged); connect(ui->hexTextView, &HexWidget::positionChanged, this, [this](RVA addr) { - if (!sent_seek) { - sent_seek = true; + if (!sentSeek) { + sentSeek = true; seekable->seek(addr); - sent_seek = false; + sentSeek = false; } }); connect(ui->hexTextView, &HexWidget::selectionChanged, this, &HexdumpWidget::selectionChanged); - connect(ui->hexSideTab_2, &QTabWidget::currentChanged, this, + connect(ui->hexSideTab2, &QTabWidget::currentChanged, this, &HexdumpWidget::refreshSelectionInfo); ui->hexTextView->installEventFilter(this); initParsing(); selectHexPreview(); + connect(ui->parseTypeComboBox, &QComboBox::currentTextChanged, this, + &HexdumpWidget::onParseTypeComboBoxCurrentTextChanged); + connect(ui->parseArchComboBox, &QComboBox::currentTextChanged, this, + &HexdumpWidget::onParseArchComboBoxCurrentTextChanged); + connect(ui->parseBitsComboBox, &QComboBox::currentTextChanged, this, + &HexdumpWidget::onParseBitsComboBoxCurrentTextChanged); + connect(ui->parseEndianComboBox, &QComboBox::currentTextChanged, this, + &HexdumpWidget::onParseEndianComboBoxCurrentTextChanged); + connect(ui->hexSideTab2, &QTabWidget::currentChanged, this, + &HexdumpWidget::onHexSideTab2CurrentChanged); + + connect(ui->copyMD5, &QToolButton::clicked, this, &HexdumpWidget::onCopyMD5Clicked); + connect(ui->copySHA1, &QToolButton::clicked, this, &HexdumpWidget::onCopyShA1Clicked); + connect(ui->copySHA256, &QToolButton::clicked, this, &HexdumpWidget::onCopyShA256Clicked); + connect(ui->copyCRC32, &QToolButton::clicked, this, &HexdumpWidget::onCopyCrC32Clicked); + // apply initial offset refresh(seekable->getOffset()); } void HexdumpWidget::onSeekChanged(RVA addr) { - if (sent_seek) { - sent_seek = false; + if (sentSeek) { + sentSeek = false; return; } refresh(addr); @@ -127,14 +142,14 @@ void HexdumpWidget::refresh(RVA addr) if (!refreshDeferrer->attemptRefresh(addr == RVA_INVALID ? nullptr : new RVA(addr))) { return; } - sent_seek = true; + sentSeek = true; if (addr != RVA_INVALID) { ui->hexTextView->seek(addr); } else { ui->hexTextView->refresh(); refreshSelectionInfo(); } - sent_seek = false; + sentSeek = false; } void HexdumpWidget::initParsing() @@ -167,19 +182,19 @@ void HexdumpWidget::selectionChanged(HexWidget::Selection selection) } } -void HexdumpWidget::on_parseArchComboBox_currentTextChanged(const QString & /*arg1*/) +void HexdumpWidget::onParseArchComboBoxCurrentTextChanged(const QString & /*arg1*/) { refreshSelectionInfo(); } -void HexdumpWidget::on_parseBitsComboBox_currentTextChanged(const QString & /*arg1*/) +void HexdumpWidget::onParseBitsComboBoxCurrentTextChanged(const QString & /*arg1*/) { refreshSelectionInfo(); } void HexdumpWidget::setupFonts() { - QFont font = Config()->getFont(); + const QFont font = Config()->getFont(); ui->hexDisasTextEdit->setFont(font); ui->hexTextView->setMonospaceFont(font); } @@ -206,7 +221,7 @@ void HexdumpWidget::clearParseWindow() void HexdumpWidget::showSidePanel(bool show) { - ui->hexSideTab_2->setVisible(show); + ui->hexSideTab2->setVisible(show); ui->openSideViewB->setHidden(show); if (show) { refreshSelectionInfo(); @@ -220,19 +235,19 @@ QString HexdumpWidget::getWindowTitle() const void HexdumpWidget::updateParseWindow(RVA start_address, int size) { - if (!ui->hexSideTab_2->isVisible()) { + if (!ui->hexSideTab2->isVisible()) { return; } - if (ui->hexSideTab_2->currentIndex() == 0) { + if (ui->hexSideTab2->currentIndex() == 0) { // scope for TempConfig // Get selected combos - QString arch = ui->parseArchComboBox->currentText(); - QString bits = ui->parseBitsComboBox->currentText(); - QString selectedCommand = ui->parseTypeComboBox->currentData().toString(); - QString commandResult = ""; - bool bigEndian = ui->parseEndianComboBox->currentIndex() == 1; + const QString arch = ui->parseArchComboBox->currentText(); + const QString bits = ui->parseBitsComboBox->currentText(); + const QString selectedCommand = ui->parseTypeComboBox->currentData().toString(); + const QString commandResult = ""; + const bool bigEndian = ui->parseEndianComboBox->currentIndex() == 1; TempConfig tempConfig; tempConfig.set("asm.arch", arch).set("asm.bits", bits).set("cfg.bigendian", bigEndian); @@ -243,32 +258,32 @@ void HexdumpWidget::updateParseWindow(RVA start_address, int size) : ""); } else { // Fill the information tab hashes and entropy - RzHashSize digest_size = 0; + RzHashSize digestSize = 0; RzCoreLocked core(Core()); - ut64 old_offset = core->offset; + const ut64 oldOffset = core->offset; rz_core_seek(core, start_address, true); - ut8 *block = core->block; + const ut8 *block = core->block; char *digest = rz_hash_cfg_calculate_small_block_string(core->hash, "md5", block, size, - &digest_size, false); + &digestSize, false); ui->bytesMD5->setText(QString(digest)); free(digest); digest = rz_hash_cfg_calculate_small_block_string(core->hash, "sha1", block, size, - &digest_size, false); + &digestSize, false); ui->bytesSHA1->setText(QString(digest)); free(digest); digest = rz_hash_cfg_calculate_small_block_string(core->hash, "sha256", block, size, - &digest_size, false); + &digestSize, false); ui->bytesSHA256->setText(QString(digest)); free(digest); digest = rz_hash_cfg_calculate_small_block_string(core->hash, "crc32", block, size, - &digest_size, false); + &digestSize, false); ui->bytesCRC32->setText(QString(digest)); free(digest); digest = rz_hash_cfg_calculate_small_block_string(core->hash, "entropy", block, size, - &digest_size, false); + &digestSize, false); ui->bytesEntropy->setText(QString(digest)); free(digest); - rz_core_seek(core, old_offset, true); + rz_core_seek(core, oldOffset, true); ui->bytesMD5->setCursorPosition(0); ui->bytesSHA1->setCursorPosition(0); ui->bytesSHA256->setCursorPosition(0); @@ -276,23 +291,23 @@ void HexdumpWidget::updateParseWindow(RVA start_address, int size) } } -void HexdumpWidget::on_parseTypeComboBox_currentTextChanged(const QString &) +void HexdumpWidget::onParseTypeComboBoxCurrentTextChanged(const QString &) { - QString currentParseTypeText = ui->parseTypeComboBox->currentData().toString(); + const QString currentParseTypeText = ui->parseTypeComboBox->currentData().toString(); if (currentParseTypeText == "pda" || currentParseTypeText == "pci") { - ui->hexSideFrame_2->show(); + ui->hexSideFrame2->show(); } else { - ui->hexSideFrame_2->hide(); + ui->hexSideFrame2->hide(); } refreshSelectionInfo(); } -void HexdumpWidget::on_parseEndianComboBox_currentTextChanged(const QString &) +void HexdumpWidget::onParseEndianComboBoxCurrentTextChanged(const QString &) { refreshSelectionInfo(); } -void HexdumpWidget::on_hexSideTab_2_currentChanged(int /*index*/) +void HexdumpWidget::onHexSideTab2CurrentChanged(int /*index*/) { /* if (index == 2) { @@ -327,33 +342,33 @@ QWidget *HexdumpWidget::widgetToFocusOnRaise() return ui->hexTextView; } -void HexdumpWidget::on_copyMD5_clicked() +void HexdumpWidget::onCopyMD5Clicked() { - QString md5 = ui->bytesMD5->text(); + const QString md5 = ui->bytesMD5->text(); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(md5); Core()->message("MD5 copied to clipboard: " + md5); } -void HexdumpWidget::on_copySHA1_clicked() +void HexdumpWidget::onCopyShA1Clicked() { - QString sha1 = ui->bytesSHA1->text(); + const QString sha1 = ui->bytesSHA1->text(); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(sha1); Core()->message("SHA1 copied to clipboard: " + sha1); } -void HexdumpWidget::on_copySHA256_clicked() +void HexdumpWidget::onCopyShA256Clicked() { - QString sha256 = ui->bytesSHA256->text(); + const QString sha256 = ui->bytesSHA256->text(); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(sha256); Core()->message("SHA256 copied to clipboard: " + sha256); } -void HexdumpWidget::on_copyCRC32_clicked() +void HexdumpWidget::onCopyCrC32Clicked() { - QString crc32 = ui->bytesCRC32->text(); + const QString crc32 = ui->bytesCRC32->text(); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(crc32); Core()->message("CRC32 copied to clipboard: " + crc32); @@ -362,8 +377,8 @@ void HexdumpWidget::on_copyCRC32_clicked() void HexdumpWidget::selectHexPreview() { // Pre-select arch and bits in the hexdump sidebar - QString arch = Core()->getConfig("asm.arch"); - QString bits = Core()->getConfig("asm.bits"); + const QString arch = Core()->getConfig("asm.arch"); + const QString bits = Core()->getConfig("asm.bits"); if (ui->parseArchComboBox->findText(arch) != -1) { ui->parseArchComboBox->setCurrentIndex(ui->parseArchComboBox->findText(arch)); diff --git a/src/widgets/HexdumpWidget.h b/src/widgets/HexdumpWidget.h index aa80fdf0..317b5b40 100644 --- a/src/widgets/HexdumpWidget.h +++ b/src/widgets/HexdumpWidget.h @@ -1,22 +1,17 @@ #ifndef HEXDUMPWIDGET_H #define HEXDUMPWIDGET_H -#include -#include -#include -#include - -#include -#include - -#include "core/Cutter.h" +#include "Dashboard.h" +#include "HexWidget.h" #include "MemoryDockWidget.h" #include "common/CutterSeekable.h" -#include "common/Highlighter.h" -#include "common/SvgIconEngine.h" -#include "HexWidget.h" -#include "Dashboard.h" +#include +#include +#include +#include + +#include namespace Ui { class HexdumpWidget; @@ -25,13 +20,17 @@ class HexdumpWidget; class RefreshDeferrer; class QSyntaxHighlighter; +/** + * @brief Hex dump widget containing a side panel for data parsing and hashing + * + * @see HexWidget + */ class HexdumpWidget : public MemoryDockWidget { Q_OBJECT public: explicit HexdumpWidget(MainWindow *main); ~HexdumpWidget() override; - Highlighter *highlighter; static QString getWidgetType(); @@ -45,7 +44,7 @@ protected: private: std::unique_ptr ui; - bool sent_seek = false; + bool sentSeek = false; RefreshDeferrer *refreshDeferrer; QSyntaxHighlighter *syntaxHighLighter; @@ -68,18 +67,18 @@ private slots: void selectionChanged(HexWidget::Selection selection); - void on_parseArchComboBox_currentTextChanged(const QString &arg1); - void on_parseBitsComboBox_currentTextChanged(const QString &arg1); - void on_parseTypeComboBox_currentTextChanged(const QString &arg1); - void on_parseEndianComboBox_currentTextChanged(const QString &arg1); + void onParseArchComboBoxCurrentTextChanged(const QString &arg1); + void onParseBitsComboBoxCurrentTextChanged(const QString &arg1); + void onParseTypeComboBoxCurrentTextChanged(const QString &arg1); + void onParseEndianComboBoxCurrentTextChanged(const QString &arg1); void fontsUpdated(); - void on_hexSideTab_2_currentChanged(int index); - void on_copyMD5_clicked(); - void on_copySHA1_clicked(); - void on_copySHA256_clicked(); - void on_copyCRC32_clicked(); + void onHexSideTab2CurrentChanged(int index); + void onCopyMD5Clicked(); + void onCopyShA1Clicked(); + void onCopyShA256Clicked(); + void onCopyCrC32Clicked(); }; #endif // HEXDUMPWIDGET_H diff --git a/src/widgets/HexdumpWidget.ui b/src/widgets/HexdumpWidget.ui index dde5d744..8e27de99 100644 --- a/src/widgets/HexdumpWidget.ui +++ b/src/widgets/HexdumpWidget.ui @@ -30,7 +30,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -40,13 +40,13 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame true - + 0 @@ -54,10 +54,10 @@ - QTabWidget::North + QTabWidget::TabPosition::North - 1 + 0 true @@ -124,7 +124,7 @@ - QComboBox::AdjustToContents + QComboBox::SizeAdjustPolicy::AdjustToContents @@ -141,7 +141,7 @@ - + 0 @@ -155,17 +155,17 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain 0 - QLayout::SetMinimumSize + QLayout::SizeConstraint::SetMinimumSize 5 @@ -180,7 +180,7 @@ 5 - + 0 @@ -201,7 +201,7 @@ - QComboBox::AdjustToContents + QComboBox::SizeAdjustPolicy::AdjustToContents false @@ -209,7 +209,7 @@ - + 0 @@ -224,7 +224,7 @@ - QComboBox::AdjustToContents + QComboBox::SizeAdjustPolicy::AdjustToContents @@ -261,7 +261,7 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame 0 @@ -292,7 +292,7 @@ - QLayout::SetDefaultConstraint + QLayout::SizeConstraint::SetDefaultConstraint 0 @@ -331,7 +331,7 @@ true - Qt::AlignJustify|Qt::AlignVCenter + Qt::AlignmentFlag::AlignJustify|Qt::AlignmentFlag::AlignVCenter true @@ -351,13 +351,13 @@ - + Copy SHA256 - Qt::RightToLeft + Qt::LayoutDirection::RightToLeft @@ -370,7 +370,7 @@ Copy SHA1 - Qt::RightToLeft + Qt::LayoutDirection::RightToLeft @@ -383,20 +383,20 @@ true - Qt::AlignJustify|Qt::AlignVCenter + Qt::AlignmentFlag::AlignJustify|Qt::AlignmentFlag::AlignVCenter true - + Copy CRC32 - Qt::RightToLeft + Qt::LayoutDirection::RightToLeft @@ -415,14 +415,14 @@ true - Qt::AlignJustify|Qt::AlignVCenter + Qt::AlignmentFlag::AlignJustify|Qt::AlignmentFlag::AlignVCenter true - + @@ -447,7 +447,7 @@ true - Qt::AlignJustify|Qt::AlignVCenter + Qt::AlignmentFlag::AlignJustify|Qt::AlignmentFlag::AlignVCenter true @@ -486,7 +486,7 @@ Copy MD5 - Qt::RightToLeft + Qt::LayoutDirection::RightToLeft @@ -499,7 +499,7 @@ true - Qt::AlignJustify|Qt::AlignVCenter + Qt::AlignmentFlag::AlignJustify|Qt::AlignmentFlag::AlignVCenter true @@ -511,7 +511,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -560,7 +560,7 @@ true - Qt::NoArrow + Qt::ArrowType::NoArrow diff --git a/src/widgets/ImportsWidget.cpp b/src/widgets/ImportsWidget.cpp index 4bde8447..08850253 100644 --- a/src/widgets/ImportsWidget.cpp +++ b/src/widgets/ImportsWidget.cpp @@ -1,8 +1,9 @@ #include "ImportsWidget.h" -#include "ui_ListDockWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" #include "shortcuts/ShortcutManager.h" +#include "ui_ListDockWidget.h" #include #include @@ -28,17 +29,19 @@ QVariant ImportsModel::data(const QModelIndex &index, int role) const case Qt::ForegroundRole: if (index.column() < ImportsModel::ColumnCount) { // Red color for unsafe functions - if (banned.match(import.name).hasMatch()) + if (banned.match(import.name).hasMatch()) { return Config()->getColor("gui.item_unsafe"); + } // Grey color for symbols at offset 0 which can only be filled at runtime - if (import.plt == 0) + if (import.plt == 0) { return Config()->getColor("gui.item_invalid"); + } } break; case Qt::DisplayRole: switch (index.column()) { case ImportsModel::AddressColumn: - return RzAddressString(import.plt); + return rzAddressString(import.plt); case ImportsModel::TypeColumn: return import.type; case ImportsModel::SafetyColumn: @@ -56,7 +59,7 @@ QVariant ImportsModel::data(const QModelIndex &index, int role) const case ImportsModel::ImportDescriptionRole: return QVariant::fromValue(import); case ImportsModel::AddressRole: - return import.plt; + return static_cast(import.plt); default: break; } @@ -120,7 +123,7 @@ ImportsProxyModel::ImportsProxyModel(ImportsModel *sourceModel, QObject *parent) bool ImportsProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); + const QModelIndex index = sourceModel()->index(row, 0, parent); auto import = index.data(ImportsModel::ImportDescriptionRole).value(); return qhelpers::filterStringContains(import.name, this); @@ -128,11 +131,13 @@ bool ImportsProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) con bool ImportsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - if (!left.isValid() || !right.isValid()) + if (!left.isValid() || !right.isValid()) { return false; + } - if (left.parent().isValid() || right.parent().isValid()) + if (left.parent().isValid() || right.parent().isValid()) { return false; + } auto leftImport = left.data(ImportsModel::ImportDescriptionRole).value(); auto rightImport = right.data(ImportsModel::ImportDescriptionRole).value(); @@ -145,8 +150,9 @@ bool ImportsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &rig case ImportsModel::SafetyColumn: break; case ImportsModel::LibraryColumn: - if (leftImport.libname != rightImport.libname) + if (leftImport.libname != rightImport.libname) { return leftImport.libname < rightImport.libname; + } // fallthrough case ImportsModel::NameColumn: return leftImport.name < rightImport.name; @@ -175,8 +181,8 @@ ImportsWidget::ImportsWidget(MainWindow *main) setModels(importsProxyModel); // Sort by library name by default to create a solid context per each group of imports ui->treeView->sortByColumn(ImportsModel::LibraryColumn, Qt::AscendingOrder); - QShortcut *toggle_shortcut = Shortcuts()->makeQShortcut("Imports.toggle", main); - connect(toggle_shortcut, &QShortcut::activated, this, [=]() { toggleDockWidget(true); }); + const QShortcut *toggleShortcut = Shortcuts()->makeQShortcut("Imports.toggle", main); + connect(toggleShortcut, &QShortcut::activated, this, [=, this]() { toggleDockWidget(true); }); connect(Core(), &CutterCore::codeRebased, this, &ImportsWidget::refreshImports); connect(Core(), &CutterCore::refreshAll, this, &ImportsWidget::refreshImports); diff --git a/src/widgets/ImportsWidget.h b/src/widgets/ImportsWidget.h index 9972b3a6..cb8d18f1 100644 --- a/src/widgets/ImportsWidget.h +++ b/src/widgets/ImportsWidget.h @@ -1,23 +1,24 @@ #ifndef IMPORTSWIDGET_H #define IMPORTSWIDGET_H -#include +#include "CutterDescriptions.h" +#include "CutterDockWidget.h" +#include "common/AddressableItemModel.h" +#include "widgets/ListDockWidget.h" #include -#include #include +#include #include #include -#include "CutterDockWidget.h" -#include "core/Cutter.h" -#include "widgets/ListDockWidget.h" -#include "common/AddressableItemModel.h" - class MainWindow; class QTreeWidget; class ImportsWidget; +/** + * @brief Source model @ref ImportsWidget + */ class ImportsModel : public AddressableItemModel { Q_OBJECT @@ -56,7 +57,7 @@ private: QList imports; public: - enum Column { + enum Column : ut8 { AddressColumn = 0, TypeColumn, LibraryColumn, @@ -65,7 +66,7 @@ public: CommentColumn, ColumnCount }; - enum Role { ImportDescriptionRole = Qt::UserRole, AddressRole }; + enum Role : ut16 { ImportDescriptionRole = Qt::UserRole, AddressRole }; ImportsModel(QObject *parent = nullptr); @@ -81,6 +82,9 @@ public: void reload(); }; +/** + * @brief Proxy model for @ref ImportsWidget + */ class ImportsProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -93,6 +97,9 @@ protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; +/** + * @brief Widgets for visualizing imports + */ class ImportsWidget : public ListDockWidget { Q_OBJECT diff --git a/src/widgets/ItemCountLineEdit.cpp b/src/widgets/ItemCountLineEdit.cpp index eb72e763..63117d9f 100644 --- a/src/widgets/ItemCountLineEdit.cpp +++ b/src/widgets/ItemCountLineEdit.cpp @@ -1,20 +1,24 @@ #include "ItemCountLineEdit.h" + #include "Configuration.h" -#include #include +#include namespace { -constexpr int PADDING = 5; +constexpr int padding = 5; } ItemCountLineEdit::ItemCountLineEdit(QWidget *parent) - : QLineEdit(parent), m_itemCountLabel(new QLabel(this)) + : QLineEdit(parent), + itemCountLabel(new QLabel(this)), + isItemCountVisible(Config()->getItemCountVisible()), + itemCountAutoHideEnabled(Config()->getItemCountAutoHide()) { // parent widget must handle the context menu this->setContextMenuPolicy(Qt::NoContextMenu); - m_itemCountLabel->setStyleSheet("QLabel { background: transparent; }"); + itemCountLabel->setStyleSheet("QLabel { background: transparent; }"); connect(this, &QLineEdit::textChanged, this, &ItemCountLineEdit::updateLabelPosition); connect(Config(), &Configuration::itemCountOptionsChanged, this, @@ -22,40 +26,38 @@ ItemCountLineEdit::ItemCountLineEdit(QWidget *parent) connect(Config(), &Configuration::itemCountOptionsChanged, this, [this] { setItemCountAutoHide(Config()->getItemCountAutoHide()); }); - m_itemCountAutoHide = Config()->getItemCountAutoHide(); - m_itemCountVisible = Config()->getItemCountVisible(); - if (!m_itemCountVisible) { - m_itemCountLabel->hide(); + if (!isItemCountVisible) { + itemCountLabel->hide(); } updateLabelPosition(); } void ItemCountLineEdit::setItemCount(int count) { - m_itemCountLabel->setText(QString("%1 Items").arg(count)); + itemCountLabel->setText(QString("%1 Items").arg(count)); updateLabelPosition(); } bool ItemCountLineEdit::itemCountVisible() const { - return m_itemCountVisible; + return isItemCountVisible; } void ItemCountLineEdit::setItemCountAutoHide(bool value) { - m_itemCountAutoHide = value; + itemCountAutoHideEnabled = value; updateLabelPosition(); } bool ItemCountLineEdit::itemCountAutoHide() const { - return m_itemCountAutoHide; + return itemCountAutoHideEnabled; } void ItemCountLineEdit::showItemCount(bool show) { - m_itemCountVisible = show; - m_itemCountLabel->setVisible(show); + isItemCountVisible = show; + itemCountLabel->setVisible(show); if (!show) { this->setTextMargins(0, 0, 0, 0); } @@ -70,26 +72,26 @@ void ItemCountLineEdit::resizeEvent(QResizeEvent *event) void ItemCountLineEdit::updateLabelPosition() { - if (!m_itemCountVisible) { + if (!isItemCountVisible) { return; } - m_itemCountLabel->adjustSize(); + itemCountLabel->adjustSize(); - int labelWidth = m_itemCountLabel->sizeHint().width(); - int x = this->width() - labelWidth - PADDING; + const int labelWidth = itemCountLabel->sizeHint().width(); + const int x = this->width() - labelWidth - padding; - if (m_itemCountAutoHide) { - QFont font = this->font(); - QFontMetrics fm(font); + if (itemCountAutoHideEnabled) { + const QFont font = this->font(); + const QFontMetrics fm(font); #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) - int textWidth = fm.horizontalAdvance(this->text()); + const int textWidth = fm.horizontalAdvance(this->text()); #else int textWidth = fm.width(this->text()); #endif - const int BUFFER = Config()->windowColorIsDark() ? 4 : 5; - if (x <= (PADDING * BUFFER) + textWidth) { - m_itemCountLabel->hide(); + const int buffer = Config()->windowColorIsDark() ? 4 : 5; + if (x <= (padding * buffer) + textWidth) { + itemCountLabel->hide(); this->setTextMargins(0, 0, 0, 0); return; } @@ -97,10 +99,10 @@ void ItemCountLineEdit::updateLabelPosition() // required so the label doesn't overlap with placeholder text auto margins = this->textMargins(); - margins.setRight(labelWidth + PADDING); + margins.setRight(labelWidth + padding); this->setTextMargins(margins); - int y = (this->height() - m_itemCountLabel->height()) / 2; - m_itemCountLabel->move(x, y); - m_itemCountLabel->show(); + const int y = (this->height() - itemCountLabel->height()) / 2; + itemCountLabel->move(x, y); + itemCountLabel->show(); } diff --git a/src/widgets/ItemCountLineEdit.h b/src/widgets/ItemCountLineEdit.h index c10fc8df..3ec30818 100644 --- a/src/widgets/ItemCountLineEdit.h +++ b/src/widgets/ItemCountLineEdit.h @@ -28,9 +28,9 @@ protected: void resizeEvent(QResizeEvent *event) override; private: - QLabel *m_itemCountLabel; - bool m_itemCountVisible; - bool m_itemCountAutoHide; + QLabel *itemCountLabel; + bool isItemCountVisible; + bool itemCountAutoHideEnabled; void updateLabelPosition(); }; diff --git a/src/widgets/ListDockWidget.cpp b/src/widgets/ListDockWidget.cpp index 8963582a..aecfb900 100644 --- a/src/widgets/ListDockWidget.cpp +++ b/src/widgets/ListDockWidget.cpp @@ -1,8 +1,9 @@ #include "ListDockWidget.h" -#include "ui_ListDockWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" #include "shortcuts/ShortcutManager.h" +#include "ui_ListDockWidget.h" #include #include @@ -38,7 +39,7 @@ void ListDockWidget::setModels(AddressableFilterProxyModel *objectFilterProxyMod { this->objectFilterProxyModel = objectFilterProxyModel; - ui->treeView->setModel(objectFilterProxyModel); + ui->treeView->setModel(static_cast(objectFilterProxyModel)); connect(ui->quickFilterView, &QuickFilterView::filterTextChanged, objectFilterProxyModel, &QSortFilterProxyModel::setFilterWildcard); diff --git a/src/widgets/ListDockWidget.h b/src/widgets/ListDockWidget.h index f67c3587..3d5e22f8 100644 --- a/src/widgets/ListDockWidget.h +++ b/src/widgets/ListDockWidget.h @@ -1,16 +1,16 @@ #ifndef LISTDOCKWIDGET_H #define LISTDOCKWIDGET_H -#include -#include -#include -#include - -#include "core/Cutter.h" -#include "common/AddressableItemModel.h" #include "CutterDockWidget.h" +#include "common/AddressableItemModel.h" #include "menus/AddressableItemContextMenu.h" +#include +#include +#include + +#include + class MainWindow; class QTreeWidgetItem; class CommentsWidget; @@ -19,6 +19,9 @@ namespace Ui { class ListDockWidget; } +/** + * @brief A dockable widget that displays data in a searchable tree or list format + */ class CUTTER_EXPORT ListDockWidget : public CutterDockWidget { Q_OBJECT diff --git a/src/widgets/MemoryDockWidget.cpp b/src/widgets/MemoryDockWidget.cpp index ac1eef74..29208a7e 100644 --- a/src/widgets/MemoryDockWidget.cpp +++ b/src/widgets/MemoryDockWidget.cpp @@ -1,13 +1,15 @@ #include "MemoryDockWidget.h" -#include "common/CutterSeekable.h" + #include "MainWindow.h" +#include "common/CutterSeekable.h" + #include +#include #include #include -#include MemoryDockWidget::MemoryDockWidget(MemoryWidgetType type, MainWindow *parent) - : AddressableDockWidget(parent), mType(type) + : AddressableDockWidget(parent), type(type) { if (parent) { parent->addMemoryDockWidget(this); @@ -20,7 +22,7 @@ bool MemoryDockWidget::tryRaiseMemoryWidget() return false; } - if (mType == MemoryWidgetType::Graph && Core()->isGraphEmpty()) { + if (type == MemoryWidgetType::Graph && Core()->isGraphEmpty()) { return false; } raiseMemoryWidget(); diff --git a/src/widgets/MemoryDockWidget.h b/src/widgets/MemoryDockWidget.h index 0b1a5952..4a4c85ea 100644 --- a/src/widgets/MemoryDockWidget.h +++ b/src/widgets/MemoryDockWidget.h @@ -2,13 +2,23 @@ #define MEMORYDOCKWIDGET_H #include "AddressableDockWidget.h" -#include "core/Cutter.h" +#include "CutterCommon.h" #include /* Disassembly/Graph/Hexdump/Decompiler view priority */ -enum class MemoryWidgetType { Disassembly, Graph, Hexdump, Decompiler, CallGraph, GlobalCallGraph }; +enum class MemoryWidgetType : ut8 { + Disassembly, + Graph, + Hexdump, + Decompiler, + CallGraph, + GlobalCallGraph +}; +/** + * @brief A base window that keeps memory-related views focused and synced + */ class CUTTER_EXPORT MemoryDockWidget : public AddressableDockWidget { Q_OBJECT @@ -17,11 +27,11 @@ public: ~MemoryDockWidget() override {} bool tryRaiseMemoryWidget(); - MemoryWidgetType getType() const { return mType; } + MemoryWidgetType getType() const { return type; } bool eventFilter(QObject *object, QEvent *event) override; private: - MemoryWidgetType mType; + MemoryWidgetType type; }; #endif // MEMORYDOCKWIDGET_H diff --git a/src/widgets/MemoryMapWidget.cpp b/src/widgets/MemoryMapWidget.cpp index 2d4f1f7f..e38b3a08 100644 --- a/src/widgets/MemoryMapWidget.cpp +++ b/src/widgets/MemoryMapWidget.cpp @@ -1,7 +1,9 @@ #include "MemoryMapWidget.h" -#include "ui_ListDockWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" +#include "ui_ListDockWidget.h" + #include MemoryMapModel::MemoryMapModel(QObject *parent) : AddressableItemModel(parent) @@ -20,8 +22,9 @@ int MemoryMapModel::columnCount(const QModelIndex &) const QVariant MemoryMapModel::data(const QModelIndex &index, int role) const { - if (index.row() >= memoryMaps.count()) + if (index.row() >= memoryMaps.count()) { return QVariant(); + } const MemoryMapDescription &memoryMap = memoryMaps.at(index.row()); @@ -29,9 +32,9 @@ QVariant MemoryMapModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case AddrStartColumn: - return RzAddressString(memoryMap.addrStart); + return rzAddressString(memoryMap.addrStart); case AddrEndColumn: - return RzAddressString(memoryMap.addrEnd); + return rzAddressString(memoryMap.addrEnd); case NameColumn: return memoryMap.name; case PermColumn: @@ -84,17 +87,17 @@ MemoryProxyModel::MemoryProxyModel(MemoryMapModel *sourceModel, QObject *parent) bool MemoryProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); - MemoryMapDescription item = + const QModelIndex index = sourceModel()->index(row, 0, parent); + const auto item = index.data(MemoryMapModel::MemoryDescriptionRole).value(); return qhelpers::filterStringContains(item.name, this); } bool MemoryProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - MemoryMapDescription leftMemMap = + const auto leftMemMap = left.data(MemoryMapModel::MemoryDescriptionRole).value(); - MemoryMapDescription rightMemMap = + const auto rightMemMap = right.data(MemoryMapModel::MemoryDescriptionRole).value(); switch (left.column()) { @@ -116,18 +119,18 @@ bool MemoryProxyModel::lessThan(const QModelIndex &left, const QModelIndex &righ return leftMemMap.addrStart < rightMemMap.addrStart; } -MemoryMapWidget::MemoryMapWidget(MainWindow *main) : ListDockWidget(main) +MemoryMapWidget::MemoryMapWidget(MainWindow *main) + : ListDockWidget(main), + memoryModel(new MemoryMapModel(this)), + memoryProxyModel(new MemoryProxyModel(memoryModel, this)), + refreshDeferrer(createRefreshDeferrer([this]() { refreshMemoryMap(); })) { setWindowTitle(tr("Memory Map")); setObjectName("MemoryMapWidget"); - memoryModel = new MemoryMapModel(this); - memoryProxyModel = new MemoryProxyModel(memoryModel, this); setModels(memoryProxyModel); ui->treeView->sortByColumn(MemoryMapModel::AddrStartColumn, Qt::AscendingOrder); - refreshDeferrer = createRefreshDeferrer([this]() { refreshMemoryMap(); }); - connect(Core(), &CutterCore::refreshAll, this, &MemoryMapWidget::refreshMemoryMap); connect(Core(), &CutterCore::registersChanged, this, &MemoryMapWidget::refreshMemoryMap); connect(Core(), &CutterCore::commentsChanged, this, diff --git a/src/widgets/MemoryMapWidget.h b/src/widgets/MemoryMapWidget.h index eb2c0345..8c4e4ad2 100644 --- a/src/widgets/MemoryMapWidget.h +++ b/src/widgets/MemoryMapWidget.h @@ -1,8 +1,7 @@ -#pragma once +#ifndef MEMORYMAPWIDGET_H +#define MEMORYMAPWIDGET_H -#include - -#include "core/Cutter.h" +#include "CutterDescriptions.h" #include "CutterDockWidget.h" #include "ListDockWidget.h" @@ -20,6 +19,9 @@ class MemoryMapWidget; class MainWindow; class QTreeWidgetItem; +/** + * @brief Source model for @ref MemoryMapWidget + */ class MemoryMapModel : public AddressableItemModel { Q_OBJECT @@ -30,7 +32,7 @@ private: QList memoryMaps; public: - enum Column { + enum Column : ut8 { AddrStartColumn = 0, AddrEndColumn, NameColumn, @@ -38,7 +40,7 @@ public: CommentColumn, ColumnCount }; - enum Role { MemoryDescriptionRole = Qt::UserRole }; + enum Role : ut16 { MemoryDescriptionRole = Qt::UserRole }; MemoryMapModel(QObject *parent = nullptr); @@ -52,6 +54,9 @@ public: RVA address(const QModelIndex &index) const override; }; +/** + * @brief Proxy model for @ref MemoryMapWidget + */ class MemoryProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -64,6 +69,9 @@ protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; +/** + * @brief Widget for displaying list of memory segments + */ class MemoryMapWidget : public ListDockWidget { Q_OBJECT @@ -82,3 +90,5 @@ private: RefreshDeferrer *refreshDeferrer; }; + +#endif // MEMORYMAPWIDGET_H diff --git a/src/widgets/Omnibar.cpp b/src/widgets/Omnibar.cpp index 8d477a89..25a44e71 100644 --- a/src/widgets/Omnibar.cpp +++ b/src/widgets/Omnibar.cpp @@ -1,18 +1,20 @@ #include "Omnibar.h" -#include "core/MainWindow.h" + +#include "CutterDescriptions.h" #include "CutterSeekable.h" +#include "core/MainWindow.h" #include "shortcuts/ShortcutManager.h" -#include -#include -#include #include -#include #include -#include -#include +#include #include #include +#include +#include +#include +#include +#include OmnibarCompleter::OmnibarCompleter(QObject *parent) : QCompleter(parent) {} @@ -23,7 +25,7 @@ QStringList OmnibarCompleter::splitPath(const QString &) const QString OmnibarCompleter::pathFromIndex(const QModelIndex &index) const { - int type = index.data(Qt::UserRole).toInt(); + const int type = index.data(Qt::UserRole).toInt(); if (type == Omnibar::ShowMore || type == Omnibar::ShowAll) { if (auto edit = qobject_cast(widget())) { @@ -35,7 +37,7 @@ QString OmnibarCompleter::pathFromIndex(const QModelIndex &index) const } Omnibar::Omnibar(MainWindow *main, QWidget *parent) - : QLineEdit(parent), main(main), m_completerModel(new QStandardItemModel(this)) + : QLineEdit(parent), main(main), completerModel(new QStandardItemModel(this)) { // QLineEdit basic features this->setMinimumHeight(16); @@ -46,25 +48,25 @@ Omnibar::Omnibar(MainWindow *main, QWidget *parent) this->setClearButtonEnabled(true); connect(this, &QLineEdit::textEdited, this, [this](const QString &text) { - m_maxShownItems = Config()->getOmnibarEntriesCount(); // reset entries count to default + maxShownItems = Config()->getOmnibarEntriesCount(); // reset entries count to default handleSearch(text); }); // Esc clears omnibar - QShortcut *clear_shortcut = Shortcuts()->makeQShortcut("Omnibar.clear", this); - connect(clear_shortcut, &QShortcut::activated, this, &Omnibar::clear); - clear_shortcut->setContext(Qt::WidgetWithChildrenShortcut); + QShortcut *clearShortcut = Shortcuts()->makeQShortcut("Omnibar.clear", this); + connect(clearShortcut, &QShortcut::activated, this, &Omnibar::clear); + clearShortcut->setContext(Qt::WidgetWithChildrenShortcut); // Set gotoEntry completer for jump history - m_completer = new OmnibarCompleter(this); - m_completer->setModel(m_completerModel); - m_completer->setMaxVisibleItems(20); - m_completer->setFilterMode(Qt::MatchContains); - m_completer->setCompletionMode(QCompleter::PopupCompletion); - m_completer->popup()->installEventFilter(this); - m_completer->popup()->viewport()->installEventFilter(this); + completer = new OmnibarCompleter(this); + completer->setModel(completerModel); + completer->setMaxVisibleItems(20); + completer->setFilterMode(Qt::MatchContains); + completer->setCompletionMode(QCompleter::PopupCompletion); + completer->popup()->installEventFilter(this); + completer->popup()->viewport()->installEventFilter(this); - this->setCompleter(m_completer); + this->setCompleter(completer); this->installEventFilter(this); connect(Core(), &CutterCore::flagsChanged, this, &Omnibar::refresh); @@ -74,7 +76,7 @@ Omnibar::Omnibar(MainWindow *main, QWidget *parent) bool Omnibar::eventFilter(QObject *obj, QEvent *event) { - QAbstractItemView *popup = m_completer->popup(); + QAbstractItemView *popup = completer->popup(); if (((obj == popup || obj == this) && (event->type() == QEvent::KeyPress)) || (obj == popup->viewport() && event->type() == QEvent::MouseButtonPress)) { @@ -82,15 +84,15 @@ bool Omnibar::eventFilter(QObject *obj, QEvent *event) QModelIndex index; if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); + const QMouseEvent *mouseEvent = static_cast(event); if (mouseEvent->button() == Qt::LeftButton) { index = popup->indexAt(mouseEvent->pos()); } } else if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); + const QKeyEvent *keyEvent = static_cast(event); - int keyInt = keyEvent->modifiers() | keyEvent->key(); - QKeySequence eventSeq(keyInt); + const int keyInt = keyEvent->modifiers() | keyEvent->key(); + const QKeySequence eventSeq(keyInt); if (eventSeq == Shortcuts()->getKeySequence("Omnibar.showMore")) { handleShowMore(popup->currentIndex().row()); return true; @@ -103,8 +105,8 @@ bool Omnibar::eventFilter(QObject *obj, QEvent *event) } if (index.isValid()) { - int row = index.row(); - int type = index.data(Qt::UserRole).toInt(); + const int row = index.row(); + const int type = index.data(Qt::UserRole).toInt(); if (type == ItemType::ShowMore) { handleShowMore(row); @@ -122,18 +124,18 @@ bool Omnibar::eventFilter(QObject *obj, QEvent *event) void Omnibar::refresh() { - m_flags.clear(); + flags.clear(); const auto flags = Core()->getAllFlags(); for (const auto &f : flags) { - m_flags.append(f.name); + this->flags.append(f.name); } QCollator collator; collator.setNumericMode(true); collator.setCaseSensitivity(Qt::CaseInsensitive); - std::sort(m_flags.begin(), m_flags.end(), [&collator](const QString &a, const QString &b) { - return collator.compare(a, b) < 0; - }); + std::sort( + this->flags.begin(), this->flags.end(), + [&collator](const QString &a, const QString &b) { return collator.compare(a, b) < 0; }); handleSearch(this->text()); } @@ -142,16 +144,16 @@ void Omnibar::clear() { QLineEdit::clear(); - m_completerModel->clear(); - m_completer->popup()->hide(); + completerModel->clear(); + completer->popup()->hide(); } void Omnibar::goToEntry() { - QString str = this->text(); + const QString str = this->text(); if (!str.isEmpty()) { if (auto memoryWidget = main->getLastMemoryWidget()) { - RVA offset = Core()->math(str); + const RVA offset = Core()->math(str); memoryWidget->getSeekable()->seek(offset); memoryWidget->raiseMemoryWidget(); } else { @@ -165,15 +167,15 @@ void Omnibar::goToEntry() void Omnibar::handleSearch(const QString &Text, bool append) { - m_searchedText = Text; - m_matchCount = 0; + searchedText = Text; + matchCount = 0; if (!append) { - m_completerModel->clear(); - m_lastIndex = 0; + completerModel->clear(); + lastIndex = 0; } else { // remove "show more" and "show all" rows (last two) - m_completerModel->removeRows(m_completerModel->rowCount() - 2, 2); + completerModel->removeRows(completerModel->rowCount() - 2, 2); } if (Text.isEmpty()) { @@ -181,35 +183,35 @@ void Omnibar::handleSearch(const QString &Text, bool append) } bool hasMore = false; - int itemsInModel = m_completerModel->rowCount(); + int itemsInModel = completerModel->rowCount(); - for (int i = 0; i < m_flags.size(); ++i) { - const QString &flag = m_flags[i]; + for (int i = 0; i < flags.size(); ++i) { + const QString &flag = flags[i]; if (flag.contains(Text, Qt::CaseInsensitive)) { const bool showAll = !Config()->getOmnibarLimitEntries(); - if ((itemsInModel < m_maxShownItems) || showAll) { - if (!append || i > m_lastIndex) { - QStandardItem *item = new QStandardItem(flag); + if ((itemsInModel < maxShownItems) || showAll) { + if (!append || i > lastIndex) { + auto *item = new QStandardItem(flag); item->setData(ItemType::Standard, Qt::UserRole); - m_completerModel->appendRow(item); + completerModel->appendRow(item); ++itemsInModel; - m_lastIndex = i; + lastIndex = i; } } else { hasMore = true; } - ++m_matchCount; + ++matchCount; } } if (hasMore) { auto addActionRow = [&](const QString &text, ItemType type) { - QStandardItem *actionItem = new QStandardItem(text); + auto *actionItem = new QStandardItem(text); actionItem->setData(type, Qt::UserRole); - QPalette palette = this->palette(); + const QPalette palette = this->palette(); #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) - QColor placeholderColor = palette.color(QPalette::PlaceholderText); + const QColor placeholderColor = palette.color(QPalette::PlaceholderText); #else QColor placeholderColor = palette.color(QPalette::Text); placeholderColor.setAlpha(128); @@ -220,35 +222,34 @@ void Omnibar::handleSearch(const QString &Text, bool append) font.setItalic(true); actionItem->setFont(font); - m_completerModel->appendRow(actionItem); + completerModel->appendRow(actionItem); }; addActionRow(tr("Show More"), ItemType::ShowMore); - addActionRow(tr("Show All (%1 of %2)").arg(m_maxShownItems).arg(m_matchCount), + addActionRow(tr("Show All (%1 of %2)").arg(maxShownItems).arg(matchCount), ItemType::ShowAll); } - m_completer->setCompletionPrefix(""); - m_completer->complete(); + completer->setCompletionPrefix(""); + completer->complete(); } void Omnibar::handleShowMore(int currentRow) { - if (m_maxShownItems >= m_matchCount) { + if (maxShownItems >= matchCount) { return; } - m_maxShownItems = - std::min(m_maxShownItems + Config()->getOmnibarEntriesIncrement(), m_matchCount); - handleSearch(m_searchedText, true); - m_completer->popup()->setCurrentIndex(m_completerModel->index(currentRow, 0)); + maxShownItems = std::min(maxShownItems + Config()->getOmnibarEntriesIncrement(), matchCount); + handleSearch(searchedText, true); + completer->popup()->setCurrentIndex(completerModel->index(currentRow, 0)); } void Omnibar::handleShowAll(int currentRow) { - if (m_maxShownItems >= m_matchCount) { + if (maxShownItems >= matchCount) { return; } - m_maxShownItems = m_matchCount; - handleSearch(m_searchedText, true); - m_completer->popup()->setCurrentIndex(m_completerModel->index(currentRow, 0)); + maxShownItems = matchCount; + handleSearch(searchedText, true); + completer->popup()->setCurrentIndex(completerModel->index(currentRow, 0)); } diff --git a/src/widgets/Omnibar.h b/src/widgets/Omnibar.h index ccab0795..a4fe0ff5 100644 --- a/src/widgets/Omnibar.h +++ b/src/widgets/Omnibar.h @@ -1,8 +1,10 @@ #ifndef OMNIBAR_H #define OMNIBAR_H -#include +#include "CutterCommon.h" + #include +#include class MainWindow; class QStandardItemModel; @@ -25,6 +27,9 @@ public: QString pathFromIndex(const QModelIndex &index) const override; }; +/** + * @brief Main search bar at the top with auto completion + */ class Omnibar : public QLineEdit { Q_OBJECT @@ -33,12 +38,9 @@ public: void refresh(); - enum ItemType { Standard = 0, ShowMore = 1, ShowAll = 2 }; + enum ItemType : ut8 { Standard = 0, ShowMore = 1, ShowAll = 2 }; private slots: - /** - * @brief Seeks to the address of selected entry/flag and shows it in the last memory widget - */ void goToEntry(); /** @@ -65,16 +67,16 @@ private: void handleShowAll(int currentRow); MainWindow *main; - QStringList m_flags; + QStringList flags; - QStringList m_filteredFlags; - QStandardItemModel *m_completerModel; - QCompleter *m_completer; + QStringList filteredFlags; + QStandardItemModel *completerModel; + QCompleter *completer; - QString m_searchedText; - int m_maxShownItems; - int m_lastIndex; - int m_matchCount; + QString searchedText; + int maxShownItems; + int lastIndex; + int matchCount; }; #endif // OMNIBAR_H diff --git a/src/widgets/OverviewView.cpp b/src/widgets/OverviewView.cpp index 808de421..e7ebd20d 100644 --- a/src/widgets/OverviewView.cpp +++ b/src/widgets/OverviewView.cpp @@ -1,11 +1,12 @@ #include "OverviewView.h" -#include -#include -#include "core/Cutter.h" -#include "common/Colors.h" #include "common/Configuration.h" -#include "common/TempConfig.h" +#include "core/Cutter.h" + +#include +#include + +#include OverviewView::OverviewView(QWidget *parent) : GraphView(parent) { @@ -19,8 +20,8 @@ void OverviewView::setData(int baseWidth, int baseHeight, { width = baseWidth; height = baseHeight; - blocks = baseBlocks; - edgeConfigurations = baseEdgeConfigurations; + blocks = std::move(baseBlocks); + edgeConfigurations = std::move(baseEdgeConfigurations); scaleAndCenter(); setCacheDirty(); viewport()->update(); @@ -28,8 +29,8 @@ void OverviewView::setData(int baseWidth, int baseHeight, void OverviewView::centreRect() { - qreal w = rangeRect.width(); - qreal h = rangeRect.height(); + const qreal w = rangeRect.width(); + const qreal h = rangeRect.height(); initialDiff = QPointF(w / 2, h / 2); } @@ -37,8 +38,8 @@ OverviewView::~OverviewView() {} void OverviewView::scaleAndCenter() { - qreal wScale = (qreal)viewport()->width() / width; - qreal hScale = (qreal)viewport()->height() / height; + const qreal wScale = (qreal)viewport()->width() / width; + const qreal hScale = (qreal)viewport()->height() / height; setViewScale(std::min(wScale, hScale)); center(); } @@ -52,7 +53,7 @@ void OverviewView::refreshView() void OverviewView::drawBlock(QPainter &p, GraphView::GraphBlock &block, bool interactive) { Q_UNUSED(interactive) - QRectF blockRect(block.x, block.y, block.width, block.height); + const QRectF blockRect(block.x, block.y, block.width, block.height); p.setPen(Qt::black); p.setBrush(Qt::gray); @@ -92,7 +93,7 @@ void OverviewView::mousePressEvent(QMouseEvent *event) if (rangeRect.contains(pos)) { initialDiff = pos - rangeRect.topLeft(); } else { - QPointF size(rangeRect.width(), rangeRect.height()); + const QPointF size(rangeRect.width(), rangeRect.height()); initialDiff = size * 0.5; rangeRect.moveCenter(pos); viewport()->update(); @@ -111,7 +112,7 @@ void OverviewView::mouseMoveEvent(QMouseEvent *event) if (!mouseActive) { return; } - QPointF topLeft = qhelpers::mouseEventPos(event) - initialDiff; + const QPointF topLeft = qhelpers::mouseEventPos(event) - initialDiff; rangeRect.setTopLeft(topLeft); viewport()->update(); emit mouseMoved(); @@ -129,9 +130,10 @@ GraphView::EdgeConfiguration OverviewView::edgeConfiguration(GraphView::GraphBlo Q_UNUSED(interactive) EdgeConfiguration ec; auto baseEcIt = edgeConfigurations.find({ from.entry, to->entry }); - if (baseEcIt != edgeConfigurations.end()) + if (baseEcIt != edgeConfigurations.end()) { ec = baseEcIt->second; - ec.width_scale = 1.0 / getViewScale(); + } + ec.widthScale = 1.0 / getViewScale(); return ec; } diff --git a/src/widgets/OverviewView.h b/src/widgets/OverviewView.h index f2ed2fe3..55a04bc1 100644 --- a/src/widgets/OverviewView.h +++ b/src/widgets/OverviewView.h @@ -1,12 +1,16 @@ #ifndef OVERVIEWVIEW_H #define OVERVIEWVIEW_H -#include +#include "widgets/DisassemblerGraphView.h" +#include "widgets/GraphView.h" + #include #include -#include "widgets/GraphView.h" -#include "widgets/DisassemblerGraphView.h" +#include +/** + * @brief A "minimap" widget that displays a scaled-down version of the function graph + */ class OverviewView : public GraphView { Q_OBJECT diff --git a/src/widgets/OverviewWidget.cpp b/src/widgets/OverviewWidget.cpp index 64822a7b..5c15637b 100644 --- a/src/widgets/OverviewWidget.cpp +++ b/src/widgets/OverviewWidget.cpp @@ -1,29 +1,31 @@ -#include "core/MainWindow.h" -#include "shortcuts/ShortcutManager.h" #include "OverviewWidget.h" + #include "GraphWidget.h" #include "OverviewView.h" +#include "core/MainWindow.h" +#include "shortcuts/ShortcutManager.h" -OverviewWidget::OverviewWidget(MainWindow *main) : CutterDockWidget(main) +OverviewWidget::OverviewWidget(MainWindow *main) + : CutterDockWidget(main), + graphView(new OverviewView(this)), + targetGraphWidget(nullptr), + graphDataRefreshDeferrer(createRefreshDeferrer([this]() { updateGraphData(); })) { setWindowTitle(tr("Graph Overview")); setObjectName("Graph Overview"); setAllowedAreas(Qt::AllDockWidgetAreas); - graphView = new OverviewView(this); + setWidget(graphView); - targetGraphWidget = nullptr; connect(graphView, &OverviewView::mouseMoved, this, &OverviewWidget::updateTargetView); - graphDataRefreshDeferrer = createRefreshDeferrer([this]() { updateGraphData(); }); - // Zoom shortcuts - QShortcut *shortcut_zoom_in = Shortcuts()->makeQShortcut("Overview.zoomIn", this); - shortcut_zoom_in->setContext(Qt::WidgetWithChildrenShortcut); - connect(shortcut_zoom_in, &QShortcut::activated, this, [this]() { zoomTarget(1); }); - QShortcut *shortcut_zoom_out = Shortcuts()->makeQShortcut("Overview.zoomOut", this); - shortcut_zoom_out->setContext(Qt::WidgetWithChildrenShortcut); - connect(shortcut_zoom_out, &QShortcut::activated, this, [this]() { zoomTarget(-1); }); + QShortcut *shortcutZoomIn = Shortcuts()->makeQShortcut("Overview.zoomIn", this); + shortcutZoomIn->setContext(Qt::WidgetWithChildrenShortcut); + connect(shortcutZoomIn, &QShortcut::activated, this, [this]() { zoomTarget(1); }); + QShortcut *shortcutZoomOut = Shortcuts()->makeQShortcut("Overview.zoomOut", this); + shortcutZoomOut->setContext(Qt::WidgetWithChildrenShortcut); + connect(shortcutZoomOut, &QShortcut::activated, this, [this]() { zoomTarget(-1); }); } OverviewWidget::~OverviewWidget() {} @@ -129,14 +131,14 @@ void OverviewWidget::updateTargetView() if (!targetGraphWidget) { return; } - qreal curScale = graphView->getViewScale(); - int rectx = graphView->getRangeRect().x(); - int recty = graphView->getRangeRect().y(); - int overview_offset_x = graphView->getViewOffset().x(); - int overview_offset_y = graphView->getViewOffset().y(); + const qreal curScale = graphView->getViewScale(); + const int rectx = graphView->getRangeRect().x(); + const int recty = graphView->getRangeRect().y(); + const int overviewOffsetX = graphView->getViewOffset().x(); + const int overviewOffsetY = graphView->getViewOffset().y(); QPoint newOffset; - newOffset.rx() = rectx / curScale + overview_offset_x; - newOffset.ry() = recty / curScale + overview_offset_y; + newOffset.rx() = rectx / curScale + overviewOffsetX; + newOffset.ry() = recty / curScale + overviewOffsetY; targetGraphWidget->getGraphView()->setViewOffset(newOffset); targetGraphWidget->getGraphView()->viewport()->update(); } @@ -161,16 +163,18 @@ void OverviewWidget::updateGraphData() void OverviewWidget::updateRangeRect() { if (targetGraphWidget) { - qreal curScale = graphView->getViewScale(); - qreal baseScale = targetGraphWidget->getGraphView()->getViewScale(); - qreal w = targetGraphWidget->getGraphView()->viewport()->width() * curScale / baseScale; - qreal h = targetGraphWidget->getGraphView()->viewport()->height() * curScale / baseScale; - int graph_offset_x = targetGraphWidget->getGraphView()->getViewOffset().x(); - int graph_offset_y = targetGraphWidget->getGraphView()->getViewOffset().y(); - int overview_offset_x = graphView->getViewOffset().x(); - int overview_offset_y = graphView->getViewOffset().y(); - int rangeRectX = graph_offset_x * curScale - overview_offset_x * curScale; - int rangeRectY = graph_offset_y * curScale - overview_offset_y * curScale; + const qreal curScale = graphView->getViewScale(); + const qreal baseScale = targetGraphWidget->getGraphView()->getViewScale(); + const qreal w = + targetGraphWidget->getGraphView()->viewport()->width() * curScale / baseScale; + const qreal h = + targetGraphWidget->getGraphView()->viewport()->height() * curScale / baseScale; + const int graphOffsetX = targetGraphWidget->getGraphView()->getViewOffset().x(); + const int graphOffsetY = targetGraphWidget->getGraphView()->getViewOffset().y(); + const int overviewOffsetX = graphView->getViewOffset().x(); + const int overviewOffsetY = graphView->getViewOffset().y(); + const int rangeRectX = graphOffsetX * curScale - overviewOffsetX * curScale; + const int rangeRectY = graphOffsetY * curScale - overviewOffsetY * curScale; graphView->setRangeRect(QRectF(rangeRectX, rangeRectY, w, h)); } else { graphView->setRangeRect(QRectF(0, 0, 0, 0)); diff --git a/src/widgets/OverviewWidget.h b/src/widgets/OverviewWidget.h index 017d444d..55110aba 100644 --- a/src/widgets/OverviewWidget.h +++ b/src/widgets/OverviewWidget.h @@ -7,6 +7,9 @@ class MainWindow; class OverviewView; class GraphWidget; +/** + * @brief Dock widget that links the graph minimap to the main active graph view + */ class OverviewWidget : public CutterDockWidget { Q_OBJECT diff --git a/src/widgets/ProcessesWidget.cpp b/src/widgets/ProcessesWidget.cpp index b729b49e..960d66c1 100644 --- a/src/widgets/ProcessesWidget.cpp +++ b/src/widgets/ProcessesWidget.cpp @@ -1,22 +1,27 @@ -#include #include "ProcessesWidget.h" -#include "ui_ProcessesWidget.h" -#include "common/JsonModel.h" -#include "QuickFilterView.h" -#include +#include "QuickFilterView.h" #include "core/MainWindow.h" #include "shortcuts/ShortcutManager.h" +#include "ui_ProcessesWidget.h" + +#include + +#include #define DEBUGGED_PID (-1) ProcessesWidget::ProcessesWidget(MainWindow *main) - : CutterDockWidget(main), ui(new Ui::ProcessesWidget) + : CutterDockWidget(main), + ui(new Ui::ProcessesWidget), + modelProcesses(new QStandardItemModel(1, 4, this)), + modelFilter(new ProcessesFilterModel(this)), + refreshDeferrer(createRefreshDeferrer([this]() { updateContents(); })) { ui->setupUi(this); // Setup processes model - modelProcesses = new QStandardItemModel(1, 4, this); + modelProcesses->setHorizontalHeaderItem(ProcessesWidget::COLUMN_PID, new QStandardItem(tr("PID"))); modelProcesses->setHorizontalHeaderItem(ProcessesWidget::COLUMN_UID, @@ -29,7 +34,6 @@ ProcessesWidget::ProcessesWidget(MainWindow *main) ui->viewProcesses->verticalHeader()->setVisible(false); ui->viewProcesses->setFont(Config()->getFont()); - modelFilter = new ProcessesFilterModel(this); modelFilter->setSourceModel(modelProcesses); ui->viewProcesses->setModel(modelFilter); @@ -47,8 +51,6 @@ ProcessesWidget::ProcessesWidget(MainWindow *main) }); clearShortcut->setContext(Qt::WidgetWithChildrenShortcut); - refreshDeferrer = createRefreshDeferrer([this]() { updateContents(); }); - connect(ui->quickFilterView, &QuickFilterView::filterTextChanged, modelFilter, &ProcessesFilterModel::setFilterWildcard); connect(Core(), &CutterCore::refreshAll, this, &ProcessesWidget::updateContents); @@ -108,19 +110,19 @@ void ProcessesWidget::setProcessesGrid() QFont font; for (const auto &processesItem : Core()->getProcesses(DEBUGGED_PID)) { - st64 pid = processesItem.pid; - st64 uid = processesItem.uid; - QString status = translateStatus(processesItem.status); - QString path = processesItem.path; - bool current = processesItem.current; + const st64 pid = processesItem.pid; + const st64 uid = processesItem.uid; + const QString status = translateStatus(processesItem.status); + const QString path = processesItem.path; + const bool current = processesItem.current; // Use bold font to highlight active thread font.setBold(current); - QStandardItem *rowPid = new QStandardItem(QString::number(pid)); - QStandardItem *rowUid = new QStandardItem(QString::number(uid)); - QStandardItem *rowStatus = new QStandardItem(status); - QStandardItem *rowPath = new QStandardItem(path); + auto *rowPid = new QStandardItem(QString::number(pid)); + auto *rowUid = new QStandardItem(QString::number(uid)); + auto *rowStatus = new QStandardItem(status); + auto *rowPath = new QStandardItem(path); rowPid->setFont(font); rowUid->setFont(font); @@ -150,10 +152,12 @@ void ProcessesWidget::fontsUpdatedSlot() void ProcessesWidget::onActivated(const QModelIndex &index) { - if (!index.isValid()) + if (!index.isValid()) { return; + } - int pid = modelFilter->data(index.sibling(index.row(), ProcessesWidget::COLUMN_PID)).toInt(); + const int pid = + modelFilter->data(index.sibling(index.row(), ProcessesWidget::COLUMN_PID)).toInt(); // Verify that the selected pid is still in the processes list since dp= will // attach to any given id. If it isn't found simply update the UI. for (const auto &value : Core()->getProcesses(DEBUGGED_PID)) { @@ -184,7 +188,7 @@ bool ProcessesFilterModel::filterAcceptsRow(int row, const QModelIndex &parent) { // All columns are checked for a match for (int i = ProcessesWidget::COLUMN_PID; i <= ProcessesWidget::COLUMN_PATH; ++i) { - QModelIndex index = sourceModel()->index(row, i, parent); + const QModelIndex index = sourceModel()->index(row, i, parent); if (qhelpers::filterStringContains(sourceModel()->data(index).toString(), this)) { return true; } diff --git a/src/widgets/ProcessesWidget.h b/src/widgets/ProcessesWidget.h index 40f2f0f6..7b954222 100644 --- a/src/widgets/ProcessesWidget.h +++ b/src/widgets/ProcessesWidget.h @@ -1,13 +1,14 @@ -#pragma once +#ifndef PROCESSESWIDGET_H +#define PROCESSESWIDGET_H + +#include "CutterDockWidget.h" #include -#include +#include #include #include -#include -#include "core/Cutter.h" -#include "CutterDockWidget.h" +#include class MainWindow; @@ -15,6 +16,9 @@ namespace Ui { class ProcessesWidget; } +/** + * @brief Filter model for @ref ProcessesWidget + */ class ProcessesFilterModel : public QSortFilterProxyModel { Q_OBJECT @@ -26,12 +30,15 @@ protected: bool filterAcceptsRow(int row, const QModelIndex &parent) const override; }; +/** + * @brief Dock widget that lists system processes during debugging/emulation + */ class ProcessesWidget : public CutterDockWidget { Q_OBJECT public: - enum ColumnIndex { + enum ColumnIndex : ut8 { COLUMN_PID = 0, COLUMN_UID, COLUMN_STATUS, @@ -54,3 +61,5 @@ private: ProcessesFilterModel *modelFilter; RefreshDeferrer *refreshDeferrer; }; + +#endif // PROCESSESWIDGET_H diff --git a/src/common/ProgressIndicator.cpp b/src/widgets/ProgressIndicator.cpp similarity index 68% rename from src/common/ProgressIndicator.cpp rename to src/widgets/ProgressIndicator.cpp index b827eed1..daec6934 100644 --- a/src/common/ProgressIndicator.cpp +++ b/src/widgets/ProgressIndicator.cpp @@ -1,13 +1,14 @@ - #include "ProgressIndicator.h" #include -static const int lineWidth = 3; -static const int paddingOuter = lineWidth + 2; -static const int paddingInner = 8; -static const int arms = 12; -static const int timerInterval = 50; +namespace { +const int lineWidth = 3; +const int paddingOuter = lineWidth + 2; +const int paddingInner = 8; +const int arms = 12; +const int timerInterval = 50; +} ProgressIndicator::ProgressIndicator(QWidget *parent) : QWidget(parent) { @@ -18,9 +19,9 @@ ProgressIndicator::~ProgressIndicator() {} void ProgressIndicator::setProgressIndicatorVisible(bool visible) { - bool change = progressIndicatorVisible != visible; - progressIndicatorVisible = visible; + const bool change = progressIndicatorVisible != visible; if (change) { + progressIndicatorVisible = visible; update(); } updateAnimationTimer(); @@ -34,7 +35,7 @@ void ProgressIndicator::setAnimating(bool animating) void ProgressIndicator::updateAnimationTimer() { - bool shouldBeAnimating = animating && progressIndicatorVisible; + const bool shouldBeAnimating = animating && progressIndicatorVisible; if (shouldBeAnimating && !animationTimerId) { animationTimerId = startTimer(timerInterval); } else { @@ -67,15 +68,15 @@ void ProgressIndicator::paintEvent(QPaintEvent *) QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); - QPen pen(palette().windowText(), lineWidth, Qt::SolidLine, Qt::RoundCap); + const QPen pen(palette().windowText(), lineWidth, Qt::SolidLine, Qt::RoundCap); painter.setPen(pen); - QPointF origin(width() * 0.5, height() * 0.5); - QLineF line(paddingInner, 0.0, width() * 0.5 - paddingOuter, 0.0); + const QPointF origin(width() * 0.5, height() * 0.5); + const QLineF line(paddingInner, 0.0, width() * 0.5 - paddingOuter, 0.0); - qreal angle = 360.0 / arms; + const qreal angle = 360.0 / arms; for (int i = 0; i < arms; i++) { - int state = (i + (arms - animationState)) % arms; + const int state = (i + (arms - animationState)) % arms; painter.setOpacity((float)state / arms); painter.drawLine(line * QTransform().translate(origin.x(), origin.y()).rotate(angle * i)); } diff --git a/src/common/ProgressIndicator.h b/src/widgets/ProgressIndicator.h similarity index 92% rename from src/common/ProgressIndicator.h rename to src/widgets/ProgressIndicator.h index bd5d2f20..3172fc1a 100644 --- a/src/common/ProgressIndicator.h +++ b/src/widgets/ProgressIndicator.h @@ -1,9 +1,11 @@ - #ifndef PROGRESSINDICATOR_H #define PROGRESSINDICATOR_H #include +/** + * @brief Widget for seeing visual progress of an async task + */ class ProgressIndicator : public QWidget { public: diff --git a/src/widgets/QuickFilterView.cpp b/src/widgets/QuickFilterView.cpp index 8b7462c3..bff862c4 100644 --- a/src/widgets/QuickFilterView.cpp +++ b/src/widgets/QuickFilterView.cpp @@ -1,6 +1,7 @@ #include "QuickFilterView.h" -#include "ui_QuickFilterView.h" + #include "Configuration.h" +#include "ui_QuickFilterView.h" QuickFilterView::QuickFilterView(QWidget *parent) : AbstractFilterView(parent), ui(new Ui::QuickFilterView()) diff --git a/src/widgets/QuickFilterView.h b/src/widgets/QuickFilterView.h index 16a74a2d..1ba79834 100644 --- a/src/widgets/QuickFilterView.h +++ b/src/widgets/QuickFilterView.h @@ -9,6 +9,9 @@ namespace Ui { class QuickFilterView; } +/** + * @brief A UI bar that allows users to type text to filter items in a list or tree + */ class QuickFilterView : public AbstractFilterView { Q_OBJECT diff --git a/src/widgets/RegisterRefsWidget.cpp b/src/widgets/RegisterRefsWidget.cpp index 601dd7d6..b72cc46b 100644 --- a/src/widgets/RegisterRefsWidget.cpp +++ b/src/widgets/RegisterRefsWidget.cpp @@ -1,12 +1,13 @@ #include "RegisterRefsWidget.h" -#include "ui_RegisterRefsWidget.h" -#include "core/MainWindow.h" -#include "common/Helpers.h" -#include "shortcuts/ShortcutManager.h" +#include "common/Helpers.h" +#include "core/MainWindow.h" +#include "shortcuts/ShortcutManager.h" +#include "ui_RegisterRefsWidget.h" + +#include #include #include -#include #include RegisterRefModel::RegisterRefModel(QObject *parent) : QAbstractListModel(parent) {} @@ -23,8 +24,9 @@ int RegisterRefModel::columnCount(const QModelIndex &) const QVariant RegisterRefModel::data(const QModelIndex &index, int role) const { - if (index.row() >= registerRefs.count()) + if (index.row() >= registerRefs.count()) { return QVariant(); + } const RegisterRefDescription ®isterRef = registerRefs.at(index.row()); @@ -85,18 +87,18 @@ RegisterRefProxyModel::RegisterRefProxyModel(RegisterRefModel *sourceModel, QObj bool RegisterRefProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); - RegisterRefDescription item = index.data(RegisterRefModel::RegisterRefDescriptionRole) - .value(); + const QModelIndex index = sourceModel()->index(row, 0, parent); + const auto item = index.data(RegisterRefModel::RegisterRefDescriptionRole) + .value(); return qhelpers::filterStringContains(item.reg, this); } bool RegisterRefProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - RegisterRefDescription leftRegRef = + const auto leftRegRef = left.data(RegisterRefModel::RegisterRefDescriptionRole).value(); - RegisterRefDescription rightRegRef = right.data(RegisterRefModel::RegisterRefDescriptionRole) - .value(); + const auto rightRegRef = right.data(RegisterRefModel::RegisterRefDescriptionRole) + .value(); switch (left.column()) { case RegisterRefModel::RegColumn: @@ -116,12 +118,15 @@ bool RegisterRefProxyModel::lessThan(const QModelIndex &left, const QModelIndex } RegisterRefsWidget::RegisterRefsWidget(MainWindow *main) - : CutterDockWidget(main), ui(new Ui::RegisterRefsWidget), addressableItemContextMenu(this, main) + : CutterDockWidget(main), + ui(new Ui::RegisterRefsWidget), + registerRefModel(new RegisterRefModel(this)), + registerRefProxyModel(new RegisterRefProxyModel(registerRefModel, this)), + refreshDeferrer(createRefreshDeferrer([this]() { refreshRegisterRef(); })), + addressableItemContextMenu(this, main) { ui->setupUi(this); - registerRefModel = new RegisterRefModel(this); - registerRefProxyModel = new RegisterRefProxyModel(registerRefModel, this); ui->registerRefTreeView->setModel(registerRefProxyModel); ui->registerRefTreeView->setAutoScroll(false); ui->registerRefTreeView->sortByColumn(RegisterRefModel::RegColumn, Qt::AscendingOrder); @@ -136,13 +141,11 @@ RegisterRefsWidget::RegisterRefsWidget(MainWindow *main) connect(ui->registerRefTreeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &RegisterRefsWidget::onCurrentChanged); - refreshDeferrer = createRefreshDeferrer([this]() { refreshRegisterRef(); }); - // Ctrl-F to show/hide the filter entry - QShortcut *search_shortcut = Shortcuts()->makeQShortcut("General.showFilter", this); - connect(search_shortcut, &QShortcut::activated, ui->quickFilterView, + QShortcut *searchShortcut = Shortcuts()->makeQShortcut("General.showFilter", this); + connect(searchShortcut, &QShortcut::activated, ui->quickFilterView, &QuickFilterView::showFilter); - search_shortcut->setContext(Qt::WidgetWithChildrenShortcut); + searchShortcut->setContext(Qt::WidgetWithChildrenShortcut); connect(ui->quickFilterView, &QuickFilterView::filterTextChanged, registerRefProxyModel, &QSortFilterProxyModel::setFilterWildcard); @@ -164,6 +167,9 @@ RegisterRefsWidget::RegisterRefsWidget(MainWindow *main) connect(ui->quickFilterView, &QuickFilterView::filterTextChanged, this, [this] { ui->quickFilterView->setItemCount(registerRefProxyModel->rowCount()); }); + + connect(ui->registerRefTreeView, &QTreeView::doubleClicked, this, + &RegisterRefsWidget::onRegisterRefTreeViewDoubleClicked); } RegisterRefsWidget::~RegisterRefsWidget() = default; @@ -180,9 +186,9 @@ void RegisterRefsWidget::refreshRegisterRef() for (const RegisterRef ® : Core()->getRegisterRefs()) { RegisterRefDescription desc; - desc.value = RzAddressString(reg.value); + desc.value = rzAddressString(reg.value); desc.reg = reg.name; - desc.refDesc = Core()->formatRefDesc(QSharedPointer::create(reg.ref)); + desc.refDesc = Core()->formatRefDesc(std::make_shared(reg.ref)); registerRefModel->registerRefs.push_back(desc); } @@ -202,10 +208,10 @@ void RegisterRefsWidget::setScrollMode() qhelpers::setVerticalScrollMode(ui->registerRefTreeView); } -void RegisterRefsWidget::on_registerRefTreeView_doubleClicked(const QModelIndex &index) +void RegisterRefsWidget::onRegisterRefTreeViewDoubleClicked(const QModelIndex &index) { - RegisterRefDescription item = index.data(RegisterRefModel::RegisterRefDescriptionRole) - .value(); + const auto item = index.data(RegisterRefModel::RegisterRefDescriptionRole) + .value(); Core()->seekAndShow(item.value); } @@ -230,18 +236,18 @@ void RegisterRefsWidget::onCurrentChanged(const QModelIndex ¤t, const QMod .toString(); } - RVA offset = Core()->math(offsetString); + const RVA offset = Core()->math(offsetString); addressableItemContextMenu.setTarget(offset); } void RegisterRefsWidget::copyClip(int column) { - int row = ui->registerRefTreeView->selectionModel()->currentIndex().row(); - QString value = ui->registerRefTreeView->selectionModel() - ->currentIndex() - .sibling(row, column) - .data() - .toString(); + const int row = ui->registerRefTreeView->selectionModel()->currentIndex().row(); + const QString value = ui->registerRefTreeView->selectionModel() + ->currentIndex() + .sibling(row, column) + .data() + .toString(); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(value); } diff --git a/src/widgets/RegisterRefsWidget.h b/src/widgets/RegisterRefsWidget.h index 6bd31b04..4a2aed32 100644 --- a/src/widgets/RegisterRefsWidget.h +++ b/src/widgets/RegisterRefsWidget.h @@ -1,14 +1,15 @@ -#pragma once +#ifndef REGISTERREFSWIDGET_H +#define REGISTERREFSWIDGET_H -#include - -#include "core/Cutter.h" #include "CutterDockWidget.h" +#include "core/Cutter.h" #include "menus/AddressableItemContextMenu.h" #include #include +#include + class MainWindow; class QTreeWidget; class RegisterRefsWidget; @@ -28,6 +29,9 @@ struct RegisterRefDescription }; Q_DECLARE_METATYPE(RegisterRefDescription) +/** + * @brief Source model for @ref RegisterRefModel + */ class RegisterRefModel : public QAbstractListModel { Q_OBJECT @@ -38,10 +42,10 @@ private: QList registerRefs; public: - enum Column { RegColumn = 0, ValueColumn, RefColumn, CommentColumn, ColumnCount }; - enum Role { RegisterRefDescriptionRole = Qt::UserRole }; + enum Column : ut8 { RegColumn = 0, ValueColumn, RefColumn, CommentColumn, ColumnCount }; + enum Role : ut16 { RegisterRefDescriptionRole = Qt::UserRole }; - RegisterRefModel(QObject *parent = 0); + RegisterRefModel(QObject *parent = nullptr); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; @@ -50,6 +54,9 @@ public: QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; }; +/** + * @brief Sort and Filter proxy model for @ref RegisterRefModel + */ class RegisterRefProxyModel : public QSortFilterProxyModel { Q_OBJECT @@ -62,6 +69,10 @@ protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; +/** + * @brief Widget that lists register values, updates them as the debugger runs, and allows users to + * "seek" (navigate) to referenced memory + */ class RegisterRefsWidget : public CutterDockWidget { Q_OBJECT @@ -71,7 +82,7 @@ public: ~RegisterRefsWidget(); private slots: - void on_registerRefTreeView_doubleClicked(const QModelIndex &index); + void onRegisterRefTreeViewDoubleClicked(const QModelIndex &index); void refreshRegisterRef(); void copyClip(int column); void customMenuRequested(QPoint pos); @@ -90,3 +101,5 @@ private: QAction *actionCopyRef; AddressableItemContextMenu addressableItemContextMenu; }; + +#endif // REGISTERREFSWIDGET_H diff --git a/src/widgets/RegistersWidget.cpp b/src/widgets/RegistersWidget.cpp index 1c98ec9f..4a2f98d8 100644 --- a/src/widgets/RegistersWidget.cpp +++ b/src/widgets/RegistersWidget.cpp @@ -1,16 +1,18 @@ #include "RegistersWidget.h" -#include "ui_RegistersWidget.h" -#include "common/JsonModel.h" -#include "dialogs/RegisterProfileDialog.h" #include "core/MainWindow.h" +#include "dialogs/RegisterProfileDialog.h" +#include "ui_RegistersWidget.h" #include #include #include RegistersWidget::RegistersWidget(MainWindow *main) - : CutterDockWidget(main), ui(new Ui::RegistersWidget), addressContextMenu(this, main) + : CutterDockWidget(main), + ui(new Ui::RegistersWidget), + addressContextMenu(this, main), + refreshDeferrer(createRefreshDeferrer([this]() { updateContents(); })) { ui->setupUi(this); @@ -19,8 +21,6 @@ RegistersWidget::RegistersWidget(MainWindow *main) registerLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop); ui->verticalLayout->addLayout(registerLayout); - refreshDeferrer = createRefreshDeferrer([this]() { updateContents(); }); - connect(Core(), &CutterCore::refreshAll, this, &RegistersWidget::updateContents); connect(Core(), &CutterCore::registersChanged, this, &RegistersWidget::updateContents); connect(ui->configureProfileBtn, &QPushButton::clicked, this, @@ -80,8 +80,8 @@ void RegistersWidget::setRegisterGrid() registerLayout->addWidget(registerLabel, i, col); registerLayout->addWidget(registerEditValue, i, col + 1); connect(registerEditValue, &QLineEdit::editingFinished, [=]() { - QString regNameString = registerLabel->text(); - QString regValueString = registerEditValue->text(); + const QString regNameString = registerLabel->text(); + const QString regValueString = registerEditValue->text(); Core()->setRegister(regNameString, regValueString); }); } else { @@ -114,7 +114,7 @@ void RegistersWidget::setRegisterGrid() } } -void RegistersWidget::openContextMenu(QPoint point, QString address) +void RegistersWidget::openContextMenu(QPoint point, const QString &address) { addressContextMenu.setTarget(address.toULongLong(nullptr, 16)); addressContextMenu.exec(point); diff --git a/src/widgets/RegistersWidget.h b/src/widgets/RegistersWidget.h index 396a2950..224b13ed 100644 --- a/src/widgets/RegistersWidget.h +++ b/src/widgets/RegistersWidget.h @@ -1,21 +1,25 @@ -#pragma once +#ifndef REGISTERSWIDGET_H +#define REGISTERSWIDGET_H -#include -#include -#include -#include -#include - -#include "core/Cutter.h" #include "CutterDockWidget.h" #include "menus/AddressableItemContextMenu.h" +#include +#include +#include +#include + +#include + class MainWindow; namespace Ui { class RegistersWidget; } +/** + * @brief Dock widget that displays CPU registers in an editable grid for debugging/emulating + */ class RegistersWidget : public CutterDockWidget { Q_OBJECT @@ -27,7 +31,7 @@ public: private slots: void updateContents(); void setRegisterGrid(); - void openContextMenu(QPoint point, QString address); + void openContextMenu(QPoint point, const QString &address); /** * @brief Opens the RegisterProfileDialog to view or edit register profile @@ -46,3 +50,5 @@ private: RefreshDeferrer *refreshDeferrer; QString currProfilePath; }; + +#endif // REGISTERSWIDGET_H diff --git a/src/widgets/RelocsWidget.cpp b/src/widgets/RelocsWidget.cpp index eb4a2c18..e93c1675 100644 --- a/src/widgets/RelocsWidget.cpp +++ b/src/widgets/RelocsWidget.cpp @@ -1,7 +1,8 @@ #include "RelocsWidget.h" -#include "ui_ListDockWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" +#include "ui_ListDockWidget.h" #include #include @@ -25,7 +26,7 @@ QVariant RelocsModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case RelocsModel::VAddrColumn: - return RzAddressString(reloc.vaddr); + return rzAddressString(reloc.vaddr); case RelocsModel::TypeColumn: return reloc.type; case RelocsModel::NameColumn: @@ -39,7 +40,7 @@ QVariant RelocsModel::data(const QModelIndex &index, int role) const case RelocsModel::RelocDescriptionRole: return QVariant::fromValue(reloc); case RelocsModel::AddressRole: - return reloc.vaddr; + return static_cast(reloc.vaddr); default: break; } @@ -48,7 +49,7 @@ QVariant RelocsModel::data(const QModelIndex &index, int role) const QVariant RelocsModel::headerData(int section, Qt::Orientation, int role) const { - if (role == Qt::DisplayRole) + if (role == Qt::DisplayRole) { switch (section) { case RelocsModel::VAddrColumn: return tr("Address"); @@ -59,6 +60,7 @@ QVariant RelocsModel::headerData(int section, Qt::Orientation, int role) const case RelocsModel::CommentColumn: return tr("Comment"); } + } return QVariant(); } @@ -90,7 +92,7 @@ RelocsProxyModel::RelocsProxyModel(RelocsModel *sourceModel, QObject *parent) bool RelocsProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); + const QModelIndex index = sourceModel()->index(row, 0, parent); auto reloc = index.data(RelocsModel::RelocDescriptionRole).value(); return qhelpers::filterStringContains(reloc.name, this); @@ -98,11 +100,13 @@ bool RelocsProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) cons bool RelocsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - if (!left.isValid() || !right.isValid()) + if (!left.isValid() || !right.isValid()) { return false; + } - if (left.parent().isValid() || right.parent().isValid()) + if (left.parent().isValid() || right.parent().isValid()) { return false; + } auto leftReloc = left.data(RelocsModel::RelocDescriptionRole).value(); auto rightReloc = right.data(RelocsModel::RelocDescriptionRole).value(); diff --git a/src/widgets/RelocsWidget.h b/src/widgets/RelocsWidget.h index eb60b756..c547c6a5 100644 --- a/src/widgets/RelocsWidget.h +++ b/src/widgets/RelocsWidget.h @@ -1,17 +1,19 @@ #ifndef RELOCSWIDGET_H #define RELOCSWIDGET_H -#include +#include "CutterDescriptions.h" +#include "CutterDockWidget.h" +#include "widgets/ListDockWidget.h" + #include #include -#include "CutterDockWidget.h" -#include "core/Cutter.h" -#include "widgets/ListDockWidget.h" - class MainWindow; class RelocsWidget; +/** + * @brief Source model for @ref RelocsWidget + */ class RelocsModel : public AddressableItemModel { Q_OBJECT @@ -22,8 +24,8 @@ private: QList relocs; public: - enum Column { VAddrColumn = 0, TypeColumn, NameColumn, CommentColumn, ColumnCount }; - enum Role { RelocDescriptionRole = Qt::UserRole, AddressRole }; + enum Column : ut8 { VAddrColumn = 0, TypeColumn, NameColumn, CommentColumn, ColumnCount }; + enum Role : ut16 { RelocDescriptionRole = Qt::UserRole, AddressRole }; RelocsModel(QObject *parent = nullptr); @@ -39,6 +41,9 @@ public: void reload(); }; +/** + * @brief Proxy model for @ref RelocsWidget + */ class RelocsProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -51,6 +56,9 @@ protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; +/** + * @brief Widget that displays the list of relocations in a searchable table + */ class RelocsWidget : public ListDockWidget { Q_OBJECT diff --git a/src/widgets/ResourcesWidget.cpp b/src/widgets/ResourcesWidget.cpp index 1273d52c..fb467683 100644 --- a/src/widgets/ResourcesWidget.cpp +++ b/src/widgets/ResourcesWidget.cpp @@ -1,7 +1,9 @@ -#include "common/Helpers.h" #include "ResourcesWidget.h" -#include "ui_ListDockWidget.h" + +#include "common/Helpers.h" #include "core/MainWindow.h" +#include "ui_ListDockWidget.h" + #include ResourcesModel::ResourcesModel(QObject *parent) : AddressableItemModel(parent) @@ -28,13 +30,13 @@ QVariant ResourcesModel::data(const QModelIndex &index, int role) const case NAME: return res.name; case VADDR: - return RzAddressString(res.vaddr); + return rzAddressString(res.vaddr); case INDEX: return QString::number(res.index); case TYPE: return res.type; case SIZE: - return qhelpers::formatBytecount(res.size); + return qhelpers::formatByteCount(res.size); case LANG: return res.lang; case COMMENT: @@ -47,13 +49,13 @@ QVariant ResourcesModel::data(const QModelIndex &index, int role) const case NAME: return res.name; case VADDR: - return res.vaddr; + return static_cast(res.vaddr); case INDEX: - return res.index; + return static_cast(res.index); case TYPE: return res.type; case SIZE: - return res.size; + return static_cast(res.size); case LANG: return res.lang; default: @@ -99,12 +101,13 @@ RVA ResourcesModel::address(const QModelIndex &index) const return res.vaddr; } -ResourcesWidget::ResourcesWidget(MainWindow *main) : ListDockWidget(main) +ResourcesWidget::ResourcesWidget(MainWindow *main) + : ListDockWidget(main), + model(new ResourcesModel(this)), + filterModel(new AddressableFilterProxyModel(model, this)) { setObjectName("ResourcesWidget"); - model = new ResourcesModel(this); - filterModel = new AddressableFilterProxyModel(model, this); filterModel->setSortRole(Qt::EditRole); setModels(filterModel); diff --git a/src/widgets/ResourcesWidget.h b/src/widgets/ResourcesWidget.h index eed088bd..177002a5 100644 --- a/src/widgets/ResourcesWidget.h +++ b/src/widgets/ResourcesWidget.h @@ -1,15 +1,17 @@ #ifndef RESOURCESWIDGET_H #define RESOURCESWIDGET_H -#include "core/Cutter.h" +#include "CutterDescriptions.h" #include "CutterDockWidget.h" -#include "CutterTreeView.h" #include "common/AddressableItemModel.h" #include "widgets/ListDockWidget.h" class MainWindow; class ResourcesWidget; +/** + * @brief Source model for @ref ResourcesWidget + */ class ResourcesModel : public AddressableItemModel { Q_OBJECT @@ -20,7 +22,7 @@ private: QList resources; public: - enum Columns { INDEX = 0, NAME, VADDR, TYPE, SIZE, LANG, COMMENT, COUNT }; + enum Columns : ut8 { INDEX = 0, NAME, VADDR, TYPE, SIZE, LANG, COMMENT, COUNT }; explicit ResourcesModel(QObject *parent = nullptr); int rowCount(const QModelIndex &parent = QModelIndex()) const override; @@ -33,6 +35,9 @@ public: RVA address(const QModelIndex &index) const override; }; +/** + * @brief Dock widget with list of all resources identified within the loaded binary + */ class ResourcesWidget : public ListDockWidget { Q_OBJECT diff --git a/src/widgets/RizinGraphWidget.cpp b/src/widgets/RizinGraphWidget.cpp index 380657ee..32f41f94 100644 --- a/src/widgets/RizinGraphWidget.cpp +++ b/src/widgets/RizinGraphWidget.cpp @@ -1,9 +1,12 @@ #include "RizinGraphWidget.h" + #include "ui_RizinGraphWidget.h" -#include #include #include +#include + +#include RizinGraphWidget::RizinGraphWidget(MainWindow *main) : CutterDockWidget(main), @@ -77,7 +80,7 @@ GenericRizinGraphView::GenericRizinGraphView(RizinGraphWidget *parent, MainWindo void GenericRizinGraphView::setGraphCommand(QString cmd) { - graphCommand = cmd; + graphCommand = std::move(cmd); } void GenericRizinGraphView::refreshView() @@ -97,15 +100,15 @@ void GenericRizinGraphView::loadCurrentGraph() return; } - CutterJson functionsDoc = Core()->cmdj(QString("%1 json").arg(graphCommand)); + const CutterJson functionsDoc = Core()->cmdj(QString("%1 json").arg(graphCommand)); auto nodes = functionsDoc["nodes"]; - for (CutterJson block : nodes) { - uint64_t id = block["id"].toUt64(); + for (const CutterJson block : nodes) { + const uint64_t id = block["id"].toUt64(); QString content; - QString title = block["title"].toString(); - QString body = block["body"].toString(); + const QString title = block["title"].toString(); + const QString body = block["body"].toString(); if (!title.isEmpty() && !body.isEmpty()) { content = title + "/n" + body; } else { @@ -128,7 +131,7 @@ void GenericRizinGraphView::loadCurrentGraph() computeGraphPlacement(); if (graphCommand != lastShownCommand) { - selectedBlock = NO_BLOCK_SELECTED; + selectedBlock = noBlockSelected; lastShownCommand = graphCommand; center(); } diff --git a/src/widgets/RizinGraphWidget.h b/src/widgets/RizinGraphWidget.h index 083c095d..e3b0ced2 100644 --- a/src/widgets/RizinGraphWidget.h +++ b/src/widgets/RizinGraphWidget.h @@ -1,12 +1,11 @@ #ifndef RZ_GRAPH_WIDGET_H #define RZ_GRAPH_WIDGET_H -#include - -#include "core/Cutter.h" #include "CutterDockWidget.h" -#include "widgets/SimpleTextGraphView.h" #include "common/RefreshDeferrer.h" +#include "widgets/SimpleTextGraphView.h" + +#include class MainWindow; @@ -51,6 +50,9 @@ private: QString lastShownCommand; }; +/** + * @brief Dock widget providing a menu to select and display graphs using Rizin commands + */ class RizinGraphWidget : public CutterDockWidget { Q_OBJECT diff --git a/src/widgets/SdbWidget.cpp b/src/widgets/SdbWidget.cpp index 37f3e419..8da42762 100644 --- a/src/widgets/SdbWidget.cpp +++ b/src/widgets/SdbWidget.cpp @@ -1,12 +1,14 @@ #include "SdbWidget.h" -#include "ui_SdbWidget.h" -#include "core/MainWindow.h" #include "common/Helpers.h" +#include "core/MainWindow.h" +#include "ui_SdbWidget.h" #include #include +#include + SdbWidget::SdbWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui::SdbWidget) { ui->setupUi(this); @@ -14,12 +16,18 @@ SdbWidget::SdbWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui::SdbW path.clear(); connect(Core(), &CutterCore::refreshAll, this, [this]() { reload(); }); + + connect(ui->treeWidget, &QTreeWidget::itemDoubleClicked, this, + &SdbWidget::onTreeWidgetItemDoubleClicked); + connect(ui->treeWidget, &QTreeWidget::itemChanged, this, &SdbWidget::onTreeWidgetItemChanged); + connect(ui->lockButton, &QToolButton::clicked, this, &SdbWidget::onLockButtonClicked); + reload(); } void SdbWidget::reload(QString _path) { - path = _path; + path = std::move(_path); ui->lineEdit->setText(path); /* insert root sdb keyvalue pairs */ @@ -28,8 +36,8 @@ void SdbWidget::reload(QString _path) QList keys; /* key-values */ keys = Core()->sdbListKeys(path); - for (const QString &key : keys) { - QTreeWidgetItem *tempItem = new QTreeWidgetItem(); + for (const QString &key : std::as_const(keys)) { + auto *tempItem = new QTreeWidgetItem(); tempItem->setText(0, key); tempItem->setText(1, Core()->sdbGet(path, key)); tempItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled @@ -42,8 +50,8 @@ void SdbWidget::reload(QString _path) if (!path.isEmpty()) { keys.append(".."); } - for (const QString &key : keys) { - QTreeWidgetItem *tempItem = new QTreeWidgetItem(); + for (const QString &key : std::as_const(keys)) { + auto *tempItem = new QTreeWidgetItem(); tempItem->setText(0, key + "/"); tempItem->setText(1, ""); ui->treeWidget->insertTopLevelItem(0, tempItem); @@ -51,16 +59,17 @@ void SdbWidget::reload(QString _path) qhelpers::adjustColumns(ui->treeWidget, 0); } -void SdbWidget::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column) +void SdbWidget::onTreeWidgetItemDoubleClicked(QTreeWidgetItem *item, int column) { - if (column < 0) + if (column < 0) { return; + } QString newpath; if (column == 0) { if (item->text(0) == "../") { - int idx = path.lastIndexOf(QLatin1Char('/')); + const int idx = path.lastIndexOf(QLatin1Char('/')); if (idx != -1) { newpath = path.mid(0, idx); } else { @@ -82,7 +91,7 @@ void SdbWidget::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int colum SdbWidget::~SdbWidget() = default; -void SdbWidget::on_lockButton_clicked() +void SdbWidget::onLockButtonClicked() { if (ui->lockButton->isChecked()) { this->setAllowedAreas(Qt::NoDockWidgetArea); @@ -93,7 +102,7 @@ void SdbWidget::on_lockButton_clicked() } } -void SdbWidget::on_treeWidget_itemChanged(QTreeWidgetItem *item, int column) +void SdbWidget::onTreeWidgetItemChanged(QTreeWidgetItem *item, int column) { Core()->sdbSet(path, item->text(0), item->text(column)); } diff --git a/src/widgets/SdbWidget.h b/src/widgets/SdbWidget.h index 42b1457f..6615d4a1 100644 --- a/src/widgets/SdbWidget.h +++ b/src/widgets/SdbWidget.h @@ -1,10 +1,10 @@ #ifndef SDBWIDGET_H #define SDBWIDGET_H -#include - #include "CutterDockWidget.h" +#include + class MainWindow; class QTreeWidgetItem; @@ -12,6 +12,9 @@ namespace Ui { class SdbWidget; } +/** + * @brief SDB browser showing entries as key-value pairs + */ class SdbWidget : public CutterDockWidget { Q_OBJECT @@ -37,9 +40,9 @@ public: ~SdbWidget() override; private slots: - void on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column); - void on_lockButton_clicked(); - void on_treeWidget_itemChanged(QTreeWidgetItem *item, int column); + void onTreeWidgetItemDoubleClicked(QTreeWidgetItem *item, int column); + void onLockButtonClicked(); + void onTreeWidgetItemChanged(QTreeWidgetItem *item, int column); void reload(QString _path = QString()); diff --git a/src/widgets/SearchBarWidget.cpp b/src/widgets/SearchBarWidget.cpp index f349468e..cac10d7a 100644 --- a/src/widgets/SearchBarWidget.cpp +++ b/src/widgets/SearchBarWidget.cpp @@ -1,18 +1,18 @@ #include "SearchBarWidget.h" -#include "ui_SearchBarWidget.h" + #include "CutterSearchable.h" #include "shortcuts/ShortcutManager.h" -#include "Configuration.h" +#include "ui_SearchBarWidget.h" +#include +#include +#include +#include +#include +#include #include #include -#include -#include #include -#include -#include -#include -#include SearchBarSizeGrip::SearchBarSizeGrip(QWidget *parent) : QSizeGrip(parent) { @@ -69,11 +69,14 @@ SearchBarWidget::SearchBarWidget(QWidget *parent) : QWidget(parent), ui(new Ui:: connect(ui->hideButton, &QToolButton::clicked, this, &SearchBarWidget::hideSearchBar); // shortcuts - QShortcut *findNextShortcut = Shortcuts()->makeQShortcut("Search.findNext", ui->searchEdit); - QShortcut *findPrevShortcut = Shortcuts()->makeQShortcut("Search.findPrev", ui->searchEdit); - QShortcut *findLastShortcut = Shortcuts()->makeQShortcut("Search.findLast", ui->searchEdit); + const QShortcut *findNextShortcut = + Shortcuts()->makeQShortcut("Search.findNext", ui->searchEdit); + const QShortcut *findPrevShortcut = + Shortcuts()->makeQShortcut("Search.findPrev", ui->searchEdit); + const QShortcut *findLastShortcut = + Shortcuts()->makeQShortcut("Search.findLast", ui->searchEdit); QShortcut *hideShortcut = Shortcuts()->makeQShortcut("Search.hide", this); - QShortcut *optionsShortcut = Shortcuts()->makeQShortcut("Search.options", this); + const QShortcut *optionsShortcut = Shortcuts()->makeQShortcut("Search.options", this); hideShortcut->setContext(Qt::WidgetWithChildrenShortcut); connect(findNextShortcut, &QShortcut::activated, this, &SearchBarWidget::findNextTriggered); connect(findPrevShortcut, &QShortcut::activated, this, &SearchBarWidget::findPrevTriggered); @@ -82,30 +85,30 @@ SearchBarWidget::SearchBarWidget(QWidget *parent) : QWidget(parent), ui(new Ui:: connect(optionsShortcut, &QShortcut::activated, ui->menuButton, &QToolButton::click); // menu - QMenu *optionsMenu = new QMenu(this); + auto *optionsMenu = new QMenu(this); ui->menuButton->setMenu(optionsMenu); auto emitSearchChanged = [this] { emit searchChanged(text(), options()); }; - m_caseSensitiveAction = optionsMenu->addAction(tr("&Case Sensitive")); - m_caseSensitiveAction->setCheckable(true); - connect(m_caseSensitiveAction, &QAction::triggered, this, emitSearchChanged); + caseSensitiveAction = optionsMenu->addAction(tr("&Case Sensitive")); + caseSensitiveAction->setCheckable(true); + connect(caseSensitiveAction, &QAction::triggered, this, emitSearchChanged); - m_wholeWordsAction = optionsMenu->addAction(tr("Match &Whole Words")); - m_wholeWordsAction->setCheckable(true); - connect(m_wholeWordsAction, &QAction::triggered, this, emitSearchChanged); + wholeWordsAction = optionsMenu->addAction(tr("Match &Whole Words")); + wholeWordsAction->setCheckable(true); + connect(wholeWordsAction, &QAction::triggered, this, emitSearchChanged); - m_regExpAction = optionsMenu->addAction(tr("Match &Regular Expression")); - m_regExpAction->setCheckable(true); - connect(m_regExpAction, &QAction::triggered, this, emitSearchChanged); + regExpAction = optionsMenu->addAction(tr("Match &Regular Expression")); + regExpAction->setCheckable(true); + connect(regExpAction, &QAction::triggered, this, emitSearchChanged); - m_highlightMatchesAction = optionsMenu->addAction(tr("&Highlight All Matches")); - m_highlightMatchesAction->setCheckable(true); - m_highlightMatchesAction->setChecked(true); - connect(m_highlightMatchesAction, &QAction::triggered, this, emitSearchChanged); + highlightMatchesAction = optionsMenu->addAction(tr("&Highlight All Matches")); + highlightMatchesAction->setCheckable(true); + highlightMatchesAction->setChecked(true); + connect(highlightMatchesAction, &QAction::triggered, this, emitSearchChanged); // debounce timer - QTimer *debounceTimer = new QTimer(this); + auto *debounceTimer = new QTimer(this); debounceTimer->setSingleShot(true); debounceTimer->setInterval(200); connect(debounceTimer, &QTimer::timeout, this, @@ -115,7 +118,7 @@ SearchBarWidget::SearchBarWidget(QWidget *parent) : QWidget(parent), ui(new Ui:: // size grip for resizing this->setWindowFlags(Qt::SubWindow); - SearchBarSizeGrip *sg = new SearchBarSizeGrip(this); + auto *sg = new SearchBarSizeGrip(this); ui->horizontalLayout->insertWidget(0, sg); setFocusProxy(ui->searchEdit); @@ -129,35 +132,35 @@ SearchBarWidget::~SearchBarWidget() {} void SearchBarWidget::setCurrentIndex(int index) { - m_index = index; + this->index = index; updateLabel(); } void SearchBarWidget::setTotalCount(int count) { - m_count = count; + this->count = count; updateLabel(); } void SearchBarWidget::setRange(int index, int count) { - m_index = index; - m_count = count; + this->index = index; + this->count = count; updateLabel(); } void SearchBarWidget::clear() { - m_index = 0; - m_count = 0; + index = 0; + count = 0; updateLabel(); } void SearchBarWidget::updateLabel() { // indexes are 0-based - int index = std::min(m_index + 1, m_count); - ui->searchLabel->setText(tr("%1 of %2").arg(index).arg(m_count)); + const int index = std::min(this->index + 1, count); + ui->searchLabel->setText(tr("%1 of %2").arg(index).arg(count)); } void SearchBarWidget::showSearchBar() @@ -181,12 +184,12 @@ void SearchBarWidget::selectText() int SearchBarWidget::totalCount() const { - return m_count; + return count; } int SearchBarWidget::currentIndex() const { - return m_index; + return index; } QString SearchBarWidget::text() const @@ -197,10 +200,10 @@ QString SearchBarWidget::text() const int SearchBarWidget::options() const { int options = 0; - options = m_caseSensitiveAction->isChecked() ? (options | CaseSensitive) : options; - options = m_wholeWordsAction->isChecked() ? (options | WholeWords) : options; - options = m_regExpAction->isChecked() ? (options | RegExp) : options; - options = m_highlightMatchesAction->isChecked() ? (options | HighlightMatches) : options; + options = caseSensitiveAction->isChecked() ? (options | CaseSensitive) : options; + options = wholeWordsAction->isChecked() ? (options | WholeWords) : options; + options = regExpAction->isChecked() ? (options | RegExp) : options; + options = highlightMatchesAction->isChecked() ? (options | HighlightMatches) : options; return options; } diff --git a/src/widgets/SearchBarWidget.h b/src/widgets/SearchBarWidget.h index 6a09d8ff..1f1b0bec 100644 --- a/src/widgets/SearchBarWidget.h +++ b/src/widgets/SearchBarWidget.h @@ -1,8 +1,9 @@ #ifndef SEARCHBARWIDGET_H #define SEARCHBARWIDGET_H -#include #include +#include + #include namespace Ui { @@ -66,13 +67,13 @@ signals: private: std::unique_ptr ui; - int m_index = 0; - int m_count = 0; + int index = 0; + int count = 0; - QAction *m_caseSensitiveAction; - QAction *m_wholeWordsAction; - QAction *m_regExpAction; - QAction *m_highlightMatchesAction; + QAction *caseSensitiveAction; + QAction *wholeWordsAction; + QAction *regExpAction; + QAction *highlightMatchesAction; }; #endif // SEARCHBARWIDGET_H diff --git a/src/widgets/SearchWidget.cpp b/src/widgets/SearchWidget.cpp index 6f134bf3..98203ed1 100644 --- a/src/widgets/SearchWidget.cpp +++ b/src/widgets/SearchWidget.cpp @@ -1,20 +1,19 @@ #include "SearchWidget.h" -#include "ui_SearchWidget.h" -#include "core/MainWindow.h" -#include "common/Helpers.h" -#include "DisassemblyPreview.h" -#include -#include +#include "DisassemblyPreview.h" +#include "common/Helpers.h" +#include "core/MainWindow.h" +#include "ui_SearchWidget.h" + #include +#include #include +#include namespace { - -static const int kMaxTooltipWidth = 500; -static const int kMaxTooltipDisasmPreviewLines = 10; -static const int kMaxTooltipHexdumpBytes = 64; - +const int kMaxTooltipWidth = 500; +const int kMaxTooltipDisasmPreviewLines = 10; +const int kMaxTooltipHexdumpBytes = 64; } static const QVector> searchBoundaries { @@ -103,8 +102,9 @@ int SearchModel::columnCount(const QModelIndex &) const QVariant SearchModel::data(const QModelIndex &index, int role) const { - if (index.row() >= search.count()) + if (index.row() >= search.count()) { return QVariant(); + } const SearchDescription &exp = search.at(index.row()); @@ -122,9 +122,9 @@ QVariant SearchModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case OFFSET: - return RzAddressString(exp.offset); + return rzAddressString(exp.offset); case SIZE: - return RzSizeString(exp.size); + return rzSizeString(exp.size); case CODE: return exp.code; case DATA: @@ -149,7 +149,7 @@ QVariant SearchModel::data(const QModelIndex &index, int role) const } const QFont &fnt = Config()->getBaseFont(); - QFontMetrics fm { fnt }; + const QFontMetrics fm { fnt }; QString toolTipContent = QString("
index(row, 0, parent); - SearchDescription search = - index.data(SearchModel::SearchDescriptionRole).value(); + const QModelIndex index = sourceModel()->index(row, 0, parent); + const auto search = index.data(SearchModel::searchDescriptionRole).value(); return qhelpers::filterStringContains(search.code, this); } bool SearchSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - SearchDescription left_search = - left.data(SearchModel::SearchDescriptionRole).value(); - SearchDescription right_search = - right.data(SearchModel::SearchDescriptionRole).value(); + const auto leftSearch = + left.data(SearchModel::searchDescriptionRole).value(); + const auto rightSearch = + right.data(SearchModel::searchDescriptionRole).value(); switch (left.column()) { case SearchModel::SIZE: - return left_search.size < right_search.size; + return leftSearch.size < rightSearch.size; case SearchModel::OFFSET: - return left_search.offset < right_search.offset; + return leftSearch.offset < rightSearch.offset; case SearchModel::CODE: - return left_search.code < right_search.code; + return leftSearch.code < rightSearch.code; case SearchModel::DATA: - return left_search.data < right_search.data; + return leftSearch.data < rightSearch.data; case SearchModel::COMMENT: - return left_search.detail < right_search.detail; + return leftSearch.detail < rightSearch.detail; default: break; } - return left_search.offset < right_search.offset; + return leftSearch.offset < rightSearch.offset; } -SearchWidget::SearchWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui::SearchWidget) +SearchWidget::SearchWidget(MainWindow *main) + : CutterDockWidget(main), + ui(new Ui::SearchWidget), + searchModel(new SearchModel(this)), + searchProxyModel(new SearchSortFilterProxyModel(searchModel, this)) { ui->setupUi(this); setStyleSheet(QString("QToolTip { max-width: %1px; opacity: 230; }").arg(kMaxTooltipWidth)); updateSearchBoundaries(); - search_model = new SearchModel(this); - search_proxy_model = new SearchSortFilterProxyModel(search_model, this); - ui->searchTreeView->setModel(search_proxy_model); + ui->searchTreeView->setModel(static_cast(searchProxyModel)); ui->searchTreeView->setMainWindow(main); ui->searchTreeView->sortByColumn(SearchModel::OFFSET, Qt::AscendingOrder); @@ -257,7 +258,7 @@ SearchWidget::SearchWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui connect(Core(), &CutterCore::toggleDebugView, this, &SearchWidget::updateSearchBoundaries); connect(Core(), &CutterCore::refreshAll, this, &SearchWidget::refreshSearchspaces); connect(Core(), &CutterCore::commentsChanged, this, - [this]() { qhelpers::emitColumnChanged(search_model, SearchModel::COMMENT); }); + [this]() { qhelpers::emitColumnChanged(searchModel, SearchModel::COMMENT); }); connect(ui->filterLineEdit, &QLineEdit::returnPressed, this, &SearchWidget::runSearch); connect(ui->searchButton, &QAbstractButton::clicked, this, &SearchWidget::runSearch); @@ -286,7 +287,7 @@ void SearchWidget::updateSearchBoundaries() ui->searchInCombo->blockSignals(true); ui->searchInCombo->clear(); - for (auto item : boundaries) { + for (const auto &item : boundaries) { ui->searchInCombo->addItem(tr(item.second), item.first); } ui->searchInCombo->blockSignals(false); @@ -301,17 +302,19 @@ void SearchWidget::searchChanged() void SearchWidget::refreshSearchspaces() { - int cur_idx = ui->searchspaceCombo->currentIndex(); - if (cur_idx < 0) - cur_idx = 0; + int curIdx = ui->searchspaceCombo->currentIndex(); + if (curIdx < 0) { + curIdx = 0; + } ui->searchspaceCombo->clear(); for (auto &kind : searchKinds) { ui->searchspaceCombo->addItem(tr(kind.name), static_cast(kind.kind)); } - if (cur_idx > 0) - ui->searchspaceCombo->setCurrentIndex(cur_idx); + if (curIdx > 0) { + ui->searchspaceCombo->setCurrentIndex(curIdx); + } refreshSearch(); } @@ -326,13 +329,13 @@ void SearchWidget::runSearch() void SearchWidget::refreshSearch() { - QString searchFor = ui->filterLineEdit->text(); + const QString searchFor = ui->filterLineEdit->text(); auto searchSpace = static_cast(ui->searchspaceCombo->currentData().toInt()); - QString searchIn = ui->searchInCombo->currentData().toString(); + const QString searchIn = ui->searchInCombo->currentData().toString(); - search_model->beginResetModel(); - search_model->search = Core()->getAllSearch(searchFor, searchSpace, searchIn); - search_model->endResetModel(); + searchModel->beginResetModel(); + searchModel->search = Core()->getAllSearch(searchFor, searchSpace, searchIn); + searchModel->endResetModel(); qhelpers::adjustColumns(ui->searchTreeView, 3, 0); } @@ -341,10 +344,11 @@ void SearchWidget::refreshSearch() // Called by &QShortcut::activated and &QAbstractButton::clicked signals void SearchWidget::checkSearchResultEmpty() { - if (!search_model->search.isEmpty()) + if (!searchModel->search.isEmpty()) { return; + } - QString searchFor = ui->filterLineEdit->text(); + const QString searchFor = ui->filterLineEdit->text(); auto searchSpace = static_cast(ui->searchspaceCombo->currentData().toInt()); if (searchFor.isEmpty() && !searchKindInfo(searchSpace).noInput) { return; diff --git a/src/widgets/SearchWidget.h b/src/widgets/SearchWidget.h index 30c7748e..5cd92584 100644 --- a/src/widgets/SearchWidget.h +++ b/src/widgets/SearchWidget.h @@ -1,19 +1,21 @@ #ifndef SEARCHWIDGET_H #define SEARCHWIDGET_H -#include +#include "AddressableItemList.h" +#include "CutterDockWidget.h" #include #include -#include "core/Cutter.h" -#include "CutterDockWidget.h" -#include "AddressableItemList.h" +#include class MainWindow; class QTreeWidgetItem; class SearchWidget; +/** + * @brief Souce model for @ref SearchWidget + */ class SearchModel : public AddressableItemModel { Q_OBJECT @@ -24,8 +26,8 @@ private: QList search; public: - enum Columns { OFFSET = 0, SIZE, CODE, DATA, COMMENT, COUNT }; - static const int SearchDescriptionRole = Qt::UserRole; + enum Columns : ut8 { OFFSET = 0, SIZE, CODE, DATA, COMMENT, COUNT }; + static const int searchDescriptionRole = Qt::UserRole; SearchModel(QObject *parent = nullptr); @@ -39,6 +41,9 @@ public: RVA address(const QModelIndex &index) const override; }; +/** + * @brief Sort and Filter proxy model for @ref SearchWidget + */ class SearchSortFilterProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -55,6 +60,9 @@ namespace Ui { class SearchWidget; } +/** + * @brief Widget for searching + */ class SearchWidget : public CutterDockWidget { Q_OBJECT @@ -73,8 +81,8 @@ private slots: private: std::unique_ptr ui; - SearchModel *search_model; - SearchSortFilterProxyModel *search_proxy_model; + SearchModel *searchModel; + SearchSortFilterProxyModel *searchProxyModel; void refreshSearch(); void checkSearchResultEmpty(); diff --git a/src/widgets/SearchableDockWidget.cpp b/src/widgets/SearchableDockWidget.cpp index fde2a5bb..2a26e5f4 100644 --- a/src/widgets/SearchableDockWidget.cpp +++ b/src/widgets/SearchableDockWidget.cpp @@ -1,8 +1,9 @@ #include "SearchableDockWidget.h" + #include "SearchBarWidget.h" -#include #include +#include #include namespace { @@ -11,9 +12,9 @@ constexpr int vPadding = 4; }; SearchableDockWidget::SearchableDockWidget(MainWindow *parent) - : CutterDockWidget(parent), m_searchBar(new SearchBarWidget(this)) + : CutterDockWidget(parent), searchBar(new SearchBarWidget(this)) { - CutterSearchableHelper::setupConnections(this, m_searchBar); + CutterSearchableHelper::setupConnections(this, searchBar); } void SearchableDockWidget::resizeEvent(QResizeEvent *event) @@ -24,7 +25,7 @@ void SearchableDockWidget::resizeEvent(QResizeEvent *event) void SearchableDockWidget::updateSearchBarPosition() { - CutterSearchableHelper::positionSearchBar(this, m_searchBar, searchableArea(), searchHPadding(), + CutterSearchableHelper::positionSearchBar(this, searchBar, searchableArea(), searchHPadding(), searchVPadding()); } diff --git a/src/widgets/SearchableDockWidget.h b/src/widgets/SearchableDockWidget.h index a1c5e9da..b26a91c7 100644 --- a/src/widgets/SearchableDockWidget.h +++ b/src/widgets/SearchableDockWidget.h @@ -9,7 +9,7 @@ class SearchBarWidget; /** * @brief A dock widget that includes a search bar */ -class CUTTER_EXPORT SearchableDockWidget : public CutterDockWidget, public CutterSearchable +class CUTTER_EXPORT SearchableDockWidget : public CutterDockWidget, public CutterSearchableI { Q_OBJECT @@ -19,7 +19,7 @@ public: void updateSearchBarPosition(); protected: - SearchBarWidget *m_searchBar; + SearchBarWidget *searchBar; void resizeEvent(QResizeEvent *event) override; int searchHPadding() const override; diff --git a/src/widgets/SearchableTextEdit.cpp b/src/widgets/SearchableTextEdit.cpp index 5eaa0f72..411d1df2 100644 --- a/src/widgets/SearchableTextEdit.cpp +++ b/src/widgets/SearchableTextEdit.cpp @@ -1,6 +1,7 @@ #include "SearchableTextEdit.h" -#include "CutterSearchable.h" + #include "Configuration.h" +#include "CutterSearchable.h" #include @@ -8,9 +9,9 @@ SearchableTextEdit::SearchableTextEdit(QWidget *parent) : QPlainTextEdit(parent) QPair SearchableTextEdit::search(const QString &string, int options) { - m_searchResults.clear(); - m_currentIndex = -1; - m_highlightMatches = options & SearchOption::HighlightMatches; + searchResults.clear(); + currentIndex = -1; + highlightMatchesEnabled = options & SearchOption::HighlightMatches; if (string.isEmpty()) { clearSearch(); @@ -23,7 +24,7 @@ QPair SearchableTextEdit::search(const QString &string, int options) flags = options & SearchOption::WholeWords ? (flags | QTextDocument::FindWholeWords) : flags; // we will search relative to this cursor - QTextCursor originalCursor = this->textCursor(); + const QTextCursor originalCursor = this->textCursor(); // start from the top QTextDocument *doc = this->document(); @@ -48,14 +49,14 @@ QPair SearchableTextEdit::search(const QString &string, int options) } // wrap around - if (m_currentIndex < 0 && !m_searchResults.isEmpty()) { - m_currentIndex = 0; + if (currentIndex < 0 && !searchResults.isEmpty()) { + currentIndex = 0; } scrollToCurrentIndex(); highlightMatches(); - return { m_currentIndex, m_searchResults.size() }; + return { currentIndex, searchResults.size() }; } void SearchableTextEdit::handleMatch(const QTextCursor ¤tCursor, @@ -63,61 +64,61 @@ void SearchableTextEdit::handleMatch(const QTextCursor ¤tCursor, { if (!currentCursor.isNull()) { - if (m_currentIndex < 0 && currentCursor.selectionEnd() >= originalCursor.selectionStart()) { - m_currentIndex = m_searchResults.size(); + if (currentIndex < 0 && currentCursor.selectionEnd() >= originalCursor.selectionStart()) { + currentIndex = searchResults.size(); } - int len = currentCursor.selectionEnd() - currentCursor.selectionStart(); - m_searchResults.append(SearchResult { currentCursor.selectionStart(), len }); + const int len = currentCursor.selectionEnd() - currentCursor.selectionStart(); + searchResults.append(SearchResult { currentCursor.selectionStart(), len }); } } void SearchableTextEdit::clearSearch() { this->setExtraSelections({}); - m_searchResults.clear(); + searchResults.clear(); } int SearchableTextEdit::findNext() { - if (m_searchResults.isEmpty()) { + if (searchResults.isEmpty()) { return 0; } - m_currentIndex = (m_currentIndex + 1) % m_searchResults.size(); + currentIndex = (currentIndex + 1) % searchResults.size(); scrollToCurrentIndex(); highlightMatches(); - return m_currentIndex; + return currentIndex; } int SearchableTextEdit::findPrev() { - if (m_searchResults.isEmpty()) { + if (searchResults.isEmpty()) { return 0; } - int count = m_searchResults.size(); - m_currentIndex = (m_currentIndex - 1 + count) % count; + const int count = searchResults.size(); + currentIndex = (currentIndex - 1 + count) % count; scrollToCurrentIndex(); highlightMatches(); - return m_currentIndex; + return currentIndex; } int SearchableTextEdit::findLast() { - if (m_searchResults.isEmpty()) { + if (searchResults.isEmpty()) { return 0; } - m_currentIndex = m_searchResults.size() - 1; + currentIndex = searchResults.size() - 1; scrollToCurrentIndex(); highlightMatches(); - return m_currentIndex; + return currentIndex; } void SearchableTextEdit::resizeEvent(QResizeEvent *event) @@ -128,15 +129,15 @@ void SearchableTextEdit::resizeEvent(QResizeEvent *event) void SearchableTextEdit::highlightMatches() { - if (m_currentIndex < 0 || m_currentIndex >= m_searchResults.size()) { + if (currentIndex < 0 || currentIndex >= searchResults.size()) { this->setExtraSelections({}); return; } QTextCursor cursor(this->document()); - if (!m_highlightMatches) { - mapCursorToResult(cursor, m_searchResults[m_currentIndex]); + if (!highlightMatchesEnabled) { + mapCursorToResult(cursor, searchResults[currentIndex]); QTextEdit::ExtraSelection selection; selection.format.setBackground(ConfigColor("searchCurrent")); selection.cursor = cursor; @@ -144,22 +145,22 @@ void SearchableTextEdit::highlightMatches() return; } - QPoint startPoint = QPoint(0, 0); - int startPos = this->cursorForPosition(startPoint).position(); + const QPoint startPoint = QPoint(0, 0); + const int startPos = this->cursorForPosition(startPoint).position(); - QPoint endPoint = QPoint(this->geometry().width(), this->geometry().height()); + const QPoint endPoint = QPoint(this->geometry().width(), this->geometry().height()); auto endCursor = this->cursorForPosition(endPoint); - int endPos = endCursor.position(); + const int endPos = endCursor.position(); endCursor.movePosition(QTextCursor::End); - int maxPos = endCursor.position(); + const int maxPos = endCursor.position(); QList selections; - for (int i = 0; i < m_searchResults.size(); ++i) { - const auto res = m_searchResults[i]; - mapCursorToResult(cursor, m_searchResults[i]); - int sPos = std::max(startPos - res.length, 0); - int ePos = std::min(endPos + res.length, maxPos); - if (i == m_currentIndex) { + for (int i = 0; i < searchResults.size(); ++i) { + const auto res = searchResults[i]; + mapCursorToResult(cursor, searchResults[i]); + const int sPos = std::max(startPos - res.length, 0); + const int ePos = std::min(endPos + res.length, maxPos); + if (i == currentIndex) { QTextEdit::ExtraSelection selection; selection.format.setBackground(ConfigColor("searchCurrent")); selection.cursor = cursor; @@ -177,12 +178,12 @@ void SearchableTextEdit::highlightMatches() void SearchableTextEdit::scrollToCurrentIndex() { - if (m_currentIndex < 0 || m_currentIndex >= m_searchResults.size()) { + if (currentIndex < 0 || currentIndex >= searchResults.size()) { return; } QTextCursor scrollCursor(this->document()); - mapCursorToResult(scrollCursor, m_searchResults[m_currentIndex]); + mapCursorToResult(scrollCursor, searchResults[currentIndex]); scrollCursor.setPosition(scrollCursor.selectionStart()); scrollCursor.clearSelection(); this->setTextCursor(scrollCursor); diff --git a/src/widgets/SearchableTextEdit.h b/src/widgets/SearchableTextEdit.h index e0a57e6f..788da761 100644 --- a/src/widgets/SearchableTextEdit.h +++ b/src/widgets/SearchableTextEdit.h @@ -45,9 +45,9 @@ private: int length; }; - int m_currentIndex; - QList m_searchResults; - bool m_highlightMatches; + int currentIndex; + QList searchResults; + bool highlightMatchesEnabled; void handleMatch(const QTextCursor ¤tCursor, const QTextCursor &originalCursor); void scrollToCurrentIndex(); diff --git a/src/widgets/SectionsWidget.cpp b/src/widgets/SectionsWidget.cpp index 49609c68..9bb16eff 100644 --- a/src/widgets/SectionsWidget.cpp +++ b/src/widgets/SectionsWidget.cpp @@ -1,17 +1,18 @@ #include "SectionsWidget.h" + #include "QuickFilterView.h" -#include "core/MainWindow.h" -#include "common/Helpers.h" #include "common/Configuration.h" +#include "common/Helpers.h" +#include "core/MainWindow.h" #include "ui_ListDockWidget.h" #include #include #include #include -#include #include #include +#include SectionsModel::SectionsModel(QObject *parent) : AddressableItemModel(parent) {} @@ -29,17 +30,17 @@ QVariant SectionsModel::data(const QModelIndex &index, int role) const { // TODO: create unique colors, e. g. use HSV color space and rotate in H for 360/size static const QList colors = { - QColor("#1ABC9C"), // TURQUOISE - QColor("#2ECC71"), // EMERALD - QColor("#3498DB"), // PETER RIVER - QColor("#9B59B6"), // AMETHYST - QColor("#34495E"), // WET ASPHALT - QColor("#F1C40F"), // SUN FLOWER - QColor("#E67E22"), // CARROT - QColor("#E74C3C"), // ALIZARIN - QColor("#ECF0F1"), // CLOUDS - QColor("#BDC3C7"), // SILVER - QColor("#95A5A6") // COBCRETE + QColor(26, 188, 156), // TURQUOISE + QColor(46, 204, 113), // EMERALD + QColor(52, 152, 219), // PETER RIVER + QColor(155, 89, 182), // AMETHYST + QColor(52, 73, 94), // WET ASPHALT + QColor(241, 196, 15), // SUN FLOWER + QColor(230, 126, 34), // CARROT + QColor(231, 76, 60), // ALIZARIN + QColor(236, 240, 241), // CLOUDS + QColor(189, 195, 199), // SILVER + QColor(149, 165, 166) // CONCRETE }; if (index.row() >= sections.count()) { @@ -54,13 +55,13 @@ QVariant SectionsModel::data(const QModelIndex &index, int role) const case SectionsModel::NameColumn: return section.name; case SectionsModel::SizeColumn: - return RzSizeString(section.size); + return rzSizeString(section.size); case SectionsModel::AddressColumn: - return RzAddressString(section.vaddr); + return rzAddressString(section.vaddr); case SectionsModel::EndAddressColumn: - return RzAddressString(section.vaddr + section.vsize); + return rzAddressString(section.vaddr + section.vsize); case SectionsModel::VirtualSizeColumn: - return RzSizeString(section.vsize); + return rzSizeString(section.vsize); case SectionsModel::PermissionsColumn: return section.perm; case SectionsModel::EntropyColumn: @@ -71,8 +72,9 @@ QVariant SectionsModel::data(const QModelIndex &index, int role) const return QVariant(); } case Qt::DecorationRole: - if (index.column() == 0) + if (index.column() == 0) { return colors[index.row() % colors.size()]; + } return QVariant(); case SectionsModel::SectionDescriptionRole: return QVariant::fromValue(section); @@ -158,15 +160,15 @@ bool SectionsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &ri } } -SectionsWidget::SectionsWidget(MainWindow *main) : ListDockWidget(main) +SectionsWidget::SectionsWidget(MainWindow *main) + : ListDockWidget(main), + sectionsRefreshDeferrer(createRefreshDeferrer([this]() { refreshSections(); })), + dockRefreshDeferrer(createRefreshDeferrer([this]() { refreshDocks(); })) { setObjectName("SectionsWidget"); setWindowTitle(tr("Sections")); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - sectionsRefreshDeferrer = createRefreshDeferrer([this]() { refreshSections(); }); - dockRefreshDeferrer = createRefreshDeferrer([this]() { refreshDocks(); }); - initSectionsTable(); initQuickFilter(); initAddrMapDocks(); @@ -196,7 +198,7 @@ void SectionsWidget::initAddrMapDocks() rawAddrDock = new RawAddrDock(sectionsModel, this); virtualAddrDock = new VirtualAddrDock(sectionsModel, this); addrDockWidget = new QWidget(); - QHBoxLayout *addrDockLayout = new QHBoxLayout(); + auto *addrDockLayout = new QHBoxLayout(); addrDockLayout->addWidget(rawAddrDock); addrDockLayout->addWidget(virtualAddrDock); addrDockWidget->setLayout(addrDockLayout); @@ -224,19 +226,19 @@ void SectionsWidget::initConnects() { connect(Core(), &CutterCore::refreshAll, this, &SectionsWidget::refreshSections); connect(Core(), &CutterCore::codeRebased, this, &SectionsWidget::refreshSections); - connect(this, &QDockWidget::visibilityChanged, this, [=](bool visibility) { + connect(this, &QDockWidget::visibilityChanged, this, [=, this](bool visibility) { if (visibility) { refreshSections(); } }); connect(Core(), &CutterCore::seekChanged, this, &SectionsWidget::refreshDocks); connect(Config(), &Configuration::colorsUpdated, this, &SectionsWidget::refreshSections); - connect(toggleButton, &QToolButton::clicked, this, [=] { + connect(toggleButton, &QToolButton::clicked, this, [=, this] { toggleButton->hide(); addrDockWidget->show(); virtualAddrDock->show(); }); - connect(virtualAddrDock, &QDockWidget::visibilityChanged, this, [=](bool visibility) { + connect(virtualAddrDock, &QDockWidget::visibilityChanged, this, [=, this](bool visibility) { if (!visibility) { updateToggle(); } @@ -269,18 +271,18 @@ void SectionsWidget::refreshDocks() void SectionsWidget::drawIndicatorOnAddrDocks() { - RVA offset = Core()->getOffset(); + const RVA offset = Core()->getOffset(); for (int i = 0; i != virtualAddrDock->proxyModel->rowCount(); i++) { - QModelIndex idx = virtualAddrDock->proxyModel->index(i, 0); - RVA vaddr = + const QModelIndex idx = virtualAddrDock->proxyModel->index(i, 0); + const RVA vaddr = idx.data(SectionsModel::SectionDescriptionRole).value().vaddr; - int vsize = + const int vsize = idx.data(SectionsModel::SectionDescriptionRole).value().vsize; - RVA end = vaddr + vsize; + const RVA end = vaddr + vsize; if (offset < end) { - QString name = idx.data(SectionsModel::SectionDescriptionRole) - .value() - .name; + const QString name = idx.data(SectionsModel::SectionDescriptionRole) + .value() + .name; float ratio = 0; if (vsize > 0 && offset > vaddr) { ratio = (float)(offset - vaddr) / (float)vsize; @@ -308,23 +310,23 @@ void SectionsWidget::updateToggle() AbstractAddrDock::AbstractAddrDock(SectionsModel *model, QWidget *parent) : QDockWidget(parent), + indicatorHeight(5), + indicatorParamPosY(20), + heightThreshold(30), + heightDivisor(1000), + rectOffset(100), + rectWidthMin(80), + rectWidthMax(400), addrDockScene(new AddrDockScene(this)), - graphicsView(new QGraphicsView(this)) + graphicsView(new QGraphicsView(this)), + proxyModel(new SectionsProxyModel(model, this)) { graphicsView->setScene(addrDockScene); setWidget(graphicsView); setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); - proxyModel = new SectionsProxyModel(model, this); setWidget(graphicsView); - indicatorHeight = 5; - indicatorParamPosY = 20; - heightThreshold = 30; - heightDivisor = 1000; - rectOffset = 100; - rectWidthMin = 80; - rectWidthMax = 400; indicatorColor = ConfigColor("gui.navbar.seek"); textColor = ConfigColor("gui.dataoffset"); } @@ -341,31 +343,31 @@ void AbstractAddrDock::updateDock() textColor = ConfigColor("gui.dataoffset"); int y = 0; - int validMinSize = getValidMinSize(); - int rectWidth = getRectWidth(); + const int validMinSize = getValidMinSize(); + const int rectWidth = getRectWidth(); proxyModel->sort(SectionsModel::AddressColumn, Qt::AscendingOrder); for (int i = 0; i < proxyModel->rowCount(); ++i) { - QModelIndex idx = proxyModel->index(i, 0); + const QModelIndex idx = proxyModel->index(i, 0); auto desc = idx.data(SectionsModel::SectionDescriptionRole).value(); - QString name = desc.name; + const QString name = desc.name; addrDockScene->seekAddrMap[name] = desc.vaddr; addrDockScene->seekAddrSizeMap[name] = desc.vsize; - RVA addr = getAddressOfSection(desc); - RVA size = getSizeOfSection(desc); + const RVA addr = getAddressOfSection(desc); + const RVA size = getSizeOfSection(desc); addrDockScene->nameAddrMap[name] = addr; addrDockScene->nameAddrSizeMap[name] = size; - int drawSize = getAdjustedSize(size, validMinSize); + const int drawSize = getAdjustedSize(size, validMinSize); - QGraphicsRectItem *rect = new QGraphicsRectItem(rectOffset, y, rectWidth, drawSize); + auto *rect = new QGraphicsRectItem(rectOffset, y, rectWidth, drawSize); rect->setBrush(QBrush(idx.data(Qt::DecorationRole).value())); addrDockScene->addItem(rect); - addTextItem(textColor, QPoint(0, y), RzAddressString(addr)); - addTextItem(textColor, QPoint(rectOffset, y), RzSizeString(size)); + addTextItem(textColor, QPoint(0, y), rzAddressString(addr)); + addTextItem(textColor, QPoint(rectOffset, y), rzSizeString(size)); addTextItem(textColor, QPoint(rectOffset + rectWidth, y), name); addrDockScene->namePosYMap[name] = y; @@ -377,16 +379,16 @@ void AbstractAddrDock::updateDock() graphicsView->setSceneRect(addrDockScene->itemsBoundingRect()); } -void AbstractAddrDock::addTextItem(QColor color, QPoint pos, QString string) +void AbstractAddrDock::addTextItem(QColor color, QPoint pos, const QString &string) { - QGraphicsTextItem *text = new QGraphicsTextItem; + auto *text = new QGraphicsTextItem; text->setDefaultTextColor(color); text->setPos(pos); text->setPlainText(string); addrDockScene->addItem(text); } -int AbstractAddrDock::getAdjustedSize(int size, int validMinSize) +int AbstractAddrDock::getAdjustedSize(int size, int validMinSize) const { if (size == 0) { return size; @@ -414,8 +416,8 @@ int AbstractAddrDock::getValidMinSize() { proxyModel->sort(SectionsModel::SizeColumn, Qt::AscendingOrder); for (int i = 0; i < proxyModel->rowCount(); i++) { - QModelIndex idx = proxyModel->index(i, 0); - int size = getSizeOfSection( + const QModelIndex idx = proxyModel->index(i, 0); + const int size = getSizeOfSection( idx.data(SectionsModel::SectionDescriptionRole).value()); if (size > 0) { return size; @@ -424,14 +426,13 @@ int AbstractAddrDock::getValidMinSize() return 0; } -void AbstractAddrDock::drawIndicator(QString name, float ratio) +void AbstractAddrDock::drawIndicator(const QString &name, float ratio) { - RVA offset = Core()->getOffset(); - float padding = addrDockScene->nameHeightMap[name] * ratio; - int y = addrDockScene->namePosYMap[name] + (int)padding; - QColor color = indicatorColor; - QGraphicsRectItem *indicator = - new QGraphicsRectItem(QRectF(0, y, getIndicatorWidth(), indicatorHeight)); + const RVA offset = Core()->getOffset(); + const float padding = addrDockScene->nameHeightMap[name] * ratio; + const int y = addrDockScene->namePosYMap[name] + (int)padding; + const QColor color = indicatorColor; + auto *indicator = new QGraphicsRectItem(QRectF(0, y, getIndicatorWidth(), indicatorHeight)); indicator->setBrush(QBrush(color)); addrDockScene->addItem(indicator); @@ -443,20 +444,17 @@ void AbstractAddrDock::drawIndicator(QString name, float ratio) addTextItem(color, QPoint(0, y - indicatorParamPosY), QString("0x%1").arg(offset, 0, 16)); } -AddrDockScene::AddrDockScene(QWidget *parent) : QGraphicsScene(parent) -{ - disableCenterOn = false; -} +AddrDockScene::AddrDockScene(QWidget *parent) : QGraphicsScene(parent), disableCenterOn(false) {} AddrDockScene::~AddrDockScene() {} void AddrDockScene::mousePressEvent(QGraphicsSceneMouseEvent *event) { - RVA addr = getAddrFromPos((int)event->scenePos().y(), false); + const RVA addr = getAddrFromPos((int)event->scenePos().y(), false); if (addr != RVA_INVALID) { - QToolTip::showText(event->screenPos(), RzAddressString(addr)); + QToolTip::showText(event->screenPos(), rzAddressString(addr)); if (event->buttons() & Qt::LeftButton) { - RVA seekAddr = getAddrFromPos((int)event->scenePos().y(), true); + const RVA seekAddr = getAddrFromPos((int)event->scenePos().y(), true); disableCenterOn = true; Core()->seekAndShow(seekAddr); disableCenterOn = false; @@ -478,9 +476,9 @@ RVA AddrDockScene::getAddrFromPos(int posY, bool seek) QHash addrMap = seek ? seekAddrMap : nameAddrMap; QHash addrSizeMap = seek ? seekAddrSizeMap : nameAddrSizeMap; for (it = namePosYMap.constBegin(); it != namePosYMap.constEnd(); ++it) { - QString name = it.key(); - int y = it.value(); - int h = nameHeightMap[name]; + const QString &name = it.key(); + const int y = it.value(); + const int h = nameHeightMap[name]; if (posY >= y && y + h >= posY) { if (h == 0) { return addrMap[name]; @@ -495,7 +493,7 @@ RawAddrDock::RawAddrDock(SectionsModel *model, QWidget *parent) : AbstractAddrDo { setWindowTitle(tr("Raw")); connect(this, &QDockWidget::featuresChanged, this, - [=]() { setFeatures(QDockWidget::NoDockWidgetFeatures); }); + [=, this]() { setFeatures(QDockWidget::NoDockWidgetFeatures); }); } VirtualAddrDock::VirtualAddrDock(SectionsModel *model, QWidget *parent) @@ -503,7 +501,7 @@ VirtualAddrDock::VirtualAddrDock(SectionsModel *model, QWidget *parent) { setWindowTitle(tr("Virtual")); connect(this, &QDockWidget::featuresChanged, this, - [=]() { setFeatures(QDockWidget::DockWidgetClosable); }); + [=, this]() { setFeatures(QDockWidget::DockWidgetClosable); }); } void RawAddrDock::updateDock() diff --git a/src/widgets/SectionsWidget.h b/src/widgets/SectionsWidget.h index 0514b38d..7a15c37c 100644 --- a/src/widgets/SectionsWidget.h +++ b/src/widgets/SectionsWidget.h @@ -1,20 +1,17 @@ #ifndef SECTIONSWIDGET_H #define SECTIONSWIDGET_H -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "core/Cutter.h" +#include "CutterDescriptions.h" #include "CutterDockWidget.h" #include "widgets/ListDockWidget.h" +#include +#include +#include +#include +#include +#include + class QAbstractItemView; class SectionsWidget; class AbstractAddrDock; @@ -26,6 +23,9 @@ class QuickFilterView; class QGraphicsView; class QGraphicsRectItem; +/** + * @brief Source model for @ref SectionsWidget + */ class SectionsModel : public AddressableItemModel { Q_OBJECT @@ -36,7 +36,7 @@ private: QList sections; public: - enum Column { + enum Column : ut8 { NameColumn = 0, SizeColumn, AddressColumn, @@ -47,7 +47,7 @@ public: CommentColumn, ColumnCount }; - enum Role { SectionDescriptionRole = Qt::UserRole }; + enum Role : ut16 { SectionDescriptionRole = Qt::UserRole }; SectionsModel(QObject *parent = nullptr); @@ -62,6 +62,9 @@ public: QString name(const QModelIndex &index) const override; }; +/** + * @brief Proxy model for @ref SectionsWidget + */ class SectionsProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -73,6 +76,9 @@ protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; +/** + * @brief Widget showing list of all sections in a binary + */ class SectionsWidget : public ListDockWidget { Q_OBJECT @@ -115,6 +121,12 @@ private: void updateToggle(); }; +/** + * @brief A base class for visual address maps that uses a QGraphicsView to render binary segments. + * + * It defines the core geometry (offsets, widths, and scaling) and requires subclasses to implement + * specific logic for retrieving addresses and sizes. + */ class AbstractAddrDock : public QDockWidget { Q_OBJECT @@ -141,8 +153,8 @@ protected: QGraphicsView *graphicsView; SectionsProxyModel *proxyModel; - void addTextItem(QColor color, QPoint pos, QString string); - int getAdjustedSize(int size, int validMinSize); + void addTextItem(QColor color, QPoint pos, const QString &string); + int getAdjustedSize(int size, int validMinSize) const; int getRectWidth(); int getIndicatorWidth(); int getValidMinSize(); @@ -151,9 +163,13 @@ protected: virtual RVA getAddressOfSection(const SectionDescription §ion) = 0; private: - void drawIndicator(QString name, float ratio); + void drawIndicator(const QString &name, float ratio); }; +/** + * @brief Graphics scene that translates mouse coordinates into memory addresses for navigation and + * "seek" interactions. + */ class AddrDockScene : public QGraphicsScene { Q_OBJECT @@ -179,6 +195,9 @@ private: RVA getAddrFromPos(int posY, bool seek); }; +/** + * @brief Visualizes the binary's physical layout using paddr + */ class RawAddrDock : public AbstractAddrDock { Q_OBJECT @@ -194,6 +213,9 @@ protected: RVA getAddressOfSection(const SectionDescription §ion) override { return section.paddr; }; }; +/** + * @brief Visualizes the binary's memory layout using virtual addresses (vaddr) + */ class VirtualAddrDock : public AbstractAddrDock { Q_OBJECT diff --git a/src/widgets/SegmentsWidget.cpp b/src/widgets/SegmentsWidget.cpp index e3ad5701..be5e66c3 100644 --- a/src/widgets/SegmentsWidget.cpp +++ b/src/widgets/SegmentsWidget.cpp @@ -1,10 +1,11 @@ #include "SegmentsWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" #include "ui_ListDockWidget.h" -#include #include +#include SegmentsModel::SegmentsModel(QObject *parent) : AddressableItemModel(parent) {} @@ -22,21 +23,22 @@ QVariant SegmentsModel::data(const QModelIndex &index, int role) const { // TODO: create unique colors, e. g. use HSV color space and rotate in H for 360/size static const QList colors = { - QColor("#1ABC9C"), // TURQUOISE - QColor("#2ECC71"), // EMERALD - QColor("#3498DB"), // PETER RIVER - QColor("#9B59B6"), // AMETHYST - QColor("#34495E"), // WET ASPHALT - QColor("#F1C40F"), // SUN FLOWER - QColor("#E67E22"), // CARROT - QColor("#E74C3C"), // ALIZARIN - QColor("#ECF0F1"), // CLOUDS - QColor("#BDC3C7"), // SILVER - QColor("#95A5A6") // COBCRETE + QColor(26, 188, 156), // TURQUOISE + QColor(46, 204, 113), // EMERALD + QColor(52, 152, 219), // PETER RIVER + QColor(155, 89, 182), // AMETHYST + QColor(52, 73, 94), // WET ASPHALT + QColor(241, 196, 15), // SUN FLOWER + QColor(230, 126, 34), // CARROT + QColor(231, 76, 60), // ALIZARIN + QColor(236, 240, 241), // CLOUDS + QColor(189, 195, 199), // SILVER + QColor(149, 165, 166) // CONCRETE }; - if (index.row() >= segments.count()) + if (index.row() >= segments.count()) { return QVariant(); + } const SegmentDescription &segment = segments.at(index.row()); @@ -48,9 +50,9 @@ QVariant SegmentsModel::data(const QModelIndex &index, int role) const case SegmentsModel::SizeColumn: return QString::number(segment.size); case SegmentsModel::AddressColumn: - return RzAddressString(segment.vaddr); + return rzAddressString(segment.vaddr); case SegmentsModel::EndAddressColumn: - return RzAddressString(segment.vaddr + segment.size); + return rzAddressString(segment.vaddr + segment.size); case SegmentsModel::PermColumn: return segment.perm; case SegmentsModel::CommentColumn: @@ -59,8 +61,9 @@ QVariant SegmentsModel::data(const QModelIndex &index, int role) const return QVariant(); } case Qt::DecorationRole: - if (index.column() == 0) + if (index.column() == 0) { return colors[index.row() % colors.size()]; + } return QVariant(); case SegmentsModel::SegmentDescriptionRole: return QVariant::fromValue(segment); @@ -134,13 +137,14 @@ bool SegmentsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &ri return false; } -SegmentsWidget::SegmentsWidget(MainWindow *main) : ListDockWidget(main) +SegmentsWidget::SegmentsWidget(MainWindow *main) + : ListDockWidget(main), + segmentsModel(new SegmentsModel(this)), + proxyModel(new SegmentsProxyModel(segmentsModel, this)) { setObjectName("SegmentsWidget"); setWindowTitle(tr("Segments")); - segmentsModel = new SegmentsModel(this); - proxyModel = new SegmentsProxyModel(segmentsModel, this); setModels(proxyModel); ui->treeView->sortByColumn(SegmentsModel::NameColumn, Qt::AscendingOrder); diff --git a/src/widgets/SegmentsWidget.h b/src/widgets/SegmentsWidget.h index 861c05cd..332b99d1 100644 --- a/src/widgets/SegmentsWidget.h +++ b/src/widgets/SegmentsWidget.h @@ -1,17 +1,18 @@ #ifndef SEGMENTSWIDGET_H #define SEGMENTSWIDGET_H -#include +#include "CutterDescriptions.h" +#include "widgets/ListDockWidget.h" #include #include -#include "core/Cutter.h" -#include "widgets/ListDockWidget.h" - class QAbstractItemView; class SegmentsWidget; +/** + * @brief Source model for @ref SegmentsWidget + */ class SegmentsModel : public AddressableItemModel { Q_OBJECT @@ -22,7 +23,7 @@ private: QList segments; public: - enum Column { + enum Column : ut8 { NameColumn = 0, SizeColumn, AddressColumn, @@ -31,7 +32,7 @@ public: CommentColumn, ColumnCount }; - enum Role { SegmentDescriptionRole = Qt::UserRole }; + enum Role : ut16 { SegmentDescriptionRole = Qt::UserRole }; SegmentsModel(QObject *parent = nullptr); @@ -46,6 +47,9 @@ public: QString name(const QModelIndex &index) const override; }; +/** + * @brief Proxy model for @ref SegmentsWidget + */ class SegmentsProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -57,6 +61,9 @@ protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; +/** + * @brief Widget showing list of all segments in a binary + */ class SegmentsWidget : public ListDockWidget { Q_OBJECT diff --git a/src/widgets/SimpleTextGraphView.cpp b/src/widgets/SimpleTextGraphView.cpp index c98c8fcf..d97069ba 100644 --- a/src/widgets/SimpleTextGraphView.cpp +++ b/src/widgets/SimpleTextGraphView.cpp @@ -1,24 +1,24 @@ - #include "SimpleTextGraphView.h" + +#include "common/Configuration.h" +#include "common/Helpers.h" +#include "common/SyntaxHighlighter.h" #include "core/Cutter.h" #include "core/MainWindow.h" -#include "common/Configuration.h" -#include "common/SyntaxHighlighter.h" -#include "common/Helpers.h" -#include -#include +#include +#include +#include #include +#include #include +#include #include #include -#include -#include -#include #include -#include -#include -#include +#include +#include +#include #include @@ -49,7 +49,7 @@ SimpleTextGraphView::SimpleTextGraphView(QWidget *parent, MainWindow *mainWindow SimpleTextGraphView::~SimpleTextGraphView() { - for (QShortcut *shortcut : shortcuts) { + for (const QShortcut *shortcut : shortcuts) { delete shortcut; } } @@ -61,7 +61,7 @@ void SimpleTextGraphView::refreshView() saveCurrentBlock(); loadCurrentGraph(); if (blocks.find(selectedBlock) == blocks.end()) { - selectedBlock = NO_BLOCK_SELECTED; + selectedBlock = noBlockSelected; } restoreCurrentBlock(); emit viewRefreshed(); @@ -80,13 +80,13 @@ void SimpleTextGraphView::selectBlockWithId(ut64 blockId) } viewport()->update(); } else { - selectedBlock = NO_BLOCK_SELECTED; + selectedBlock = noBlockSelected; } } void SimpleTextGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, bool interactive) { - QRectF blockRect(block.x, block.y, block.width, block.height); + const QRectF blockRect(block.x, block.y, block.width, block.height); p.setPen(Qt::black); p.setBrush(Qt::gray); @@ -100,7 +100,7 @@ void SimpleTextGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, b p.setBrush(QColor(0, 0, 0, 100)); p.setPen(QPen(graphNodeColor, 1)); - bool blockSelected = interactive && (block.entry == selectedBlock); + const bool blockSelected = interactive && (block.entry == selectedBlock); if (blockSelected) { p.setBrush(disassemblySelectedBackgroundColor); } else { @@ -111,7 +111,7 @@ void SimpleTextGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, b // Stop rendering text when it's too small auto transform = p.combinedTransform(); - QRect screenChar = transform.mapRect(QRect(0, 0, ACharWidth, charHeight)); + const QRect screenChar = transform.mapRect(QRect(0, 0, charWidthA, charHeight)); if (screenChar.width() < Config()->getGraphMinFontSize()) { return; @@ -119,9 +119,9 @@ void SimpleTextGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, b p.setPen(palette().color(QPalette::WindowText)); // Render node text - QFontMetrics fm = QFontMetrics(p.font()); + const QFontMetrics fm = QFontMetrics(p.font()); auto x = block.x + padding / 2; - int y = block.y + padding / 2 + fm.ascent(); + const int y = block.y + padding / 2 + fm.ascent(); p.drawText(QPoint(x, y), content.text); } @@ -131,10 +131,10 @@ GraphView::EdgeConfiguration SimpleTextGraphView::edgeConfiguration(GraphView::G { EdgeConfiguration ec; ec.color = jmpColor; - ec.start_arrow = false; - ec.end_arrow = true; + ec.startArrow = false; + ec.endArrow = true; if (interactive && (selectedBlock == from.entry || selectedBlock == to->entry)) { - ec.width_scale = 2.0; + ec.widthScale = 2.0; } return ec; } @@ -143,7 +143,7 @@ void SimpleTextGraphView::setBlockSelectionEnabled(bool value) { enableBlockSelection = value; if (!value) { - selectedBlock = NO_BLOCK_SELECTED; + selectedBlock = noBlockSelected; } } @@ -153,11 +153,11 @@ void SimpleTextGraphView::addBlock(GraphLayout::GraphBlock block, const QString content.text = text; content.address = address; - int height = 1; - int width = mFontMetrics->width(text); + const int height = 1; + const int width = mFontMetrics->width(text); block.width = static_cast(width + padding); block.height = (height * charHeight) + padding; - GraphView::addBlock(std::move(block)); + GraphView::addBlock(block); } void SimpleTextGraphView::enableAddresses(bool enabled) @@ -187,7 +187,7 @@ void SimpleTextGraphView::contextMenuEvent(QContextMenuEvent *event) { GraphView::contextMenuEvent(event); if (!event->isAccepted() && event->reason() != QContextMenuEvent::Mouse && enableBlockSelection - && selectedBlock != NO_BLOCK_SELECTED) { + && selectedBlock != noBlockSelected) { auto blockIt = blocks.find(selectedBlock); if (blockIt != blocks.end()) { blockContextMenuRequested(blockIt->second, event, {}); @@ -223,7 +223,7 @@ void SimpleTextGraphView::blockHelpEvent(GraphView::GraphBlock &block, QHelpEven QPoint /*pos*/) { if (haveAddresses) { - QToolTip::showText(event->globalPos(), RzAddressString(blockContent[block.entry].address)); + QToolTip::showText(event->globalPos(), rzAddressString(blockContent[block.entry].address)); } } diff --git a/src/widgets/SimpleTextGraphView.h b/src/widgets/SimpleTextGraphView.h index a9a87bf7..a96793e2 100644 --- a/src/widgets/SimpleTextGraphView.h +++ b/src/widgets/SimpleTextGraphView.h @@ -3,15 +3,15 @@ // Based on the DisassemblerGraphView from x64dbg -#include +#include "common/CutterSeekable.h" +#include "common/RichTextPainter.h" +#include "menus/AddressableItemContextMenu.h" +#include "widgets/CutterGraphView.h" + +#include #include #include -#include - -#include "widgets/CutterGraphView.h" -#include "menus/AddressableItemContextMenu.h" -#include "common/RichTextPainter.h" -#include "common/CutterSeekable.h" +#include /** * @brief Graphview with nodes containing simple plaintext labels. @@ -77,8 +77,8 @@ protected: AddressableItemContextMenu addressableItemContextMenu; QAction copyAction; - static const ut64 NO_BLOCK_SELECTED = RVA_INVALID; - ut64 selectedBlock = NO_BLOCK_SELECTED; + static const ut64 noBlockSelected = RVA_INVALID; + ut64 selectedBlock = noBlockSelected; bool enableBlockSelection = true; bool haveAddresses = false; diff --git a/src/widgets/StackWidget.cpp b/src/widgets/StackWidget.cpp index 71b66fe4..b06ce04b 100644 --- a/src/widgets/StackWidget.cpp +++ b/src/widgets/StackWidget.cpp @@ -1,17 +1,17 @@ #include "StackWidget.h" -#include "ui_StackWidget.h" -#include "common/JsonModel.h" -#include "common/Helpers.h" -#include "dialogs/EditInstructionDialog.h" -#include "core/MainWindow.h" #include "QHeaderView" #include "QMenu" +#include "common/Helpers.h" +#include "core/MainWindow.h" +#include "dialogs/EditInstructionDialog.h" +#include "ui_StackWidget.h" StackWidget::StackWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui::StackWidget), menuText(this), + refreshDeferrer(createRefreshDeferrer([this]() { updateContents(); })), addressableItemContextMenu(this, main) { ui->setupUi(this); @@ -33,8 +33,6 @@ StackWidget::StackWidget(MainWindow *main) editAction = new QAction(tr("Edit stack value..."), this); viewStack->setContextMenuPolicy(Qt::CustomContextMenu); - refreshDeferrer = createRefreshDeferrer([this]() { updateContents(); }); - connect(Core(), &CutterCore::refreshAll, this, &StackWidget::updateContents); connect(Core(), &CutterCore::registersChanged, this, &StackWidget::updateContents); connect(Core(), &CutterCore::stackChanged, this, &StackWidget::updateContents); @@ -79,12 +77,13 @@ void StackWidget::fontsUpdatedSlot() void StackWidget::onDoubleClicked(const QModelIndex &index) { - if (!index.isValid()) + if (!index.isValid()) { return; + } // Check if we are clicking on the offset or value columns and seek if it is the case - int column = index.column(); + const int column = index.column(); if (column <= StackModel::ValueColumn) { - QString item = index.data().toString(); + const QString item = index.data().toString(); Core()->seek(item); if (column == StackModel::OffsetColumn) { mainWindow->showMemoryWidget(MemoryWidgetType::Hexdump); @@ -102,17 +101,17 @@ void StackWidget::customMenuRequested(QPoint pos) void StackWidget::editStack() { bool ok; - int row = viewStack->selectionModel()->currentIndex().row(); + const int row = viewStack->selectionModel()->currentIndex().row(); auto model = viewStack->model(); - QString offset = model->index(row, StackModel::OffsetColumn).data().toString(); + const QString offset = model->index(row, StackModel::OffsetColumn).data().toString(); EditInstructionDialog e(EDIT_NONE, this); e.setWindowTitle(tr("Edit stack at %1").arg(offset)); - QString oldBytes = model->index(row, StackModel::ValueColumn).data().toString(); + const QString oldBytes = model->index(row, StackModel::ValueColumn).data().toString(); e.setInstruction(oldBytes); if (e.exec()) { - QString bytes = e.getInstruction(); + const QString bytes = e.getInstruction(); if (bytes != oldBytes) { Core()->editBytesEndian(offset.toULongLong(&ok, 16), bytes); } @@ -132,7 +131,7 @@ void StackWidget::onCurrentChanged(const QModelIndex ¤t, const QModelIndex currentIndex.sibling(currentIndex.row(), StackModel::ValueColumn).data().toString(); } - RVA offset = Core()->math(offsetString); + const RVA offset = Core()->math(offsetString); addressableItemContextMenu.setTarget(offset); if (currentIndex.column() == StackModel::OffsetColumn) { menuText.setText(tr("Stack position")); @@ -145,7 +144,7 @@ StackModel::StackModel(QObject *parent) : QAbstractTableModel(parent) {} void StackModel::reload() { - QList stackItems = Core()->getStack(); + const QList stackItems = Core()->getStack(); beginResetModel(); values.clear(); @@ -153,8 +152,8 @@ void StackModel::reload() Item item; item.offset = stackItem.addr; - item.value = RzAddressString(stackItem.value); - if (!stackItem.ref.isNull()) { + item.value = rzAddressString(stackItem.value); + if (stackItem.ref) { item.refDesc = Core()->formatRefDesc(stackItem.ref); } @@ -175,8 +174,9 @@ int StackModel::columnCount(const QModelIndex &) const QVariant StackModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= values.count()) + if (!index.isValid() || index.row() >= values.count()) { return QVariant(); + } const auto &item = values.at(index.row()); @@ -184,7 +184,7 @@ QVariant StackModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case OffsetColumn: - return RzAddressString(item.offset); + return rzAddressString(item.offset); case ValueColumn: return item.value; case DescriptionColumn: diff --git a/src/widgets/StackWidget.h b/src/widgets/StackWidget.h index 9feb801b..ac72dc40 100644 --- a/src/widgets/StackWidget.h +++ b/src/widgets/StackWidget.h @@ -1,13 +1,15 @@ -#pragma once +#ifndef STACKWIDGET_H +#define STACKWIDGET_H + +#include "CutterDescriptions.h" +#include "CutterDockWidget.h" +#include "menus/AddressableItemContextMenu.h" #include -#include #include #include -#include "core/Cutter.h" -#include "CutterDockWidget.h" -#include "menus/AddressableItemContextMenu.h" +#include class MainWindow; @@ -15,6 +17,9 @@ namespace Ui { class StackWidget; } +/** + * @brief Source model for @ref StackWidget + */ class StackModel : public QAbstractTableModel { Q_OBJECT @@ -26,8 +31,14 @@ public: RefDescription refDesc; }; - enum Column { OffsetColumn = 0, ValueColumn, DescriptionColumn, CommentColumn, ColumnCount }; - enum Role { StackDescriptionRole = Qt::UserRole }; + enum Column : ut8 { + OffsetColumn = 0, + ValueColumn, + DescriptionColumn, + CommentColumn, + ColumnCount + }; + enum Role : ut16 { StackDescriptionRole = Qt::UserRole }; StackModel(QObject *parent = nullptr); @@ -48,6 +59,9 @@ private: }; Q_DECLARE_METATYPE(StackModel::Item) +/** + * @brief Widget listing stack information during debugging/emulation + */ class StackWidget : public CutterDockWidget { Q_OBJECT @@ -74,3 +88,5 @@ private: RefreshDeferrer *refreshDeferrer; AddressableItemContextMenu addressableItemContextMenu; }; + +#endif // STACKWIDGET_H diff --git a/src/widgets/StringsWidget.cpp b/src/widgets/StringsWidget.cpp index 575364d9..a4840d5b 100644 --- a/src/widgets/StringsWidget.cpp +++ b/src/widgets/StringsWidget.cpp @@ -1,14 +1,17 @@ #include "StringsWidget.h" -#include "ui_StringsWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" #include "shortcuts/ShortcutManager.h" +#include "ui_StringsWidget.h" #include #include #include #include +#include + StringsModel::StringsModel(QObject *parent) : AddressableItemModel(parent) {} int StringsModel::rowCount(const QModelIndex &) const @@ -23,8 +26,9 @@ int StringsModel::columnCount(const QModelIndex &) const QVariant StringsModel::data(const QModelIndex &index, int role) const { - if (index.row() >= strings.count()) + if (index.row() >= strings.count()) { return QVariant(); + } const StringDescription &str = strings.at(index.row()); @@ -32,7 +36,7 @@ QVariant StringsModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case StringsModel::OffsetColumn: - return RzAddressString(str.vaddr); + return rzAddressString(str.vaddr); case StringsModel::StringColumn: return str.string; case StringsModel::TypeColumn: @@ -48,7 +52,7 @@ QVariant StringsModel::data(const QModelIndex &index, int role) const default: return QVariant(); } - case StringDescriptionRole: + case stringDescriptionRole: return QVariant::fromValue(str); default: return QVariant(); @@ -102,19 +106,26 @@ StringsProxyModel::StringsProxyModel(StringsModel *sourceModel, QObject *parent) void StringsProxyModel::setSelectedSection(QString section) { - selectedSection = section; + +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + beginFilterChange(); +#endif + + selectedSection = std::move(section); + #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) invalidateFilter(); -#else +#elif QT_VERSION < QT_VERSION_CHECK(6, 9, 0) invalidateRowsFilter(); +#else + endFilterChange(); #endif } bool StringsProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); - StringDescription str = - index.data(StringsModel::StringDescriptionRole).value(); + const QModelIndex index = sourceModel()->index(row, 0, parent); + const auto str = index.data(StringsModel::stringDescriptionRole).value(); if (selectedSection.isEmpty()) { return qhelpers::filterStringContains(str.string, this); } else { @@ -151,7 +162,11 @@ bool StringsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &rig return leftStr->vaddr < rightStr->vaddr; } -StringsWidget::StringsWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui::StringsWidget) +StringsWidget::StringsWidget(MainWindow *main) + : CutterDockWidget(main), + ui(new Ui::StringsWidget), + model(new StringsModel(this)), + proxyModel(new StringsProxyModel(model, this)) { ui->setupUi(this); ui->quickFilterView->setLabelText(tr("Section:")); @@ -159,24 +174,22 @@ StringsWidget::StringsWidget(MainWindow *main) : CutterDockWidget(main), ui(new qhelpers::setVerticalScrollMode(ui->stringsTreeView); // Shift-F12 to toggle strings window - QShortcut *toggle_shortcut = Shortcuts()->makeQShortcut("Strings.toggle", main); - connect(toggle_shortcut, &QShortcut::activated, this, [=]() { toggleDockWidget(true); }); + const QShortcut *toggleShortcut = Shortcuts()->makeQShortcut("Strings.toggle", main); + connect(toggleShortcut, &QShortcut::activated, this, [=, this]() { toggleDockWidget(true); }); - connect(ui->actionCopy_String, &QAction::triggered, this, &StringsWidget::on_actionCopy); + connect(ui->actionCopyString, &QAction::triggered, this, &StringsWidget::onActionCopy); ui->actionFilter->setShortcut(QKeySequence::Find); ui->stringsTreeView->setContextMenuPolicy(Qt::CustomContextMenu); - model = new StringsModel(this); - proxyModel = new StringsProxyModel(model, this); ui->stringsTreeView->setMainWindow(main); - ui->stringsTreeView->setModel(proxyModel); + ui->stringsTreeView->setModel(static_cast(proxyModel)); ui->stringsTreeView->sortByColumn(-1, Qt::AscendingOrder); // auto menu = ui->stringsTreeView->getItemContextMenu(); - menu->addAction(ui->actionCopy_String); + menu->addAction(ui->actionCopyString); connect(ui->quickFilterView, &ComboQuickFilterView::filterTextChanged, proxyModel, &QSortFilterProxyModel::setFilterWildcard); @@ -221,8 +234,8 @@ void StringsWidget::refreshStrings() task->wait(); } - task = QSharedPointer(new StringsTask()); - connect(task.data(), &StringsTask::stringSearchFinished, this, + task = std::shared_ptr(new StringsTask()); + connect(task.get(), &StringsTask::stringSearchFinished, this, &StringsWidget::stringSearchFinished); Core()->getAsyncTaskManager()->start(task); @@ -252,13 +265,13 @@ void StringsWidget::stringSearchFinished(const QList &strings // set the initial item count ui->quickFilterView->setItemCount(proxyModel->rowCount()); - task.clear(); + task.reset(); } -void StringsWidget::on_actionCopy() +void StringsWidget::onActionCopy() { - QModelIndex current_item = ui->stringsTreeView->currentIndex(); - int row = current_item.row(); + const QModelIndex currentItem = ui->stringsTreeView->currentIndex(); + const int row = currentItem.row(); QModelIndex index; diff --git a/src/widgets/StringsWidget.h b/src/widgets/StringsWidget.h index d5e3d65c..1101dabd 100644 --- a/src/widgets/StringsWidget.h +++ b/src/widgets/StringsWidget.h @@ -1,16 +1,16 @@ #ifndef STRINGSWIDGET_H #define STRINGSWIDGET_H -#include - -#include "core/Cutter.h" +#include "AddressableItemModel.h" +#include "CutterDescriptions.h" #include "CutterDockWidget.h" #include "common/StringsTask.h" -#include "AddressableItemModel.h" #include #include +#include + class MainWindow; class QTreeWidgetItem; class StringsWidget; @@ -19,6 +19,9 @@ namespace Ui { class StringsWidget; } +/** + * @brief Source model for @ref StringsWidget + */ class StringsModel : public AddressableItemModel { Q_OBJECT @@ -29,7 +32,7 @@ private: QList strings; public: - enum Column { + enum Column : ut8 { OffsetColumn = 0, StringColumn, TypeColumn, @@ -39,7 +42,7 @@ public: CommentColumn, ColumnCount }; - static const int StringDescriptionRole = Qt::UserRole; + static const int stringDescriptionRole = Qt::UserRole; StringsModel(QObject *parent = nullptr); @@ -54,6 +57,9 @@ public: const StringDescription *description(const QModelIndex &index) const; }; +/** + * @brief Proxy model for @ref StringsWidget + */ class StringsProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -69,6 +75,9 @@ protected: QString selectedSection; }; +/** + * @brief Widget listing all of the strings in binary + */ class StringsWidget : public CutterDockWidget { Q_OBJECT @@ -82,12 +91,12 @@ private slots: void stringSearchFinished(const QList &strings); void refreshSectionCombo(); - void on_actionCopy(); + void onActionCopy(); private: std::unique_ptr ui; - QSharedPointer task; + std::shared_ptr task; StringsModel *model; StringsProxyModel *proxyModel; diff --git a/src/widgets/StringsWidget.ui b/src/widgets/StringsWidget.ui index 6eb97a78..4dd3c59d 100644 --- a/src/widgets/StringsWidget.ui +++ b/src/widgets/StringsWidget.ui @@ -46,7 +46,7 @@ } - QFrame::NoFrame + QFrame::Shape::NoFrame 0 @@ -71,7 +71,7 @@ - + Copy String diff --git a/src/widgets/SymbolsWidget.cpp b/src/widgets/SymbolsWidget.cpp index c95e521d..0f06ec09 100644 --- a/src/widgets/SymbolsWidget.cpp +++ b/src/widgets/SymbolsWidget.cpp @@ -1,7 +1,8 @@ #include "SymbolsWidget.h" -#include "ui_ListDockWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" +#include "ui_ListDockWidget.h" #include @@ -29,7 +30,7 @@ QVariant SymbolsModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case SymbolsModel::AddressColumn: - return RzAddressString(symbol.vaddr); + return rzAddressString(symbol.vaddr); case SymbolsModel::TypeColumn: return QString("%1 %2").arg(symbol.bind, symbol.type).trimmed(); case SymbolsModel::NameColumn: @@ -88,7 +89,7 @@ SymbolsProxyModel::SymbolsProxyModel(SymbolsModel *sourceModel, QObject *parent) bool SymbolsProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); + const QModelIndex index = sourceModel()->index(row, 0, parent); auto symbol = index.data(SymbolsModel::SymbolDescriptionRole).value(); return qhelpers::filterStringContains(symbol.name, this); @@ -115,13 +116,14 @@ bool SymbolsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &rig return false; } -SymbolsWidget::SymbolsWidget(MainWindow *main) : ListDockWidget(main) +SymbolsWidget::SymbolsWidget(MainWindow *main) + : ListDockWidget(main), + symbolsModel(new SymbolsModel(this)), + symbolsProxyModel(new SymbolsProxyModel(symbolsModel, this)) { setWindowTitle(tr("Symbols")); setObjectName("SymbolsWidget"); - symbolsModel = new SymbolsModel(this); - symbolsProxyModel = new SymbolsProxyModel(symbolsModel, this); setModels(symbolsProxyModel); ui->treeView->sortByColumn(SymbolsModel::AddressColumn, Qt::AscendingOrder); diff --git a/src/widgets/SymbolsWidget.h b/src/widgets/SymbolsWidget.h index c9913e74..e11f7b29 100644 --- a/src/widgets/SymbolsWidget.h +++ b/src/widgets/SymbolsWidget.h @@ -1,18 +1,20 @@ #ifndef SYMBOLSWIDGET_H #define SYMBOLSWIDGET_H -#include -#include -#include - -#include "core/Cutter.h" +#include "CutterDescriptions.h" #include "CutterDockWidget.h" #include "widgets/ListDockWidget.h" +#include +#include + class MainWindow; class QTreeWidgetItem; class SymbolsWidget; +/** + * @brief Source model for @ref SymbolsWidget + */ class SymbolsModel : public AddressableItemModel { Q_OBJECT @@ -23,8 +25,8 @@ private: QList symbols; public: - enum Column { AddressColumn = 0, TypeColumn, NameColumn, CommentColumn, ColumnCount }; - enum Role { SymbolDescriptionRole = Qt::UserRole }; + enum Column : ut8 { AddressColumn = 0, TypeColumn, NameColumn, CommentColumn, ColumnCount }; + enum Role : ut16 { SymbolDescriptionRole = Qt::UserRole }; SymbolsModel(QObject *parent = nullptr); @@ -39,6 +41,9 @@ public: QString name(const QModelIndex &index) const override; }; +/** + * @brief Proxy model for @ref SymbolsWidget + */ class SymbolsProxyModel : public AddressableFilterProxyModel { Q_OBJECT @@ -51,6 +56,9 @@ protected: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; +/** + * @brief Widget listing all symbols in binary + */ class SymbolsWidget : public ListDockWidget { Q_OBJECT diff --git a/src/widgets/ThreadsWidget.cpp b/src/widgets/ThreadsWidget.cpp index 7992b5c0..483a7312 100644 --- a/src/widgets/ThreadsWidget.cpp +++ b/src/widgets/ThreadsWidget.cpp @@ -1,20 +1,23 @@ -#include #include "ThreadsWidget.h" + #include "CutterCommon.h" #include "Helpers.h" -#include "ui_ThreadsWidget.h" #include "QuickFilterView.h" -#include - #include "core/MainWindow.h" #include "shortcuts/ShortcutManager.h" +#include "ui_ThreadsWidget.h" + +#include + +#include +#include ThreadModel::ThreadModel(QObject *parent) : QAbstractListModel(parent) {} void ThreadModel::setList(QList data) { beginResetModel(); - this->threads = data; + this->threads = std::move(data); endResetModel(); } @@ -30,8 +33,9 @@ int ThreadModel::columnCount(const QModelIndex &) const QVariant ThreadModel::data(const QModelIndex &index, int role) const { - if (index.row() >= threads.count()) + if (index.row() >= threads.count()) { return QVariant(); + } const ThreadDescription &thread = threads.at(index.row()); @@ -45,9 +49,9 @@ QVariant ThreadModel::data(const QModelIndex &index, int role) const case ColumnIndex::COLUMN_PATH: return thread.path; case ColumnIndex::COLUMN_PC: - return RzAddressString(thread.pc); + return rzAddressString(thread.pc); case ColumnIndex::COLUMN_TLS: - return RzAddressString(thread.tls); + return rzAddressString(thread.tls); default: return QVariant(); } @@ -102,19 +106,20 @@ QVariant ThreadModel::headerData(int section, Qt::Orientation, int role) const ThreadsWidget::ThreadsWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui::ThreadsWidget), + modelThreads(new ThreadModel(this)), + modelFilter(new QSortFilterProxyModel(this)), + refreshDeferrer(createRefreshDeferrer([this]() { updateContents(); })), menuText(this), addressableItemContextMenu(this, main) { ui->setupUi(this); // Setup threads model - modelThreads = new ThreadModel(this); ui->viewThreads->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); ui->viewThreads->verticalHeader()->setVisible(false); fontsUpdatedSlot(); - modelFilter = new QSortFilterProxyModel(this); modelFilter->setSourceModel(modelThreads); modelFilter->setFilterCaseSensitivity(Qt::CaseInsensitive); @@ -139,8 +144,6 @@ ThreadsWidget::ThreadsWidget(MainWindow *main) }); clearShortcut->setContext(Qt::WidgetWithChildrenShortcut); - refreshDeferrer = createRefreshDeferrer([this]() { updateContents(); }); - menuText.setSeparator(true); qhelpers::prependQAction(&menuText, &addressableItemContextMenu); @@ -216,11 +219,13 @@ void ThreadsWidget::fontsUpdatedSlot() void ThreadsWidget::onActivated(const QModelIndex &index) { - if (!index.isValid()) + if (!index.isValid()) { return; + } - int tid = modelFilter->data(index.sibling(index.row(), ThreadModel::COLUMN_PID), Qt::EditRole) - .toInt(); + const int tid = + modelFilter->data(index.sibling(index.row(), ThreadModel::COLUMN_PID), Qt::EditRole) + .toInt(); // Verify that the selected tid is still in the threads list since dpt= will // attach to any given id. If it isn't found simply update the UI. @@ -241,12 +246,12 @@ void ThreadsWidget::onCurrentChanged(const QModelIndex ¤t, const QModelInd RVA offset = 0; if (current.column() == ThreadModel::ColumnIndex::COLUMN_TLS) { offset = current.data(Qt::EditRole).toULongLong(); - menuText.setText(tr("TLS (%0)").arg(RzAddressString(offset))); + menuText.setText(tr("TLS (%0)").arg(rzAddressString(offset))); } else { offset = current.sibling(current.row(), ThreadModel::ColumnIndex::COLUMN_PC) .data(Qt::EditRole) .toULongLong(); - menuText.setText(tr("PC (%0)").arg(RzAddressString(offset))); + menuText.setText(tr("PC (%0)").arg(rzAddressString(offset))); } addressableItemContextMenu.setTarget(offset); diff --git a/src/widgets/ThreadsWidget.h b/src/widgets/ThreadsWidget.h index 8a3ff5ac..954cf997 100644 --- a/src/widgets/ThreadsWidget.h +++ b/src/widgets/ThreadsWidget.h @@ -1,18 +1,23 @@ -#pragma once +#ifndef THREADSWIDGET_H +#define THREADSWIDGET_H -#include - -#include "core/Cutter.h" #include "AddressableItemContextMenu.h" #include "CutterDescriptions.h" #include "CutterDockWidget.h" +#include + +#include + class MainWindow; namespace Ui { class ThreadsWidget; } +/** + * @brief Source model for @ref ThreadsWidget + */ class ThreadModel : public QAbstractListModel { Q_OBJECT @@ -23,7 +28,7 @@ private: QList threads; public: - enum ColumnIndex { + enum ColumnIndex : ut8 { COLUMN_PID = 0, COLUMN_STATUS, COLUMN_PATH, @@ -48,6 +53,9 @@ public: QString translateStatus(const char status) const; }; +/** + * @brief Widget listing info about threads during debugging/emulating + */ class ThreadsWidget : public CutterDockWidget { Q_OBJECT @@ -71,3 +79,5 @@ private: QAction menuText; AddressableItemContextMenu addressableItemContextMenu; }; + +#endif // THREADSWIDGET_H \ No newline at end of file diff --git a/src/widgets/TypesWidget.cpp b/src/widgets/TypesWidget.cpp index 7763a73e..cfe88a66 100644 --- a/src/widgets/TypesWidget.cpp +++ b/src/widgets/TypesWidget.cpp @@ -1,21 +1,24 @@ #include "TypesWidget.h" -#include "ui_TypesWidget.h" -#include "core/MainWindow.h" + #include "common/Helpers.h" +#include "core/MainWindow.h" #include "dialogs/TypesInteractionDialog.h" #include "dialogs/TypesVariablesDialog.h" #include "shortcuts/ShortcutManager.h" +#include "ui_TypesWidget.h" -#include #include -#include #include +#include +#include + +#include TypesModel::TypesModel(QObject *parent) : QAbstractListModel(parent) {} QVariant TypesModel::toolTipValue(const QModelIndex &index) const { - TypeDescription t = index.data(TypesModel::TypeDescriptionRole).value(); + const auto t = index.data(TypesModel::typeDescriptionRole).value(); if (t.category == "Primitive") { return QVariant(); @@ -36,8 +39,9 @@ int TypesModel::columnCount(const QModelIndex &) const QVariant TypesModel::data(const QModelIndex &index, int role) const { - if (index.row() >= types.count()) + if (index.row() >= types.count()) { return QVariant(); + } const TypeDescription &exp = types.at(index.row()); @@ -57,7 +61,7 @@ QVariant TypesModel::data(const QModelIndex &index, int role) const } case Qt::ToolTipRole: return toolTipValue(index); - case TypeDescriptionRole: + case typeDescriptionRole: return QVariant::fromValue(exp); default: return QVariant(); @@ -106,18 +110,15 @@ TypesSortFilterProxyModel::TypesSortFilterProxyModel(TypesModel *source_model, Q void TypesSortFilterProxyModel::setCategory(QString category) { - selectedCategory = category; -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - invalidateFilter(); -#else - invalidateRowsFilter(); -#endif + beginResetModel(); + selectedCategory = std::move(category); + endResetModel(); } bool TypesSortFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const { - QModelIndex index = sourceModel()->index(row, 0, parent); - TypeDescription exp = index.data(TypesModel::TypeDescriptionRole).value(); + const QModelIndex index = sourceModel()->index(row, 0, parent); + const auto exp = index.data(TypesModel::typeDescriptionRole).value(); if (!selectedCategory.isEmpty() && selectedCategory != exp.category) { return false; } @@ -126,27 +127,30 @@ bool TypesSortFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &par bool TypesSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - TypeDescription left_exp = left.data(TypesModel::TypeDescriptionRole).value(); - TypeDescription right_exp = - right.data(TypesModel::TypeDescriptionRole).value(); + const auto leftExp = left.data(TypesModel::typeDescriptionRole).value(); + const auto rightExp = right.data(TypesModel::typeDescriptionRole).value(); switch (left.column()) { case TypesModel::TYPE: - return left_exp.type < right_exp.type; + return leftExp.type < rightExp.type; case TypesModel::SIZE: - return left_exp.size < right_exp.size; + return leftExp.size < rightExp.size; case TypesModel::FORMAT: - return left_exp.format < right_exp.format; + return leftExp.format < rightExp.format; case TypesModel::CATEGORY: - return left_exp.category < right_exp.category; + return leftExp.category < rightExp.category; default: break; } - return left_exp.size < right_exp.size; + return leftExp.size < rightExp.size; } -TypesWidget::TypesWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui::TypesWidget) +TypesWidget::TypesWidget(MainWindow *main) + : CutterDockWidget(main), + ui(new Ui::TypesWidget), + typesModel(new TypesModel(this)), + typesProxyModel(new TypesSortFilterProxyModel(typesModel, this)) { ui->setupUi(this); ui->quickFilterView->setLabelText(tr("Category")); @@ -155,9 +159,8 @@ TypesWidget::TypesWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui:: ui->typesTreeView->setSelectionMode(QAbstractItemView::SingleSelection); // Setup up the model and the proxy model - types_model = new TypesModel(this); - types_proxy_model = new TypesSortFilterProxyModel(types_model, this); - ui->typesTreeView->setModel(types_proxy_model); + + ui->typesTreeView->setModel(typesProxyModel); ui->typesTreeView->sortByColumn(TypesModel::TYPE, Qt::AscendingOrder); setScrollMode(); @@ -168,11 +171,11 @@ TypesWidget::TypesWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui:: ui->typesTreeView->setContextMenuPolicy(Qt::CustomContextMenu); - connect(ui->quickFilterView, &ComboQuickFilterView::filterTextChanged, types_proxy_model, + connect(ui->quickFilterView, &ComboQuickFilterView::filterTextChanged, typesProxyModel, &QSortFilterProxyModel::setFilterWildcard); connect(ui->quickFilterView, &ComboQuickFilterView::filterTextChanged, this, - [this] { ui->quickFilterView->setItemCount(types_proxy_model->rowCount()); }); + [this] { ui->quickFilterView->setItemCount(typesProxyModel->rowCount()); }); QShortcut *searchShortcut = Shortcuts()->makeQShortcut("General.showFilter", this); connect(searchShortcut, &QShortcut::activated, ui->quickFilterView, @@ -187,8 +190,8 @@ TypesWidget::TypesWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui:: connect(Core(), &CutterCore::refreshAll, this, &TypesWidget::refreshTypes); connect(ui->quickFilterView->comboBox(), &QComboBox::currentTextChanged, this, [this]() { - types_proxy_model->setCategory(ui->quickFilterView->comboBox()->currentData().toString()); - ui->quickFilterView->setItemCount(types_proxy_model->rowCount()); + typesProxyModel->setCategory(ui->quickFilterView->comboBox()->currentData().toString()); + ui->quickFilterView->setItemCount(typesProxyModel->rowCount()); }); actionViewType = new QAction(tr("View Type"), this); @@ -201,25 +204,32 @@ TypesWidget::TypesWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui:: &TypesWidget::typeItemDoubleClicked); connect(actionShowVariables, &QAction::triggered, [this]() { showVariables(); }); + + connect(ui->actionExportTypes, &QAction::triggered, this, + &TypesWidget::onActionExportTypesTriggered); + connect(ui->actionLoadNewTypes, &QAction::triggered, this, + &TypesWidget::onActionLoadNewTypesTriggered); + connect(ui->actionDeleteType, &QAction::triggered, this, + &TypesWidget::onActionDeleteTypeTriggered); } TypesWidget::~TypesWidget() {} void TypesWidget::refreshTypes() { - types_model->beginResetModel(); - types_model->types = Core()->getAllTypes(); - types_model->endResetModel(); + typesModel->beginResetModel(); + typesModel->types = Core()->getAllTypes(); + typesModel->endResetModel(); QStringList categories; - for (const TypeDescription &exp : types_model->types) { + for (const TypeDescription &exp : std::as_const(typesModel->types)) { categories << exp.category; } categories.removeDuplicates(); refreshCategoryCombo(categories); // set the initial count - ui->quickFilterView->setItemCount(types_proxy_model->rowCount()); + ui->quickFilterView->setItemCount(typesProxyModel->rowCount()); qhelpers::adjustColumns(ui->typesTreeView, 4, 0); } @@ -235,7 +245,7 @@ void TypesWidget::refreshCategoryCombo(const QStringList &categories) combo->addItem(category, category); } - types_proxy_model->setCategory(QString()); + typesProxyModel->setCategory(QString()); } void TypesWidget::setScrollMode() @@ -245,13 +255,13 @@ void TypesWidget::setScrollMode() void TypesWidget::showTypesContextMenu(const QPoint &pt) { - QModelIndex index = ui->typesTreeView->indexAt(pt); + const QModelIndex index = ui->typesTreeView->indexAt(pt); QMenu menu(ui->typesTreeView); - menu.addAction(ui->actionLoad_New_Types); + menu.addAction(ui->actionLoadNewTypes); if (index.isValid()) { - TypeDescription t = index.data(TypesModel::TypeDescriptionRole).value(); + const auto t = index.data(TypesModel::typeDescriptionRole).value(); if (t.category != "Primitive") { // Add "Link To Address" option menu.addAction(actionViewType); @@ -260,27 +270,27 @@ void TypesWidget::showTypesContextMenu(const QPoint &pt) } } - menu.addAction(ui->actionExport_Types); + menu.addAction(ui->actionExportTypes); if (index.isValid()) { - TypeDescription t = index.data(TypesModel::TypeDescriptionRole).value(); + const auto t = index.data(TypesModel::typeDescriptionRole).value(); if (t.category != "Typedef") { menu.addSeparator(); - menu.addAction(ui->actionDelete_Type); + menu.addAction(ui->actionDeleteType); } } menu.exec(ui->typesTreeView->mapToGlobal(pt)); } -void TypesWidget::on_actionExport_Types_triggered() +void TypesWidget::onActionExportTypesTriggered() { auto core = Core()->lock(); char *str = rz_core_types_as_c_all(core, true); if (!str) { return; } - QString filename = + const QString filename = QFileDialog::getSaveFileName(this, tr("Save File"), Config()->getRecentFolder()); if (filename.isEmpty()) { return; @@ -289,7 +299,7 @@ void TypesWidget::on_actionExport_Types_triggered() QFile file(filename); if (!file.open(QIODevice::WriteOnly)) { QMessageBox::critical(this, tr("Error"), file.errorString()); - on_actionExport_Types_triggered(); + onActionExportTypesTriggered(); return; } QTextStream fileOut(&file); @@ -298,14 +308,14 @@ void TypesWidget::on_actionExport_Types_triggered() file.close(); } -void TypesWidget::on_actionLoad_New_Types_triggered() +void TypesWidget::onActionLoadNewTypesTriggered() { - QModelIndex index = ui->typesTreeView->currentIndex(); + const QModelIndex index = ui->typesTreeView->currentIndex(); if (!index.isValid()) { return; } - TypeDescription t = index.data(TypesModel::TypeDescriptionRole).value(); + const auto t = index.data(TypesModel::typeDescriptionRole).value(); TypesInteractionDialog dialog(this); connect(&dialog, &TypesInteractionDialog::newTypesLoaded, this, &TypesWidget::refreshTypes); @@ -316,14 +326,14 @@ void TypesWidget::on_actionLoad_New_Types_triggered() void TypesWidget::viewType(bool readOnly) { - QModelIndex index = ui->typesTreeView->currentIndex(); + const QModelIndex index = ui->typesTreeView->currentIndex(); if (!index.isValid()) { return; } TypesInteractionDialog dialog(this, readOnly); - TypeDescription t = index.data(TypesModel::TypeDescriptionRole).value(); + const auto t = index.data(TypesModel::typeDescriptionRole).value(); if (!readOnly) { dialog.setWindowTitle(tr("Edit Type: ") + t.type); connect(&dialog, &TypesInteractionDialog::newTypesLoaded, this, &TypesWidget::refreshTypes); @@ -335,22 +345,22 @@ void TypesWidget::viewType(bool readOnly) dialog.exec(); } -void TypesWidget::on_actionDelete_Type_triggered() +void TypesWidget::onActionDeleteTypeTriggered() { - QModelIndex proxyIndex = ui->typesTreeView->currentIndex(); + const QModelIndex proxyIndex = ui->typesTreeView->currentIndex(); if (!proxyIndex.isValid()) { return; } - QModelIndex index = types_proxy_model->mapToSource(proxyIndex); + const QModelIndex index = typesProxyModel->mapToSource(proxyIndex); if (!index.isValid()) { return; } - TypeDescription exp = index.data(TypesModel::TypeDescriptionRole).value(); - QMessageBox::StandardButton reply = QMessageBox::question( + const auto exp = index.data(TypesModel::typeDescriptionRole).value(); + const QMessageBox::StandardButton reply = QMessageBox::question( this, tr("Cutter"), tr("Are you sure you want to delete \"%1\"?").arg(exp.type)); if (reply == QMessageBox::Yes) { - types_model->removeRow(index.row()); + typesModel->removeRow(index.row()); } } @@ -361,7 +371,7 @@ void TypesWidget::typeItemDoubleClicked(const QModelIndex &index) } TypesInteractionDialog dialog(this, true); - TypeDescription t = index.data(TypesModel::TypeDescriptionRole).value(); + const auto t = index.data(TypesModel::typeDescriptionRole).value(); if (t.category == "Primitive") { return; } @@ -373,12 +383,12 @@ void TypesWidget::typeItemDoubleClicked(const QModelIndex &index) void TypesWidget::showVariables() { - QModelIndex index = ui->typesTreeView->currentIndex(); + const QModelIndex index = ui->typesTreeView->currentIndex(); if (!index.isValid()) { return; } - TypeDescription t = index.data(TypesModel::TypeDescriptionRole).value(); + const auto t = index.data(TypesModel::typeDescriptionRole).value(); TypesVariablesDialog tvd(this, t.type); tvd.exec(); @@ -390,32 +400,32 @@ void TypesWidget::selectTypeByName(const QString &typeName) return; } - QModelIndexList results = types_proxy_model->match( - types_proxy_model->index(0, 0), Qt::DisplayRole, typeName, 1, Qt::MatchExactly); + QModelIndexList results = typesProxyModel->match(typesProxyModel->index(0, 0), Qt::DisplayRole, + typeName, 1, Qt::MatchExactly); // if results are empty, remove the filter and try again // avoids removing the filter unnecessarily bool isTextFilterEmpty; #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - isTextFilterEmpty = types_proxy_model->filterRegExp().pattern().isEmpty(); + isTextFilterEmpty = typesProxyModel->filterRegExp().pattern().isEmpty(); #else - isTextFilterEmpty = types_proxy_model->filterRegularExpression().pattern().isEmpty(); + isTextFilterEmpty = typesProxyModel->filterRegularExpression().pattern().isEmpty(); #endif if (results.isEmpty() && (!isTextFilterEmpty || ui->quickFilterView->comboBox()->currentIndex() != 0)) { ui->quickFilterView->clearFilter(); ui->quickFilterView->comboBox()->setCurrentIndex(0); // select (All) - types_proxy_model->setFilterFixedString(""); - results = types_proxy_model->match(types_proxy_model->index(0, 0), Qt::DisplayRole, - typeName, 1, Qt::MatchExactly); + typesProxyModel->setFilterFixedString(""); + results = typesProxyModel->match(typesProxyModel->index(0, 0), Qt::DisplayRole, typeName, 1, + Qt::MatchExactly); } if (results.isEmpty()) { return; } - QModelIndex index = results.first(); + const QModelIndex index = results.first(); ui->typesTreeView->setCurrentIndex(index); ui->typesTreeView->selectionModel()->select( index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); diff --git a/src/widgets/TypesWidget.h b/src/widgets/TypesWidget.h index 9b02d169..99f6f8c8 100644 --- a/src/widgets/TypesWidget.h +++ b/src/widgets/TypesWidget.h @@ -1,14 +1,14 @@ #ifndef TYPESWIDGET_H #define TYPESWIDGET_H -#include - -#include "core/Cutter.h" +#include "CutterDescriptions.h" #include "CutterDockWidget.h" #include #include +#include + class MainWindow; class QTreeWidget; class TypesWidget; @@ -20,6 +20,9 @@ class TypesWidget; class MainWindow; class QTreeWidgetItem; +/** + * @brief Source model for @ref TypesWidget + */ class TypesModel : public QAbstractListModel { Q_OBJECT @@ -35,8 +38,8 @@ private: QVariant toolTipValue(const QModelIndex &index) const; public: - enum Columns { TYPE = 0, SIZE, CATEGORY, FORMAT, COUNT }; - static const int TypeDescriptionRole = Qt::UserRole; + enum Columns : ut8 { TYPE = 0, SIZE, CATEGORY, FORMAT, COUNT }; + static const int typeDescriptionRole = Qt::UserRole; TypesModel(QObject *parent = nullptr); @@ -65,6 +68,9 @@ protected: QString selectedCategory; }; +/** + * @brief Widget for listing all types + */ class TypesWidget : public CutterDockWidget { Q_OBJECT @@ -94,14 +100,14 @@ private slots: * It shows the user a file dialog box to select a file where the types * will be exported. */ - void on_actionExport_Types_triggered(); + void onActionExportTypesTriggered(); /** * @brief Executed on clicking the Load New types option in the context menu * It will open the TypesInteractionDialog where the user can either enter the * types manually, or can select a file from where the types will be loaded */ - void on_actionLoad_New_Types_triggered(); + void onActionLoadNewTypesTriggered(); /** * @brief Executed on clicking either the Edit Type or View Type options in the context menu @@ -114,7 +120,7 @@ private slots: * @brief Executed on clicking the Delete Type option in the context menu * Upon confirmation from the user, it will delete the selected type. */ - void on_actionDelete_Type_triggered(); + void onActionDeleteTypeTriggered(); /** * @brief triggers when the user double-clicks an item. This will open @@ -131,8 +137,8 @@ private slots: private: std::unique_ptr ui; - TypesModel *types_model; - TypesSortFilterProxyModel *types_proxy_model; + TypesModel *typesModel; + TypesSortFilterProxyModel *typesProxyModel; QAction *actionViewType; QAction *actionEditType; QAction *actionShowVariables; diff --git a/src/widgets/TypesWidget.ui b/src/widgets/TypesWidget.ui index c333cd95..4431e970 100644 --- a/src/widgets/TypesWidget.ui +++ b/src/widgets/TypesWidget.ui @@ -46,7 +46,7 @@ } - QFrame::NoFrame + QFrame::Shape::NoFrame 0 @@ -71,7 +71,7 @@ - + Export Types @@ -79,7 +79,7 @@ Export Types - + Load New Types @@ -87,7 +87,7 @@ Load New Types - + Delete Type diff --git a/src/widgets/VTablesWidget.cpp b/src/widgets/VTablesWidget.cpp index fa0d93f0..3d5dc90b 100644 --- a/src/widgets/VTablesWidget.cpp +++ b/src/widgets/VTablesWidget.cpp @@ -1,13 +1,13 @@ -#include -#include - -#include "core/MainWindow.h" -#include "common/Helpers.h" -#include "shortcuts/ShortcutManager.h" - #include "VTablesWidget.h" + +#include "common/Helpers.h" +#include "core/MainWindow.h" +#include "shortcuts/ShortcutManager.h" #include "ui_VTablesWidget.h" +#include +#include + VTableModel::VTableModel(QObject *parent) : QAbstractItemModel(parent) {} QModelIndex VTableModel::index(int row, int column, const QModelIndex &parent) const @@ -36,7 +36,7 @@ int VTableModel::columnCount(const QModelIndex &) const QVariant VTableModel::data(const QModelIndex &index, int role) const { - QModelIndex parent = index.parent(); + const QModelIndex parent = index.parent(); if (parent.isValid()) { const BinClassMethodDescription &res = vtables.at(parent.row()).methods.at(index.row()); switch (role) { @@ -45,31 +45,32 @@ QVariant VTableModel::data(const QModelIndex &index, int role) const case NAME: return res.name.isEmpty() ? tr("No Name found") : res.name; case ADDRESS: - return RzAddressString(res.addr); + return rzAddressString(res.addr); } break; - case VTableDescriptionRole: + case vTableDescriptionRole: return QVariant::fromValue(res); default: break; } - } else + } else { switch (role) { case Qt::DisplayRole: switch (index.column()) { case NAME: return tr("VTable") + " " + QString::number(index.row() + 1); case ADDRESS: - return RzAddressString(vtables.at(index.row()).addr); + return rzAddressString(vtables.at(index.row()).addr); } break; - case VTableDescriptionRole: { + case vTableDescriptionRole: { const VTableDescription &res = vtables.at(index.row()); return QVariant::fromValue(res); } default: break; } + } return QVariant(); } @@ -107,44 +108,50 @@ VTableSortFilterProxyModel::VTableSortFilterProxyModel(VTableModel *model, QObje bool VTableSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { - if (QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent)) + if (QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent)) { return true; - if (source_parent.isValid()) + } + if (source_parent.isValid()) { return QSortFilterProxyModel::filterAcceptsRow(source_parent.row(), QModelIndex()); + } #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) else { QAbstractItemModel *const model = sourceModel(); const QModelIndex source = model->index(source_row, 0, QModelIndex()); const int rows = model->rowCount(source); - for (int i = 0; i < rows; ++i) - if (QSortFilterProxyModel::filterAcceptsRow(i, source)) + for (int i = 0; i < rows; ++i) { + if (QSortFilterProxyModel::filterAcceptsRow(i, source)) { return true; + } + } } #endif return false; } -VTablesWidget::VTablesWidget(MainWindow *main) : CutterDockWidget(main), ui(new Ui::VTablesWidget) +VTablesWidget::VTablesWidget(MainWindow *main) + : CutterDockWidget(main), + ui(new Ui::VTablesWidget), + model(new VTableModel(this)), + proxy(new VTableSortFilterProxyModel(model, this)), + refreshDeferrer(createRefreshDeferrer([this]() { refreshVTables(); })) { ui->setupUi(this); - model = new VTableModel(this); - proxy = new VTableSortFilterProxyModel(model, this); - ui->vTableTreeView->setModel(proxy); ui->vTableTreeView->sortByColumn(VTableModel::ADDRESS, Qt::AscendingOrder); // Esc to clear the filter entry - QShortcut *clear_shortcut = Shortcuts()->makeQShortcut("General.clearFilter", this); - connect(clear_shortcut, &QShortcut::activated, ui->quickFilterView, + QShortcut *clearShortcut = Shortcuts()->makeQShortcut("General.clearFilter", this); + connect(clearShortcut, &QShortcut::activated, ui->quickFilterView, &QuickFilterView::clearFilter); - clear_shortcut->setContext(Qt::WidgetWithChildrenShortcut); + clearShortcut->setContext(Qt::WidgetWithChildrenShortcut); // Ctrl-F to show/hide the filter entry - QShortcut *search_shortcut = Shortcuts()->makeQShortcut("General.showFilter", this); - connect(search_shortcut, &QShortcut::activated, ui->quickFilterView, + QShortcut *searchShortcut = Shortcuts()->makeQShortcut("General.showFilter", this); + connect(searchShortcut, &QShortcut::activated, ui->quickFilterView, &QuickFilterView::showFilter); - search_shortcut->setContext(Qt::WidgetWithChildrenShortcut); + searchShortcut->setContext(Qt::WidgetWithChildrenShortcut); connect(ui->quickFilterView, &QuickFilterView::filterTextChanged, proxy, &QSortFilterProxyModel::setFilterWildcard); @@ -157,7 +164,8 @@ VTablesWidget::VTablesWidget(MainWindow *main) : CutterDockWidget(main), ui(new connect(Core(), &CutterCore::codeRebased, this, &VTablesWidget::refreshVTables); connect(Core(), &CutterCore::refreshAll, this, &VTablesWidget::refreshVTables); - refreshDeferrer = createRefreshDeferrer([this]() { refreshVTables(); }); + connect(ui->vTableTreeView, &QTreeView::doubleClicked, this, + &VTablesWidget::onVTableTreeViewDoubleClicked); } VTablesWidget::~VTablesWidget() {} @@ -180,19 +188,19 @@ void VTablesWidget::refreshVTables() ui->quickFilterView->setItemCount(proxy->rowCount()); } -void VTablesWidget::on_vTableTreeView_doubleClicked(const QModelIndex &index) +void VTablesWidget::onVTableTreeViewDoubleClicked(const QModelIndex &index) { if (!index.isValid()) { return; } - QModelIndex parent = index.parent(); + const QModelIndex parent = index.parent(); if (parent.isValid()) { - Core()->seekAndShow(index.data(VTableModel::VTableDescriptionRole) + Core()->seekAndShow(index.data(VTableModel::vTableDescriptionRole) .value() .addr); } else { Core()->seekAndShow( - index.data(VTableModel::VTableDescriptionRole).value().addr); + index.data(VTableModel::vTableDescriptionRole).value().addr); } } diff --git a/src/widgets/VTablesWidget.h b/src/widgets/VTablesWidget.h index 19a60688..8c13c1ce 100644 --- a/src/widgets/VTablesWidget.h +++ b/src/widgets/VTablesWidget.h @@ -1,14 +1,14 @@ #ifndef VTABLESWIDGET_H #define VTABLESWIDGET_H -#include - -#include -#include - -#include "core/Cutter.h" +#include "CutterDescriptions.h" #include "CutterDockWidget.h" +#include +#include + +#include + namespace Ui { class VTablesWidget; } @@ -16,6 +16,9 @@ class VTablesWidget; class MainWindow; class VTablesWidget; +/** + * @brief Source model for @ref VTablesWidget + */ class VTableModel : public QAbstractItemModel { Q_OBJECT @@ -26,8 +29,8 @@ private: QList vtables; public: - enum Columns { NAME = 0, ADDRESS, COUNT }; - static const int VTableDescriptionRole = Qt::UserRole; + enum Columns : ut8 { NAME = 0, ADDRESS, COUNT }; + static const int vTableDescriptionRole = Qt::UserRole; VTableModel(QObject *parent = nullptr); @@ -41,6 +44,9 @@ public: QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; }; +/** + * @brief Proxy model for @ref VTablesWidget + */ class VTableSortFilterProxyModel : public QSortFilterProxyModel { public: @@ -50,6 +56,9 @@ protected: bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; }; +/** + * @brief Widget for listing C++ Virtual Tables (vtables) and their methods + */ class VTablesWidget : public CutterDockWidget { Q_OBJECT @@ -60,7 +69,7 @@ public: private slots: void refreshVTables(); - void on_vTableTreeView_doubleClicked(const QModelIndex &index); + void onVTableTreeViewDoubleClicked(const QModelIndex &index); private: std::unique_ptr ui; diff --git a/src/widgets/VisualNavbar.cpp b/src/widgets/VisualNavbar.cpp index 584be4f7..3265f1d9 100644 --- a/src/widgets/VisualNavbar.cpp +++ b/src/widgets/VisualNavbar.cpp @@ -1,44 +1,47 @@ #include "VisualNavbar.h" -#include "core/MainWindow.h" -#include "common/TempConfig.h" -#include +#include "core/Cutter.h" +#include "core/MainWindow.h" + #include -#include #include +#include +#include +#include #include #include -#include #include -#include -#include #include +#include +#include #include #include -static const int NAVBAR_HEIGHT = 15; -static const int LEGEND_HEIGHT = 25; -static const int TOTAL_HEIGHT = NAVBAR_HEIGHT + LEGEND_HEIGHT; +namespace { +const int navbarHeight = 15; +const int legendHeight = 25; +const int totalHeight = navbarHeight + legendHeight; -static const int LEGEND_BOX_SIZE = 16; -static const int LEGEND_BOX_Y_OFFSET = 7; // Relative to navbar bottom -static const int LEGEND_TEXT_X_OFFSET = 17; -static const int LEGEND_TEXT_Y_OFFSET = -5; -static const int LEGEND_ITEM_SPACING = 30; +const int legendBoxSize = 16; +const int legendBoxYOffset = 7; // Relative to navbar bottom +const int legendTextXOffset = 17; +const int legendTextYOffset = -5; +const int legendItemSpacing = 30; +} VisualNavbar::VisualNavbar(MainWindow *main, QWidget *parent) : QToolBar(main), graphicsView(new QGraphicsView), + graphicsScene(new QGraphicsScene(this)), seekGraphicsItem(nullptr), - PCGraphicsItem(nullptr), + pcGraphicsItem(nullptr), legendItem(nullptr), - main(main) + main(main), + blockTooltip(false) { Q_UNUSED(parent); - blockTooltip = false; - setObjectName("visualNavbar"); setWindowTitle(tr("Visual navigation bar")); // setMovable(false); @@ -57,23 +60,21 @@ VisualNavbar::VisualNavbar(MainWindow *main, QWidget *parent) addWidget(this->graphicsView); // addWidget(addsCombo); - connect(Core(), &CutterCore::seekChanged, this, &VisualNavbar::on_seekChanged); + connect(Core(), &CutterCore::seekChanged, this, &VisualNavbar::onSeekChanged); connect(Core(), &CutterCore::registersChanged, this, &VisualNavbar::drawPCCursor); connect(Core(), &CutterCore::refreshAll, this, &VisualNavbar::fetchAndPaintData); connect(Core(), &CutterCore::functionsChanged, this, &VisualNavbar::fetchAndPaintData); connect(Core(), &CutterCore::flagsChanged, this, &VisualNavbar::fetchAndPaintData); connect(Core(), &CutterCore::globalVarsChanged, this, &VisualNavbar::fetchAndPaintData); - graphicsScene = new QGraphicsScene(this); - const QBrush bg = QBrush(QColor(74, 74, 74)); graphicsScene->setBackgroundBrush(bg); this->graphicsView->setAlignment(Qt::AlignLeft); - bool legendEnabled = Config()->getNavBarLegendEnabled(); - int initialHeight = legendEnabled ? TOTAL_HEIGHT : NAVBAR_HEIGHT; + const bool legendEnabled = Config()->getNavBarLegendEnabled(); + const int initialHeight = legendEnabled ? totalHeight : navbarHeight; this->graphicsView->setMinimumHeight(initialHeight); this->graphicsView->setMaximumHeight(initialHeight); @@ -107,7 +108,7 @@ void VisualNavbar::paintEvent(QPaintEvent *event) { Q_UNUSED(event); - QPainter painter(this); + const QPainter painter(this); auto w = static_cast(width()); bool fetch = false; @@ -149,8 +150,8 @@ void VisualNavbar::fetchStats() ut64 from = UT64_MAX; ut64 to = 0; CutterRzListForeach (list.get(), iter, RzIOMap, map) { - ut64 f = rz_itv_begin(map->itv); - ut64 t = rz_itv_end(map->itv); + const ut64 f = rz_itv_begin(map->itv); + const ut64 t = rz_itv_end(map->itv); if (f < from) { from = f; } @@ -166,15 +167,15 @@ void VisualNavbar::fetchStats() rz_core_analysis_get_stats(core, from, to, RZ_MAX(1, (to + 1 - from) / blocksCount))); } -enum class DataType : int { Signature, Code, Data, String, Import, Symbol, Unexplored, Count }; +enum class DataType : ut8 { Signature, Code, Data, String, Import, Symbol, Unexplored, Count }; void VisualNavbar::updateGraphicsScene() { - bool legendVisible = Config()->getNavBarLegendEnabled(); + const bool legendVisible = Config()->getNavBarLegendEnabled(); graphicsScene->clear(); xToAddress.clear(); seekGraphicsItem = nullptr; - PCGraphicsItem = nullptr; + pcGraphicsItem = nullptr; legendItem = nullptr; graphicsScene->setBackgroundBrush(QBrush(Config()->getColor("gui.navbar.unexplored"))); @@ -182,12 +183,12 @@ void VisualNavbar::updateGraphicsScene() return; } - int w = graphicsView->width(); + const int w = graphicsView->width(); - RVA totalSize = stats->to - stats->from + 1; - RVA beginAddr = stats->from; + const RVA totalSize = stats->to - stats->from + 1; + const RVA beginAddr = stats->from; - double widthPerByte = (double)w + const double widthPerByte = (double)w / (double)(totalSize ? totalSize : pow(2.0, 64.0)); // account for overflow on 2^64 auto xFromAddr = [widthPerByte, beginAddr](RVA addr) -> double { return (addr - beginAddr) * widthPerByte; @@ -211,19 +212,19 @@ void VisualNavbar::updateGraphicsScene() DataType lastDataType = DataType::Unexplored; QGraphicsRectItem *dataItem = nullptr; - QRectF dataItemRect(0.0, 0.0, 0.0, (double)NAVBAR_HEIGHT); + QRectF dataItemRect(0.0, 0.0, 0.0, (double)navbarHeight); for (size_t i = 0; i < rz_vector_len(&stats->blocks); i++) { - RzCoreAnalysisStatsItem *block = + const auto *block = reinterpret_cast(rz_vector_index_ptr(&stats->blocks, i)); - ut64 from = rz_core_analysis_stats_get_block_from(stats.get(), i); - ut64 to = rz_core_analysis_stats_get_block_to(stats.get(), i) + 1; + const ut64 from = rz_core_analysis_stats_get_block_from(stats.get(), i); + const ut64 to = rz_core_analysis_stats_get_block_to(stats.get(), i) + 1; // Keep track of where which memory segment is mapped so we are able to convert from // address to X coordinate and vice versa. XToAddress x2a; - x2a.x_start = xFromAddr(from); - x2a.x_end = xFromAddr(to); - x2a.address_from = from; - x2a.address_to = to; + x2a.xStart = xFromAddr(from); + x2a.xEnd = xFromAddr(to); + x2a.addressFrom = from; + x2a.addressTo = to; xToAddress.append(x2a); DataType dataType; @@ -247,7 +248,7 @@ void VisualNavbar::updateGraphicsScene() } if (dataType == lastDataType) { - double r = xFromAddr(to); + const double r = xFromAddr(to); if (r > dataItemRect.right()) { dataItemRect.setRight(r); dataItem->setRect(dataItemRect); @@ -271,10 +272,10 @@ void VisualNavbar::updateGraphicsScene() legendItem = new QGraphicsItemGroup(); - QColor themeBg = Config()->windowColorIsDark() ? palette().color(QPalette::Window) - : Config()->getColor("gui.background"); + const QColor themeBg = Config()->windowColorIsDark() ? palette().color(QPalette::Window) + : Config()->getColor("gui.background"); - QGraphicsRectItem *lBg = new QGraphicsRectItem(0, NAVBAR_HEIGHT, w, LEGEND_HEIGHT); + auto *lBg = new QGraphicsRectItem(0, navbarHeight, w, legendHeight); lBg->setBrush(themeBg); lBg->setPen(Qt::NoPen); legendItem->addToGroup(lBg); @@ -284,7 +285,7 @@ void VisualNavbar::updateGraphicsScene() QString name; QBrush brush; }; - QList parts = { + const QList parts = { { tr("Signatures"), dataTypeBrushes[static_cast(DataType::Signature)] }, { tr("Code"), dataTypeBrushes[static_cast(DataType::Code)] }, { tr("Data"), dataTypeBrushes[static_cast(DataType::Data)] }, @@ -295,37 +296,37 @@ void VisualNavbar::updateGraphicsScene() }; qreal curX = 10; - qreal legY = NAVBAR_HEIGHT + LEGEND_BOX_Y_OFFSET; + const qreal legY = navbarHeight + legendBoxYOffset; for (const auto &p : parts) { - QGraphicsRectItem *r = new QGraphicsRectItem(curX, legY, LEGEND_BOX_SIZE, LEGEND_BOX_SIZE); + auto *r = new QGraphicsRectItem(curX, legY, legendBoxSize, legendBoxSize); r->setBrush(p.brush); r->setPen(QPen(Qt::black, 0.5)); legendItem->addToGroup(r); - QGraphicsTextItem *t = new QGraphicsTextItem(p.name); - t->setPos(curX + LEGEND_TEXT_X_OFFSET, legY + LEGEND_TEXT_Y_OFFSET); + auto *t = new QGraphicsTextItem(p.name); + t->setPos(curX + legendTextXOffset, legY + legendTextYOffset); legendItem->addToGroup(t); - curX += t->boundingRect().width() + LEGEND_ITEM_SPACING; + curX += t->boundingRect().width() + legendItemSpacing; } graphicsScene->addItem(legendItem); legendItem->setVisible(legendVisible); - graphicsScene->setSceneRect(0, 0, w, legendVisible ? TOTAL_HEIGHT : NAVBAR_HEIGHT); + graphicsScene->setSceneRect(0, 0, w, legendVisible ? totalHeight : navbarHeight); } void VisualNavbar::drawCursor(RVA addr, QColor color, QGraphicsRectItem *&graphicsItem) { - double cursor_x = addressToLocalX(addr); + const double cursorX = addressToLocalX(addr); if (graphicsItem != nullptr) { graphicsScene->removeItem(graphicsItem); delete graphicsItem; graphicsItem = nullptr; } - if (std::isnan(cursor_x)) { + if (std::isnan(cursorX)) { return; } // Subtract 1 so the 2px wide cursor is centered - graphicsItem = new QGraphicsRectItem(cursor_x - 1, 0, 2, NAVBAR_HEIGHT); + graphicsItem = new QGraphicsRectItem(cursorX - 1, 0, 2, navbarHeight); graphicsItem->setPen(Qt::NoPen); graphicsItem->setBrush(QBrush(color)); graphicsScene->addItem(graphicsItem); @@ -334,7 +335,7 @@ void VisualNavbar::drawCursor(RVA addr, QColor color, QGraphicsRectItem *&graphi void VisualNavbar::drawPCCursor() { drawCursor(Core()->getProgramCounterValue(), Config()->getColor("gui.navbar.pc"), - PCGraphicsItem); + pcGraphicsItem); } void VisualNavbar::drawSeekCursor() @@ -342,7 +343,7 @@ void VisualNavbar::drawSeekCursor() drawCursor(Core()->getOffset(), Config()->getColor("gui.navbar.seek"), seekGraphicsItem); } -void VisualNavbar::on_seekChanged(RVA addr) +void VisualNavbar::onSeekChanged(RVA addr) { Q_UNUSED(addr); // Update cursor @@ -356,7 +357,7 @@ bool VisualNavbar::eventFilter(QObject *watched, QEvent *event) auto *mouseEvent = static_cast(event); const QPoint scenePos = mouseEvent->pos(); - if (scenePos.y() <= NAVBAR_HEIGHT) { + if (scenePos.y() <= navbarHeight) { isDraggable = true; handleMouseAction(mouseEvent, scenePos); return true; @@ -369,7 +370,7 @@ bool VisualNavbar::eventFilter(QObject *watched, QEvent *event) const QPoint scenePos = mouseEvent->pos(); if ((mouseEvent->buttons() & Qt::LeftButton && isDraggable) - || scenePos.y() <= NAVBAR_HEIGHT) { + || scenePos.y() <= navbarHeight) { handleMouseAction(mouseEvent, scenePos); } else { QToolTip::hideText(); @@ -389,8 +390,8 @@ void VisualNavbar::handleMouseAction(QMouseEvent *event, const QPoint &scenePos) return; } - qreal x = scenePos.x(); - RVA address = localXToAddress(x); + const qreal x = scenePos.x(); + const RVA address = localXToAddress(x); if (address != RVA_INVALID) { auto tooltipPos = qhelpers::mouseEventGlobalPos(event); blockTooltip = true; // on Haiku, the below call sometimes triggers another mouseMoveEvent, @@ -406,11 +407,11 @@ void VisualNavbar::handleMouseAction(QMouseEvent *event, const QPoint &scenePos) RVA VisualNavbar::localXToAddress(double x) { - for (const XToAddress &x2a : xToAddress) { - if ((x2a.x_start <= x) && (x <= x2a.x_end)) { - double offset = (x - x2a.x_start) / (x2a.x_end - x2a.x_start); - double size = x2a.address_to - x2a.address_from; - return x2a.address_from + (offset * size); + for (const XToAddress &x2a : std::as_const(xToAddress)) { + if ((x2a.xStart <= x) && (x <= x2a.xEnd)) { + const double offset = (x - x2a.xStart) / (x2a.xEnd - x2a.xStart); + const double size = x2a.addressTo - x2a.addressFrom; + return x2a.addressFrom + (offset * size); } } return RVA_INVALID; @@ -418,12 +419,12 @@ RVA VisualNavbar::localXToAddress(double x) double VisualNavbar::addressToLocalX(RVA address) { - for (const XToAddress &x2a : xToAddress) { - if ((x2a.address_from <= address) && (address < x2a.address_to)) { - double offset = (double)(address - x2a.address_from) - / (double)(x2a.address_to - x2a.address_from); - double size = x2a.x_end - x2a.x_start; - return x2a.x_start + (offset * size); + for (const XToAddress &x2a : std::as_const(xToAddress)) { + if ((x2a.addressFrom <= address) && (address < x2a.addressTo)) { + const double offset = + (double)(address - x2a.addressFrom) / (double)(x2a.addressTo - x2a.addressFrom); + const double size = x2a.xEnd - x2a.xStart; + return x2a.xStart + (offset * size); } } return nan(""); @@ -432,7 +433,7 @@ double VisualNavbar::addressToLocalX(RVA address) QList VisualNavbar::sectionsForAddress(RVA address) { QList ret; - QList sections = Core()->getAllSections(); + const QList sections = Core()->getAllSections(); for (const SectionDescription §ion : sections) { if (address >= section.vaddr && address < section.vaddr + section.vsize) { ret << section.name; @@ -443,7 +444,7 @@ QList VisualNavbar::sectionsForAddress(RVA address) QString VisualNavbar::toolTipForAddress(RVA address) { - QString ret = tr("Address: %1").arg(RzAddressString(address)); + QString ret = tr("Address: %1").arg(rzAddressString(address)); // Don't append sections when a debug task is in progress to avoid freezing the interface if (Core()->isDebugTaskInProgress()) { @@ -454,7 +455,7 @@ QString VisualNavbar::toolTipForAddress(RVA address) if (sections.count()) { ret += "\n" + tr("Sections: \n"); bool first = true; - for (const QString §ion : sections) { + for (const QString §ion : std::as_const(sections)) { if (!first) { ret.append(QLatin1Char('\n')); } else { @@ -474,9 +475,9 @@ void VisualNavbar::showLegendContextMenu(const QPoint &pos) toggleLegend->setChecked(Config()->getNavBarLegendEnabled()); if (menu.exec(mapToGlobal(pos))) { - bool checked = toggleLegend->isChecked(); + const bool checked = toggleLegend->isChecked(); Config()->setNavBarLegendEnabled(checked); - int h = checked ? TOTAL_HEIGHT : NAVBAR_HEIGHT; + const int h = checked ? totalHeight : navbarHeight; this->graphicsView->setMinimumHeight(h); this->graphicsView->setMaximumHeight(h); diff --git a/src/widgets/VisualNavbar.h b/src/widgets/VisualNavbar.h index 5fd7c4bf..d8cc0e3a 100644 --- a/src/widgets/VisualNavbar.h +++ b/src/widgets/VisualNavbar.h @@ -1,29 +1,31 @@ #ifndef VISUALNAVBAR_H #define VISUALNAVBAR_H -#include -#include +#include "CutterCommon.h" +#include "RizinCpp.h" -#include "core/Cutter.h" +#include +#include #include -#include - class MainWindow; class QGraphicsView; class QGraphicsItemGroup; +/** + * @brief Visual navigation bar at the top for quick navigation through the binary + */ class VisualNavbar : public QToolBar { Q_OBJECT struct XToAddress { - double x_start; - double x_end; - RVA address_from; - RVA address_to; + double xStart; + double xEnd; + RVA addressFrom; + RVA addressTo; }; public: @@ -39,14 +41,14 @@ private slots: void drawSeekCursor(); void drawPCCursor(); void drawCursor(RVA addr, QColor color, QGraphicsRectItem *&graphicsItem); - void on_seekChanged(RVA addr); + void onSeekChanged(RVA addr); void showLegendContextMenu(const QPoint &pos); private: QGraphicsView *graphicsView; QGraphicsScene *graphicsScene; QGraphicsRectItem *seekGraphicsItem; - QGraphicsRectItem *PCGraphicsItem; + QGraphicsRectItem *pcGraphicsItem; QGraphicsItemGroup *legendItem; MainWindow *main;