diff --git a/src/disassemblysettingspage.ui b/src/disassemblysettingspage.ui index b1f2471b..69221f36 100644 --- a/src/disassemblysettingspage.ui +++ b/src/disassemblysettingspage.ui @@ -32,14 +32,14 @@ 0 - + Source Code Search Paths: - + KEditListWidget::All @@ -60,20 +60,30 @@ - + Show hexdump: - + + + + + Tab width + + + + + + diff --git a/src/models/disassemblymodel.cpp b/src/models/disassemblymodel.cpp index 5daec8d4..3046a55f 100644 --- a/src/models/disassemblymodel.cpp +++ b/src/models/disassemblymodel.cpp @@ -11,9 +11,9 @@ #include "search.h" #include "sourcecodemodel.h" -DisassemblyModel::DisassemblyModel(KSyntaxHighlighting::Repository* repository, QObject* parent) +DisassemblyModel::DisassemblyModel(KSyntaxHighlighting::Repository* repository, int tabWidth, QObject* parent) : QAbstractTableModel(parent) - , m_highlightedText(repository) + , m_highlightedText(repository, tabWidth) { } diff --git a/src/models/disassemblymodel.h b/src/models/disassemblymodel.h index 7c65a546..faf2c880 100644 --- a/src/models/disassemblymodel.h +++ b/src/models/disassemblymodel.h @@ -27,7 +27,7 @@ class DisassemblyModel : public QAbstractTableModel { Q_OBJECT public: - explicit DisassemblyModel(KSyntaxHighlighting::Repository* repository, QObject* parent = nullptr); + explicit DisassemblyModel(KSyntaxHighlighting::Repository* repository, int tabWidth = 8, QObject* parent = nullptr); ~DisassemblyModel() override; void setDisassembly(const DisassemblyOutput& disassemblyOutput, const Data::CallerCalleeResults& results); diff --git a/src/models/highlightedtext.cpp b/src/models/highlightedtext.cpp index 2ce792ed..b656dd4b 100644 --- a/src/models/highlightedtext.cpp +++ b/src/models/highlightedtext.cpp @@ -7,6 +7,7 @@ #include "highlightedtext.h" +#include #include #include #include @@ -15,6 +16,8 @@ #include +#include + #if KFSyntaxHighlighting_FOUND #include #include @@ -229,10 +232,11 @@ class HighlightedLine { public: HighlightedLine() = default; - HighlightedLine(HighlightingImplementation* highlighter, const QString& text, int index) + HighlightedLine(HighlightingImplementation* highlighter, const QString& text, int index, int tabWidth) : m_highlighter(highlighter) , m_text(Util::removeAnsi(text)) , m_index(index) + , m_tabWidth(tabWidth) , m_layout(nullptr) { } @@ -250,13 +254,25 @@ class HighlightedLine m_layout = nullptr; } + void setTabWidth(int tabWidth) + { + m_tabWidth = tabWidth; + m_layout = nullptr; + } + private: std::unique_ptr buildLayout() const { Q_ASSERT(m_index != -1); auto layout = std::make_unique(); - layout->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); + auto font = QFontDatabase::systemFont(QFontDatabase::FixedFont); + + auto option = layout->textOption(); + option.setTabStopDistance(m_tabWidth * QFontMetrics(font).horizontalAdvance(QLatin1Char(' '))); + layout->setTextOption(option); + + layout->setFont(font); layout->setText(m_text); layout->setFormats(m_highlighter->format(m_index)); @@ -276,16 +292,17 @@ class HighlightedLine HighlightingImplementation* m_highlighter = nullptr; QString m_text; int m_index = -1; + int m_tabWidth = 8; mutable std::unique_ptr m_layout; }; static_assert(std::is_nothrow_move_constructible_v); static_assert(std::is_nothrow_destructible_v); -HighlightedText::HighlightedText(KSyntaxHighlighting::Repository* repository, QObject* parent) +HighlightedText::HighlightedText(KSyntaxHighlighting::Repository* repository, int tabWidth, QObject* parent) : QObject(parent) , m_repository(repository) + , m_tabWidth(tabWidth) { - Q_UNUSED(repository); } HighlightedText::~HighlightedText() = default; @@ -310,7 +327,7 @@ void HighlightedText::setText(const QStringList& text) m_highlighter->formatText(text); int index = 0; std::transform(text.cbegin(), text.cend(), m_highlightedLines.begin(), [this, &index](const QString& text) { - return HighlightedLine {m_highlighter.get(), text, index++}; + return HighlightedLine {m_highlighter.get(), text, index++, m_tabWidth}; }); m_cleanedLines = text; @@ -358,3 +375,9 @@ void HighlightedText::updateHighlighting() std::for_each(m_highlightedLines.begin(), m_highlightedLines.end(), [](HighlightedLine& line) { line.updateHighlighting(); }); } + +void HighlightedText::updateTabWidth(int tabWidth) +{ + std::for_each(m_highlightedLines.begin(), m_highlightedLines.end(), + [tabWidth](HighlightedLine& line) { line.setTabWidth(tabWidth); }); +} diff --git a/src/models/highlightedtext.h b/src/models/highlightedtext.h index 0c79f763..400419ca 100644 --- a/src/models/highlightedtext.h +++ b/src/models/highlightedtext.h @@ -14,8 +14,6 @@ class QTextLayout; class QTextLine; -#include "hotspot-config.h" - namespace KSyntaxHighlighting { class SyntaxHighlighter; class Definition; @@ -29,7 +27,7 @@ class HighlightedText : public QObject { Q_OBJECT public: - HighlightedText(KSyntaxHighlighting::Repository* repository, QObject* parent = nullptr); + HighlightedText(KSyntaxHighlighting::Repository* repository, int tabWidth, QObject* parent = nullptr); ~HighlightedText() override; void setText(const QStringList& text); @@ -53,6 +51,7 @@ class HighlightedText : public QObject public slots: void updateHighlighting(); + void updateTabWidth(int tabWidth); private: KSyntaxHighlighting::Repository* m_repository; @@ -61,4 +60,5 @@ public slots: QStringList m_lines; QStringList m_cleanedLines; bool m_isUsingAnsi = false; + int m_tabWidth = 8; }; diff --git a/src/models/sourcecodemodel.cpp b/src/models/sourcecodemodel.cpp index 26b91012..8abd2674 100644 --- a/src/models/sourcecodemodel.cpp +++ b/src/models/sourcecodemodel.cpp @@ -23,9 +23,9 @@ Q_LOGGING_CATEGORY(sourcecodemodel, "hotspot.sourcecodemodel", QtWarningMsg) -SourceCodeModel::SourceCodeModel(KSyntaxHighlighting::Repository* repository, QObject* parent) +SourceCodeModel::SourceCodeModel(KSyntaxHighlighting::Repository* repository, int tabWidth, QObject* parent) : QAbstractTableModel(parent) - , m_highlightedText(repository) + , m_highlightedText(repository, tabWidth) { qRegisterMetaType(); } diff --git a/src/models/sourcecodemodel.h b/src/models/sourcecodemodel.h index 94e38d3a..e4bafae0 100644 --- a/src/models/sourcecodemodel.h +++ b/src/models/sourcecodemodel.h @@ -28,7 +28,7 @@ class SourceCodeModel : public QAbstractTableModel { Q_OBJECT public: - explicit SourceCodeModel(KSyntaxHighlighting::Repository* repository, QObject* parent = nullptr); + explicit SourceCodeModel(KSyntaxHighlighting::Repository* repository, int tabWidth = 8, QObject* parent = nullptr); ~SourceCodeModel() override; void clear(); diff --git a/src/resultsdisassemblypage.cpp b/src/resultsdisassemblypage.cpp index 813afe8a..fea6c92b 100644 --- a/src/resultsdisassemblypage.cpp +++ b/src/resultsdisassemblypage.cpp @@ -221,11 +221,11 @@ ResultsDisassemblyPage::ResultsDisassemblyPage(CostContextMenu* costContextMenu, , ui(std::make_unique()) #if KFSyntaxHighlighting_FOUND , m_repository(std::make_unique()) - , m_disassemblyModel(new DisassemblyModel(m_repository.get(), this)) - , m_sourceCodeModel(new SourceCodeModel(m_repository.get(), this)) + , m_disassemblyModel(new DisassemblyModel(m_repository.get(), 8, this)) + , m_sourceCodeModel(new SourceCodeModel(m_repository.get(), 8, this)) #else - , m_disassemblyModel(new DisassemblyModel(nullptr, this)) - , m_sourceCodeModel(new SourceCodeModel(nullptr, this)) + , m_disassemblyModel(new DisassemblyModel(nullptr, 8, this)) + , m_sourceCodeModel(new SourceCodeModel(nullptr, 8, this)) #endif , m_disassemblyCostDelegate(new CostDelegate(DisassemblyModel::CostRole, DisassemblyModel::TotalCostRole, this)) , m_sourceCodeCostDelegate(new CostDelegate(SourceCodeModel::CostRole, SourceCodeModel::TotalCostRole, this)) @@ -274,6 +274,9 @@ ResultsDisassemblyPage::ResultsDisassemblyPage(CostContextMenu* costContextMenu, connect(ui->assemblyView, &QTreeView::entered, this, updateFromDisassembly); connect(ui->sourceCodeView, &QTreeView::entered, this, updateFromSource); + connect(settings, &Settings::tabWidthChanged, this->m_sourceCodeModel->highlightedText(), + &HighlightedText::updateTabWidth); + auto createContextMenu = [](QTreeView* view, auto* model, auto&& addEntries) { auto gotoMenuWidget = new QWidget(view); auto layout = new QHBoxLayout(gotoMenuWidget); diff --git a/src/settings.cpp b/src/settings.cpp index 8f1f13c7..8fc3eb81 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -253,6 +253,11 @@ void Settings::loadFromFile() connect(this, &Settings::showHexdumpChanged, [sharedConfig](bool showHexdump) { sharedConfig->group(QStringLiteral("Disassembly")).writeEntry("showHexdump", showHexdump); }); + + setTabWidth(sharedConfig->group(QStringLiteral("Disassembly")).readEntry("tabWidth", 8)); + connect(this, &Settings::tabWidthChanged, [sharedConfig](int distance) { + sharedConfig->group(QStringLiteral("Disassembly")).writeEntry("tabWidth", distance); + }); } void Settings::setSourceCodePaths(const QString& paths) @@ -286,3 +291,11 @@ void Settings::setShowHexdump(bool showHexdump) emit showHexdumpChanged(m_showHexdump); } } + +void Settings::setTabWidth(int distance) +{ + if (m_tabWidth != distance) { + m_tabWidth = distance; + emit tabWidthChanged(m_tabWidth); + } +} diff --git a/src/settings.h b/src/settings.h index 90d7d16b..bf396aae 100644 --- a/src/settings.h +++ b/src/settings.h @@ -163,6 +163,11 @@ class Settings : public QObject return m_showHexdump; } + int tabWidth() const + { + return m_tabWidth; + } + void loadFromFile(); signals: @@ -187,6 +192,7 @@ class Settings : public QObject void perfPathChanged(const QString& perfPath); void showBranchesChanged(bool showBranches); void showHexdumpChanged(bool showHexdump); + void tabWidthChanged(int distance); public slots: void setPrettifySymbols(bool prettifySymbols); @@ -212,6 +218,7 @@ public slots: void setPerfPath(const QString& path); void setShowBranches(bool showBranches); void setShowHexdump(bool showHexdump); + void setTabWidth(int distance); private: using QObject::QObject; @@ -237,6 +244,7 @@ public slots: QString m_perfMapPath; bool m_showBranches = true; bool m_showHexdump = false; + int m_tabWidth = 8; QString m_lastUsedEnvironment; diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index e41defd2..2a4003db 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -337,10 +337,12 @@ void SettingsDialog::addSourcePathPage() disassemblyPage->showBranches->setChecked(settings->showBranches()); disassemblyPage->showHexdump->setChecked(settings->showHexdump()); + disassemblyPage->tabWidth->setValue(settings->tabWidth()); connect(buttonBox(), &QDialogButtonBox::accepted, this, [this, colon, settings] { settings->setSourceCodePaths(disassemblyPage->sourcePaths->items().join(colon)); settings->setShowBranches(disassemblyPage->showBranches->isChecked()); settings->setShowHexdump(disassemblyPage->showHexdump->isChecked()); + settings->setTabStopDistance(disassemblyPage->tabWidth->value()); }); } diff --git a/tests/modeltests/tst_formatting.cpp b/tests/modeltests/tst_formatting.cpp index 790a2a3e..54a91066 100644 --- a/tests/modeltests/tst_formatting.cpp +++ b/tests/modeltests/tst_formatting.cpp @@ -72,7 +72,7 @@ private slots: QFETCH(QStringList, ansiStrings); QFETCH(QVector>, formatting); - HighlightedText highlighter(nullptr); + HighlightedText highlighter(nullptr, 0, nullptr); highlighter.setText(ansiStrings); @@ -101,7 +101,7 @@ private slots: auto repository = std::make_unique(); - HighlightedText text(repository.get()); + HighlightedText text(repository.get(), 0); text.setText(testfunc); text.setDefinition(repository->definitionForFileName(QStringLiteral("test.cpp")));