File indexing completed on 2024-05-12 05:43:34
0001 /* 0002 Copyright (C) 2015 Volker Krause <vkrause@kde.org> 0003 0004 This program is free software; you can redistribute it and/or modify it 0005 under the terms of the GNU Library General Public License as published by 0006 the Free Software Foundation; either version 2 of the License, or (at your 0007 option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, but WITHOUT 0010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0012 License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program. If not, see <https://www.gnu.org/licenses/>. 0016 */ 0017 0018 #include "elfstructureview.h" 0019 #include "ui_elfstructureview.h" 0020 0021 #include <elfmodel/elfmodel.h> 0022 #include <navigator/codenavigator.h> 0023 0024 #include <QSortFilterProxyModel> 0025 0026 #include <QMouseEvent> 0027 0028 ElfStructureView::ElfStructureView(QWidget* parent): 0029 QWidget(parent), 0030 ui(new Ui::ElfStructureView), 0031 m_proxy(new QSortFilterProxyModel(this)) 0032 { 0033 ui->setupUi(this); 0034 ui->elfStructureView->setModel(m_proxy); 0035 m_proxy->setRecursiveFilteringEnabled(true); 0036 ui->elfStructureView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); 0037 0038 connect(ui->elfStructureView->selectionModel(), &QItemSelectionModel::selectionChanged, 0039 this, &ElfStructureView::selectionChanged); 0040 connect(ui->elfStructureSearchLine, &QLineEdit::textChanged, this, [this](const QString &text) { 0041 m_proxy->setFilterFixedString(text); 0042 }); 0043 connect(ui->elfDetailView, &QTextBrowser::anchorClicked, this, &ElfStructureView::anchorClicked); 0044 0045 ui->actionBack->setShortcut(QKeySequence::Back); 0046 ui->actionForward->setShortcut(QKeySequence::Forward); 0047 0048 connect(ui->actionBack, &QAction::triggered, this, [this]() { 0049 --m_historyIndex; 0050 m_historyLock = true; 0051 selectUrl(m_history.at(m_historyIndex)); 0052 m_historyLock = false; 0053 updateActionState(); 0054 }); 0055 connect(ui->actionForward, &QAction::triggered, this, [this]() { 0056 ++m_historyIndex; 0057 m_historyLock = true; 0058 selectUrl(m_history.at(m_historyIndex)); 0059 m_historyLock = false; 0060 updateActionState(); 0061 }); 0062 addActions({ ui->actionBack, ui->actionForward }); 0063 updateActionState(); 0064 0065 installEventFilter(this); 0066 } 0067 0068 ElfStructureView::~ElfStructureView() = default; 0069 0070 void ElfStructureView::setModel(ElfModel* model) 0071 { 0072 m_elfModel = model; 0073 m_proxy->setSourceModel(model); 0074 } 0075 0076 void ElfStructureView::selectionChanged(const QItemSelection &selection) 0077 { 0078 if (selection.isEmpty()) { 0079 ui->elfDetailView->clear(); 0080 return; 0081 } 0082 0083 const QModelIndex index = selection.first().topLeft(); 0084 ui->elfDetailView->setHtml(index.data(ElfModel::DetailRole).toString()); 0085 0086 if (m_historyLock) 0087 return; 0088 const auto url = index.data(ElfModel::NodeUrl).toUrl(); 0089 if (url.isValid() && !url.isEmpty()) { 0090 m_history.resize(m_historyIndex + 2); 0091 m_history[++m_historyIndex] = url; 0092 updateActionState(); 0093 } 0094 } 0095 0096 void ElfStructureView::anchorClicked(const QUrl& url) 0097 { 0098 if (url.scheme() == QLatin1String("code")) 0099 CodeNavigator::goTo(url); 0100 else if (url.scheme() == QLatin1String("elfmodel")) 0101 selectUrl(url); 0102 } 0103 0104 void ElfStructureView::updateActionState() 0105 { 0106 ui->actionBack->setEnabled(m_historyIndex > 0); 0107 ui->actionForward->setEnabled(m_historyIndex + 1 < m_history.size()); 0108 } 0109 0110 void ElfStructureView::selectUrl(const QUrl& url) 0111 { 0112 auto idx = m_elfModel->indexForUrl(url); 0113 idx = m_proxy->mapFromSource(idx); 0114 ui->elfStructureView->selectionModel()->select(idx, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); 0115 ui->elfStructureView->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); 0116 ui->elfStructureView->scrollTo(idx); 0117 } 0118 0119 bool ElfStructureView::eventFilter(QObject *receiver, QEvent *event) 0120 { 0121 if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) { 0122 auto mouseEv = static_cast<QMouseEvent*>(event); 0123 if (mouseEv->button() == Qt::BackButton) { 0124 if (ui->actionBack->isEnabled()) 0125 ui->actionBack->trigger(); 0126 return true; 0127 } else if (mouseEv->button() == Qt::ForwardButton) { 0128 if (ui->actionForward->isEnabled()) 0129 ui->actionForward->trigger(); 0130 return true; 0131 } 0132 } 0133 return QObject::eventFilter(receiver, event); 0134 }