1// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#include "maindialog.h"
6
7#include "detailwidget.h"
8
9#include "services/language/languageservice.h"
10
11#include <QLabel>
12#include <QTreeView>
13#include <QHBoxLayout>
14#include <QPushButton>
15#include <QStandardItemModel>
16#include <QListWidget>
17#include <QMessageBox>
18#include <QDebug>
19#include <QUuid>
20#include <QStackedWidget>
21
22using namespace dpfservice;
23
24class MainDialogPrivate
25{
26 friend class MainDialog;
27 QMap<QString, DetailWidget*> detailWidgetMap;
28 QStackedWidget *detailStackedWidget = nullptr;
29 QWidget *blankWidget = nullptr;
30};
31
32MainDialog::MainDialog(QDialog *parent)
33 : QDialog(parent)
34 , d(new MainDialogPrivate())
35{
36 setWindowTitle(tr("New File or Project"));
37 setMinimumSize(850, 550);
38
39 TemplateVector templateVec;
40 TemplateParser::readTemplateConfig(templateVec);
41
42 setupUI(templateVec);
43}
44
45MainDialog::~MainDialog()
46{
47 if (d)
48 delete d;
49}
50
51void MainDialog::setupUI(TemplateVector &templateVec)
52{
53 QLabel * title = new QLabel(tr("Choose a template:"));
54
55 d->detailStackedWidget = new QStackedWidget();
56 d->blankWidget = new DetailWidget(this);
57 d->detailStackedWidget->addWidget(d->blankWidget);
58
59 QTreeView * treeView = new QTreeView();
60 treeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
61 treeView->setSelectionMode(QAbstractItemView::SingleSelection);
62 treeView->setSelectionBehavior(QAbstractItemView::SelectItems);
63
64 QStandardItemModel *standardModel = new QStandardItemModel();
65 standardModel->setHorizontalHeaderLabels(QStringList{tr("Templates")});
66
67 QStandardItem * rootItem = standardModel->invisibleRootItem();
68
69 for (auto iterTpl = templateVec.begin(); iterTpl != templateVec.end(); ++iterTpl) {
70 QStandardItem *tpl = new QStandardItem(iterTpl->category);
71 rootItem->appendRow(tpl);
72
73 QVector<TemplateCategory> tplVec = iterTpl->templateVec;
74 for (auto iterCate = tplVec.begin(); iterCate != tplVec.end(); ++iterCate) {
75 QStandardItem *typeItem = new QStandardItem(iterCate->type);
76 tpl->appendRow(typeItem);
77
78 auto iterDetail = iterCate->templateVec.begin();
79 for (; iterDetail != iterCate->templateVec.end(); ++iterDetail) {
80 QStandardItem *detailItem = new QStandardItem(iterDetail->name);
81 TemplateDetail detail;
82 detail.name = iterDetail->name;
83 detail.path = iterDetail->path;
84 detail.leafNode = iterDetail->leafNode;
85
86 detailItem->setData(QVariant::fromValue(detail), Qt::UserRole + 1);
87 detailItem->setData(QVariant::fromValue(QUuid::createUuid().toString()), Qt::UserRole + 2);
88 typeItem->appendRow(detailItem);
89 }
90 }
91
92 treeView->setModel(standardModel);
93 }
94
95 connect(treeView, &QTreeView::clicked, [=](){
96 QModelIndex index = treeView->selectionModel()->currentIndex();
97 if (!index.isValid()){
98 d->detailStackedWidget->setCurrentWidget(d->blankWidget);
99 return;
100 }
101
102 QVariant varDetail = index.data(Qt::UserRole + 1);
103 if (!varDetail.isValid()){
104 d->detailStackedWidget->setCurrentWidget(d->blankWidget);
105 return;
106 }
107
108 TemplateDetail detail = varDetail.value<TemplateDetail>();
109 if (!detail.leafNode) {
110 d->detailStackedWidget->setCurrentWidget(d->blankWidget);
111 return;
112 }
113
114 QVariant varUuid = index.data(Qt::UserRole + 2);
115 if (!varUuid.isValid()){
116 d->detailStackedWidget->setCurrentWidget(d->blankWidget);
117 return;
118 }
119
120 QString uuid = varUuid.value<QString>();
121 if (d->detailWidgetMap.contains(uuid)) {
122 DetailWidget * detailWidget = d->detailWidgetMap.value(uuid);
123 if (detailWidget) {
124 d->detailStackedWidget->setCurrentWidget(detailWidget);
125 }
126 } else {
127 DetailWidget * detailWidget = new DetailWidget(detail.path, this);
128 d->detailWidgetMap.insert(uuid, detailWidget);
129 d->detailStackedWidget->addWidget(detailWidget);
130 d->detailStackedWidget->setCurrentWidget(detailWidget);
131 }
132 });
133
134 QVBoxLayout *vItemLayout = new QVBoxLayout();
135 vItemLayout->addWidget(treeView);
136
137 QWidget *contentWidget = new QWidget();
138 QHBoxLayout *hLayout = new QHBoxLayout();
139 contentWidget->setLayout(hLayout);
140 hLayout->addLayout(vItemLayout);
141 hLayout->addWidget(d->detailStackedWidget);
142 hLayout->setStretchFactor(vItemLayout, 1);
143 hLayout->setStretchFactor(d->detailStackedWidget, 2);
144
145 QWidget *bottomWidget = new QWidget();
146 QHBoxLayout * bottomLayout = new QHBoxLayout();
147 bottomWidget->setLayout(bottomLayout);
148
149 QPushButton *create = new QPushButton(tr("Create"));
150 QPushButton *cancel = new QPushButton(tr("Cancel"));
151 bottomLayout->addStretch(15);
152 bottomLayout->addWidget(create, Qt::AlignRight);
153 bottomLayout->addWidget(cancel, Qt::AlignRight);
154
155 connect(create, &QPushButton::clicked, [&](){
156 DetailWidget *detailWidget = dynamic_cast<DetailWidget*>(d->detailStackedWidget->currentWidget());
157 if (detailWidget) {
158 PojectGenParam param;
159 if (detailWidget->getGenParams(param)) {
160 generate(param);
161 }
162 }
163 });
164
165 connect(cancel, &QPushButton::clicked, [&](){
166 close();
167 });
168
169 QVBoxLayout *vLayout = new QVBoxLayout();
170 vLayout->addWidget(title);
171 vLayout->addWidget(contentWidget);
172 vLayout->addWidget(bottomWidget);
173
174 setLayout(vLayout);
175}
176
177void MainDialog::generate(const PojectGenParam &param)
178{
179 ProjectGenerate projectGen;
180 PojectGenResult result;
181 if (!projectGen.create(result, param)) {
182 QMessageBox::critical(this, tr("Tip"), result.message);
183 return;
184 }
185
186 if (param.type == Project) {
187 auto &ctx = dpfInstance.serviceContext();
188 LanguageService *service = ctx.service<LanguageService>(LanguageService::name());
189 if (service) {
190 auto generator = service->create<LanguageGenerator>(result.kit);
191 if (generator) {
192 close();
193 project.openProject(result.kit, result.language, result.projectPath);
194 } else {
195 QMessageBox::critical(this, tr("Tip"), tr("Can not find kit."));
196 }
197 }
198 } else if (param.type == File) {
199 close();
200 editor.openFile(result.filePath);
201 }
202}
203