diff --git a/src/models/disassemblymodel.cpp b/src/models/disassemblymodel.cpp index 1120e4b70..ba3fac82f 100644 --- a/src/models/disassemblymodel.cpp +++ b/src/models/disassemblymodel.cpp @@ -80,6 +80,8 @@ QVariant DisassemblyModel::headerData(int section, Qt::Orientation orientation, if (section == AddrColumn) return tr("Address"); + else if (section == BranchColumn) + return tr("Branches"); else if (section == DisassemblyColumn) return tr("Assembly / Disassembly"); @@ -116,6 +118,8 @@ QVariant DisassemblyModel::data(const QModelIndex& index, int role) const if (!data.addr) return {}; return QString::number(data.addr, 16); + } else if (index.column() == BranchColumn) { + return data.branchVisualisation; } else if (index.column() == DisassemblyColumn) { const auto block = m_document->findBlockByLineNumber(index.row()); if (role == SyntaxHighlightRole) diff --git a/src/models/disassemblymodel.h b/src/models/disassemblymodel.h index 1da6f1db0..47993d7f7 100644 --- a/src/models/disassemblymodel.h +++ b/src/models/disassemblymodel.h @@ -54,6 +54,7 @@ class DisassemblyModel : public QAbstractTableModel enum Columns { AddrColumn, + BranchColumn, DisassemblyColumn, COLUMN_COUNT }; diff --git a/src/models/disassemblyoutput.cpp b/src/models/disassemblyoutput.cpp index 505bc25bb..041c20d3c 100644 --- a/src/models/disassemblyoutput.cpp +++ b/src/models/disassemblyoutput.cpp @@ -199,8 +199,23 @@ ObjectdumpOutput objdumpParse(const QByteArray& output) assembly = asmLine; } - disassemblyLines.push_back( - {addr, assembly, extractLinkedFunction(asmLine), {currentSourceFileName, sourceCodeLine}}); + auto isHexCharacter = [](const QChar c) { + return (c >= QLatin1Char('0') && c <= QLatin1Char('9')) || (c >= QLatin1Char('a') && c <= QLatin1Char('f')); + }; + + // format is the following: + // /- a5 54 12 ... + // | 64 a3 .... + // \-> 65 23 .... + // so we can simply skip all characters until we meet a letter or a number + const auto branchVisualisationRange = + std::distance(assembly.cbegin(), std::find_if(assembly.cbegin(), assembly.cend(), isHexCharacter)); + + disassemblyLines.push_back({addr, + assembly.mid(branchVisualisationRange), + branchVisualisationRange ? assembly.left(branchVisualisationRange) : QString {}, + extractLinkedFunction(asmLine), + {currentSourceFileName, sourceCodeLine}}); } return {disassemblyLines, sourceFileName}; } diff --git a/src/models/disassemblyoutput.h b/src/models/disassemblyoutput.h index d44261f91..d3682f875 100644 --- a/src/models/disassemblyoutput.h +++ b/src/models/disassemblyoutput.h @@ -24,6 +24,7 @@ struct DisassemblyOutput { quint64 addr = 0; QString disassembly; + QString branchVisualisation; LinkedFunction linkedFunction; Data::FileLine fileLine; }; diff --git a/src/resultsdisassemblypage.cpp b/src/resultsdisassemblypage.cpp index a533dbd00..831e12005 100644 --- a/src/resultsdisassemblypage.cpp +++ b/src/resultsdisassemblypage.cpp @@ -101,7 +101,6 @@ ResultsDisassemblyPage::ResultsDisassemblyPage(CostContextMenu* costContextMenu, connect(settings, &Settings::sourceCodePathsChanged, this, [this](const QString&) { showDisassembly(); }); connect(ui->assemblyView, &QTreeView::entered, this, updateFromDisassembly); - connect(ui->sourceCodeView, &QTreeView::entered, this, updateFromSource); ui->sourceCodeView->setContextMenuPolicy(Qt::CustomContextMenu); @@ -253,6 +252,12 @@ ResultsDisassemblyPage::ResultsDisassemblyPage(CostContextMenu* costContextMenu, ui->disasmSearchWidget, ui->disasmSearchEdit, ui->assemblyView, ui->disasmEndReachedWidget, m_disassemblyModel, &m_currentDisasmSearchIndex, 0); + ui->assemblyView->setColumnHidden(DisassemblyModel::BranchColumn, !settings->showBranches()); + + connect(settings, &Settings::showBranchesChanged, this, [this](bool showBranches) { + ui->assemblyView->setColumnHidden(DisassemblyModel::BranchColumn, !showBranches); + }); + #if KFSyntaxHighlighting_FOUND QStringList schemes; @@ -308,7 +313,9 @@ void ResultsDisassemblyPage::setupAsmViewModel() ui->assemblyView->header()->setStretchLastSection(false); ui->assemblyView->header()->setSectionResizeMode(DisassemblyModel::AddrColumn, QHeaderView::ResizeToContents); + ui->assemblyView->header()->setSectionResizeMode(DisassemblyModel::BranchColumn, QHeaderView::ResizeToContents); ui->assemblyView->header()->setSectionResizeMode(DisassemblyModel::DisassemblyColumn, QHeaderView::Stretch); + ui->assemblyView->setItemDelegateForColumn(DisassemblyModel::BranchColumn, m_disassemblyDelegate); ui->assemblyView->setItemDelegateForColumn(DisassemblyModel::DisassemblyColumn, m_disassemblyDelegate); for (int col = DisassemblyModel::COLUMN_COUNT; col < m_disassemblyModel->columnCount(); col++) { diff --git a/src/settings.cpp b/src/settings.cpp index dc2adcc66..03c33a9cc 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -191,10 +191,6 @@ void Settings::loadFromFile() sharedConfig->group("PathSettings").writeEntry("userPaths", this->userPaths()); sharedConfig->group("PathSettings").writeEntry("systemPaths", this->systemPaths()); }); - setSourceCodePaths(sharedConfig->group("PathSettings").readEntry("sourceCodePaths", QString())); - connect(this, &Settings::sourceCodePathsChanged, this, [sharedConfig](const QString& paths) { - sharedConfig->group("PathSettings").writeEntry("sourceCodePaths", paths); - }); // fix build error in app image build const auto colorScheme = KColorScheme(QPalette::Normal, KColorScheme::View, sharedConfig); @@ -237,6 +233,16 @@ void Settings::loadFromFile() connect(this, &Settings::lastUsedEnvironmentChanged, this, [sharedConfig](const QString& envName) { sharedConfig->group("PerfPaths").writeEntry("lastUsed", envName); }); + + setSourceCodePaths(sharedConfig->group("Disassembly").readEntry("sourceCodePaths", QString())); + connect(this, &Settings::sourceCodePathsChanged, this, [sharedConfig](const QString& paths) { + sharedConfig->group("Disassembly").writeEntry("sourceCodePaths", paths); + }); + + setShowBranches(sharedConfig->group("Disassembly").readEntry("showBranches", true)); + connect(this, &Settings::showBranchesChanged, [sharedConfig](bool showBranches) { + sharedConfig->group("Disassembly").writeEntry("showBranches", showBranches); + }); } void Settings::setSourceCodePaths(const QString& paths) @@ -254,3 +260,11 @@ void Settings::setPerfPath(const QString& path) emit perfPathChanged(m_perfPath); } } + +void Settings::setShowBranches(bool showBranches) +{ + if (m_showBranches != showBranches) { + m_showBranches = showBranches; + emit showBranchesChanged(m_showBranches); + } +} diff --git a/src/settings.h b/src/settings.h index 065a7fa7a..b038a5af7 100644 --- a/src/settings.h +++ b/src/settings.h @@ -154,6 +154,11 @@ class Settings : public QObject return m_perfPath; } + bool showBranches() const + { + return m_showBranches; + } + void loadFromFile(); signals: @@ -176,6 +181,7 @@ class Settings : public QObject void lastUsedEnvironmentChanged(const QString& envName); void sourceCodePathsChanged(const QString& paths); void perfPathChanged(const QString& perfPath); + void showBranchesChanged(bool showBranches); public slots: void setPrettifySymbols(bool prettifySymbols); @@ -199,6 +205,7 @@ public slots: void setLastUsedEnvironment(const QString& envName); void setSourceCodePaths(const QString& paths); void setPerfPath(const QString& path); + void setShowBranches(bool showBranches); private: Settings() = default; @@ -222,6 +229,7 @@ public slots: QString m_objdump; QString m_sourceCodePaths; QString m_perfMapPath; + bool m_showBranches = true; QString m_lastUsedEnvironment; diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 16d7ee18d..92b1a73aa 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -327,13 +327,18 @@ void SettingsDialog::addSourcePathPage() disassemblyPage->setupUi(page); + auto settings = Settings::instance(); + const auto colon = QLatin1Char(':'); - connect(Settings::instance(), &Settings::sourceCodePathsChanged, this, + connect(settings, &Settings::sourceCodePathsChanged, this, [this, colon](const QString& paths) { disassemblyPage->sourcePaths->setItems(paths.split(colon)); }); setupMultiPath(disassemblyPage->sourcePaths, disassemblyPage->label, buttonBox()->button(QDialogButtonBox::Ok)); - connect(buttonBox(), &QDialogButtonBox::accepted, this, [this, colon] { - Settings::instance()->setSourceCodePaths(disassemblyPage->sourcePaths->items().join(colon)); + disassemblyPage->showBranches->setChecked(settings->showBranches()); + + connect(buttonBox(), &QDialogButtonBox::accepted, this, [this, colon, settings] { + settings->setSourceCodePaths(disassemblyPage->sourcePaths->items().join(colon)); + settings->setShowBranches(disassemblyPage->showBranches->isChecked()); }); }