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 "dependencyview.h" 0019 #include "ui_dependencyview.h" 0020 #include <dependencymodel/dependencymodel.h> 0021 #include <dependencymodel/usedsymbolmodel.h> 0022 #include <dependencymodel/unuseddependenciesmodel.h> 0023 #include <dependencymodel/filelistmodel.h> 0024 #include <dependencymodel/fileusermodel.h> 0025 0026 #include <elf/elffile.h> 0027 #include <elf/elffileset.h> 0028 #include <optimizers/dependencysorter.h> 0029 0030 #include <QDebug> 0031 #include <QSortFilterProxyModel> 0032 0033 DependencyView::DependencyView(QWidget* parent): 0034 QWidget(parent), 0035 ui(new Ui::DependencyView), 0036 m_dependencyModel(new DependencyModel(this)), 0037 m_symbolModel(new UsedSymbolModel(this)), 0038 m_unusedDependenciesModel(new UnusedDependenciesModel(this)), 0039 m_fileListModel(new FileListModel(this)), 0040 m_fileUserModel(new FileUserModel(this)), 0041 m_inverseSymbolModel(new UsedSymbolModel(this)) 0042 { 0043 ui->setupUi(this); 0044 0045 // top down dependencies tab 0046 ui->dependencyView->setModel(m_dependencyModel); 0047 ui->dependencyView->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); 0048 connect(ui->dependencySearchLine, &QLineEdit::textChanged, this, &DependencyView::search); 0049 connect(ui->dependencyView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &DependencyView::dependencySelected); 0050 0051 auto proxy = new QSortFilterProxyModel(this); 0052 proxy->setFilterCaseSensitivity(Qt::CaseInsensitive); 0053 proxy->setSourceModel(m_symbolModel); 0054 ui->symbolView->setModel(proxy); 0055 connect(ui->symbolSearchLine, &QLineEdit::textChanged, proxy, &QSortFilterProxyModel::setFilterFixedString); 0056 0057 // inverse dependencies tab 0058 proxy = new QSortFilterProxyModel(this); 0059 proxy->setFilterCaseSensitivity(Qt::CaseInsensitive); 0060 proxy->setSourceModel(m_fileListModel); 0061 ui->inverseFileList->setModel(proxy); 0062 connect(ui->inverseFileListSearchLine, &QLineEdit::textChanged, proxy, &QSortFilterProxyModel::setFilterFixedString); 0063 connect(ui->inverseFileList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &DependencyView::inverseFileSelected); 0064 0065 proxy = new QSortFilterProxyModel(this); 0066 proxy->setFilterCaseSensitivity(Qt::CaseInsensitive); 0067 proxy->setSourceModel(m_fileUserModel); 0068 ui->inverseDependencyList->setModel(proxy); 0069 connect(ui->inverseDependencyListSearchLine, &QLineEdit::textChanged, proxy, &QSortFilterProxyModel::setFilterFixedString); 0070 connect(ui->inverseDependencyList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &DependencyView::inverseUserSelected); 0071 0072 proxy = new QSortFilterProxyModel(this); 0073 proxy->setFilterCaseSensitivity(Qt::CaseInsensitive); 0074 proxy->setSourceModel(m_inverseSymbolModel); 0075 ui->inverseSymbolList->setModel(proxy); 0076 ui->inverseSymbolList->header()->setSortIndicator(0, Qt::AscendingOrder); 0077 connect(ui->inverseSymbolListSearchLine, &QLineEdit::textChanged, proxy, &QSortFilterProxyModel::setFilterFixedString); 0078 0079 // unused dependencies tab 0080 proxy = new QSortFilterProxyModel(this); 0081 proxy->setFilterCaseSensitivity(Qt::CaseInsensitive); 0082 proxy->setFilterKeyColumn(-1); 0083 proxy->setSourceModel(m_unusedDependenciesModel); 0084 ui->unusedDependencyView->setModel(proxy); 0085 ui->unusedDependencyView->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); 0086 connect(ui->unusedSearchLine, &QLineEdit::textChanged, proxy, &QSortFilterProxyModel::setFilterFixedString); 0087 connect(ui->tabWidget, &QTabWidget::currentChanged, this, [this]{ 0088 if (ui->tabWidget->currentWidget() == ui->unusedDependenciesTab) 0089 m_unusedDependenciesModel->findUnusedDependencies(); 0090 }); 0091 0092 addAction(ui->actionOptimizeDependencyOrder); 0093 connect(ui->actionOptimizeDependencyOrder, &QAction::triggered, this, [this]() { 0094 const auto selection = ui->dependencyView->selectionModel()->selectedRows(); 0095 if (selection.isEmpty()) 0096 return; 0097 const auto idx = selection.first(); 0098 const auto f = idx.data(DependencyModel::ProviderFileRole).value<ElfFile*>(); 0099 if (f) { 0100 qDebug() << f->fileName(); 0101 ElfFileSet set; 0102 set.addFile(f->fileName()); 0103 DependencySorter sorter; 0104 sorter.sortDtNeeded(&set); 0105 0106 // TODO reload file set! 0107 } 0108 }); 0109 } 0110 0111 DependencyView::~DependencyView() = default; 0112 0113 void DependencyView::setFileSet(ElfFileSet* fileSet) 0114 { 0115 m_dependencyModel->setFileSet(fileSet); 0116 if (m_dependencyModel->rowCount() > 0) 0117 ui->dependencyView->expand(m_dependencyModel->index(0, 0)); 0118 m_fileListModel->setFileSet(fileSet); 0119 m_unusedDependenciesModel->setFileSet(fileSet); 0120 if (ui->tabWidget->currentWidget() == ui->unusedDependenciesTab) 0121 m_unusedDependenciesModel->findUnusedDependencies(); 0122 } 0123 0124 void DependencyView::search(const QString& text) 0125 { 0126 if (text.isEmpty()) 0127 return; 0128 0129 const auto result = m_dependencyModel->match(m_dependencyModel->index(0, 0), Qt::DisplayRole, text, 1, Qt::MatchContains | Qt::MatchRecursive); 0130 if (result.isEmpty()) 0131 return; 0132 const auto index = result.first(); 0133 ui->dependencyView->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); 0134 ui->dependencyView->scrollTo(index); 0135 } 0136 0137 void DependencyView::dependencySelected(const QItemSelection& selection) 0138 { 0139 if (selection.isEmpty()) 0140 return; 0141 const auto idx = selection.first().topLeft(); 0142 0143 auto user = idx.data(DependencyModel::UserFileRole).value<ElfFile*>(); 0144 auto provider = idx.data(DependencyModel::ProviderFileRole).value<ElfFile*>(); 0145 m_symbolModel->setFiles(user, provider); 0146 } 0147 0148 void DependencyView::inverseFileSelected(const QItemSelection& selection) 0149 { 0150 if (selection.isEmpty()) { 0151 m_fileUserModel->setFile(nullptr, nullptr); 0152 return; 0153 } 0154 0155 const auto idx = selection.first().topLeft(); 0156 m_fileUserModel->setFile(m_fileListModel->fileSet(), idx.data(FileListModel::FileRole).value<ElfFile*>()); 0157 } 0158 0159 void DependencyView::inverseUserSelected(const QItemSelection& selection) 0160 { 0161 if (selection.isEmpty()) { 0162 m_inverseSymbolModel->setFiles(nullptr, nullptr); 0163 return; 0164 } 0165 0166 const auto idx = selection.first().topLeft(); 0167 m_inverseSymbolModel->setFiles(idx.data(FileUserModel::FileRole).value<ElfFile*>(), m_fileUserModel->usedFile()); 0168 }