File indexing completed on 2024-05-19 05:42:19
0001 // ct_lvtqtc_inspect_dependency_window.cpp -*-C++-*- 0002 0003 /* 0004 // Copyright 2023 Codethink Ltd <codethink@codethink.co.uk> 0005 // SPDX-License-Identifier: Apache-2.0 0006 // 0007 // Licensed under the Apache License, Version 2.0 (the "License"); 0008 // you may not use this file except in compliance with the License. 0009 // You may obtain a copy of the License at 0010 // 0011 // http://www.apache.org/licenses/LICENSE-2.0 0012 // 0013 // Unless required by applicable law or agreed to in writing, software 0014 // distributed under the License is distributed on an "AS IS" BASIS, 0015 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0016 // See the License for the specific language governing permissions and 0017 // limitations under the License. 0018 */ 0019 0020 #include <ct_lvtprj_projectfile.h> 0021 #include <ct_lvtqtc_inspect_dependency_window.h> 0022 0023 #include <QDebug> 0024 #include <QDesktopServices> 0025 #include <QDialog> 0026 #include <QFileInfo> 0027 #include <QGraphicsScene> 0028 #include <QHeaderView> 0029 #include <QLabel> 0030 #include <QLayout> 0031 #include <QLine> 0032 #include <QMessageBox> 0033 #include <QUrl> 0034 0035 Q_DECLARE_METATYPE(Codethink::lvtldr::LakosianNode *) 0036 0037 namespace Codethink::lvtqtc { 0038 0039 InspectDependencyWindow::InspectDependencyWindow(lvtprj::ProjectFile const& projectFile, 0040 LakosRelation const& r, 0041 QDialog *parent): 0042 QDialog(parent), d_lakosRelation(r), d_projectFile(projectFile) 0043 { 0044 setWindowModality(Qt::ApplicationModal); 0045 setWindowTitle(tr("Dependency inspector")); 0046 setMinimumWidth(600); 0047 setMinimumHeight(400); 0048 0049 setupUi(); 0050 0051 d_contentsTable->setContextMenuPolicy(Qt::CustomContextMenu); 0052 connect(d_contentsTable, &QTableWidget::customContextMenuRequested, this, [this](const QPoint& pos) { 0053 QTableWidgetItem *item = d_contentsTable->itemAt(pos); 0054 if (!item) { 0055 return; 0056 } 0057 0058 auto *menu = item->data(MenuRole).value<QMenu *>(); 0059 if (!menu) { 0060 return; 0061 } 0062 0063 menu->exec(pos); 0064 }); 0065 populateContentsTable(); 0066 } 0067 0068 void InspectDependencyWindow::setupUi() 0069 { 0070 auto *from = d_lakosRelation.from(); 0071 auto *to = d_lakosRelation.to(); 0072 auto *layout = new QVBoxLayout{this}; 0073 auto *titleLabel = new QLabel{this}; 0074 titleLabel->setText(tr("Inspect dependencies from %1 to %2") 0075 .arg(QString::fromStdString(from->name()), QString::fromStdString(to->name()))); 0076 titleLabel->setStyleSheet("font-weight: bold;"); 0077 0078 layout->addWidget(titleLabel); 0079 d_contentsTable = new QTableWidget{this}; 0080 d_contentsTable->setColumnCount(2); 0081 d_contentsTable->setHorizontalHeaderLabels({tr("From component"), tr("To component")}); 0082 0083 auto *header = d_contentsTable->horizontalHeader(); 0084 header->setMinimumSectionSize(10); 0085 header->setSectionResizeMode(0, QHeaderView::Stretch); 0086 header->setSectionResizeMode(1, QHeaderView::Stretch); 0087 layout->addWidget(d_contentsTable); 0088 0089 // make the scrollbar touch the window frame on the right. 0090 layout->setSpacing(0); 0091 layout->setContentsMargins(6, 6, 0, 6); 0092 setLayout(layout); 0093 } 0094 0095 void InspectDependencyWindow::openFile(lvtldr::LakosianNode *pkg, lvtldr::LakosianNode *component, const QString& ext) 0096 { 0097 auto prefix = d_projectFile.sourceCodePath(); 0098 auto filepath = [&]() { 0099 if (pkg->parent()) { 0100 return QString::fromStdString( 0101 (prefix / "groups" / pkg->parent()->name() / pkg->name() / component->name()).string()) 0102 + ext; 0103 } 0104 return QString::fromStdString((prefix / "standalones" / pkg->name() / component->name()).string()) + ext; 0105 }(); 0106 0107 if (!QFileInfo::exists(filepath) || !QDesktopServices::openUrl(QUrl::fromLocalFile(filepath))) { 0108 showFileNotFoundWarning(filepath); 0109 } 0110 } 0111 0112 void InspectDependencyWindow::showFileNotFoundWarning(QString const& filepath) const 0113 { 0114 QMessageBox::warning(nullptr, tr("Warning"), tr("File not found: %1").arg(filepath)); 0115 } 0116 0117 void InspectDependencyWindow::populateContentsTable() 0118 { 0119 auto *from = d_lakosRelation.from(); 0120 auto *to = d_lakosRelation.to(); 0121 0122 auto createContentActionButton = [&](lvtldr::LakosianNode *fromChild) -> QMenu * { 0123 auto *menu = new QMenu(); 0124 auto *open_source = menu->addAction(tr("Open source")); 0125 connect(open_source, &QAction::triggered, this, [this, from, fromChild] { 0126 openFile(from->internalNode(), fromChild, ".cpp"); 0127 }); 0128 0129 auto *open_header = menu->addAction(tr("Open header")); 0130 connect(open_header, &QAction::triggered, this, [this, from, fromChild] { 0131 openFile(from->internalNode(), fromChild, ".h"); 0132 }); 0133 0134 auto *open_test = menu->addAction(tr("Open test")); 0135 connect(open_test, &QAction::triggered, this, [this, from, fromChild] { 0136 openFile(from->internalNode(), fromChild, ".t.cpp"); 0137 }); 0138 return menu; 0139 }; 0140 0141 for (auto const& fromChild : from->internalNode()->children()) { 0142 for (auto const& dep : fromChild->providers()) { 0143 if (dep.other()->parent() == to->internalNode()) { 0144 auto const& toChild = dep.other(); 0145 auto *fromItem = new QTableWidgetItem(); 0146 fromItem->setText(QString::fromStdString(fromChild->name())); 0147 fromItem->setFlags(Qt::ItemFlag::ItemIsEnabled); 0148 auto *toItem = new QTableWidgetItem(); 0149 toItem->setText(QString::fromStdString(toChild->name())); 0150 toItem->setFlags(Qt::ItemFlag::ItemIsEnabled); 0151 0152 auto i = d_contentsTable->rowCount(); 0153 d_contentsTable->insertRow(i); 0154 d_contentsTable->setItem(i, 0, fromItem); 0155 d_contentsTable->setItem(i, 1, toItem); 0156 fromItem->setData(MenuRole, QVariant::fromValue(createContentActionButton(fromChild))); 0157 } 0158 } 0159 } 0160 } 0161 0162 } // namespace Codethink::lvtqtc