1// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#include "gradleasynparse.h"
6#include "services/project/projectgenerator.h"
7
8#include "common/common.h"
9
10#include <QAction>
11#include <QDebug>
12#include <QtXml>
13
14class GradleAsynParsePrivate
15{
16 friend class GradleAsynParse;
17 QDomDocument xmlDoc;
18 QThread *thread {nullptr};
19 QString rootPath;
20 QList<QStandardItem *> rows {};
21};
22
23GradleAsynParse::GradleAsynParse()
24 : d(new GradleAsynParsePrivate)
25{
26 QObject::connect(this, &QFileSystemWatcher::directoryChanged,
27 this, &GradleAsynParse::doDirectoryChanged);
28
29 d->thread = new QThread();
30 this->moveToThread(d->thread);
31 d->thread->start();
32}
33
34GradleAsynParse::~GradleAsynParse()
35{
36 if (d) {
37 if (d->thread) {
38 if (d->thread->isRunning())
39 d->thread->quit();
40 d->thread->wait();
41 d->thread->deleteLater();
42 d->thread = nullptr;
43 }
44 delete d;
45 }
46}
47
48void GradleAsynParse::parseProject(const dpfservice::ProjectInfo &info)
49{
50 createRows(info.workspaceFolder());
51 emit itemsModified(d->rows);
52}
53
54void GradleAsynParse::doDirectoryChanged(const QString &path)
55{
56 if (!path.startsWith(d->rootPath))
57 return;
58
59 d->rows.clear();
60
61 createRows(d->rootPath);
62
63 emit itemsModified(d->rows);
64}
65
66QString GradleAsynParse::itemDisplayName(const QStandardItem *item) const
67{
68 if (!item)
69 return "";
70 return item->data(Qt::DisplayRole).toString();
71}
72
73void GradleAsynParse::createRows(const QString &path)
74{
75 QString rootPath = path;
76 if (rootPath.endsWith(QDir::separator())) {
77 int separatorSize = QString(QDir::separator()).size();
78 rootPath = rootPath.remove(rootPath.size() - separatorSize, separatorSize);
79 }
80
81 // 缓存当前工程目录
82 d->rootPath = rootPath;
83 QFileSystemWatcher::addPath(d->rootPath);
84
85 {// 避免变量冲突 迭代文件夹
86 QDir dir;
87 dir.setPath(rootPath);
88 dir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
89 dir.setSorting(QDir::Name);
90 QDirIterator dirItera(dir, QDirIterator::Subdirectories);
91 while (dirItera.hasNext()) {
92 QString childPath = dirItera.next().remove(0, rootPath.size());
93 QFileSystemWatcher::addPath(dirItera.filePath());
94 QStandardItem *item = findItem(childPath);
95 QIcon icon = CustomIcons::icon(dirItera.fileInfo());
96 auto newItem = new QStandardItem(icon, dirItera.fileName());
97 newItem->setToolTip(dirItera.filePath());
98 if (!item) {
99 d->rows.append(newItem);
100 } else {
101 item->appendRow(newItem);
102 }
103 }
104 }
105 {// 避免变量冲突 迭代文件
106 QDir dir;
107 dir.setPath(rootPath);
108 dir.setFilter(QDir::NoDotAndDotDot | QDir::Files);
109 dir.setSorting(QDir::Name);
110 QDirIterator fileItera(dir, QDirIterator::Subdirectories);
111 while (fileItera.hasNext()) {
112 QString childPath = fileItera.next().remove(0, rootPath.size());
113 QStandardItem *item = findItem(childPath);
114 QIcon icon = CustomIcons::icon(fileItera.fileInfo());
115 auto newItem = new QStandardItem(icon, fileItera.fileName());
116 newItem->setToolTip(fileItera.filePath());
117 if (!item) {
118 d->rows.append(newItem);
119 } else {
120 item->appendRow(newItem);
121 }
122 }
123 }
124}
125
126QList<QStandardItem *> GradleAsynParse::rows(const QStandardItem *item) const
127{
128 QList<QStandardItem *> result;
129 for (int i = 0; i < item->rowCount(); i++) {
130 result << item->child(i);
131 }
132 return result;
133}
134
135QStandardItem *GradleAsynParse::findItem(const QString &path,
136 QStandardItem *parent) const
137{
138 QString pathTemp = path;
139 if (pathTemp.endsWith(QDir::separator())) {
140 pathTemp = pathTemp.remove(pathTemp.size() - separatorSize(), separatorSize());
141 }
142
143 if (pathTemp.startsWith(QDir::separator()))
144 pathTemp.remove(0, separatorSize());
145
146 if (pathTemp.endsWith(QDir::separator()))
147 pathTemp.remove(pathTemp.size() - separatorSize(), separatorSize());
148
149 if (pathTemp.isEmpty())
150 return parent;
151
152 QStringList splitPaths = pathTemp.split(QDir::separator());
153 QString name = splitPaths.takeFirst();
154
155 QList<QStandardItem*> currRows{};
156 if (parent) {
157 currRows = rows(parent);
158 } else {
159 currRows = d->rows;
160 }
161
162 for (int i = 0; i < currRows.size(); i++) {
163 QStandardItem *child = currRows[i];
164 if (name == itemDisplayName(child)) {
165 if (splitPaths.isEmpty()) {
166 return child;
167 } else {
168 return findItem(splitPaths.join(QDir::separator()), child);
169 }
170 }
171 }
172 return parent;
173}
174
175int GradleAsynParse::separatorSize() const
176{
177 return QString(QDir::separator()).size();
178}
179