1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Designer of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28
29 #include "qtresourceeditordialog_p.h"
30 #include "ui_qtresourceeditordialog.h"
31 #include "qtresourcemodel_p.h"
32 #include "iconloader_p.h"
33
34 #include <abstractdialoggui_p.h>
35
36 #include <QtDesigner/abstractsettings.h>
37 #include <QtDesigner/abstractformeditor.h>
38
39 #include <QtCore/qfileinfo.h>
40 #include <QtCore/qdir.h>
41 #include <QtCore/qcoreapplication.h>
42 #include <QtXml/qdom.h>
43 #include <QtWidgets/qmenu.h>
44 #include <QtWidgets/qheaderview.h>
45 #include <QtWidgets/qinputdialog.h>
46 #include <QtWidgets/qmessagebox.h>
47 #include <QtWidgets/qpushbutton.h>
48 #include <QtGui/qstandarditemmodel.h>
49
50 QT_BEGIN_NAMESPACE
51
52 static const char *rccRootTag = "RCC";
53 static const char *rccTag = "qresource";
54 static const char *rccFileTag = "file";
55 static const char *rccAliasAttribute = "alias";
56 static const char *rccPrefixAttribute = "prefix";
57 static const char *rccLangAttribute = "lang";
58 static const char *SplitterPosition = "SplitterPosition";
59 static const char *Geometry = "Geometry";
60 static const char *QrcDialogC = "QrcDialog";
61
msgOverwrite(const QString & fname)62 static QString msgOverwrite(const QString &fname)
63 {
64 return QCoreApplication::translate("QtResourceEditorDialog", "%1 already exists.\nDo you want to replace it?").arg(fname);
65 }
66
msgTagMismatch(const QString & got,const QString & expected)67 static QString msgTagMismatch(const QString &got, const QString &expected)
68 {
69 return QCoreApplication::translate("QtResourceEditorDialog", "The file does not appear to be a resource file; element '%1' was found where '%2' was expected.").arg(got, expected);
70 }
71
72 namespace {
73
74 // below 3 data classes should be derived from QSharedData and made implicit shared class
75 struct QtResourceFileData {
76 QString path;
77 QString alias;
operator ==__anon2e706ab10111::QtResourceFileData78 bool operator==(const QtResourceFileData &other) const
79 { return path == other.path && alias == other.alias; }
80 };
81
82 struct QtResourcePrefixData {
83 QString prefix;
84 QString language;
85 QList<QtResourceFileData> resourceFileList;
operator ==__anon2e706ab10111::QtResourcePrefixData86 bool operator==(const QtResourcePrefixData &other) const
87 {
88 return prefix == other.prefix && language == other.language
89 && resourceFileList == other.resourceFileList;
90 }
91 };
92
93 struct QtQrcFileData {
94 QString qrcPath;
95 QList<QtResourcePrefixData> resourceList;
operator ==__anon2e706ab10111::QtQrcFileData96 bool operator==(const QtQrcFileData &other) const
97 { return qrcPath == other.qrcPath && resourceList == other.resourceList; }
98 };
99
loadResourceFileData(const QDomElement & fileElem,QtResourceFileData * fileData,QString * errorMessage)100 bool loadResourceFileData(const QDomElement &fileElem, QtResourceFileData *fileData, QString *errorMessage)
101 {
102 if (!fileData)
103 return false;
104
105 if (fileElem.tagName() != QLatin1String(rccFileTag)) {
106 *errorMessage = msgTagMismatch(fileElem.tagName(), QLatin1String(rccFileTag));
107 return false;
108 }
109
110 QtResourceFileData &data = *fileData;
111
112 data.path = fileElem.text();
113 data.alias = fileElem.attribute(QLatin1String(rccAliasAttribute));
114
115 return true;
116 }
117
loadResourcePrefixData(const QDomElement & prefixElem,QtResourcePrefixData * prefixData,QString * errorMessage)118 static bool loadResourcePrefixData(const QDomElement &prefixElem, QtResourcePrefixData *prefixData, QString *errorMessage)
119 {
120 if (!prefixData)
121 return false;
122
123 if (prefixElem.tagName() != QLatin1String(rccTag)) {
124 *errorMessage = msgTagMismatch(prefixElem.tagName(), QLatin1String(rccTag));
125 return false;
126 }
127
128 QtResourcePrefixData &data = *prefixData;
129
130 data.prefix = prefixElem.attribute(QLatin1String(rccPrefixAttribute));
131 data.language = prefixElem.attribute(QLatin1String(rccLangAttribute));
132 QDomElement fileElem = prefixElem.firstChildElement();
133 while (!fileElem.isNull()) {
134 QtResourceFileData fileData;
135 if (!loadResourceFileData(fileElem, &fileData, errorMessage))
136 return false;
137 data.resourceFileList.append(fileData);
138 fileElem = fileElem.nextSiblingElement();
139 }
140 return true;
141 }
142
loadQrcFileData(const QDomDocument & doc,const QString & path,QtQrcFileData * qrcFileData,QString * errorMessage)143 static bool loadQrcFileData(const QDomDocument &doc, const QString &path, QtQrcFileData *qrcFileData, QString *errorMessage)
144 {
145 if (!qrcFileData)
146 return false;
147
148 QtQrcFileData &data = *qrcFileData;
149
150 QDomElement docElem = doc.documentElement();
151 if (docElem.tagName() != QLatin1String(rccRootTag)) {
152 *errorMessage = msgTagMismatch(docElem.tagName(), QLatin1String(rccRootTag));
153 return false;
154 }
155
156 QDomElement prefixElem = docElem.firstChildElement();
157 while (!prefixElem.isNull()) {
158 QtResourcePrefixData prefixData;
159 if (!loadResourcePrefixData(prefixElem, &prefixData, errorMessage))
160 return false;
161 data.resourceList.append(prefixData);
162 prefixElem = prefixElem.nextSiblingElement();
163 }
164
165 data.qrcPath = path;
166
167 return true;
168 }
169
saveResourceFileData(QDomDocument & doc,const QtResourceFileData & fileData)170 QDomElement saveResourceFileData(QDomDocument &doc, const QtResourceFileData &fileData)
171 {
172 QDomElement fileElem = doc.createElement(QLatin1String(rccFileTag));
173 if (!fileData.alias.isEmpty())
174 fileElem.setAttribute(QLatin1String(rccAliasAttribute), fileData.alias);
175
176 QDomText textElem = doc.createTextNode(fileData.path);
177 fileElem.appendChild(textElem);
178
179 return fileElem;
180 }
181
saveResourcePrefixData(QDomDocument & doc,const QtResourcePrefixData & prefixData)182 QDomElement saveResourcePrefixData(QDomDocument &doc, const QtResourcePrefixData &prefixData)
183 {
184 QDomElement prefixElem = doc.createElement(QLatin1String(rccTag));
185 if (!prefixData.prefix.isEmpty())
186 prefixElem.setAttribute(QLatin1String(rccPrefixAttribute), prefixData.prefix);
187 if (!prefixData.language.isEmpty())
188 prefixElem.setAttribute(QLatin1String(rccLangAttribute), prefixData.language);
189
190 for (const QtResourceFileData &rfd : prefixData.resourceFileList) {
191 QDomElement fileElem = saveResourceFileData(doc, rfd);
192 prefixElem.appendChild(fileElem);
193 }
194
195 return prefixElem;
196 }
197
saveQrcFileData(const QtQrcFileData & qrcFileData)198 QDomDocument saveQrcFileData(const QtQrcFileData &qrcFileData)
199 {
200 QDomDocument doc;
201 QDomElement docElem = doc.createElement(QLatin1String(rccRootTag));
202 for (const QtResourcePrefixData &prefixData : qrcFileData.resourceList) {
203 QDomElement prefixElem = saveResourcePrefixData(doc, prefixData);
204
205 docElem.appendChild(prefixElem);
206 }
207 doc.appendChild(docElem);
208
209 return doc;
210 }
211 // --------------- QtResourceFile
212 class QtResourceFile {
213 public:
214 friend class QtQrcManager;
215
path() const216 QString path() const { return m_path; }
alias() const217 QString alias() const { return m_alias; }
fullPath() const218 QString fullPath() const { return m_fullPath; }
219 private:
220 QtResourceFile() = default;
221
222 QString m_path;
223 QString m_alias;
224 QString m_fullPath;
225 };
226
227 class QtResourcePrefix {
228 public:
229 friend class QtQrcManager;
230
prefix() const231 QString prefix() const { return m_prefix; }
language() const232 QString language() const { return m_language; }
resourceFiles() const233 QList<QtResourceFile *> resourceFiles() const { return m_resourceFiles; }
234 private:
235 QtResourcePrefix() = default;
236
237 QString m_prefix;
238 QString m_language;
239 QList<QtResourceFile *> m_resourceFiles;
240
241 };
242 // ------------------- QtQrcFile
243 class QtQrcFile {
244 public:
245 friend class QtQrcManager;
246
path() const247 QString path() const { return m_path; }
fileName() const248 QString fileName() const { return m_fileName; }
resourcePrefixList() const249 QList<QtResourcePrefix *> resourcePrefixList() const { return m_resourcePrefixes; }
initialState() const250 QtQrcFileData initialState() const { return m_initialState; }
251
252 private:
253 QtQrcFile() = default;
254
setPath(const QString & path)255 void setPath(const QString &path) {
256 m_path = path;
257 QFileInfo fi(path);
258 m_fileName = fi.fileName();
259 }
260
261 QString m_path;
262 QString m_fileName;
263 QList<QtResourcePrefix *> m_resourcePrefixes;
264 QtQrcFileData m_initialState;
265 };
266
267 // ------------------ QtQrcManager
268 class QtQrcManager : public QObject
269 {
270 Q_OBJECT
271 public:
272 QtQrcManager(QObject *parent = nullptr);
273 ~QtQrcManager() override;
274
275 QList<QtQrcFile *> qrcFiles() const;
276
277 // helpers
278 QtQrcFile *qrcFileOf(const QString &path) const;
279 QtQrcFile *qrcFileOf(QtResourcePrefix *resourcePrefix) const;
280 QtResourcePrefix *resourcePrefixOf(QtResourceFile *resourceFile) const;
281
282 QtQrcFile *importQrcFile(const QtQrcFileData &qrcFileData, QtQrcFile *beforeQrcFile = nullptr);
283 void exportQrcFile(QtQrcFile *qrcFile, QtQrcFileData *qrcFileData) const;
284
285 QIcon icon(const QString &resourceFullPath) const;
286 bool exists(const QString &resourceFullPath) const;
287 bool exists(QtQrcFile *qrcFile) const;
288
289 QtQrcFile *prevQrcFile(QtQrcFile *qrcFile) const;
290 QtQrcFile *nextQrcFile(QtQrcFile *qrcFile) const;
291 QtResourcePrefix *prevResourcePrefix(QtResourcePrefix *resourcePrefix) const;
292 QtResourcePrefix *nextResourcePrefix(QtResourcePrefix *resourcePrefix) const;
293 QtResourceFile *prevResourceFile(QtResourceFile *resourceFile) const;
294 QtResourceFile *nextResourceFile(QtResourceFile *resourceFile) const;
295
296 void clear();
297
298 public slots:
299
300 QtQrcFile *insertQrcFile(const QString &path, QtQrcFile *beforeQrcFile = nullptr, bool newFile = false);
301 void moveQrcFile(QtQrcFile *qrcFile, QtQrcFile *beforeQrcFile);
302 void setInitialState(QtQrcFile *qrcFile, const QtQrcFileData &initialState);
303 void removeQrcFile(QtQrcFile *qrcFile);
304
305 QtResourcePrefix *insertResourcePrefix(QtQrcFile *qrcFile, const QString &prefix,
306 const QString &language, QtResourcePrefix *beforeResourcePrefix = nullptr);
307 void moveResourcePrefix(QtResourcePrefix *resourcePrefix, QtResourcePrefix *beforeResourcePrefix); // the same qrc file???
308 void changeResourcePrefix(QtResourcePrefix *resourcePrefix, const QString &newPrefix);
309 void changeResourceLanguage(QtResourcePrefix *resourcePrefix, const QString &newLanguage);
310 void removeResourcePrefix(QtResourcePrefix *resourcePrefix);
311
312 QtResourceFile *insertResourceFile(QtResourcePrefix *resourcePrefix, const QString &path,
313 const QString &alias, QtResourceFile *beforeResourceFile = nullptr);
314 void moveResourceFile(QtResourceFile *resourceFile, QtResourceFile *beforeResourceFile); // the same prefix???
315 void changeResourceAlias(QtResourceFile *resourceFile, const QString &newAlias);
316 void removeResourceFile(QtResourceFile *resourceFile);
317
318 signals:
319 void qrcFileInserted(QtQrcFile *qrcFile);
320 void qrcFileMoved(QtQrcFile *qrcFile, QtQrcFile *oldBeforeQrcFile);
321 void qrcFileRemoved(QtQrcFile *qrcFile);
322
323 void resourcePrefixInserted(QtResourcePrefix *resourcePrefix);
324 void resourcePrefixMoved(QtResourcePrefix *resourcePrefix, QtResourcePrefix *oldBeforeResourcePrefix);
325 void resourcePrefixChanged(QtResourcePrefix *resourcePrefix, const QString &oldPrefix);
326 void resourceLanguageChanged(QtResourcePrefix *resourcePrefix, const QString &oldLanguage);
327 void resourcePrefixRemoved(QtResourcePrefix *resourcePrefix);
328
329 void resourceFileInserted(QtResourceFile *resourceFile);
330 void resourceFileMoved(QtResourceFile *resourceFile, QtResourceFile *oldBeforeResourceFile);
331 void resourceAliasChanged(QtResourceFile *resourceFile, const QString &oldAlias);
332 void resourceFileRemoved(QtResourceFile *resourceFile);
333 private:
334
335 QList<QtQrcFile *> m_qrcFiles;
336 QMap<QString, QtQrcFile *> m_pathToQrc;
337 QMap<QtQrcFile *, bool> m_qrcFileToExists;
338 QMap<QtResourcePrefix *, QtQrcFile *> m_prefixToQrc;
339 QMap<QtResourceFile *, QtResourcePrefix *> m_fileToPrefix;
340 QMap<QString, QList<QtResourceFile *> > m_fullPathToResourceFiles;
341 QMap<QString, QIcon> m_fullPathToIcon;
342 QMap<QString, bool> m_fullPathToExists;
343 };
344
QtQrcManager(QObject * parent)345 QtQrcManager::QtQrcManager(QObject *parent)
346 : QObject(parent)
347 {
348
349 }
350
~QtQrcManager()351 QtQrcManager::~QtQrcManager()
352 {
353 clear();
354 }
355
qrcFiles() const356 QList<QtQrcFile *> QtQrcManager::qrcFiles() const
357 {
358 return m_qrcFiles;
359 }
360
qrcFileOf(const QString & path) const361 QtQrcFile *QtQrcManager::qrcFileOf(const QString &path) const
362 {
363 return m_pathToQrc.value(path);
364 }
365
qrcFileOf(QtResourcePrefix * resourcePrefix) const366 QtQrcFile *QtQrcManager::qrcFileOf(QtResourcePrefix *resourcePrefix) const
367 {
368 return m_prefixToQrc.value(resourcePrefix);
369 }
370
resourcePrefixOf(QtResourceFile * resourceFile) const371 QtResourcePrefix *QtQrcManager::resourcePrefixOf(QtResourceFile *resourceFile) const
372 {
373 return m_fileToPrefix.value(resourceFile);
374 }
375
importQrcFile(const QtQrcFileData & qrcFileData,QtQrcFile * beforeQrcFile)376 QtQrcFile *QtQrcManager::importQrcFile(const QtQrcFileData &qrcFileData, QtQrcFile *beforeQrcFile)
377 {
378 QtQrcFile *qrcFile = insertQrcFile(qrcFileData.qrcPath, beforeQrcFile);
379 if (!qrcFile)
380 return nullptr;
381 for (const QtResourcePrefixData &prefixData : qrcFileData.resourceList) {
382 QtResourcePrefix *resourcePrefix = insertResourcePrefix(qrcFile, prefixData.prefix, prefixData.language, nullptr);
383 for (const QtResourceFileData &fileData : prefixData.resourceFileList)
384 insertResourceFile(resourcePrefix, fileData.path, fileData.alias, nullptr);
385 }
386 setInitialState(qrcFile, qrcFileData);
387 return qrcFile;
388 }
389
exportQrcFile(QtQrcFile * qrcFile,QtQrcFileData * qrcFileData) const390 void QtQrcManager::exportQrcFile(QtQrcFile *qrcFile, QtQrcFileData *qrcFileData) const
391 {
392 if (!qrcFileData)
393 return;
394
395 if (!qrcFile)
396 return;
397
398 QtQrcFileData &data = *qrcFileData;
399
400 QList<QtResourcePrefixData> resourceList;
401
402 const auto resourcePrefixes = qrcFile->resourcePrefixList();
403 for (const QtResourcePrefix *prefix : resourcePrefixes) {
404 QList<QtResourceFileData> resourceFileList;
405 const auto resourceFiles = prefix->resourceFiles();
406 for (QtResourceFile *file : resourceFiles) {
407 QtResourceFileData fileData;
408 fileData.path = file->path();
409 fileData.alias = file->alias();
410 resourceFileList << fileData;
411 }
412 QtResourcePrefixData prefixData;
413 prefixData.prefix = prefix->prefix();
414 prefixData.language = prefix->language();
415 prefixData.resourceFileList = resourceFileList;
416
417 resourceList << prefixData;
418 }
419 data = QtQrcFileData();
420 data.qrcPath = qrcFile->path();
421 data.resourceList = resourceList;
422 }
423
icon(const QString & resourceFullPath) const424 QIcon QtQrcManager::icon(const QString &resourceFullPath) const
425 {
426 return m_fullPathToIcon.value(resourceFullPath);
427 }
428
exists(const QString & resourceFullPath) const429 bool QtQrcManager::exists(const QString &resourceFullPath) const
430 {
431 return m_fullPathToExists.value(resourceFullPath, false);
432 }
433
exists(QtQrcFile * qrcFile) const434 bool QtQrcManager::exists(QtQrcFile *qrcFile) const
435 {
436 return m_qrcFileToExists.value(qrcFile, false);
437 }
438
prevQrcFile(QtQrcFile * qrcFile) const439 QtQrcFile *QtQrcManager::prevQrcFile(QtQrcFile *qrcFile) const
440 {
441 if (!qrcFile)
442 return nullptr;
443 const int idx = m_qrcFiles.indexOf(qrcFile);
444 if (idx <= 0)
445 return nullptr;
446 return m_qrcFiles.at(idx - 1);
447 }
448
nextQrcFile(QtQrcFile * qrcFile) const449 QtQrcFile *QtQrcManager::nextQrcFile(QtQrcFile *qrcFile) const
450 {
451 if (!qrcFile)
452 return nullptr;
453 const int idx = m_qrcFiles.indexOf(qrcFile);
454 if (idx < 0 || idx == m_qrcFiles.size() - 1)
455 return nullptr;
456 return m_qrcFiles.at(idx + 1);
457 }
458
prevResourcePrefix(QtResourcePrefix * resourcePrefix) const459 QtResourcePrefix *QtQrcManager::prevResourcePrefix(QtResourcePrefix *resourcePrefix) const
460 {
461 if (!resourcePrefix)
462 return nullptr;
463 const auto prefixes = qrcFileOf(resourcePrefix)->resourcePrefixList();
464 const int idx = prefixes.indexOf(resourcePrefix);
465 if (idx <= 0)
466 return nullptr;
467 return prefixes.at(idx - 1);
468 }
469
nextResourcePrefix(QtResourcePrefix * resourcePrefix) const470 QtResourcePrefix *QtQrcManager::nextResourcePrefix(QtResourcePrefix *resourcePrefix) const
471 {
472 if (!resourcePrefix)
473 return nullptr;
474 const auto prefixes = qrcFileOf(resourcePrefix)->resourcePrefixList();
475 const int idx = prefixes.indexOf(resourcePrefix);
476 if (idx < 0 || idx == prefixes.size() - 1)
477 return nullptr;
478 return prefixes.at(idx + 1);
479 }
480
prevResourceFile(QtResourceFile * resourceFile) const481 QtResourceFile *QtQrcManager::prevResourceFile(QtResourceFile *resourceFile) const
482 {
483 if (!resourceFile)
484 return nullptr;
485 const auto files = resourcePrefixOf(resourceFile)->resourceFiles();
486 const int idx = files.indexOf(resourceFile);
487 if (idx <= 0)
488 return nullptr;
489 return files.at(idx - 1);
490 }
491
nextResourceFile(QtResourceFile * resourceFile) const492 QtResourceFile *QtQrcManager::nextResourceFile(QtResourceFile *resourceFile) const
493 {
494 if (!resourceFile)
495 return nullptr;
496 const auto files = resourcePrefixOf(resourceFile)->resourceFiles();
497 const int idx = files.indexOf(resourceFile);
498 if (idx < 0 || idx == files.size() - 1)
499 return nullptr;
500 return files.at(idx + 1);
501 }
502
clear()503 void QtQrcManager::clear()
504 {
505 const auto oldQrcFiles = qrcFiles();
506 for (QtQrcFile *qf : oldQrcFiles)
507 removeQrcFile(qf);
508 }
509
insertQrcFile(const QString & path,QtQrcFile * beforeQrcFile,bool newFile)510 QtQrcFile *QtQrcManager::insertQrcFile(const QString &path, QtQrcFile *beforeQrcFile, bool newFile)
511 {
512 if (m_pathToQrc.contains(path))
513 return nullptr;
514
515 int idx = m_qrcFiles.indexOf(beforeQrcFile);
516 if (idx < 0)
517 idx = m_qrcFiles.size();
518
519 QtQrcFile *qrcFile = new QtQrcFile();
520 qrcFile->setPath(path);
521
522 m_qrcFiles.insert(idx, qrcFile);
523 m_pathToQrc[path] = qrcFile;
524
525 const QFileInfo fi(path);
526 m_qrcFileToExists[qrcFile] = fi.exists() || newFile;
527
528 emit qrcFileInserted(qrcFile);
529 return qrcFile;
530 }
531
moveQrcFile(QtQrcFile * qrcFile,QtQrcFile * beforeQrcFile)532 void QtQrcManager::moveQrcFile(QtQrcFile *qrcFile, QtQrcFile *beforeQrcFile)
533 {
534 if (qrcFile == beforeQrcFile)
535 return;
536
537 const int idx = m_qrcFiles.indexOf(qrcFile);
538 if (idx < 0)
539 return;
540
541 int beforeIdx = m_qrcFiles.indexOf(beforeQrcFile);
542 if (beforeIdx < 0)
543 beforeIdx = m_qrcFiles.size();
544
545 if (idx == beforeIdx - 1) // the same position, nothing changes
546 return;
547
548 QtQrcFile *oldBefore = nullptr;
549 if (idx < m_qrcFiles.size() - 1)
550 oldBefore = m_qrcFiles.at(idx + 1);
551
552 m_qrcFiles.removeAt(idx);
553 if (idx < beforeIdx)
554 beforeIdx -= 1;
555
556 m_qrcFiles.insert(beforeIdx, qrcFile);
557
558 emit qrcFileMoved(qrcFile, oldBefore);
559 }
560
setInitialState(QtQrcFile * qrcFile,const QtQrcFileData & initialState)561 void QtQrcManager::setInitialState(QtQrcFile *qrcFile, const QtQrcFileData &initialState)
562 {
563 qrcFile->m_initialState = initialState;
564 }
565
removeQrcFile(QtQrcFile * qrcFile)566 void QtQrcManager::removeQrcFile(QtQrcFile *qrcFile)
567 {
568 const int idx = m_qrcFiles.indexOf(qrcFile);
569 if (idx < 0)
570 return;
571
572 const auto resourcePrefixes = qrcFile->resourcePrefixList();
573 for (QtResourcePrefix *rp : resourcePrefixes)
574 removeResourcePrefix(rp);
575
576 emit qrcFileRemoved(qrcFile);
577
578 m_qrcFiles.removeAt(idx);
579 m_pathToQrc.remove(qrcFile->path());
580 m_qrcFileToExists.remove(qrcFile);
581 delete qrcFile;
582 }
583
insertResourcePrefix(QtQrcFile * qrcFile,const QString & prefix,const QString & language,QtResourcePrefix * beforeResourcePrefix)584 QtResourcePrefix *QtQrcManager::insertResourcePrefix(QtQrcFile *qrcFile, const QString &prefix,
585 const QString &language, QtResourcePrefix *beforeResourcePrefix)
586 {
587 if (!qrcFile)
588 return nullptr;
589
590 int idx = qrcFile->m_resourcePrefixes.indexOf(beforeResourcePrefix);
591 if (idx < 0)
592 idx = qrcFile->m_resourcePrefixes.size();
593
594 QtResourcePrefix *resourcePrefix = new QtResourcePrefix();
595 resourcePrefix->m_prefix = prefix;
596 resourcePrefix->m_language = language;
597
598 qrcFile->m_resourcePrefixes.insert(idx, resourcePrefix);
599 m_prefixToQrc[resourcePrefix] = qrcFile;
600
601 emit resourcePrefixInserted(resourcePrefix);
602 return resourcePrefix;
603 }
604
moveResourcePrefix(QtResourcePrefix * resourcePrefix,QtResourcePrefix * beforeResourcePrefix)605 void QtQrcManager::moveResourcePrefix(QtResourcePrefix *resourcePrefix, QtResourcePrefix *beforeResourcePrefix)
606 {
607 if (resourcePrefix == beforeResourcePrefix)
608 return;
609
610 QtQrcFile *qrcFile = qrcFileOf(resourcePrefix);
611 if (!qrcFile)
612 return;
613
614 if (beforeResourcePrefix && qrcFileOf(beforeResourcePrefix) != qrcFile)
615 return;
616
617 const int idx = qrcFile->m_resourcePrefixes.indexOf(resourcePrefix);
618
619 int beforeIdx = qrcFile->m_resourcePrefixes.indexOf(beforeResourcePrefix);
620 if (beforeIdx < 0)
621 beforeIdx = qrcFile->m_resourcePrefixes.size();
622
623 if (idx == beforeIdx - 1) // the same position, nothing changes
624 return;
625
626 QtResourcePrefix *oldBefore = nullptr;
627 if (idx < qrcFile->m_resourcePrefixes.size() - 1)
628 oldBefore = qrcFile->m_resourcePrefixes.at(idx + 1);
629
630 qrcFile->m_resourcePrefixes.removeAt(idx);
631 if (idx < beforeIdx)
632 beforeIdx -= 1;
633
634 qrcFile->m_resourcePrefixes.insert(beforeIdx, resourcePrefix);
635
636 emit resourcePrefixMoved(resourcePrefix, oldBefore);
637 }
638
changeResourcePrefix(QtResourcePrefix * resourcePrefix,const QString & newPrefix)639 void QtQrcManager::changeResourcePrefix(QtResourcePrefix *resourcePrefix, const QString &newPrefix)
640 {
641 if (!resourcePrefix)
642 return;
643
644 const QString oldPrefix = resourcePrefix->m_prefix;
645 if (oldPrefix == newPrefix)
646 return;
647
648 resourcePrefix->m_prefix = newPrefix;
649
650 emit resourcePrefixChanged(resourcePrefix, oldPrefix);
651 }
652
changeResourceLanguage(QtResourcePrefix * resourcePrefix,const QString & newLanguage)653 void QtQrcManager::changeResourceLanguage(QtResourcePrefix *resourcePrefix, const QString &newLanguage)
654 {
655 if (!resourcePrefix)
656 return;
657
658 const QString oldLanguage = resourcePrefix->m_language;
659 if (oldLanguage == newLanguage)
660 return;
661
662 resourcePrefix->m_language = newLanguage;
663
664 emit resourceLanguageChanged(resourcePrefix, oldLanguage);
665 }
666
removeResourcePrefix(QtResourcePrefix * resourcePrefix)667 void QtQrcManager::removeResourcePrefix(QtResourcePrefix *resourcePrefix)
668 {
669 QtQrcFile *qrcFile = qrcFileOf(resourcePrefix);
670 if (!qrcFile)
671 return;
672
673 const int idx = qrcFile->m_resourcePrefixes.indexOf(resourcePrefix);
674
675 const auto resourceFiles = resourcePrefix->resourceFiles();
676 for (QtResourceFile *rf : resourceFiles)
677 removeResourceFile(rf);
678
679 emit resourcePrefixRemoved(resourcePrefix);
680
681 qrcFile->m_resourcePrefixes.removeAt(idx);
682 m_prefixToQrc.remove(resourcePrefix);
683 delete resourcePrefix;
684 }
685
insertResourceFile(QtResourcePrefix * resourcePrefix,const QString & path,const QString & alias,QtResourceFile * beforeResourceFile)686 QtResourceFile *QtQrcManager::insertResourceFile(QtResourcePrefix *resourcePrefix, const QString &path,
687 const QString &alias, QtResourceFile *beforeResourceFile)
688 {
689 if (!resourcePrefix)
690 return nullptr;
691
692 int idx = resourcePrefix->m_resourceFiles.indexOf(beforeResourceFile);
693 if (idx < 0)
694 idx = resourcePrefix->m_resourceFiles.size();
695
696 QtResourceFile *resourceFile = new QtResourceFile();
697 resourceFile->m_path = path;
698 resourceFile->m_alias = alias;
699 const QFileInfo fi(qrcFileOf(resourcePrefix)->path());
700 const QDir dir(fi.absolutePath());
701 const QString fullPath = dir.absoluteFilePath(path);
702 resourceFile->m_fullPath = fullPath;
703
704 resourcePrefix->m_resourceFiles.insert(idx, resourceFile);
705 m_fileToPrefix[resourceFile] = resourcePrefix;
706 m_fullPathToResourceFiles[fullPath].append(resourceFile);
707 if (!m_fullPathToIcon.contains(fullPath)) {
708 m_fullPathToIcon[fullPath] = QIcon(fullPath);
709 const QFileInfo fullInfo(fullPath);
710 m_fullPathToExists[fullPath] = fullInfo.exists();
711 }
712
713 emit resourceFileInserted(resourceFile);
714 return resourceFile;
715 }
716
moveResourceFile(QtResourceFile * resourceFile,QtResourceFile * beforeResourceFile)717 void QtQrcManager::moveResourceFile(QtResourceFile *resourceFile, QtResourceFile *beforeResourceFile)
718 {
719 if (resourceFile == beforeResourceFile)
720 return;
721
722 QtResourcePrefix *resourcePrefix = resourcePrefixOf(resourceFile);
723 if (!resourcePrefix)
724 return;
725
726 if (beforeResourceFile && resourcePrefixOf(beforeResourceFile) != resourcePrefix)
727 return;
728
729 const int idx = resourcePrefix->m_resourceFiles.indexOf(resourceFile);
730
731 int beforeIdx = resourcePrefix->m_resourceFiles.indexOf(beforeResourceFile);
732 if (beforeIdx < 0)
733 beforeIdx = resourcePrefix->m_resourceFiles.size();
734
735 if (idx == beforeIdx - 1) // the same position, nothing changes
736 return;
737
738 QtResourceFile *oldBefore = nullptr;
739 if (idx < resourcePrefix->m_resourceFiles.size() - 1)
740 oldBefore = resourcePrefix->m_resourceFiles.at(idx + 1);
741
742 resourcePrefix->m_resourceFiles.removeAt(idx);
743 if (idx < beforeIdx)
744 beforeIdx -= 1;
745
746 resourcePrefix->m_resourceFiles.insert(beforeIdx, resourceFile);
747
748 emit resourceFileMoved(resourceFile, oldBefore);
749 }
750
changeResourceAlias(QtResourceFile * resourceFile,const QString & newAlias)751 void QtQrcManager::changeResourceAlias(QtResourceFile *resourceFile, const QString &newAlias)
752 {
753 if (!resourceFile)
754 return;
755
756 const QString oldAlias = resourceFile->m_alias;
757 if (oldAlias == newAlias)
758 return;
759
760 resourceFile->m_alias = newAlias;
761
762 emit resourceAliasChanged(resourceFile, oldAlias);
763 }
764
removeResourceFile(QtResourceFile * resourceFile)765 void QtQrcManager::removeResourceFile(QtResourceFile *resourceFile)
766 {
767 QtResourcePrefix *resourcePrefix = resourcePrefixOf(resourceFile);
768 if (!resourcePrefix)
769 return;
770
771 const int idx = resourcePrefix->m_resourceFiles.indexOf(resourceFile);
772
773 emit resourceFileRemoved(resourceFile);
774
775 resourcePrefix->m_resourceFiles.removeAt(idx);
776 m_fileToPrefix.remove(resourceFile);
777 const QString fullPath = resourceFile->fullPath();
778 m_fullPathToResourceFiles[fullPath].removeAll(resourceFile); // optimize me
779 if (m_fullPathToResourceFiles[fullPath].isEmpty()) {
780 m_fullPathToResourceFiles.remove(fullPath);
781 m_fullPathToIcon.remove(fullPath);
782 m_fullPathToExists.remove(fullPath);
783 }
784 delete resourceFile;
785 }
786
787
788
789 }
790
791 // ----------------- QtResourceEditorDialogPrivate
792 class QtResourceEditorDialogPrivate
793 {
794 QtResourceEditorDialog *q_ptr;
795 Q_DECLARE_PUBLIC(QtResourceEditorDialog)
796 public:
797 QtResourceEditorDialogPrivate() = default;
798
799 void slotQrcFileInserted(QtQrcFile *qrcFile);
800 void slotQrcFileMoved(QtQrcFile *qrcFile);
801 void slotQrcFileRemoved(QtQrcFile *qrcFile);
802
803 QStandardItem *insertResourcePrefix(QtResourcePrefix *resourcePrefix);
804
slotResourcePrefixInserted(QtResourcePrefix * resourcePrefix)805 void slotResourcePrefixInserted(QtResourcePrefix *resourcePrefix) { insertResourcePrefix(resourcePrefix); }
806 void slotResourcePrefixMoved(QtResourcePrefix *resourcePrefix);
807 void slotResourcePrefixChanged(QtResourcePrefix *resourcePrefix);
808 void slotResourceLanguageChanged(QtResourcePrefix *resourcePrefix);
809 void slotResourcePrefixRemoved(QtResourcePrefix *resourcePrefix);
810 void slotResourceFileInserted(QtResourceFile *resourceFile);
811 void slotResourceFileMoved(QtResourceFile *resourceFile);
812 void slotResourceAliasChanged(QtResourceFile *resourceFile);
813 void slotResourceFileRemoved(QtResourceFile *resourceFile);
814
815 void slotCurrentQrcFileChanged(QListWidgetItem *item);
816 void slotCurrentTreeViewItemChanged(const QModelIndex &index);
817 void slotListWidgetContextMenuRequested(const QPoint &pos);
818 void slotTreeViewContextMenuRequested(const QPoint &pos);
819 void slotTreeViewItemChanged(QStandardItem *item);
820
821 void slotNewQrcFile();
822 void slotImportQrcFile();
823 void slotRemoveQrcFile();
824 void slotMoveUpQrcFile();
825 void slotMoveDownQrcFile();
826
827 void slotNewPrefix();
828 void slotAddFiles();
829 void slotChangePrefix();
830 void slotChangeLanguage();
831 void slotChangeAlias();
832 void slotClonePrefix();
833 void slotRemove();
834 void slotMoveUp();
835 void slotMoveDown();
836
837 bool loadQrcFile(const QString &path, QtQrcFileData *qrcFileData, QString *errorMessage);
838 bool loadQrcFile(const QString &path, QtQrcFileData *qrcFileData);
839 bool saveQrcFile(const QtQrcFileData &qrcFileData);
840
841 QString qrcFileText(QtQrcFile *qrcFile) const;
842
843 QMessageBox::StandardButton warning(const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
844 QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) const;
845
846 QString browseForNewLocation(const QString &resourceFile, const QDir &rootDir) const;
847 QString copyResourceFile(const QString &resourceFile, const QString &destPath) const;
848 QtResourceFile *getCurrentResourceFile() const;
849 QtResourcePrefix *getCurrentResourcePrefix() const;
850 void selectTreeRow(QStandardItem *item);
851 QString getSaveFileNameWithExtension(QWidget *parent,
852 const QString &title, QString dir, const QString &filter, const QString &extension) const;
853 QString qrcStartDirectory() const;
854
855 Ui::QtResourceEditorDialog m_ui;
856 QDesignerFormEditorInterface *m_core = nullptr;
857 QtResourceModel *m_resourceModel = nullptr;
858 QDesignerDialogGuiInterface *m_dlgGui = nullptr;
859 QtQrcManager *m_qrcManager = nullptr;
860 QList<QtQrcFileData> m_initialState;
861
862 QMap<QtQrcFile *, QListWidgetItem *> m_qrcFileToItem;
863 QMap<QListWidgetItem *, QtQrcFile *> m_itemToQrcFile;
864 QMap<QtResourcePrefix *, QStandardItem *> m_resourcePrefixToPrefixItem;
865 QMap<QtResourcePrefix *, QStandardItem *> m_resourcePrefixToLanguageItem;
866 QMap<QStandardItem *, QtResourcePrefix *> m_prefixItemToResourcePrefix;
867 QMap<QStandardItem *, QtResourcePrefix *> m_languageItemToResourcePrefix;
868 QMap<QtResourceFile *, QStandardItem *> m_resourceFileToPathItem;
869 QMap<QtResourceFile *, QStandardItem *> m_resourceFileToAliasItem;
870 QMap<QStandardItem *, QtResourceFile *> m_pathItemToResourceFile;
871 QMap<QStandardItem *, QtResourceFile *> m_aliasItemToResourceFile;
872
873 bool m_ignoreCurrentChanged = false;
874 bool m_firstQrcFileDialog = true;
875 QtQrcFile *m_currentQrcFile = nullptr;
876
877 QAction *m_newQrcFileAction = nullptr;
878 QAction *m_importQrcFileAction = nullptr;
879 QAction *m_removeQrcFileAction = nullptr;
880 QAction *m_moveUpQrcFileAction = nullptr;
881 QAction *m_moveDownQrcFileAction = nullptr;
882
883 QAction *m_newPrefixAction = nullptr;
884 QAction *m_addResourceFileAction = nullptr;
885 QAction *m_changePrefixAction = nullptr;
886 QAction *m_changeLanguageAction = nullptr;
887 QAction *m_changeAliasAction = nullptr;
888 QAction *m_clonePrefixAction = nullptr;
889 QAction *m_moveUpAction = nullptr;
890 QAction *m_moveDownAction = nullptr;
891 QAction *m_removeAction = nullptr;
892
893 QStandardItemModel *m_treeModel = nullptr;
894 QItemSelectionModel *m_treeSelection = nullptr;
895 };
896
warning(const QString & title,const QString & text,QMessageBox::StandardButtons buttons,QMessageBox::StandardButton defaultButton) const897 QMessageBox::StandardButton QtResourceEditorDialogPrivate::warning(const QString &title, const QString &text, QMessageBox::StandardButtons buttons,
898 QMessageBox::StandardButton defaultButton) const
899 {
900 return m_dlgGui->message(q_ptr, QDesignerDialogGuiInterface::ResourceEditorMessage, QMessageBox::Warning, title, text, buttons, defaultButton);
901 }
902
qrcFileText(QtQrcFile * qrcFile) const903 QString QtResourceEditorDialogPrivate::qrcFileText(QtQrcFile *qrcFile) const
904 {
905 const QString path = qrcFile->path();
906 const QString fileName = qrcFile->fileName();
907 const QFileInfo fi(path);
908 if (fi.exists() && !fi.isWritable())
909 return QApplication::translate("QtResourceEditorDialog", "%1 [read-only]").arg(fileName);
910 if (!m_qrcManager->exists(qrcFile))
911 return QApplication::translate("QtResourceEditorDialog", "%1 [missing]").arg(fileName);
912 return fileName;
913 }
914
slotQrcFileInserted(QtQrcFile * qrcFile)915 void QtResourceEditorDialogPrivate::slotQrcFileInserted(QtQrcFile *qrcFile)
916 {
917 QListWidgetItem *currentItem = m_ui.qrcFileList->currentItem();
918 int idx = m_ui.qrcFileList->count();
919 QtQrcFile *nextQrcFile = m_qrcManager->nextQrcFile(qrcFile);
920 QListWidgetItem *nextItem = m_qrcFileToItem.value(nextQrcFile);
921 if (nextItem) {
922 const int row = m_ui.qrcFileList->row(nextItem);
923 if (row >= 0)
924 idx = row;
925 }
926 const QString path = qrcFile->path();
927 QListWidgetItem *item = new QListWidgetItem(qrcFileText(qrcFile));
928 item->setToolTip(path);
929 m_ignoreCurrentChanged = true;
930 m_ui.qrcFileList->insertItem(idx, item);
931 m_ui.qrcFileList->setCurrentItem(currentItem);
932 m_ignoreCurrentChanged = false;
933 m_qrcFileToItem[qrcFile] = item;
934 m_itemToQrcFile[item] = qrcFile;
935 if (!m_qrcManager->exists(qrcFile))
936 item->setForeground(QBrush(Qt::red));
937 }
938
slotQrcFileMoved(QtQrcFile * qrcFile)939 void QtResourceEditorDialogPrivate::slotQrcFileMoved(QtQrcFile *qrcFile)
940 {
941 QListWidgetItem *currentItem = m_ui.qrcFileList->currentItem();
942 QListWidgetItem *item = m_qrcFileToItem.value(qrcFile);
943 m_ignoreCurrentChanged = true;
944 m_ui.qrcFileList->takeItem(m_ui.qrcFileList->row(item));
945
946 int idx = m_ui.qrcFileList->count();
947 QtQrcFile *nextQrcFile = m_qrcManager->nextQrcFile(qrcFile);
948 QListWidgetItem *nextItem = m_qrcFileToItem.value(nextQrcFile);
949 if (nextItem) {
950 int row = m_ui.qrcFileList->row(nextItem);
951 if (row >= 0)
952 idx = row;
953 }
954 m_ui.qrcFileList->insertItem(idx, item);
955 if (currentItem == item)
956 m_ui.qrcFileList->setCurrentItem(item);
957 m_ignoreCurrentChanged = false;
958 }
959
slotQrcFileRemoved(QtQrcFile * qrcFile)960 void QtResourceEditorDialogPrivate::slotQrcFileRemoved(QtQrcFile *qrcFile)
961 {
962 QListWidgetItem *item = m_qrcFileToItem.value(qrcFile);
963 if (item == m_ui.qrcFileList->currentItem())
964 m_ui.qrcFileList->setCurrentItem(nullptr); // this should trigger list view signal currentItemChanged(0), and slot should set m_currentQrcFile to 0
965 m_ignoreCurrentChanged = true;
966 delete item;
967 m_ignoreCurrentChanged = false;
968 m_itemToQrcFile.remove(item);
969 m_qrcFileToItem.remove(qrcFile);
970 }
971
insertResourcePrefix(QtResourcePrefix * resourcePrefix)972 QStandardItem *QtResourceEditorDialogPrivate::insertResourcePrefix(QtResourcePrefix *resourcePrefix)
973 {
974 if (m_qrcManager->qrcFileOf(resourcePrefix) != m_currentQrcFile)
975 return nullptr;
976
977 QtResourcePrefix *prevResourcePrefix = m_qrcManager->prevResourcePrefix(resourcePrefix);
978 QStandardItem *prevItem = m_resourcePrefixToPrefixItem.value(prevResourcePrefix);
979
980 int row = 0;
981 if (prevItem)
982 row = m_treeModel->indexFromItem(prevItem).row() + 1;
983
984 QStandardItem *prefixItem = new QStandardItem();
985 QStandardItem *languageItem = new QStandardItem();
986 QList<QStandardItem *> items;
987 items << prefixItem;
988 items << languageItem;
989 m_treeModel->insertRow(row, items);
990 const QModelIndex newIndex = m_treeModel->indexFromItem(prefixItem);
991 m_ui.resourceTreeView->setExpanded(newIndex, true);
992 prefixItem->setFlags(prefixItem->flags() | Qt::ItemIsEditable);
993 languageItem->setFlags(languageItem->flags() | Qt::ItemIsEditable);
994 m_resourcePrefixToPrefixItem[resourcePrefix] = prefixItem;
995 m_resourcePrefixToLanguageItem[resourcePrefix] = languageItem;
996 m_prefixItemToResourcePrefix[prefixItem] = resourcePrefix;
997 m_languageItemToResourcePrefix[languageItem] = resourcePrefix;
998 slotResourcePrefixChanged(resourcePrefix);
999 slotResourceLanguageChanged(resourcePrefix);
1000 return prefixItem;
1001 }
1002
slotResourcePrefixMoved(QtResourcePrefix * resourcePrefix)1003 void QtResourceEditorDialogPrivate::slotResourcePrefixMoved(QtResourcePrefix *resourcePrefix)
1004 {
1005 QStandardItem *prefixItem = m_resourcePrefixToPrefixItem.value(resourcePrefix);
1006 if (!prefixItem)
1007 return;
1008
1009 QStandardItem *languageItem = m_resourcePrefixToLanguageItem.value(resourcePrefix);
1010 if (!languageItem)
1011 return;
1012
1013 const QModelIndex index = m_treeModel->indexFromItem(prefixItem);
1014 const bool expanded = m_ui.resourceTreeView->isExpanded(index);
1015 m_ignoreCurrentChanged = true;
1016 const auto items = m_treeModel->takeRow(index.row());
1017
1018 int row = m_treeModel->rowCount();
1019 QtResourcePrefix *nextResourcePrefix = m_qrcManager->nextResourcePrefix(resourcePrefix);
1020 QStandardItem *nextItem = m_resourcePrefixToPrefixItem.value(nextResourcePrefix);
1021 if (nextItem)
1022 row = m_treeModel->indexFromItem(nextItem).row();
1023 m_treeModel->insertRow(row, items);
1024 m_ignoreCurrentChanged = false;
1025 m_ui.resourceTreeView->setExpanded(m_treeModel->indexFromItem(items.at(0)), expanded);
1026 }
1027
slotResourcePrefixChanged(QtResourcePrefix * resourcePrefix)1028 void QtResourceEditorDialogPrivate::slotResourcePrefixChanged(QtResourcePrefix *resourcePrefix)
1029 {
1030 QStandardItem *item = m_resourcePrefixToPrefixItem.value(resourcePrefix);
1031 if (!item)
1032 return;
1033
1034 m_ignoreCurrentChanged = true;
1035 QString prefix = resourcePrefix->prefix();
1036 if (prefix.isEmpty())
1037 prefix = QCoreApplication::translate("QtResourceEditorDialog", "<no prefix>");
1038 item->setText(prefix);
1039 item->setToolTip(prefix);
1040 m_ignoreCurrentChanged = false;
1041 }
1042
slotResourceLanguageChanged(QtResourcePrefix * resourcePrefix)1043 void QtResourceEditorDialogPrivate::slotResourceLanguageChanged(QtResourcePrefix *resourcePrefix)
1044 {
1045 QStandardItem *item = m_resourcePrefixToLanguageItem.value(resourcePrefix);
1046 if (!item)
1047 return;
1048
1049 m_ignoreCurrentChanged = true;
1050 const QString language = resourcePrefix->language();
1051 item->setText(language);
1052 item->setToolTip(language);
1053
1054 m_ignoreCurrentChanged = false;
1055 }
1056
slotResourcePrefixRemoved(QtResourcePrefix * resourcePrefix)1057 void QtResourceEditorDialogPrivate::slotResourcePrefixRemoved(QtResourcePrefix *resourcePrefix)
1058 {
1059 QStandardItem *prefixItem = m_resourcePrefixToPrefixItem.value(resourcePrefix);
1060 if (!prefixItem)
1061 return;
1062
1063 QStandardItem *languageItem = m_resourcePrefixToLanguageItem.value(resourcePrefix);
1064 if (!languageItem)
1065 return;
1066
1067 m_ignoreCurrentChanged = true;
1068 m_treeModel->takeRow(m_treeModel->indexFromItem(prefixItem).row());
1069 delete prefixItem;
1070 delete languageItem;
1071 m_ignoreCurrentChanged = false;
1072 m_prefixItemToResourcePrefix.remove(prefixItem);
1073 m_languageItemToResourcePrefix.remove(languageItem);
1074 m_resourcePrefixToPrefixItem.remove(resourcePrefix);
1075 m_resourcePrefixToLanguageItem.remove(resourcePrefix);
1076 }
1077
slotResourceFileInserted(QtResourceFile * resourceFile)1078 void QtResourceEditorDialogPrivate::slotResourceFileInserted(QtResourceFile *resourceFile)
1079 {
1080 QtResourcePrefix *resourcePrefix = m_qrcManager->resourcePrefixOf(resourceFile);
1081 if (m_qrcManager->qrcFileOf(resourcePrefix) != m_currentQrcFile)
1082 return;
1083
1084 QtResourceFile *prevResourceFile = m_qrcManager->prevResourceFile(resourceFile);
1085 QStandardItem *prevItem = m_resourceFileToPathItem.value(prevResourceFile);
1086
1087 QStandardItem *pathItem = new QStandardItem(resourceFile->path());
1088 QStandardItem *aliasItem = new QStandardItem();
1089 QStandardItem *parentItem = m_resourcePrefixToPrefixItem.value(resourcePrefix);
1090 QList<QStandardItem *> items;
1091 items << pathItem;
1092 items << aliasItem;
1093
1094 int row = 0;
1095 if (prevItem)
1096 row = m_treeModel->indexFromItem(prevItem).row() + 1;
1097
1098 parentItem->insertRow(row, items);
1099
1100 pathItem->setFlags(pathItem->flags() & ~Qt::ItemIsEditable);
1101 aliasItem->setFlags(aliasItem->flags() | Qt::ItemIsEditable);
1102 m_resourceFileToPathItem[resourceFile] = pathItem;
1103 m_resourceFileToAliasItem[resourceFile] = aliasItem;
1104 m_pathItemToResourceFile[pathItem] = resourceFile;
1105 m_aliasItemToResourceFile[aliasItem] = resourceFile;
1106 pathItem->setToolTip(resourceFile->path());
1107 pathItem->setIcon(m_qrcManager->icon(resourceFile->fullPath()));
1108 if (!m_qrcManager->exists(resourceFile->fullPath())) {
1109 pathItem->setText(QApplication::translate("QtResourceEditorDialog", "%1 [missing]").arg(resourceFile->path()));
1110 QBrush redBrush(Qt::red);
1111 pathItem->setForeground(redBrush);
1112 aliasItem->setForeground(redBrush);
1113 }
1114 slotResourceAliasChanged(resourceFile);
1115 }
1116
slotResourceFileMoved(QtResourceFile * resourceFile)1117 void QtResourceEditorDialogPrivate::slotResourceFileMoved(QtResourceFile *resourceFile)
1118 {
1119 QStandardItem *pathItem = m_resourceFileToPathItem.value(resourceFile);
1120 if (!pathItem)
1121 return;
1122
1123 QStandardItem *aliasItem = m_resourceFileToAliasItem.value(resourceFile);
1124 if (!aliasItem)
1125 return;
1126
1127 QStandardItem *parentItem = pathItem->parent();
1128 m_ignoreCurrentChanged = true;
1129 const auto items = parentItem->takeRow(m_treeModel->indexFromItem(pathItem).row());
1130
1131 int row = parentItem->rowCount();
1132 QtResourceFile *nextResourceFile = m_qrcManager->nextResourceFile(resourceFile);
1133 QStandardItem *nextItem = m_resourceFileToPathItem.value(nextResourceFile);
1134 if (nextItem)
1135 row = m_treeModel->indexFromItem(nextItem).row();
1136 parentItem->insertRow(row, items);
1137 m_ignoreCurrentChanged = false;
1138 }
1139
slotResourceAliasChanged(QtResourceFile * resourceFile)1140 void QtResourceEditorDialogPrivate::slotResourceAliasChanged(QtResourceFile *resourceFile)
1141 {
1142 QStandardItem *item = m_resourceFileToAliasItem.value(resourceFile);
1143 if (!item)
1144 return;
1145
1146 m_ignoreCurrentChanged = true;
1147 const QString alias = resourceFile->alias();
1148 item->setText(alias);
1149 item->setToolTip(alias);
1150
1151 m_ignoreCurrentChanged = false;
1152 }
1153
slotResourceFileRemoved(QtResourceFile * resourceFile)1154 void QtResourceEditorDialogPrivate::slotResourceFileRemoved(QtResourceFile *resourceFile)
1155 {
1156 QStandardItem *pathItem = m_resourceFileToPathItem.value(resourceFile);
1157 if (!pathItem)
1158 return;
1159
1160 QStandardItem *aliasItem = m_resourceFileToAliasItem.value(resourceFile);
1161 if (!aliasItem)
1162 return;
1163
1164 QStandardItem *parentItem = pathItem->parent();
1165
1166 m_ignoreCurrentChanged = true;
1167 parentItem->takeRow(m_treeModel->indexFromItem(pathItem).row());
1168 delete pathItem;
1169 delete aliasItem;
1170 m_ignoreCurrentChanged = false;
1171 m_pathItemToResourceFile.remove(pathItem);
1172 m_aliasItemToResourceFile.remove(aliasItem);
1173 m_resourceFileToPathItem.remove(resourceFile);
1174 m_resourceFileToAliasItem.remove(resourceFile);
1175 }
1176
1177
slotCurrentQrcFileChanged(QListWidgetItem * item)1178 void QtResourceEditorDialogPrivate::slotCurrentQrcFileChanged(QListWidgetItem *item)
1179 {
1180 if (m_ignoreCurrentChanged)
1181 return;
1182
1183 QtQrcFile *newCurrentQrcFile = m_itemToQrcFile.value(item);
1184
1185 if (newCurrentQrcFile == m_currentQrcFile)
1186 return;
1187
1188 if (m_currentQrcFile) {
1189 QMap<QtResourcePrefix *, QStandardItem *> currentPrefixList = m_resourcePrefixToPrefixItem;
1190 for (auto it = currentPrefixList.cbegin(), end = currentPrefixList.cend(); it != end; ++it) {
1191 QtResourcePrefix *resourcePrefix = it.key();
1192 const auto currentResourceFiles = resourcePrefix->resourceFiles();
1193 for (QtResourceFile *rf : currentResourceFiles)
1194 slotResourceFileRemoved(rf);
1195 slotResourcePrefixRemoved(resourcePrefix);
1196 }
1197 }
1198
1199 m_currentQrcFile = newCurrentQrcFile;
1200 slotCurrentTreeViewItemChanged(QModelIndex());
1201 QStandardItem *firstPrefix = nullptr; // select first prefix
1202 if (m_currentQrcFile) {
1203 const auto newPrefixList = m_currentQrcFile->resourcePrefixList();
1204 for (QtResourcePrefix *resourcePrefix : newPrefixList) {
1205 if (QStandardItem *newPrefixItem = insertResourcePrefix(resourcePrefix))
1206 if (!firstPrefix)
1207 firstPrefix = newPrefixItem;
1208 const auto newResourceFiles = resourcePrefix->resourceFiles();
1209 for (QtResourceFile *rf : newResourceFiles)
1210 slotResourceFileInserted(rf);
1211 }
1212 }
1213 m_ui.resourceTreeView->setCurrentIndex(firstPrefix ? m_treeModel->indexFromItem(firstPrefix) : QModelIndex());
1214
1215 m_removeQrcFileAction->setEnabled(m_currentQrcFile);
1216 m_moveUpQrcFileAction->setEnabled(m_currentQrcFile && m_qrcManager->prevQrcFile(m_currentQrcFile));
1217 m_moveDownQrcFileAction->setEnabled(m_currentQrcFile && m_qrcManager->nextQrcFile(m_currentQrcFile));
1218 }
1219
slotCurrentTreeViewItemChanged(const QModelIndex & index)1220 void QtResourceEditorDialogPrivate::slotCurrentTreeViewItemChanged(const QModelIndex &index)
1221 {
1222 QStandardItem *item = m_treeModel->itemFromIndex(index);
1223 QtResourceFile *resourceFile = m_pathItemToResourceFile.value(item);
1224 if (!resourceFile)
1225 resourceFile = m_aliasItemToResourceFile.value(item);
1226 QtResourcePrefix *resourcePrefix = m_prefixItemToResourcePrefix.value(item);
1227 if (!resourcePrefix)
1228 resourcePrefix = m_languageItemToResourcePrefix.value(item);
1229
1230 bool moveUpEnabled = false;
1231 bool moveDownEnabled = false;
1232 bool currentItem = resourceFile || resourcePrefix;
1233
1234 if (resourceFile) {
1235 if (m_qrcManager->prevResourceFile(resourceFile))
1236 moveUpEnabled = true;
1237 if (m_qrcManager->nextResourceFile(resourceFile))
1238 moveDownEnabled = true;
1239 } else if (resourcePrefix) {
1240 if (m_qrcManager->prevResourcePrefix(resourcePrefix))
1241 moveUpEnabled = true;
1242 if (m_qrcManager->nextResourcePrefix(resourcePrefix))
1243 moveDownEnabled = true;
1244 }
1245
1246 m_newPrefixAction->setEnabled(m_currentQrcFile);
1247 m_addResourceFileAction->setEnabled(currentItem);
1248 m_changePrefixAction->setEnabled(currentItem);
1249 m_changeLanguageAction->setEnabled(currentItem);
1250 m_changeAliasAction->setEnabled(resourceFile);
1251 m_removeAction->setEnabled(currentItem);
1252 m_moveUpAction->setEnabled(moveUpEnabled);
1253 m_moveDownAction->setEnabled(moveDownEnabled);
1254 m_clonePrefixAction->setEnabled(currentItem);
1255 }
1256
slotListWidgetContextMenuRequested(const QPoint & pos)1257 void QtResourceEditorDialogPrivate::slotListWidgetContextMenuRequested(const QPoint &pos)
1258 {
1259 QMenu menu(q_ptr);
1260 menu.addAction(m_newQrcFileAction);
1261 menu.addAction(m_importQrcFileAction);
1262 menu.addAction(m_removeQrcFileAction);
1263 menu.addSeparator();
1264 menu.addAction(m_moveUpQrcFileAction);
1265 menu.addAction(m_moveDownQrcFileAction);
1266 menu.exec(m_ui.qrcFileList->mapToGlobal(pos));
1267 }
1268
slotTreeViewContextMenuRequested(const QPoint & pos)1269 void QtResourceEditorDialogPrivate::slotTreeViewContextMenuRequested(const QPoint &pos)
1270 {
1271 QMenu menu(q_ptr);
1272 menu.addAction(m_newPrefixAction);
1273 menu.addAction(m_addResourceFileAction);
1274 menu.addAction(m_removeAction);
1275 menu.addSeparator();
1276 menu.addAction(m_changePrefixAction);
1277 menu.addAction(m_changeLanguageAction);
1278 menu.addAction(m_changeAliasAction);
1279 menu.addSeparator();
1280 menu.addAction(m_clonePrefixAction);
1281 menu.addSeparator();
1282 menu.addAction(m_moveUpAction);
1283 menu.addAction(m_moveDownAction);
1284 menu.exec(m_ui.resourceTreeView->mapToGlobal(pos));
1285 }
1286
slotTreeViewItemChanged(QStandardItem * item)1287 void QtResourceEditorDialogPrivate::slotTreeViewItemChanged(QStandardItem *item)
1288 {
1289 if (m_ignoreCurrentChanged)
1290 return;
1291
1292 const QString newValue = item->text();
1293 QtResourceFile *resourceFile = m_aliasItemToResourceFile.value(item);
1294 if (resourceFile) {
1295 m_qrcManager->changeResourceAlias(resourceFile, newValue);
1296 return;
1297 }
1298
1299 QtResourcePrefix *resourcePrefix = m_prefixItemToResourcePrefix.value(item);
1300 if (resourcePrefix) {
1301 m_qrcManager->changeResourcePrefix(resourcePrefix, newValue);
1302 return;
1303 }
1304
1305 resourcePrefix = m_languageItemToResourcePrefix.value(item);
1306 if (resourcePrefix) {
1307 m_qrcManager->changeResourceLanguage(resourcePrefix, newValue);
1308 return;
1309 }
1310 }
1311
getSaveFileNameWithExtension(QWidget * parent,const QString & title,QString dir,const QString & filter,const QString & extension) const1312 QString QtResourceEditorDialogPrivate::getSaveFileNameWithExtension(QWidget *parent,
1313 const QString &title, QString dir, const QString &filter, const QString &extension) const
1314 {
1315 const QChar dot = QLatin1Char('.');
1316
1317 QString saveFile;
1318 while (true) {
1319 saveFile = m_dlgGui->getSaveFileName(parent, title, dir, filter, nullptr, QFileDialog::DontConfirmOverwrite);
1320 if (saveFile.isEmpty())
1321 return saveFile;
1322
1323 const QFileInfo fInfo(saveFile);
1324 if (fInfo.suffix().isEmpty() && !fInfo.fileName().endsWith(dot)) {
1325 saveFile += dot;
1326 saveFile += extension;
1327 }
1328
1329 const QFileInfo fi(saveFile);
1330 if (!fi.exists())
1331 break;
1332
1333 if (warning(title, msgOverwrite(fi.fileName()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
1334 break;
1335
1336 dir = saveFile;
1337 }
1338 return saveFile;
1339 }
1340
qrcStartDirectory() const1341 QString QtResourceEditorDialogPrivate::qrcStartDirectory() const
1342 {
1343 if (!m_currentQrcFile)
1344 return QString();
1345 const QDir dir = QFileInfo(m_currentQrcFile->path()).dir();
1346 return dir.exists() ? dir.absolutePath() : QString();
1347 }
1348
slotNewQrcFile()1349 void QtResourceEditorDialogPrivate::slotNewQrcFile()
1350 {
1351 const QString qrcPath = getSaveFileNameWithExtension(q_ptr,
1352 QCoreApplication::translate("QtResourceEditorDialog", "New Resource File"),
1353 m_firstQrcFileDialog ? qrcStartDirectory() : QString(),
1354 QCoreApplication::translate("QtResourceEditorDialog", "Resource files (*.qrc)"),
1355 QStringLiteral("qrc"));
1356 if (qrcPath.isEmpty())
1357 return;
1358
1359 m_firstQrcFileDialog = false;
1360 if (QtQrcFile *sameQrcFile = m_qrcManager->qrcFileOf(qrcPath)) {
1361 // QMessageBox ???
1362 QListWidgetItem *item = m_qrcFileToItem.value(sameQrcFile);
1363 m_ui.qrcFileList->setCurrentItem(item);
1364 item->setSelected(true);
1365 return;
1366 }
1367
1368 QtQrcFile *nextQrcFile = m_qrcManager->nextQrcFile(m_currentQrcFile);
1369
1370 QtQrcFile *qrcFile = m_qrcManager->insertQrcFile(qrcPath, nextQrcFile, true);
1371 m_ui.qrcFileList->setCurrentItem(m_qrcFileToItem.value(qrcFile));
1372 }
1373
slotImportQrcFile()1374 void QtResourceEditorDialogPrivate::slotImportQrcFile()
1375 {
1376 const QString qrcPath = m_dlgGui->getOpenFileName(q_ptr,
1377 QCoreApplication::translate("QtResourceEditorDialog", "Import Resource File"),
1378 m_firstQrcFileDialog ? qrcStartDirectory() : QString(),
1379 QCoreApplication::translate("QtResourceEditorDialog", "Resource files (*.qrc)"));
1380 if (qrcPath.isEmpty())
1381 return;
1382 m_firstQrcFileDialog = false;
1383 if (QtQrcFile *sameQrcFile = m_qrcManager->qrcFileOf(qrcPath)) {
1384 // QMessageBox ???
1385 QListWidgetItem *item = m_qrcFileToItem.value(sameQrcFile);
1386 m_ui.qrcFileList->setCurrentItem(item);
1387 item->setSelected(true);
1388 return;
1389 }
1390
1391 QtQrcFile *nextQrcFile = m_qrcManager->nextQrcFile(m_currentQrcFile);
1392
1393 QtQrcFileData qrcFileData;
1394 loadQrcFile(qrcPath, &qrcFileData);
1395 QtQrcFile *qrcFile = m_qrcManager->importQrcFile(qrcFileData, nextQrcFile);
1396 m_ui.qrcFileList->setCurrentItem(m_qrcFileToItem.value(qrcFile));
1397 }
1398
slotRemoveQrcFile()1399 void QtResourceEditorDialogPrivate::slotRemoveQrcFile()
1400 {
1401 if (!m_currentQrcFile)
1402 return;
1403
1404 QtQrcFile *currentQrcFile = m_qrcManager->nextQrcFile(m_currentQrcFile);
1405 if (!currentQrcFile)
1406 currentQrcFile = m_qrcManager->prevQrcFile(m_currentQrcFile);
1407
1408 m_qrcManager->removeQrcFile(m_currentQrcFile);
1409 QListWidgetItem *item = m_qrcFileToItem.value(currentQrcFile);
1410 if (item) {
1411 m_ui.qrcFileList->setCurrentItem(item);
1412 item->setSelected(true);
1413 }
1414 }
1415
slotMoveUpQrcFile()1416 void QtResourceEditorDialogPrivate::slotMoveUpQrcFile()
1417 {
1418 if (!m_currentQrcFile)
1419 return;
1420
1421 QtQrcFile *prevQrcFile = m_qrcManager->prevQrcFile(m_currentQrcFile);
1422 if (!prevQrcFile)
1423 return;
1424
1425 m_qrcManager->moveQrcFile(m_currentQrcFile, prevQrcFile);
1426 }
1427
slotMoveDownQrcFile()1428 void QtResourceEditorDialogPrivate::slotMoveDownQrcFile()
1429 {
1430 if (!m_currentQrcFile)
1431 return;
1432
1433 QtQrcFile *nextQrcFile = m_qrcManager->nextQrcFile(m_currentQrcFile);
1434 if (!nextQrcFile)
1435 return;
1436 nextQrcFile = m_qrcManager->nextQrcFile(nextQrcFile);
1437
1438 m_qrcManager->moveQrcFile(m_currentQrcFile, nextQrcFile);
1439 }
1440
getCurrentResourceFile() const1441 QtResourceFile *QtResourceEditorDialogPrivate::getCurrentResourceFile() const
1442 {
1443 QStandardItem *currentItem = m_treeModel->itemFromIndex(m_treeSelection->currentIndex());
1444
1445
1446 QtResourceFile *currentResourceFile = nullptr;
1447 if (currentItem) {
1448 currentResourceFile = m_pathItemToResourceFile.value(currentItem);
1449 if (!currentResourceFile)
1450 currentResourceFile = m_aliasItemToResourceFile.value(currentItem);
1451 }
1452 return currentResourceFile;
1453 }
1454
getCurrentResourcePrefix() const1455 QtResourcePrefix *QtResourceEditorDialogPrivate::getCurrentResourcePrefix() const
1456 {
1457 QStandardItem *currentItem = m_treeModel->itemFromIndex(m_treeSelection->currentIndex());
1458
1459 QtResourcePrefix *currentResourcePrefix = nullptr;
1460 if (currentItem) {
1461 currentResourcePrefix = m_prefixItemToResourcePrefix.value(currentItem);
1462 if (!currentResourcePrefix) {
1463 currentResourcePrefix = m_languageItemToResourcePrefix.value(currentItem);
1464 if (!currentResourcePrefix) {
1465 QtResourceFile *currentResourceFile = getCurrentResourceFile();
1466 if (currentResourceFile)
1467 currentResourcePrefix = m_qrcManager->resourcePrefixOf(currentResourceFile);
1468 }
1469 }
1470 }
1471 return currentResourcePrefix;
1472 }
1473
selectTreeRow(QStandardItem * item)1474 void QtResourceEditorDialogPrivate::selectTreeRow(QStandardItem *item)
1475 {
1476 const QModelIndex index = m_treeModel->indexFromItem(item);
1477 m_treeSelection->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
1478 m_treeSelection->setCurrentIndex(index, QItemSelectionModel::Select);
1479 }
1480
slotNewPrefix()1481 void QtResourceEditorDialogPrivate::slotNewPrefix()
1482 {
1483 if (!m_currentQrcFile)
1484 return;
1485
1486 QtResourcePrefix *currentResourcePrefix = getCurrentResourcePrefix();
1487 QtResourcePrefix *nextResourcePrefix = m_qrcManager->nextResourcePrefix(currentResourcePrefix);
1488 QtResourcePrefix *newResourcePrefix = m_qrcManager->insertResourcePrefix(m_currentQrcFile,
1489 QCoreApplication::translate("QtResourceEditorDialog", "newPrefix"),
1490 QString(), nextResourcePrefix);
1491 if (!newResourcePrefix)
1492 return;
1493
1494 QStandardItem *newItem = m_resourcePrefixToPrefixItem.value(newResourcePrefix);
1495 if (!newItem)
1496 return;
1497
1498 const QModelIndex index = m_treeModel->indexFromItem(newItem);
1499 selectTreeRow(newItem);
1500 m_ui.resourceTreeView->edit(index);
1501 }
1502
outOfPathWarning(const QString & fname)1503 static inline QString outOfPathWarning(const QString &fname)
1504 {
1505 return QApplication::translate("QtResourceEditorDialog",
1506 "<p><b>Warning:</b> The file</p>"
1507 "<p>%1</p>"
1508 "<p>is outside of the current resource file's parent directory.</p>").arg(fname);
1509 }
1510
outOfPathWarningInfo()1511 static inline QString outOfPathWarningInfo()
1512 {
1513 return QApplication::translate("QtResourceEditorDialog",
1514 "<p>To resolve the issue, press:</p>"
1515 "<table>"
1516 "<tr><th align=\"left\">Copy</th><td>to copy the file to the resource file's parent directory.</td></tr>"
1517 "<tr><th align=\"left\">Copy As...</th><td>to copy the file into a subdirectory of the resource file's parent directory.</td></tr>"
1518 "<tr><th align=\"left\">Keep</th><td>to use its current location.</td></tr></table>");
1519 }
1520
slotAddFiles()1521 void QtResourceEditorDialogPrivate::slotAddFiles()
1522 {
1523 if (!m_currentQrcFile)
1524 return;
1525
1526 QtResourcePrefix *currentResourcePrefix = getCurrentResourcePrefix();
1527 QtResourceFile *currentResourceFile = getCurrentResourceFile();
1528 if (!currentResourcePrefix)
1529 return;
1530
1531 QString initialPath = m_currentQrcFile->path();
1532 if (currentResourceFile) {
1533 QFileInfo fi(currentResourceFile->fullPath());
1534 initialPath = fi.absolutePath();
1535 }
1536
1537 const QStringList resourcePaths = m_dlgGui->getOpenImageFileNames(q_ptr,
1538 QCoreApplication::translate("QtResourceEditorDialog", "Add Files"),
1539 initialPath);
1540 if (resourcePaths.isEmpty())
1541 return;
1542
1543 QtResourceFile *nextResourceFile = m_qrcManager->nextResourceFile(currentResourceFile);
1544 if (!currentResourceFile) {
1545 const auto resourceFiles = currentResourcePrefix->resourceFiles();
1546 if (resourceFiles.count() > 0)
1547 nextResourceFile = resourceFiles.first();
1548 }
1549
1550 const QFileInfo fi(m_currentQrcFile->path());
1551 const QString destDir = fi.absolutePath();
1552 const QDir dir(fi.absolutePath());
1553 for (QString resourcePath : resourcePaths) {
1554 QString relativePath = dir.relativeFilePath(resourcePath);
1555 if (relativePath.startsWith(QStringLiteral(".."))) {
1556 QMessageBox msgBox(QMessageBox::Warning,
1557 QCoreApplication::translate("QtResourceEditorDialog", "Incorrect Path"),
1558 outOfPathWarning(relativePath), QMessageBox::Cancel);
1559 msgBox.setInformativeText(outOfPathWarningInfo());
1560 QPushButton *copyButton = msgBox.addButton(QCoreApplication::translate("QtResourceEditorDialog",
1561 "Copy"), QMessageBox::ActionRole);
1562 QPushButton *copyAsButton = msgBox.addButton(QCoreApplication::translate("QtResourceEditorDialog",
1563 "Copy As..."), QMessageBox::ActionRole);
1564 QPushButton *keepButton = msgBox.addButton(QCoreApplication::translate("QtResourceEditorDialog",
1565 "Keep"), QMessageBox::ActionRole);
1566 QPushButton *skipButton = msgBox.addButton(QCoreApplication::translate("QtResourceEditorDialog",
1567 "Skip"), QMessageBox::ActionRole);
1568 msgBox.setEscapeButton(QMessageBox::Cancel);
1569 msgBox.setDefaultButton(copyButton);
1570 msgBox.exec();
1571 QString destPath;
1572 if (msgBox.clickedButton() == keepButton) {
1573 // nothing
1574 } else if (msgBox.clickedButton() == copyButton) {
1575 QFileInfo resInfo(resourcePath);
1576 QDir dd(destDir);
1577 destPath = dd.absoluteFilePath(resInfo.fileName());
1578 if (dd.exists(resInfo.fileName())) {
1579 if (warning(QCoreApplication::translate("QtResourceEditorDialog", "Copy"),
1580 msgOverwrite(resInfo.fileName()),
1581 QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Yes)
1582 continue;
1583 }
1584 resourcePath = copyResourceFile(resourcePath, destPath); // returns empty string in case copy failed or was canceled
1585 } else if (msgBox.clickedButton() == copyAsButton) {
1586 destPath = browseForNewLocation(resourcePath, dir); // returns empty string in case browsing was canceled
1587 if (destPath.isEmpty())
1588 continue;
1589 resourcePath = copyResourceFile(resourcePath, destPath); // returns empty string in case copy failed or was canceled
1590 } else if (msgBox.clickedButton() == skipButton) { // skipped
1591 continue;
1592 } else { // canceled
1593 return;
1594 }
1595 if (resourcePath.isEmpty())
1596 continue;
1597 }
1598 relativePath = dir.relativeFilePath(resourcePath);
1599 QtResourceFile *newResourceFile = m_qrcManager->insertResourceFile(currentResourcePrefix, relativePath, QString(), nextResourceFile);
1600
1601 QStandardItem *newItem = m_resourceFileToPathItem.value(newResourceFile);
1602 if (newItem)
1603 selectTreeRow(newItem);
1604 }
1605 }
1606
slotChangePrefix()1607 void QtResourceEditorDialogPrivate::slotChangePrefix()
1608 {
1609 QtResourcePrefix *currentResourcePrefix = getCurrentResourcePrefix();
1610 if (!currentResourcePrefix)
1611 return;
1612
1613 QStandardItem *item = m_resourcePrefixToPrefixItem.value(currentResourcePrefix);
1614 QModelIndex index = m_treeModel->indexFromItem(item);
1615 selectTreeRow(item);
1616 m_ui.resourceTreeView->scrollTo(index);
1617 m_ui.resourceTreeView->edit(index);
1618 }
1619
slotChangeLanguage()1620 void QtResourceEditorDialogPrivate::slotChangeLanguage()
1621 {
1622 QtResourcePrefix *currentResourcePrefix = getCurrentResourcePrefix();
1623 if (!currentResourcePrefix)
1624 return;
1625
1626 QStandardItem *item = m_resourcePrefixToLanguageItem.value(currentResourcePrefix);
1627 QModelIndex index = m_treeModel->indexFromItem(item);
1628 selectTreeRow(item);
1629 m_ui.resourceTreeView->scrollTo(index);
1630 m_ui.resourceTreeView->edit(index);
1631 }
1632
slotChangeAlias()1633 void QtResourceEditorDialogPrivate::slotChangeAlias()
1634 {
1635 QtResourceFile *currentResourceFile = getCurrentResourceFile();
1636 if (!currentResourceFile)
1637 return;
1638
1639 QStandardItem *item = m_resourceFileToAliasItem.value(currentResourceFile);
1640 QModelIndex index = m_treeModel->indexFromItem(item);
1641 selectTreeRow(item);
1642 m_ui.resourceTreeView->scrollTo(index);
1643 m_ui.resourceTreeView->edit(index);
1644 }
1645
slotClonePrefix()1646 void QtResourceEditorDialogPrivate::slotClonePrefix()
1647 {
1648 QtResourcePrefix *currentResourcePrefix = getCurrentResourcePrefix();
1649 if (!currentResourcePrefix)
1650 return;
1651
1652 bool ok;
1653 QString suffix = QInputDialog::getText(q_ptr, QApplication::translate("QtResourceEditorDialog", "Clone Prefix"),
1654 QCoreApplication::translate("QtResourceEditorDialog", "Enter the suffix which you want to add to the names of the cloned files.\n"
1655 "This could for example be a language extension like \"_de\"."),
1656 QLineEdit::Normal, QString(), &ok);
1657 if (!ok)
1658 return;
1659
1660 QtResourcePrefix *newResourcePrefix = m_qrcManager->insertResourcePrefix(m_currentQrcFile, currentResourcePrefix->prefix(),
1661 currentResourcePrefix->language(), m_qrcManager->nextResourcePrefix(currentResourcePrefix));
1662 if (newResourcePrefix) {
1663 const auto files = currentResourcePrefix->resourceFiles();
1664 for (QtResourceFile *resourceFile : files) {
1665 QString path = resourceFile->path();
1666 QFileInfo fi(path);
1667 QDir dir(fi.dir());
1668 QString oldSuffix = fi.completeSuffix();
1669 if (!oldSuffix.isEmpty())
1670 oldSuffix = QLatin1Char('.') + oldSuffix;
1671 const QString newBaseName = fi.baseName() + suffix + oldSuffix;
1672 const QString newPath = QDir::cleanPath(dir.filePath(newBaseName));
1673 m_qrcManager->insertResourceFile(newResourcePrefix, newPath,
1674 resourceFile->alias());
1675 }
1676 }
1677 }
1678
slotRemove()1679 void QtResourceEditorDialogPrivate::slotRemove()
1680 {
1681 QStandardItem *item = m_treeModel->itemFromIndex(m_treeSelection->currentIndex());
1682 if (!item)
1683 return;
1684
1685 QtResourceFile *resourceFile = m_pathItemToResourceFile.value(item);
1686 if (!resourceFile)
1687 resourceFile = m_aliasItemToResourceFile.value(item);
1688 QtResourcePrefix *resourcePrefix = m_prefixItemToResourcePrefix.value(item);
1689 if (!resourcePrefix)
1690 resourcePrefix = m_languageItemToResourcePrefix.value(item);
1691
1692 QStandardItem *newCurrentItem = nullptr;
1693
1694 if (resourceFile) {
1695 QtResourceFile *nextFile = m_qrcManager->nextResourceFile(resourceFile);
1696 if (!nextFile)
1697 nextFile = m_qrcManager->prevResourceFile(resourceFile);
1698 newCurrentItem = m_resourceFileToPathItem.value(nextFile);
1699 if (!newCurrentItem)
1700 newCurrentItem = m_resourcePrefixToPrefixItem.value(m_qrcManager->resourcePrefixOf(resourceFile));
1701 }
1702 if (!newCurrentItem) {
1703 QtResourcePrefix *nextPrefix = m_qrcManager->nextResourcePrefix(resourcePrefix);
1704 if (!nextPrefix)
1705 nextPrefix = m_qrcManager->prevResourcePrefix(resourcePrefix);
1706 newCurrentItem = m_resourcePrefixToPrefixItem.value(nextPrefix);
1707 }
1708
1709 selectTreeRow(newCurrentItem);
1710
1711 if (resourcePrefix)
1712 m_qrcManager->removeResourcePrefix(resourcePrefix);
1713 else if (resourceFile)
1714 m_qrcManager->removeResourceFile(resourceFile);
1715 }
1716
slotMoveUp()1717 void QtResourceEditorDialogPrivate::slotMoveUp()
1718 {
1719 if (QtResourceFile *resourceFile = getCurrentResourceFile()) {
1720 QtResourceFile *prevFile = m_qrcManager->prevResourceFile(resourceFile);
1721
1722 if (!prevFile)
1723 return;
1724
1725 m_qrcManager->moveResourceFile(resourceFile, prevFile);
1726 selectTreeRow(m_resourceFileToPathItem.value(resourceFile));
1727 } else if (QtResourcePrefix *resourcePrefix = getCurrentResourcePrefix()) {
1728 QtResourcePrefix *prevPrefix = m_qrcManager->prevResourcePrefix(resourcePrefix);
1729
1730 if (!prevPrefix)
1731 return;
1732
1733 m_qrcManager->moveResourcePrefix(resourcePrefix, prevPrefix);
1734 selectTreeRow(m_resourcePrefixToPrefixItem.value(resourcePrefix));
1735 }
1736 }
1737
slotMoveDown()1738 void QtResourceEditorDialogPrivate::slotMoveDown()
1739 {
1740 if (QtResourceFile *resourceFile = getCurrentResourceFile()) {
1741 QtResourceFile *nextFile = m_qrcManager->nextResourceFile(resourceFile);
1742
1743 if (!nextFile)
1744 return;
1745
1746 m_qrcManager->moveResourceFile(resourceFile, m_qrcManager->nextResourceFile(nextFile));
1747 selectTreeRow(m_resourceFileToPathItem.value(resourceFile));
1748 } else if (QtResourcePrefix *resourcePrefix = getCurrentResourcePrefix()) {
1749 QtResourcePrefix *nextPrefix = m_qrcManager->nextResourcePrefix(resourcePrefix);
1750
1751 if (!nextPrefix)
1752 return;
1753
1754 m_qrcManager->moveResourcePrefix(resourcePrefix, m_qrcManager->nextResourcePrefix(nextPrefix));
1755 selectTreeRow(m_resourcePrefixToPrefixItem.value(resourcePrefix));
1756 }
1757 }
1758
browseForNewLocation(const QString & resourceFile,const QDir & rootDir) const1759 QString QtResourceEditorDialogPrivate::browseForNewLocation(const QString &resourceFile, const QDir &rootDir) const
1760 {
1761 QFileInfo fi(resourceFile);
1762 const QString initialPath = rootDir.absoluteFilePath(fi.fileName());
1763 while (true) {
1764 QString newPath = m_dlgGui->getSaveFileName(q_ptr,
1765 QCoreApplication::translate("QtResourceEditorDialog", "Copy As"),
1766 initialPath);
1767 QString relativePath = rootDir.relativeFilePath(newPath);
1768 if (relativePath.startsWith(QStringLiteral(".."))) {
1769 if (warning(QCoreApplication::translate("QtResourceEditorDialog", "Copy As"),
1770 QCoreApplication::translate("QtResourceEditorDialog", "<p>The selected file:</p>"
1771 "<p>%1</p><p>is outside of the current resource file's directory:</p><p>%2</p>"
1772 "<p>Please select another path within this directory.<p>").
1773 arg(relativePath, rootDir.absolutePath()),
1774 QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok) != QMessageBox::Ok)
1775 return QString();
1776 } else {
1777 return newPath;
1778 }
1779 }
1780
1781 return QString();
1782 }
1783
copyResourceFile(const QString & resourceFile,const QString & destPath) const1784 QString QtResourceEditorDialogPrivate::copyResourceFile(const QString &resourceFile, const QString &destPath) const
1785 {
1786 QFileInfo fi(destPath);
1787 if (fi.exists()) {
1788 while (fi.exists() && !QFile::remove(destPath)) {
1789 if (warning(QCoreApplication::translate("QtResourceEditorDialog", "Copy"),
1790 QCoreApplication::translate("QtResourceEditorDialog", "Could not overwrite %1.").arg(fi.fileName()),
1791 QMessageBox::Retry | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Retry)
1792 return QString();
1793 }
1794 }
1795 while (!QFile::copy(resourceFile, destPath)) {
1796 if (warning(QCoreApplication::translate("QtResourceEditorDialog", "Copy"),
1797 QCoreApplication::translate("QtResourceEditorDialog", "Could not copy\n%1\nto\n%2")
1798 .arg(resourceFile, destPath),
1799 QMessageBox::Retry | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Retry)
1800 return QString();
1801 }
1802 return destPath;
1803 }
loadQrcFile(const QString & path,QtQrcFileData * qrcFileData)1804 bool QtResourceEditorDialogPrivate::loadQrcFile(const QString &path, QtQrcFileData *qrcFileData)
1805 {
1806 QString errorMessage;
1807 const bool rc = loadQrcFile(path, qrcFileData, &errorMessage);
1808 // if (!rc)
1809 // warning(QApplication::translate("QtResourceEditorDialog", "Resource File Load Error"), errorMessage);
1810 return rc;
1811 }
loadQrcFile(const QString & path,QtQrcFileData * qrcFileData,QString * errorMessage)1812 bool QtResourceEditorDialogPrivate::loadQrcFile(const QString &path, QtQrcFileData *qrcFileData, QString *errorMessage)
1813 {
1814 if (!qrcFileData)
1815 return false;
1816
1817 qrcFileData->qrcPath = path;
1818
1819 QFile file(path);
1820 if (!file.open(QIODevice::ReadOnly)) {
1821 // there is sufficient hint while loading a form and after opening the editor (qrc marked marked with red and with [missing] text)
1822 //*errorMessage = QApplication::translate("QtResourceEditorDialog", "Unable to open %1 for reading: %2").arg(path).arg(file.errorString());
1823 return false;
1824 }
1825
1826 QByteArray dataArray = file.readAll();
1827 file.close();
1828
1829 QDomDocument doc;
1830 int errLine, errCol;
1831 if (!doc.setContent(dataArray, errorMessage, &errLine, &errCol)) {
1832 *errorMessage =
1833 QCoreApplication::translate("QtResourceEditorDialog",
1834 "A parse error occurred at line %1, column %2 of %3:\n%4")
1835 .arg(errLine).arg(errCol).arg(path, *errorMessage);
1836 return false;
1837 }
1838
1839 return loadQrcFileData(doc, path, qrcFileData, errorMessage);
1840 }
1841
saveQrcFile(const QtQrcFileData & qrcFileData)1842 bool QtResourceEditorDialogPrivate::saveQrcFile(const QtQrcFileData &qrcFileData)
1843 {
1844 QFile file(qrcFileData.qrcPath);
1845 while (!file.open(QIODevice::WriteOnly)) {
1846 QMessageBox msgBox(QMessageBox::Warning,
1847 QCoreApplication::translate("QtResourceEditorDialog",
1848 "Save Resource File"),
1849 QCoreApplication::translate("QtResourceEditorDialog",
1850 "Could not write %1: %2")
1851 .arg(qrcFileData.qrcPath,
1852 file.errorString()),
1853 QMessageBox::Cancel|QMessageBox::Ignore|QMessageBox::Retry);
1854 msgBox.setEscapeButton(QMessageBox::Cancel);
1855 msgBox.setDefaultButton(QMessageBox::Ignore);
1856 switch (msgBox.exec()) {
1857 case QMessageBox::Retry:
1858 break; // nothing
1859 case QMessageBox::Ignore:
1860 return true;
1861 default:
1862 return false;
1863 }
1864 }
1865
1866 QDomDocument doc = saveQrcFileData(qrcFileData);
1867
1868 QByteArray dataArray = doc.toByteArray(2);
1869 file.write(dataArray);
1870
1871 file.close();
1872 return true;
1873 }
1874
QtResourceEditorDialog(QDesignerFormEditorInterface * core,QDesignerDialogGuiInterface * dlgGui,QWidget * parent)1875 QtResourceEditorDialog::QtResourceEditorDialog(QDesignerFormEditorInterface *core, QDesignerDialogGuiInterface *dlgGui, QWidget *parent)
1876 : QDialog(parent), d_ptr(new QtResourceEditorDialogPrivate())
1877 {
1878 d_ptr->q_ptr = this;
1879 d_ptr->m_ui.setupUi(this);
1880 d_ptr->m_qrcManager = new QtQrcManager(this);
1881 d_ptr->m_dlgGui = dlgGui;
1882 d_ptr->m_core = core;
1883
1884 setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
1885 setWindowTitle(tr("Edit Resources"));
1886
1887 connect(d_ptr->m_qrcManager, SIGNAL(qrcFileInserted(QtQrcFile*)),
1888 this, SLOT(slotQrcFileInserted(QtQrcFile*)));
1889 connect(d_ptr->m_qrcManager, SIGNAL(qrcFileMoved(QtQrcFile*,QtQrcFile*)),
1890 this, SLOT(slotQrcFileMoved(QtQrcFile*)));
1891 connect(d_ptr->m_qrcManager, SIGNAL(qrcFileRemoved(QtQrcFile*)),
1892 this, SLOT(slotQrcFileRemoved(QtQrcFile*)));
1893 connect(d_ptr->m_qrcManager, SIGNAL(resourcePrefixInserted(QtResourcePrefix*)),
1894 this, SLOT(slotResourcePrefixInserted(QtResourcePrefix*)));
1895 connect(d_ptr->m_qrcManager, SIGNAL(resourcePrefixMoved(QtResourcePrefix*,QtResourcePrefix*)),
1896 this, SLOT(slotResourcePrefixMoved(QtResourcePrefix*)));
1897 connect(d_ptr->m_qrcManager, SIGNAL(resourcePrefixChanged(QtResourcePrefix*,QString)),
1898 this, SLOT(slotResourcePrefixChanged(QtResourcePrefix*)));
1899 connect(d_ptr->m_qrcManager, SIGNAL(resourceLanguageChanged(QtResourcePrefix*,QString)),
1900 this, SLOT(slotResourceLanguageChanged(QtResourcePrefix*)));
1901 connect(d_ptr->m_qrcManager, SIGNAL(resourcePrefixRemoved(QtResourcePrefix*)),
1902 this, SLOT(slotResourcePrefixRemoved(QtResourcePrefix*)));
1903 connect(d_ptr->m_qrcManager, SIGNAL(resourceFileInserted(QtResourceFile*)),
1904 this, SLOT(slotResourceFileInserted(QtResourceFile*)));
1905 connect(d_ptr->m_qrcManager, SIGNAL(resourceFileMoved(QtResourceFile*,QtResourceFile*)),
1906 this, SLOT(slotResourceFileMoved(QtResourceFile*)));
1907 connect(d_ptr->m_qrcManager, SIGNAL(resourceAliasChanged(QtResourceFile*,QString)),
1908 this, SLOT(slotResourceAliasChanged(QtResourceFile*)));
1909 connect(d_ptr->m_qrcManager, SIGNAL(resourceFileRemoved(QtResourceFile*)),
1910 this, SLOT(slotResourceFileRemoved(QtResourceFile*)));
1911
1912 QIcon upIcon = qdesigner_internal::createIconSet(QString::fromUtf8("up.png"));
1913 QIcon downIcon = qdesigner_internal::createIconSet(QString::fromUtf8("down.png"));
1914 QIcon minusIcon = qdesigner_internal::createIconSet(QString::fromUtf8("minus-16.png"));
1915 QIcon newIcon = qdesigner_internal::createIconSet(QString::fromUtf8("filenew-16.png"));
1916 QIcon openIcon = qdesigner_internal::createIconSet(QString::fromUtf8("fileopen-16.png"));
1917 QIcon removeIcon = qdesigner_internal::createIconSet(QString::fromUtf8("editdelete-16.png"));
1918 QIcon addPrefixIcon = qdesigner_internal::createIconSet(QString::fromUtf8("prefix-add.png"));
1919
1920 d_ptr->m_newQrcFileAction = new QAction(newIcon, tr("New..."), this);
1921 d_ptr->m_newQrcFileAction->setToolTip(tr("New Resource File"));
1922 d_ptr->m_importQrcFileAction = new QAction(openIcon, tr("Open..."), this);
1923 d_ptr->m_importQrcFileAction->setToolTip(tr("Open Resource File"));
1924 d_ptr->m_removeQrcFileAction = new QAction(removeIcon, tr("Remove"), this);
1925 d_ptr->m_moveUpQrcFileAction = new QAction(upIcon, tr("Move Up"), this);
1926 d_ptr->m_moveDownQrcFileAction = new QAction(downIcon, tr("Move Down"), this);
1927
1928 d_ptr->m_newPrefixAction = new QAction(addPrefixIcon, tr("Add Prefix"), this);
1929 d_ptr->m_newPrefixAction->setToolTip(tr("Add Prefix"));
1930 d_ptr->m_addResourceFileAction = new QAction(openIcon, tr("Add Files..."), this);
1931 d_ptr->m_changePrefixAction = new QAction(tr("Change Prefix"), this);
1932 d_ptr->m_changeLanguageAction = new QAction(tr("Change Language"), this);
1933 d_ptr->m_changeAliasAction = new QAction(tr("Change Alias"), this);
1934 d_ptr->m_clonePrefixAction = new QAction(tr("Clone Prefix..."), this);
1935 d_ptr->m_removeAction = new QAction(minusIcon, tr("Remove"), this);
1936 d_ptr->m_moveUpAction = new QAction(upIcon, tr("Move Up"), this);
1937 d_ptr->m_moveDownAction = new QAction(downIcon, tr("Move Down"), this);
1938
1939 d_ptr->m_ui.newQrcButton->setDefaultAction(d_ptr->m_newQrcFileAction);
1940 d_ptr->m_ui.importQrcButton->setDefaultAction(d_ptr->m_importQrcFileAction);
1941 d_ptr->m_ui.removeQrcButton->setDefaultAction(d_ptr->m_removeQrcFileAction);
1942
1943 d_ptr->m_ui.newResourceButton->setDefaultAction(d_ptr->m_newPrefixAction);
1944 d_ptr->m_ui.addResourceButton->setDefaultAction(d_ptr->m_addResourceFileAction);
1945 d_ptr->m_ui.removeResourceButton->setDefaultAction(d_ptr->m_removeAction);
1946
1947 connect(d_ptr->m_newQrcFileAction, SIGNAL(triggered()), this, SLOT(slotNewQrcFile()));
1948 connect(d_ptr->m_importQrcFileAction, SIGNAL(triggered()), this, SLOT(slotImportQrcFile()));
1949 connect(d_ptr->m_removeQrcFileAction, SIGNAL(triggered()), this, SLOT(slotRemoveQrcFile()));
1950 connect(d_ptr->m_moveUpQrcFileAction, SIGNAL(triggered()), this, SLOT(slotMoveUpQrcFile()));
1951 connect(d_ptr->m_moveDownQrcFileAction, SIGNAL(triggered()), this, SLOT(slotMoveDownQrcFile()));
1952
1953 connect(d_ptr->m_newPrefixAction, SIGNAL(triggered()), this, SLOT(slotNewPrefix()));
1954 connect(d_ptr->m_addResourceFileAction, SIGNAL(triggered()), this, SLOT(slotAddFiles()));
1955 connect(d_ptr->m_changePrefixAction, SIGNAL(triggered()), this, SLOT(slotChangePrefix()));
1956 connect(d_ptr->m_changeLanguageAction, SIGNAL(triggered()), this, SLOT(slotChangeLanguage()));
1957 connect(d_ptr->m_changeAliasAction, SIGNAL(triggered()), this, SLOT(slotChangeAlias()));
1958 connect(d_ptr->m_clonePrefixAction, SIGNAL(triggered()), this, SLOT(slotClonePrefix()));
1959 connect(d_ptr->m_removeAction, SIGNAL(triggered()), this, SLOT(slotRemove()));
1960 connect(d_ptr->m_moveUpAction, SIGNAL(triggered()), this, SLOT(slotMoveUp()));
1961 connect(d_ptr->m_moveDownAction, SIGNAL(triggered()), this, SLOT(slotMoveDown()));
1962
1963 d_ptr->m_ui.qrcFileList->setContextMenuPolicy(Qt::CustomContextMenu);
1964 connect(d_ptr->m_ui.qrcFileList, SIGNAL(customContextMenuRequested(QPoint)),
1965 this, SLOT(slotListWidgetContextMenuRequested(QPoint)));
1966 connect(d_ptr->m_ui.qrcFileList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
1967 this, SLOT(slotCurrentQrcFileChanged(QListWidgetItem*)));
1968
1969 d_ptr->m_treeModel = new QStandardItemModel(this);
1970 d_ptr->m_treeModel->setColumnCount(2);
1971 d_ptr->m_treeModel->setHorizontalHeaderItem(0, new QStandardItem(tr("Prefix / Path")));
1972 d_ptr->m_treeModel->setHorizontalHeaderItem(1, new QStandardItem(tr("Language / Alias")));
1973 d_ptr->m_ui.resourceTreeView->setModel(d_ptr->m_treeModel);
1974 d_ptr->m_ui.resourceTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
1975 d_ptr->m_treeSelection = d_ptr->m_ui.resourceTreeView->selectionModel();
1976 connect(d_ptr->m_ui.resourceTreeView->header(), &QHeaderView::sectionDoubleClicked,
1977 d_ptr->m_ui.resourceTreeView, &QTreeView::resizeColumnToContents);
1978 d_ptr->m_ui.resourceTreeView->setTextElideMode(Qt::ElideLeft);
1979
1980 connect(d_ptr->m_ui.resourceTreeView, SIGNAL(customContextMenuRequested(QPoint)),
1981 this, SLOT(slotTreeViewContextMenuRequested(QPoint)));
1982 connect(d_ptr->m_treeModel, SIGNAL(itemChanged(QStandardItem*)),
1983 this, SLOT(slotTreeViewItemChanged(QStandardItem*)));
1984 connect(d_ptr->m_treeSelection, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
1985 this, SLOT(slotCurrentTreeViewItemChanged(QModelIndex)));
1986
1987 d_ptr->m_ui.resourceTreeView->setColumnWidth(0, 200);
1988
1989 d_ptr->slotCurrentTreeViewItemChanged(QModelIndex());
1990 d_ptr->m_removeQrcFileAction->setEnabled(false);
1991 d_ptr->m_moveUpQrcFileAction->setEnabled(false);
1992 d_ptr->m_moveDownQrcFileAction->setEnabled(false);
1993
1994 QDesignerSettingsInterface *settings = core->settingsManager();
1995 settings->beginGroup(QLatin1String(QrcDialogC));
1996
1997 d_ptr->m_ui.splitter->restoreState(settings->value(QLatin1String(SplitterPosition)).toByteArray());
1998 const QVariant geometry = settings->value(QLatin1String(Geometry));
1999 if (geometry.type() == QVariant::ByteArray) // Used to be a QRect up until 5.4.0, QTBUG-43374
2000 restoreGeometry(geometry.toByteArray());
2001
2002 settings->endGroup();
2003 }
2004
~QtResourceEditorDialog()2005 QtResourceEditorDialog::~QtResourceEditorDialog()
2006 {
2007 QDesignerSettingsInterface *settings = d_ptr->m_core->settingsManager();
2008 settings->beginGroup(QLatin1String(QrcDialogC));
2009
2010 settings->setValue(QLatin1String(SplitterPosition), d_ptr->m_ui.splitter->saveState());
2011 settings->setValue(QLatin1String(Geometry), saveGeometry());
2012 settings->endGroup();
2013 }
2014
model() const2015 QtResourceModel *QtResourceEditorDialog::model() const
2016 {
2017 return d_ptr->m_resourceModel;
2018 }
2019
setResourceModel(QtResourceModel * model)2020 void QtResourceEditorDialog::setResourceModel(QtResourceModel *model)
2021 {
2022 d_ptr->m_resourceModel = model;
2023
2024 QtResourceSet *resourceSet = d_ptr->m_resourceModel->currentResourceSet();
2025 if (!resourceSet) {
2026 // disable everything but cancel button
2027 return;
2028 }
2029
2030 d_ptr->m_initialState.clear();
2031
2032 // enable qrcBox
2033
2034 const QStringList paths = resourceSet->activeResourceFilePaths();
2035 for (const QString &path : paths) {
2036 QtQrcFileData qrcFileData;
2037 d_ptr->loadQrcFile(path, &qrcFileData);
2038 d_ptr->m_initialState << qrcFileData;
2039 d_ptr->m_qrcManager->importQrcFile(qrcFileData);
2040 }
2041 if (d_ptr->m_ui.qrcFileList->count() > 0) {
2042 d_ptr->m_ui.qrcFileList->item(0)->setSelected(true);
2043 }
2044 }
2045
selectedResource() const2046 QString QtResourceEditorDialog::selectedResource() const
2047 {
2048 //QtResourcePrefix *currentResourcePrefix = d_ptr->m_qrcManager->resourcePrefixOf(currentResourceFile);
2049 QtResourcePrefix *currentResourcePrefix = d_ptr->getCurrentResourcePrefix();
2050 if (!currentResourcePrefix)
2051 return QString();
2052
2053 const QChar slash(QLatin1Char('/'));
2054 QString resource = currentResourcePrefix->prefix();
2055 if (!resource.startsWith(slash))
2056 resource.prepend(slash);
2057 if (!resource.endsWith(slash))
2058 resource.append(slash);
2059 resource.prepend(QLatin1Char(':'));
2060
2061 QtResourceFile *currentResourceFile = d_ptr->getCurrentResourceFile();
2062 if (!currentResourceFile)
2063 return resource;
2064
2065 QString resourceEnding = currentResourceFile->path();
2066 if (!currentResourceFile->alias().isEmpty())
2067 resourceEnding = currentResourceFile->alias();
2068
2069 const QString dotSlash(QStringLiteral("./"));
2070 const QString dotDotSlash(QStringLiteral("../"));
2071 while (true) {
2072 if (resourceEnding.startsWith(slash))
2073 resourceEnding = resourceEnding.mid(1);
2074 else if (resourceEnding.startsWith(dotSlash))
2075 resourceEnding = resourceEnding.mid(dotSlash.count());
2076 else if (resourceEnding.startsWith(dotDotSlash))
2077 resourceEnding = resourceEnding.mid(dotDotSlash.count());
2078 else
2079 break;
2080 }
2081
2082 resource.append(resourceEnding);
2083
2084 return resource;
2085 }
2086
displayResourceFailures(const QString & logOutput,QDesignerDialogGuiInterface * dlgGui,QWidget * parent)2087 void QtResourceEditorDialog::displayResourceFailures(const QString &logOutput, QDesignerDialogGuiInterface *dlgGui, QWidget *parent)
2088 {
2089 const QString msg = tr("<html><p><b>Warning:</b> There have been problems while reloading the resources:</p><pre>%1</pre></html>").arg(logOutput);
2090 dlgGui->message(parent, QDesignerDialogGuiInterface::ResourceEditorMessage, QMessageBox::Warning,
2091 tr("Resource Warning"), msg);
2092 }
2093
accept()2094 void QtResourceEditorDialog::accept()
2095 {
2096 QStringList newQrcPaths;
2097 QList<QtQrcFileData> currentState;
2098
2099 const auto qrcFiles = d_ptr->m_qrcManager->qrcFiles();
2100 for (QtQrcFile *qrcFile : qrcFiles) {
2101 QtQrcFileData qrcFileData;
2102 d_ptr->m_qrcManager->exportQrcFile(qrcFile, &qrcFileData);
2103 currentState << qrcFileData;
2104 if (qrcFileData == qrcFile->initialState()) {
2105 // nothing
2106 } else {
2107 d_ptr->m_resourceModel->setWatcherEnabled(qrcFileData.qrcPath, false);
2108 bool ok = d_ptr->saveQrcFile(qrcFileData);
2109 d_ptr->m_resourceModel->setWatcherEnabled(qrcFileData.qrcPath, true);
2110 if (!ok)
2111 return;
2112
2113 d_ptr->m_resourceModel->setModified(qrcFileData.qrcPath);
2114 }
2115 newQrcPaths << qrcFileData.qrcPath;
2116 }
2117
2118 if (currentState == d_ptr->m_initialState) {
2119 // nothing
2120 } else {
2121 int errorCount;
2122 QString errorMessages;
2123 d_ptr->m_resourceModel->currentResourceSet()->activateResourceFilePaths(newQrcPaths, &errorCount, &errorMessages);
2124 if (errorCount)
2125 displayResourceFailures(errorMessages, d_ptr->m_dlgGui, this);
2126 }
2127 QDialog::accept();
2128 }
2129
editResources(QDesignerFormEditorInterface * core,QtResourceModel * model,QDesignerDialogGuiInterface * dlgGui,QWidget * parent)2130 QString QtResourceEditorDialog::editResources(QDesignerFormEditorInterface *core,
2131 QtResourceModel *model,
2132 QDesignerDialogGuiInterface *dlgGui,
2133 QWidget *parent)
2134 {
2135 QtResourceEditorDialog dialog(core, dlgGui, parent);
2136 dialog.setResourceModel(model);
2137 if (dialog.exec() == QDialog::Accepted)
2138 return dialog.selectedResource();
2139 return QString();
2140 }
2141
2142 QT_END_NAMESPACE
2143
2144 #include "moc_qtresourceeditordialog_p.cpp"
2145 #include "qtresourceeditordialog.moc"
2146