File indexing completed on 2024-05-19 05:42:22

0001 // ct_lvtqtc_pluginmanagerutils.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 <QDockWidget>
0021 #include <QFormLayout>
0022 #include <QLabel>
0023 #include <QLineEdit>
0024 #include <QTreeView>
0025 #include <ct_lvtqtc_lakosentitypluginutils.h>
0026 #include <ct_lvtqtc_pluginmanagerutils.h>
0027 
0028 namespace Codethink::lvtqtc {
0029 
0030 using lvtplg::PluginManager;
0031 using QtUserDataMap = QMap<QString, void *>;
0032 
0033 PluginTreeItemHandler PluginManagerQtUtils::createPluginTreeItemHandler(
0034     PluginManager *pm, QTreeView *treeView, QStandardItemModel *treeModel, QStandardItem *item, GraphicsScene *gs)
0035 {
0036     auto getPluginData = [pm](auto&& id) {
0037         return pm->getPluginData(id);
0038     };
0039     auto addItem = [pm, treeView, treeModel, item, gs](std::string const& label) {
0040         auto *child = new QStandardItem(QString::fromStdString(label));
0041         child->setData(QVariant::fromValue(QtUserDataMap{}));
0042         item->appendRow(child);
0043         return createPluginTreeItemHandler(pm, treeView, treeModel, child, gs);
0044     };
0045     auto addOnClickAction = [pm, treeView, treeModel, item, gs](
0046                                 std::function<void(PluginTreeItemClickedActionHandler * selectedItem)> const& f) {
0047         QObject::connect(treeView,
0048                          &QTreeView::clicked,
0049                          treeView,
0050                          [pm, item, f, treeView, treeModel, gs](const QModelIndex& index) {
0051                              auto *selectedItem = qobject_cast<QStandardItemModel *>(treeModel)->itemFromIndex(index);
0052                              if (selectedItem != item) {
0053                                  return;
0054                              }
0055                              auto handler = createPluginTreeItemClickedActionHandler(pm, treeView, treeModel, item, gs);
0056                              f(&handler);
0057                          });
0058     };
0059     auto addUserData = [item](std::string const& dataId, void *userData) {
0060         auto userDataMap = item->data().value<QtUserDataMap>();
0061         userDataMap[QString::fromStdString(dataId)] = userData;
0062         item->setData(QVariant::fromValue(userDataMap));
0063     };
0064     auto getUserData = [item](std::string const& dataId) {
0065         auto userDataMap = item->data().value<QtUserDataMap>();
0066         return userDataMap[QString::fromStdString(dataId)];
0067     };
0068     return PluginTreeItemHandler{getPluginData, addItem, addUserData, getUserData, addOnClickAction};
0069 }
0070 
0071 PluginTreeWidgetHandler
0072 PluginManagerQtUtils::createPluginTreeWidgetHandler(PluginManager *pm, std::string const& id, GraphicsScene *gs)
0073 {
0074     auto getPluginData = [pm](auto&& id) {
0075         return pm->getPluginData(id);
0076     };
0077     auto addRootItem = [pm, id, gs](std::string const& label) -> PluginTreeItemHandler {
0078         auto *treeView = dynamic_cast<QTreeView *>(pm->getPluginQObject(id + "::view"));
0079         auto *treeModel = dynamic_cast<QStandardItemModel *>(pm->getPluginQObject(id + "::model"));
0080         auto *item = new QStandardItem(QString::fromStdString(label));
0081         item->setData(QVariant::fromValue(QtUserDataMap{}));
0082         treeModel->invisibleRootItem()->appendRow(item);
0083         return PluginManagerQtUtils::createPluginTreeItemHandler(pm, treeView, treeModel, item, gs);
0084     };
0085 
0086     auto clear = [pm, id]() {
0087         auto *treeModel = dynamic_cast<QStandardItemModel *>(pm->getPluginQObject(id + "::model"));
0088         treeModel->clear();
0089     };
0090 
0091     return PluginTreeWidgetHandler{getPluginData, addRootItem, clear};
0092 }
0093 
0094 PluginTreeItemClickedActionHandler PluginManagerQtUtils::createPluginTreeItemClickedActionHandler(
0095     PluginManager *pm, QTreeView *treeView, QStandardItemModel *treeModel, QStandardItem *item, GraphicsScene *gs)
0096 {
0097     auto getPluginData = [pm](auto&& id) {
0098         return pm->getPluginData(id);
0099     };
0100     auto getItem = [pm, treeView, treeModel, item, gs]() {
0101         return createPluginTreeItemHandler(pm, treeView, treeModel, item, gs);
0102     };
0103     auto getGraphicsView = [gs]() {
0104         return createPluginGraphicsViewHandler(gs);
0105     };
0106 
0107     return PluginTreeItemClickedActionHandler{getPluginData, getItem, getGraphicsView};
0108 }
0109 
0110 PluginGraphicsViewHandler PluginManagerQtUtils::createPluginGraphicsViewHandler(GraphicsScene *gs)
0111 {
0112     auto getEntityByQualifiedName = [gs](std::string const& qualifiedName) -> std::optional<Entity> {
0113         auto *e = gs->entityByQualifiedName(qualifiedName);
0114         if (!e) {
0115             return std::nullopt;
0116         }
0117         return createWrappedEntityFromLakosEntity(e);
0118     };
0119     auto getVisibleEntities = [gs]() {
0120         auto entities = std::vector<Entity>{};
0121         for (auto&& e : gs->allEntities()) {
0122             entities.push_back(createWrappedEntityFromLakosEntity(e));
0123         }
0124         return entities;
0125     };
0126     auto getEdgeByQualifiedName = [gs](std::string const& fromQualifiedName,
0127                                        std::string const& toQualifiedName) -> std::optional<Edge> {
0128         auto *fromEntity = gs->entityByQualifiedName(fromQualifiedName);
0129         if (!fromEntity) {
0130             return std::nullopt;
0131         }
0132         auto *toEntity = gs->entityByQualifiedName(toQualifiedName);
0133         if (!toEntity) {
0134             return std::nullopt;
0135         }
0136         return createWrappedEdgeFromLakosEntity(fromEntity, toEntity);
0137     };
0138 
0139     return PluginGraphicsViewHandler{getEntityByQualifiedName, getVisibleEntities, getEdgeByQualifiedName};
0140 }
0141 
0142 PluginDockWidgetHandler PluginManagerQtUtils::createPluginDockWidgetHandler(PluginManager *pm,
0143                                                                             std::string const& dockId)
0144 {
0145     auto addDockWdgFileField = [pm, dockId](std::string const& label, std::string& dataModel) {
0146         auto *pluginDockWidget = dynamic_cast<QDockWidget *>(pm->getPluginQObject(dockId));
0147         if (pluginDockWidget == nullptr) {
0148             return;
0149         }
0150         auto *lineEdit = new QLineEdit();
0151         QObject::connect(lineEdit, &QLineEdit::textChanged, pluginDockWidget, [&dataModel](QString const& newText) {
0152             dataModel = newText.toStdString();
0153         });
0154         auto *formLayout = dynamic_cast<QFormLayout *>(pluginDockWidget->widget()->layout());
0155         formLayout->addRow(new QLabel(QString::fromStdString(label)), lineEdit);
0156     };
0157     auto addTree = [pm, dockId](std::string const& treeId) {
0158         auto *pluginDockWidget = dynamic_cast<QDockWidget *>(pm->getPluginQObject(dockId));
0159         if (pluginDockWidget == nullptr) {
0160             return;
0161         }
0162         auto *treeView = new QTreeView(pluginDockWidget);
0163         auto *treeModel = new QStandardItemModel{treeView};
0164         treeView->setHeaderHidden(true);
0165         treeView->setModel(treeModel);
0166         auto *formLayout = dynamic_cast<QFormLayout *>(pluginDockWidget->widget()->layout());
0167         formLayout->addRow(treeView);
0168         pm->registerPluginQObject(treeId + "::view", treeView);
0169         pm->registerPluginQObject(treeId + "::model", treeModel);
0170     };
0171     auto setVisible = [pm, dockId](bool visible) {
0172         auto *pluginDockWidget = dynamic_cast<QDockWidget *>(pm->getPluginQObject(dockId));
0173         if (pluginDockWidget == nullptr) {
0174             return;
0175         }
0176         pluginDockWidget->setVisible(visible);
0177     };
0178 
0179     return PluginDockWidgetHandler{addDockWdgFileField, addTree, setVisible};
0180 }
0181 
0182 } // namespace Codethink::lvtqtc