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 | |
14 | class GradleAsynParsePrivate |
15 | { |
16 | friend class GradleAsynParse; |
17 | QDomDocument xmlDoc; |
18 | QThread *thread {nullptr}; |
19 | QString rootPath; |
20 | QList<QStandardItem *> rows {}; |
21 | }; |
22 | |
23 | GradleAsynParse::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 | |
34 | GradleAsynParse::~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 | |
48 | void GradleAsynParse::parseProject(const dpfservice::ProjectInfo &info) |
49 | { |
50 | createRows(info.workspaceFolder()); |
51 | emit itemsModified(d->rows); |
52 | } |
53 | |
54 | void 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 | |
66 | QString GradleAsynParse::itemDisplayName(const QStandardItem *item) const |
67 | { |
68 | if (!item) |
69 | return "" ; |
70 | return item->data(Qt::DisplayRole).toString(); |
71 | } |
72 | |
73 | void 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 | |
126 | QList<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 | |
135 | QStandardItem *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 | |
175 | int GradleAsynParse::separatorSize() const |
176 | { |
177 | return QString(QDir::separator()).size(); |
178 | } |
179 | |