1// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#include "jsprojectgenerator.h"
6#include "jsasynparse.h"
7#include "properties/configpropertywidget.h"
8#include "common/dialog/propertiesdialog.h"
9#include "services/window/windowservice.h"
10#include "services/builder/builderservice.h"
11#include "services/option/optionmanager.h"
12
13#include <QtConcurrent>
14#include <QtXml>
15#include <QFileIconProvider>
16
17using namespace dpfservice;
18class JSProjectGeneratorPrivate
19{
20 friend class JSProjectGenerator;
21 QStandardItem* configureRootItem {nullptr};
22 QMenu *jsMenu {nullptr};
23 QProcess *menuGenProcess {nullptr};
24 QHash<QStandardItem*, JSAsynParse*> projectParses {};
25};
26
27JSProjectGenerator::JSProjectGenerator()
28 : d(new JSProjectGeneratorPrivate())
29{
30 ProjectService *projectService = dpfGetService(ProjectService);
31 if (!projectService) {
32 qCritical() << "Failed, not found service : projectService";
33 abort();
34 }
35}
36
37JSProjectGenerator::~JSProjectGenerator()
38{
39 qInfo() << __FUNCTION__;
40
41 if (d)
42 delete d;
43}
44
45QStringList JSProjectGenerator::supportLanguages()
46{
47 return {"JS"};
48}
49
50QDialog *JSProjectGenerator::configureWidget(const QString &language,
51 const QString &projectPath)
52{
53 ProjectInfo info;
54 info.setLanguage(language);
55 info.setKitName(JSProjectGenerator::toolKitName());
56 info.setWorkspaceFolder(projectPath);
57
58 configure(info);
59
60 return nullptr;
61}
62
63bool JSProjectGenerator::configure(const ProjectInfo &info)
64{
65 ProjectGenerator::configure(info);
66
67 auto root = createRootItem(info);
68 auto &ctx = dpfInstance.serviceContext();
69 ProjectService *projectService = ctx.service<ProjectService>(ProjectService::name());
70 if (projectService && root) {
71 projectService->projectView.addRootItem(root);
72 projectService->projectView.expandedDepth(root, 1);
73 }
74
75 return true;
76}
77
78QStandardItem *JSProjectGenerator::createRootItem(const ProjectInfo &info)
79{
80 QStandardItem * rootItem = ProjectGenerator::createRootItem(info);
81
82 d->projectParses[rootItem] = new JSAsynParse();
83 QObject::connect(d->projectParses[rootItem],
84 &JSAsynParse::itemsModified,
85 this, &JSProjectGenerator::doProjectChildsModified,
86 Qt::ConnectionType::UniqueConnection);
87
88 ProjectInfo tempInfo = info;
89 d->projectParses[rootItem]->parseProject(tempInfo);
90 ProjectInfo::set(rootItem, tempInfo);
91
92 return rootItem;
93}
94
95void JSProjectGenerator::removeRootItem(QStandardItem *root)
96{
97 if (!root)
98 return;
99 auto parser = d->projectParses[root];
100
101 while (root->hasChildren()) {
102 root->takeRow(0);
103 }
104 d->projectParses.remove(root);
105
106 delete root;
107
108 if (parser)
109 delete parser;
110}
111
112QMenu *JSProjectGenerator::createItemMenu(const QStandardItem *item)
113{
114 if (item->parent())
115 return nullptr;
116
117 QMenu *menu = new QMenu();
118 ProjectInfo info = ProjectInfo::get(item);
119 if (info.isEmpty())
120 return nullptr;
121
122 QStandardItem *itemTemp = const_cast<QStandardItem *>(item);
123 if (!itemTemp)
124 return nullptr;
125
126 QAction *action = new QAction(tr("Properties"));
127 menu->addAction(action);
128 QObject::connect(action, &QAction::triggered, [=](){
129 actionProperties(info, itemTemp);
130 });
131
132 return menu;
133}
134
135void JSProjectGenerator::doProjectChildsModified(const QList<QStandardItem *> &info)
136{
137 auto rootItem = d->projectParses.key(qobject_cast<JSAsynParse*>(sender()));
138 if (rootItem) {
139 while (rootItem->hasChildren()) {
140 rootItem->takeRow(0);
141 }
142 rootItem->appendRows(info);
143 }
144}
145
146void JSProjectGenerator::doJSCleanMenu()
147{
148 if (d->jsMenu) {
149 for (auto &action : d->jsMenu->actions()) {
150 d->jsMenu->removeAction(action);
151 }
152 }
153}
154
155void JSProjectGenerator::actionProperties(const ProjectInfo &info, QStandardItem *item)
156{
157 PropertiesDialog dlg;
158 ConfigPropertyWidget *property = new ConfigPropertyWidget(info, item);
159 dlg.insertPropertyPanel("Config", property);
160 dlg.exec();
161}
162