diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 38d1f9b2..f863b1cf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,12 +7,14 @@ endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(DisallowInSource) +include(Utils) set(CUTTER_PYTHON_MIN 3.5) option(CUTTER_ENABLE_PYTHON "Enable Python integration. Requires Python >= ${CUTTER_PYTHON_MIN}." OFF) option(CUTTER_ENABLE_PYTHON_BINDINGS "Enable generating Python bindings with Shiboken2. Unused if CUTTER_ENABLE_PYTHON=OFF." OFF) option(CUTTER_ENABLE_CRASH_REPORTS "Enable crash report system. Unused if CUTTER_ENABLE_CRASH_REPORTS=OFF" OFF) +tri_option(CUTTER_ENABLE_KSYNTAXHIGHLIGHTING "Use KSyntaxHighlighting" AUTO) if(NOT CUTTER_ENABLE_PYTHON) set(CUTTER_ENABLE_PYTHON_BINDINGS OFF) @@ -95,6 +97,22 @@ if(CUTTER_ENABLE_PYTHON) endif() endif() +if(CUTTER_ENABLE_KSYNTAXHIGHLIGHTING) + if(CUTTER_ENABLE_KSYNTAXHIGHLIGHTING STREQUAL AUTO) + find_package(KF5SyntaxHighlighting) + if(KF5SyntaxHighlighting_FOUND) + set(KSYNTAXHIGHLIGHTING_STATUS ON) + else() + set(KSYNTAXHIGHLIGHTING_STATUS "OFF (KSyntaxHighlighting not found)") + endif() + else() + find_package(KF5SyntaxHighlighting REQUIRED) + set(KSYNTAXHIGHLIGHTING_STATUS ON) + endif() +else() + set(KSYNTAXHIGHLIGHTING_STATUS OFF) +endif() + message(STATUS "") @@ -103,6 +121,7 @@ message(STATUS "Options:") message(STATUS "- Python: ${CUTTER_ENABLE_PYTHON}") message(STATUS "- Python Bindings: ${CUTTER_ENABLE_PYTHON_BINDINGS}") message(STATUS "- Crash Handling: ${CUTTER_ENABLE_CRASH_REPORTS}") +message(STATUS "- KSyntaxHighlighting: ${KSYNTAXHIGHLIGHTING_STATUS}") message(STATUS "") @@ -184,4 +203,8 @@ if(CUTTER_ENABLE_PYTHON) endif() endif() +if(TARGET KF5::SyntaxHighlighting) + target_link_libraries(Cutter KF5::SyntaxHighlighting) + target_compile_definitions(Cutter PRIVATE CUTTER_ENABLE_KSYNTAXHIGHLIGHTING) +endif() diff --git a/src/cmake/Utils.cmake b/src/cmake/Utils.cmake new file mode 100644 index 00000000..3bf2d26d --- /dev/null +++ b/src/cmake/Utils.cmake @@ -0,0 +1,6 @@ + +# Like option(), but the value can also be AUTO +macro(tri_option name desc default) + set("${name}" "${default}" CACHE STRING "${desc}") + set_property(CACHE "${name}" PROPERTY STRINGS AUTO ON OFF) +endmacro() \ No newline at end of file diff --git a/src/common/Configuration.cpp b/src/common/Configuration.cpp index f180e850..974c0f36 100644 --- a/src/common/Configuration.cpp +++ b/src/common/Configuration.cpp @@ -7,7 +7,15 @@ #include #include +#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING +#include +#include +#include +#include +#endif + #include "common/ColorThemeWorker.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 @@ -133,6 +141,9 @@ Configuration::Configuration() : QObject(), nativePalette(qApp->palette()) .arg(s.fileName()) ); } +#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING + kSyntaxHighlightingRepository = nullptr; +#endif } Configuration *Configuration::instance() @@ -147,6 +158,10 @@ void Configuration::loadInitial() setInterfaceTheme(getInterfaceTheme()); setColorTheme(getColorTheme()); applySavedAsmOptions(); + +#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING + kSyntaxHighlightingRepository = new KSyntaxHighlighting::Repository(); +#endif } QString Configuration::getDirProjects() @@ -397,6 +412,40 @@ const CutterInterfaceTheme *Configuration::getCurrentTheme() return &cutterInterfaceThemesList()[i]; } +#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING +KSyntaxHighlighting::Repository *Configuration::getKSyntaxHighlightingRepository() +{ + return kSyntaxHighlightingRepository; +} + +KSyntaxHighlighting::Theme Configuration::getKSyntaxHighlightingTheme() +{ + auto repo = getKSyntaxHighlightingRepository(); + if (!repo) { + return KSyntaxHighlighting::Theme(); + } + return repo->defaultTheme( + getCurrentTheme()->flag & DarkFlag + ? KSyntaxHighlighting::Repository::DefaultTheme::DarkTheme + : KSyntaxHighlighting::Repository::DefaultTheme::LightTheme); +} +#endif + +QSyntaxHighlighter *Configuration::createSyntaxHighlighter(QTextDocument *document) +{ +#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING + auto syntaxHighlighter = new KSyntaxHighlighting::SyntaxHighlighter(document); + auto repo = getKSyntaxHighlightingRepository(); + if (repo) { + syntaxHighlighter->setDefinition(repo->definitionForName("C")); + syntaxHighlighter->setTheme(repo->defaultTheme(KSyntaxHighlighting::Repository::DefaultTheme::DarkTheme)); + } + return syntaxHighlighter; +#else + return new SyntaxHighlighter(document); +#endif +} + QString Configuration::getLogoFile() { return windowColorIsDark() diff --git a/src/common/Configuration.h b/src/common/Configuration.h index b4301ff9..a92fbeb2 100644 --- a/src/common/Configuration.h +++ b/src/common/Configuration.h @@ -8,6 +8,16 @@ #define Config() (Configuration::instance()) #define ConfigColor(x) Config()->getColor(x) +#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING +namespace KSyntaxHighlighting { + class Repository; + class Theme; +} +#endif + +class QSyntaxHighlighter; +class QTextDocument; + enum ColorFlags { LightFlag = 1, DarkFlag = 2 @@ -27,6 +37,10 @@ private: QSettings s; static Configuration *mPtr; +#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING + KSyntaxHighlighting::Repository *kSyntaxHighlightingRepository; +#endif + // Colors void loadBaseThemeNative(); void loadBaseThemeDark(); @@ -77,6 +91,12 @@ public: const CutterInterfaceTheme *getCurrentTheme(); +#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING + KSyntaxHighlighting::Repository *getKSyntaxHighlightingRepository(); + KSyntaxHighlighting::Theme getKSyntaxHighlightingTheme(); +#endif + QSyntaxHighlighter *createSyntaxHighlighter(QTextDocument *document); + QString getDirProjects(); void setDirProjects(const QString &dir); diff --git a/src/dialogs/TypesInteractionDialog.cpp b/src/dialogs/TypesInteractionDialog.cpp index 4ae27de5..8b07a42c 100644 --- a/src/dialogs/TypesInteractionDialog.cpp +++ b/src/dialogs/TypesInteractionDialog.cpp @@ -15,7 +15,7 @@ TypesInteractionDialog::TypesInteractionDialog(QWidget *parent, bool readOnly) : { ui->setupUi(this); ui->plainTextEdit->setPlainText(""); - syntaxHighLighter = new SyntaxHighlighter(ui->plainTextEdit->document()); + syntaxHighLighter = Config()->createSyntaxHighlighter(ui->plainTextEdit->document()); ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); ui->plainTextEdit->setReadOnly(readOnly); } diff --git a/src/dialogs/TypesInteractionDialog.h b/src/dialogs/TypesInteractionDialog.h index 08b1910a..d45640b3 100644 --- a/src/dialogs/TypesInteractionDialog.h +++ b/src/dialogs/TypesInteractionDialog.h @@ -7,7 +7,8 @@ namespace Ui { class TypesInteractionDialog; } -class SyntaxHighlighter; + +class QSyntaxHighlighter; class TypesInteractionDialog : public QDialog { @@ -48,7 +49,7 @@ private slots: private: std::unique_ptr ui; - SyntaxHighlighter *syntaxHighLighter; + QSyntaxHighlighter *syntaxHighLighter; signals: /** diff --git a/src/widgets/PseudocodeWidget.cpp b/src/widgets/PseudocodeWidget.cpp index c39f670f..218fa87c 100644 --- a/src/widgets/PseudocodeWidget.cpp +++ b/src/widgets/PseudocodeWidget.cpp @@ -1,20 +1,19 @@ #include "PseudocodeWidget.h" #include "ui_PseudocodeWidget.h" -#include - #include "common/Configuration.h" #include "common/Helpers.h" -#include "common/SyntaxHighlighter.h" #include "common/TempConfig.h" +#include + PseudocodeWidget::PseudocodeWidget(MainWindow *main, QAction *action) : MemoryDockWidget(CutterCore::MemoryWidgetType::Pseudocode, main, action), ui(new Ui::PseudocodeWidget) { ui->setupUi(this); - syntaxHighLighter = new SyntaxHighlighter(ui->textEdit->document()); + syntaxHighlighter = Config()->createSyntaxHighlighter(ui->textEdit->document()); setupFonts(); colorsUpdatedSlot(); diff --git a/src/widgets/PseudocodeWidget.h b/src/widgets/PseudocodeWidget.h index f3d04b59..6e3a02ca 100644 --- a/src/widgets/PseudocodeWidget.h +++ b/src/widgets/PseudocodeWidget.h @@ -11,7 +11,7 @@ class PseudocodeWidget; } class QTextEdit; -class SyntaxHighlighter; +class QSyntaxHighlighter; class PseudocodeWidget : public MemoryDockWidget { @@ -30,7 +30,7 @@ private: enum DecompilerComboBoxValues { DecompilerCBR2Dec, DecompilerCBPdc }; std::unique_ptr ui; - SyntaxHighlighter *syntaxHighLighter; + QSyntaxHighlighter *syntaxHighlighter; void doRefresh(RVA addr); void setupFonts();