5#include "ui_qtresourceeditordialog.h"
9#include <abstractdialoggui_p.h>
11#include <QtDesigner/abstractsettings.h>
12#include <QtDesigner/abstractformeditor.h>
14#include <QtCore/qcompare.h>
15#include <QtCore/qfileinfo.h>
16#include <QtCore/qdir.h>
17#include <QtCore/qcoreapplication.h>
18#include <QtXml/qdom.h>
19#include <QtWidgets/qmenu.h>
20#include <QtWidgets/qheaderview.h>
21#include <QtWidgets/qinputdialog.h>
22#include <QtWidgets/qmessagebox.h>
23#include <QtWidgets/qpushbutton.h>
24#include <QtGui/qstandarditemmodel.h>
28using namespace Qt::StringLiterals;
31static constexpr auto rccTag =
"qresource"_L1;
42 return QCoreApplication::translate(
"QtResourceEditorDialog",
"%1 already exists.\nDo you want to replace it?").arg(fname);
47 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);
61 return lhs.path == rhs.path && lhs.alias == rhs.alias;
75 return lhs.prefix == rhs.prefix && lhs.language == rhs.language
76 && lhs.resourceFileList == rhs.resourceFileList;
89 return lhs.qrcPath == rhs.qrcPath && lhs.resourceList == rhs.resourceList;
101 QString *errorMessage)
106 if (fileElem.tagName() != rccFileTag) {
107 *errorMessage = msgTagMismatch(fileElem.tagName(), rccFileTag);
111 QtResourceFileData &data = *fileData;
113 data.path = fileElem.text();
114 data.alias = fileElem.attribute(rccAliasAttribute);
119static bool loadResourcePrefixData(
const QDomElement &prefixElem, QtResourcePrefixData *prefixData, QString *errorMessage)
124 if (prefixElem.tagName() != rccTag) {
125 *errorMessage = msgTagMismatch(prefixElem.tagName(), rccTag);
129 QtResourcePrefixData &data = *prefixData;
131 data.prefix = prefixElem.attribute(rccPrefixAttribute);
132 data.language = prefixElem.attribute(rccLangAttribute);
133 QDomElement fileElem = prefixElem.firstChildElement();
134 while (!fileElem.isNull()) {
135 QtResourceFileData fileData;
136 if (!loadResourceFileData(fileElem, &fileData, errorMessage))
138 data.resourceFileList.append(fileData);
139 fileElem = fileElem.nextSiblingElement();
144static bool loadQrcFileData(
const QDomDocument &doc,
const QString &path, QtQrcFileData *qrcFileData, QString *errorMessage)
149 QtQrcFileData &data = *qrcFileData;
151 QDomElement docElem = doc.documentElement();
152 if (docElem.tagName() != rccRootTag) {
153 *errorMessage = msgTagMismatch(docElem.tagName(), rccRootTag);
157 QDomElement prefixElem = docElem.firstChildElement();
158 while (!prefixElem.isNull()) {
159 QtResourcePrefixData prefixData;
160 if (!loadResourcePrefixData(prefixElem, &prefixData, errorMessage))
162 data.resourceList.append(prefixData);
163 prefixElem = prefixElem.nextSiblingElement();
173 QDomElement fileElem = doc.createElement(rccFileTag);
174 if (!fileData.alias.isEmpty())
175 fileElem.setAttribute(rccAliasAttribute, fileData.alias);
177 QDomText textElem = doc.createTextNode(fileData.path);
178 fileElem.appendChild(textElem);
185 QDomElement prefixElem = doc.createElement(rccTag);
186 if (!prefixData.prefix.isEmpty())
187 prefixElem.setAttribute(rccPrefixAttribute, prefixData.prefix);
188 if (!prefixData.language.isEmpty())
189 prefixElem.setAttribute(rccLangAttribute, prefixData.language);
191 for (
const QtResourceFileData &rfd : prefixData.resourceFileList) {
192 QDomElement fileElem = saveResourceFileData(doc, rfd);
193 prefixElem.appendChild(fileElem);
202 QDomElement docElem = doc.createElement(rccRootTag);
203 for (
const QtResourcePrefixData &prefixData : qrcFileData.resourceList) {
204 QDomElement prefixElem = saveResourcePrefixData(doc, prefixData);
206 docElem.appendChild(prefixElem);
208 doc.appendChild(docElem);
220 QString
path()
const {
return m_path; }
221 QString
alias()
const {
return m_alias; }
224 QtResourceFile() =
default;
235 QString
prefix()
const {
return m_prefix; }
239 QtResourcePrefix() =
default;
243 QList<QtResourceFile *> m_resourceFiles;
251 QString
path()
const {
return m_path; }
257 QtQrcFile() =
default;
259 void setPath(
const QString &path) {
262 m_fileName = fi.fileName();
267 QList<QtResourcePrefix *> m_resourcePrefixes;
289 QIcon
icon(
const QString &resourceFullPath)
const;
290 bool exists(
const QString &resourceFullPath)
const;
312 const QString &prefix,
const QString &language,
320 const QString &path,
const QString &alias,
337 const QString &oldPrefix);
339 const QString &oldLanguage);
346 const QString &oldAlias);
350 QList<QtQrcFile *> m_qrcFiles;
351 QMap<QString, QtQrcFile *> m_pathToQrc;
352 QHash<QtQrcFile *,
bool> m_qrcFileToExists;
353 QHash<QtResourcePrefix *, QtQrcFile *> m_prefixToQrc;
354 QHash<QtResourceFile *, QtResourcePrefix *> m_fileToPrefix;
355 QMap<QString, QList<QtResourceFile *> > m_fullPathToResourceFiles;
356 QMap<QString, QIcon> m_fullPathToIcon;
357 QMap<QString,
bool> m_fullPathToExists;
378 return m_pathToQrc.value(path);
383 return m_prefixToQrc.value(resourcePrefix);
388 return m_fileToPrefix.value(resourceFile);
393 QtQrcFile *qrcFile = insertQrcFile(qrcFileData.qrcPath, beforeQrcFile);
396 for (
const QtResourcePrefixData &prefixData : qrcFileData.resourceList) {
397 QtResourcePrefix *resourcePrefix = insertResourcePrefix(qrcFile, prefixData.prefix, prefixData.language,
nullptr);
398 for (
const QtResourceFileData &fileData : prefixData.resourceFileList)
399 insertResourceFile(resourcePrefix, fileData.path, fileData.alias,
nullptr);
415 QList<QtResourcePrefixData> resourceList;
417 const auto resourcePrefixes = qrcFile->resourcePrefixList();
418 for (
const QtResourcePrefix *prefix : resourcePrefixes) {
419 QList<QtResourceFileData> resourceFileList;
420 const auto resourceFiles = prefix->resourceFiles();
421 for (QtResourceFile *file : resourceFiles) {
422 QtResourceFileData fileData;
423 fileData.path = file->path();
424 fileData.alias = file->alias();
425 resourceFileList << fileData;
427 QtResourcePrefixData prefixData;
428 prefixData.prefix = prefix->prefix();
429 prefixData.language = prefix->language();
430 prefixData.resourceFileList = resourceFileList;
432 resourceList << prefixData;
435 data.qrcPath = qrcFile->path();
436 data.resourceList = resourceList;
441 return m_fullPathToIcon.value(resourceFullPath);
446 return m_fullPathToExists.value(resourceFullPath,
false);
451 return m_qrcFileToExists.value(qrcFile,
false);
458 const int idx = m_qrcFiles.indexOf(qrcFile);
461 return m_qrcFiles.at(idx - 1);
468 const int idx = m_qrcFiles.indexOf(qrcFile);
469 if (idx < 0 || idx == m_qrcFiles.size() - 1)
471 return m_qrcFiles.at(idx + 1);
478 const auto prefixes =
qrcFileOf(resourcePrefix
)->resourcePrefixList();
479 const int idx = prefixes.indexOf(resourcePrefix);
482 return prefixes.at(idx - 1);
489 const auto prefixes =
qrcFileOf(resourcePrefix
)->resourcePrefixList();
490 const int idx = prefixes.indexOf(resourcePrefix);
491 if (idx < 0 || idx == prefixes.size() - 1)
493 return prefixes.at(idx + 1);
501 const int idx = files.indexOf(resourceFile);
504 return files.at(idx - 1);
512 const int idx = files.indexOf(resourceFile);
513 if (idx < 0 || idx == files.size() - 1)
515 return files.at(idx + 1);
520 const auto oldQrcFiles = qrcFiles();
521 for (QtQrcFile *qf : oldQrcFiles)
527 if (m_pathToQrc.contains(path))
530 int idx = m_qrcFiles.indexOf(beforeQrcFile);
532 idx = m_qrcFiles.size();
535 qrcFile->setPath(path);
537 m_qrcFiles.insert(idx, qrcFile);
538 m_pathToQrc[path] = qrcFile;
540 const QFileInfo fi(path);
541 m_qrcFileToExists[qrcFile] = fi.exists() || newFile;
543 emit qrcFileInserted(qrcFile);
549 if (qrcFile == beforeQrcFile)
552 const int idx = m_qrcFiles.indexOf(qrcFile);
556 int beforeIdx = m_qrcFiles.indexOf(beforeQrcFile);
558 beforeIdx = m_qrcFiles.size();
560 if (idx == beforeIdx - 1)
564 if (idx < m_qrcFiles.size() - 1)
565 oldBefore = m_qrcFiles.at(idx + 1);
567 m_qrcFiles.removeAt(idx);
571 m_qrcFiles.insert(beforeIdx, qrcFile);
573 emit qrcFileMoved(qrcFile, oldBefore);
578 qrcFile->m_initialState = initialState;
583 const int idx = m_qrcFiles.indexOf(qrcFile);
587 const auto resourcePrefixes = qrcFile->resourcePrefixList();
588 for (QtResourcePrefix *rp : resourcePrefixes)
589 removeResourcePrefix(rp);
591 emit qrcFileRemoved(qrcFile);
593 m_qrcFiles.removeAt(idx);
594 m_pathToQrc.remove(qrcFile->path());
595 m_qrcFileToExists.remove(qrcFile);
605 int idx = qrcFile->m_resourcePrefixes.indexOf(beforeResourcePrefix);
607 idx = qrcFile->m_resourcePrefixes.size();
610 resourcePrefix->m_prefix = prefix;
611 resourcePrefix->m_language = language;
613 qrcFile->m_resourcePrefixes.insert(idx, resourcePrefix);
614 m_prefixToQrc[resourcePrefix] = qrcFile;
616 emit resourcePrefixInserted(resourcePrefix);
617 return resourcePrefix;
622 if (resourcePrefix == beforeResourcePrefix)
629 if (beforeResourcePrefix &&
qrcFileOf(beforeResourcePrefix
) != qrcFile)
632 const int idx = qrcFile->m_resourcePrefixes.indexOf(resourcePrefix);
634 int beforeIdx = qrcFile->m_resourcePrefixes.indexOf(beforeResourcePrefix);
636 beforeIdx = qrcFile->m_resourcePrefixes.size();
638 if (idx == beforeIdx - 1)
642 if (idx < qrcFile->m_resourcePrefixes.size() - 1)
643 oldBefore = qrcFile->m_resourcePrefixes.at(idx + 1);
645 qrcFile->m_resourcePrefixes.removeAt(idx);
649 qrcFile->m_resourcePrefixes.insert(beforeIdx, resourcePrefix);
651 emit resourcePrefixMoved(resourcePrefix, oldBefore);
659 const QString oldPrefix = resourcePrefix->m_prefix;
660 if (oldPrefix == newPrefix)
663 resourcePrefix->m_prefix = newPrefix;
665 emit resourcePrefixChanged(resourcePrefix, oldPrefix);
673 const QString oldLanguage = resourcePrefix->m_language;
674 if (oldLanguage == newLanguage)
677 resourcePrefix->m_language = newLanguage;
679 emit resourceLanguageChanged(resourcePrefix, oldLanguage);
688 const int idx = qrcFile->m_resourcePrefixes.indexOf(resourcePrefix);
690 const auto resourceFiles = resourcePrefix->resourceFiles();
691 for (QtResourceFile *rf : resourceFiles)
692 removeResourceFile(rf);
694 emit resourcePrefixRemoved(resourcePrefix);
696 qrcFile->m_resourcePrefixes.removeAt(idx);
697 m_prefixToQrc.remove(resourcePrefix);
698 delete resourcePrefix;
707 int idx = resourcePrefix->m_resourceFiles.indexOf(beforeResourceFile);
709 idx = resourcePrefix->m_resourceFiles.size();
712 resourceFile->m_path = path;
713 resourceFile->m_alias = alias;
714 const QFileInfo fi(qrcFileOf(resourcePrefix)->path());
715 const QDir dir(fi.absolutePath());
716 const QString fullPath = dir.absoluteFilePath(path);
717 resourceFile->m_fullPath = fullPath;
719 resourcePrefix->m_resourceFiles.insert(idx, resourceFile);
720 m_fileToPrefix[resourceFile] = resourcePrefix;
721 m_fullPathToResourceFiles[fullPath].append(resourceFile);
722 if (!m_fullPathToIcon.contains(fullPath)) {
723 m_fullPathToIcon[fullPath] = QIcon(fullPath);
724 const QFileInfo fullInfo(fullPath);
725 m_fullPathToExists[fullPath] = fullInfo.exists();
728 emit resourceFileInserted(resourceFile);
734 if (resourceFile == beforeResourceFile)
744 const int idx = resourcePrefix->m_resourceFiles.indexOf(resourceFile);
746 int beforeIdx = resourcePrefix->m_resourceFiles.indexOf(beforeResourceFile);
748 beforeIdx = resourcePrefix->m_resourceFiles.size();
750 if (idx == beforeIdx - 1)
754 if (idx < resourcePrefix->m_resourceFiles.size() - 1)
755 oldBefore = resourcePrefix->m_resourceFiles.at(idx + 1);
757 resourcePrefix->m_resourceFiles.removeAt(idx);
761 resourcePrefix->m_resourceFiles.insert(beforeIdx, resourceFile);
763 emit resourceFileMoved(resourceFile, oldBefore);
771 const QString oldAlias = resourceFile->m_alias;
772 if (oldAlias == newAlias)
775 resourceFile->m_alias = newAlias;
777 emit resourceAliasChanged(resourceFile, oldAlias);
786 const int idx = resourcePrefix->m_resourceFiles.indexOf(resourceFile);
788 emit resourceFileRemoved(resourceFile);
790 resourcePrefix->m_resourceFiles.removeAt(idx);
791 m_fileToPrefix.remove(resourceFile);
792 const QString fullPath = resourceFile->fullPath();
793 m_fullPathToResourceFiles[fullPath].removeAll(resourceFile);
794 if (m_fullPathToResourceFiles[fullPath].isEmpty()) {
795 m_fullPathToResourceFiles.remove(fullPath);
796 m_fullPathToIcon.remove(fullPath);
797 m_fullPathToExists.remove(fullPath);
813 Q_DECLARE_PUBLIC(QtResourceEditorDialog)
855 bool loadQrcFile(
const QString &path, QtQrcFileData *qrcFileData, QString *errorMessage);
856 bool loadQrcFile(
const QString &path, QtQrcFileData *qrcFileData);
870 const QString &title, QString dir,
const QString &filter,
const QString &extension)
const;
874 QDesignerFormEditorInterface *
m_core =
nullptr;
916 QMessageBox::StandardButton defaultButton)
const
918 return m_dlgGui->message(q_ptr, QDesignerDialogGuiInterface::ResourceEditorMessage, QMessageBox::Warning, title, text, buttons, defaultButton);
923 const QString path = qrcFile->path();
924 const QString fileName = qrcFile->fileName();
925 const QFileInfo fi(path);
926 if (fi.exists() && !fi.isWritable())
927 return QApplication::translate(
"QtResourceEditorDialog",
"%1 [read-only]").arg(fileName);
928 if (!m_qrcManager->exists(qrcFile))
929 return QApplication::translate(
"QtResourceEditorDialog",
"%1 [missing]").arg(fileName);
935 QListWidgetItem *currentItem = m_ui.qrcFileList->currentItem();
936 int idx = m_ui.qrcFileList->count();
938 QListWidgetItem *nextItem = m_qrcFileToItem.value(nextQrcFile);
940 const int row = m_ui.qrcFileList->row(nextItem);
944 const QString path = qrcFile->path();
945 QListWidgetItem *item =
new QListWidgetItem(qrcFileText(qrcFile));
946 item->setToolTip(path);
948 m_ui.qrcFileList->insertItem(idx, item);
949 m_ui.qrcFileList->setCurrentItem(currentItem);
951 m_qrcFileToItem[qrcFile] = item;
952 m_itemToQrcFile[item] = qrcFile;
953 if (!m_qrcManager->exists(qrcFile))
954 item->setForeground(QBrush(Qt::red));
959 QListWidgetItem *currentItem = m_ui.qrcFileList->currentItem();
960 QListWidgetItem *item = m_qrcFileToItem.value(qrcFile);
962 m_ui.qrcFileList->takeItem(m_ui.qrcFileList->row(item));
964 int idx = m_ui.qrcFileList->count();
966 QListWidgetItem *nextItem = m_qrcFileToItem.value(nextQrcFile);
968 int row = m_ui.qrcFileList->row(nextItem);
972 m_ui.qrcFileList->insertItem(idx, item);
973 if (currentItem == item)
974 m_ui.qrcFileList->setCurrentItem(item);
980 QListWidgetItem *item = m_qrcFileToItem.value(qrcFile);
981 if (item == m_ui.qrcFileList->currentItem())
982 m_ui.qrcFileList->setCurrentItem(
nullptr);
986 m_itemToQrcFile.remove(item);
987 m_qrcFileToItem.remove(qrcFile);
996 QStandardItem *prevItem = m_resourcePrefixToPrefixItem.value(prevResourcePrefix);
1000 row = m_treeModel->indexFromItem(prevItem).row() + 1;
1002 QStandardItem *prefixItem =
new QStandardItem();
1003 QStandardItem *languageItem =
new QStandardItem();
1004 QList<QStandardItem *> items;
1005 items << prefixItem;
1006 items << languageItem;
1007 m_treeModel->insertRow(row, items);
1008 const QModelIndex newIndex = m_treeModel->indexFromItem(prefixItem);
1009 m_ui.resourceTreeView->setExpanded(newIndex,
true);
1010 prefixItem->setFlags(prefixItem->flags() | Qt::ItemIsEditable);
1011 languageItem->setFlags(languageItem->flags() | Qt::ItemIsEditable);
1012 m_resourcePrefixToPrefixItem[resourcePrefix] = prefixItem;
1013 m_resourcePrefixToLanguageItem[resourcePrefix] = languageItem;
1014 m_prefixItemToResourcePrefix[prefixItem] = resourcePrefix;
1015 m_languageItemToResourcePrefix[languageItem] = resourcePrefix;
1023 QStandardItem *prefixItem = m_resourcePrefixToPrefixItem.value(resourcePrefix);
1027 QStandardItem *languageItem = m_resourcePrefixToLanguageItem.value(resourcePrefix);
1031 const QModelIndex index = m_treeModel->indexFromItem(prefixItem);
1032 const bool expanded = m_ui.resourceTreeView->isExpanded(index);
1034 const auto items = m_treeModel->takeRow(index.row());
1036 int row = m_treeModel->rowCount();
1038 QStandardItem *nextItem = m_resourcePrefixToPrefixItem.value(nextResourcePrefix);
1040 row = m_treeModel->indexFromItem(nextItem).row();
1041 m_treeModel->insertRow(row, items);
1043 m_ui.resourceTreeView->setExpanded(m_treeModel->indexFromItem(items.at(0)), expanded);
1048 QStandardItem *item = m_resourcePrefixToPrefixItem.value(resourcePrefix);
1053 QString prefix = resourcePrefix->prefix();
1054 if (prefix.isEmpty())
1055 prefix = QCoreApplication::translate(
"QtResourceEditorDialog",
"<no prefix>");
1056 item->setText(prefix);
1057 item->setToolTip(prefix);
1063 QStandardItem *item = m_resourcePrefixToLanguageItem.value(resourcePrefix);
1068 const QString language = resourcePrefix->language();
1069 item->setText(language);
1070 item->setToolTip(language);
1077 QStandardItem *prefixItem = m_resourcePrefixToPrefixItem.value(resourcePrefix);
1081 QStandardItem *languageItem = m_resourcePrefixToLanguageItem.value(resourcePrefix);
1086 m_treeModel->takeRow(m_treeModel->indexFromItem(prefixItem).row());
1088 delete languageItem;
1090 m_prefixItemToResourcePrefix.remove(prefixItem);
1091 m_languageItemToResourcePrefix.remove(languageItem);
1092 m_resourcePrefixToPrefixItem.remove(resourcePrefix);
1093 m_resourcePrefixToLanguageItem.remove(resourcePrefix);
1103 QStandardItem *prevItem = m_resourceFileToPathItem.value(prevResourceFile);
1105 QStandardItem *pathItem =
new QStandardItem(resourceFile->path());
1106 QStandardItem *aliasItem =
new QStandardItem();
1107 QStandardItem *parentItem = m_resourcePrefixToPrefixItem.value(resourcePrefix);
1108 QList<QStandardItem *> items;
1114 row = m_treeModel->indexFromItem(prevItem).row() + 1;
1116 parentItem->insertRow(row, items);
1118 pathItem->setFlags(pathItem->flags() & ~Qt::ItemIsEditable);
1119 aliasItem->setFlags(aliasItem->flags() | Qt::ItemIsEditable);
1120 m_resourceFileToPathItem[resourceFile] = pathItem;
1121 m_resourceFileToAliasItem[resourceFile] = aliasItem;
1122 m_pathItemToResourceFile[pathItem] = resourceFile;
1123 m_aliasItemToResourceFile[aliasItem] = resourceFile;
1124 pathItem->setToolTip(resourceFile->path());
1125 pathItem->setIcon(
m_qrcManager->icon(resourceFile->fullPath()));
1127 pathItem->setText(QApplication::translate(
"QtResourceEditorDialog",
"%1 [missing]").arg(resourceFile->path()));
1128 QBrush redBrush(Qt::red);
1129 pathItem->setForeground(redBrush);
1130 aliasItem->setForeground(redBrush);
1137 QStandardItem *pathItem = m_resourceFileToPathItem.value(resourceFile);
1141 QStandardItem *aliasItem = m_resourceFileToAliasItem.value(resourceFile);
1145 QStandardItem *parentItem = pathItem->parent();
1147 const auto items = parentItem->takeRow(m_treeModel->indexFromItem(pathItem).row());
1149 int row = parentItem->rowCount();
1151 QStandardItem *nextItem = m_resourceFileToPathItem.value(nextResourceFile);
1153 row = m_treeModel->indexFromItem(nextItem).row();
1154 parentItem->insertRow(row, items);
1160 QStandardItem *item = m_resourceFileToAliasItem.value(resourceFile);
1165 const QString alias = resourceFile->alias();
1166 item->setText(alias);
1167 item->setToolTip(alias);
1174 QStandardItem *pathItem = m_resourceFileToPathItem.value(resourceFile);
1178 QStandardItem *aliasItem = m_resourceFileToAliasItem.value(resourceFile);
1182 QStandardItem *parentItem = pathItem->parent();
1185 parentItem->takeRow(m_treeModel->indexFromItem(pathItem).row());
1189 m_pathItemToResourceFile.remove(pathItem);
1190 m_aliasItemToResourceFile.remove(aliasItem);
1191 m_resourceFileToPathItem.remove(resourceFile);
1192 m_resourceFileToAliasItem.remove(resourceFile);
1201 QtQrcFile *newCurrentQrcFile = m_itemToQrcFile.value(item);
1207 QHash<QtResourcePrefix *, QStandardItem *> currentPrefixList = m_resourcePrefixToPrefixItem;
1208 for (
auto it = currentPrefixList.cbegin(), end = currentPrefixList.cend(); it != end; ++it) {
1209 QtResourcePrefix *resourcePrefix = it.key();
1210 const auto currentResourceFiles = resourcePrefix->resourceFiles();
1211 for (QtResourceFile *rf : currentResourceFiles)
1212 slotResourceFileRemoved(rf);
1218 slotCurrentTreeViewItemChanged(QModelIndex());
1219 QStandardItem *firstPrefix =
nullptr;
1222 for (QtResourcePrefix *resourcePrefix : newPrefixList) {
1223 if (QStandardItem *newPrefixItem = insertResourcePrefix(resourcePrefix))
1225 firstPrefix = newPrefixItem;
1226 const auto newResourceFiles = resourcePrefix->resourceFiles();
1227 for (QtResourceFile *rf : newResourceFiles)
1228 slotResourceFileInserted(rf);
1231 m_ui.resourceTreeView->setCurrentIndex(firstPrefix ? m_treeModel->indexFromItem(firstPrefix) : QModelIndex());
1233 m_removeQrcFileAction->setEnabled(m_currentQrcFile);
1234 m_moveUpQrcFileAction->setEnabled(m_currentQrcFile && m_qrcManager->prevQrcFile(m_currentQrcFile));
1235 m_moveDownQrcFileAction->setEnabled(m_currentQrcFile && m_qrcManager->nextQrcFile(m_currentQrcFile));
1240 QStandardItem *item = m_treeModel->itemFromIndex(index);
1241 QtResourceFile *resourceFile = m_pathItemToResourceFile.value(item);
1243 resourceFile = m_aliasItemToResourceFile.value(item);
1244 QtResourcePrefix *resourcePrefix = m_prefixItemToResourcePrefix.value(item);
1245 if (!resourcePrefix)
1246 resourcePrefix = m_languageItemToResourcePrefix.value(item);
1248 bool moveUpEnabled =
false;
1249 bool moveDownEnabled =
false;
1250 bool currentItem = resourceFile || resourcePrefix;
1254 moveUpEnabled =
true;
1256 moveDownEnabled =
true;
1257 }
else if (resourcePrefix) {
1259 moveUpEnabled =
true;
1261 moveDownEnabled =
true;
1264 m_newPrefixAction->setEnabled(m_currentQrcFile);
1265 m_addResourceFileAction->setEnabled(currentItem);
1266 m_changePrefixAction->setEnabled(currentItem);
1267 m_changeLanguageAction->setEnabled(currentItem);
1268 m_changeAliasAction->setEnabled(resourceFile);
1269 m_removeAction->setEnabled(currentItem);
1270 m_moveUpAction->setEnabled(moveUpEnabled);
1271 m_moveDownAction->setEnabled(moveDownEnabled);
1272 m_clonePrefixAction->setEnabled(currentItem);
1278 menu.addAction(m_newQrcFileAction);
1279 menu.addAction(m_importQrcFileAction);
1280 menu.addAction(m_removeQrcFileAction);
1281 menu.addSeparator();
1282 menu.addAction(m_moveUpQrcFileAction);
1283 menu.addAction(m_moveDownQrcFileAction);
1284 menu.exec(m_ui.qrcFileList->mapToGlobal(pos));
1290 menu.addAction(m_newPrefixAction);
1291 menu.addAction(m_addResourceFileAction);
1292 menu.addAction(m_removeAction);
1293 menu.addSeparator();
1294 menu.addAction(m_changePrefixAction);
1295 menu.addAction(m_changeLanguageAction);
1296 menu.addAction(m_changeAliasAction);
1297 menu.addSeparator();
1298 menu.addAction(m_clonePrefixAction);
1299 menu.addSeparator();
1300 menu.addAction(m_moveUpAction);
1301 menu.addAction(m_moveDownAction);
1302 menu.exec(m_ui.resourceTreeView->mapToGlobal(pos));
1310 const QString newValue = item->text();
1311 QtResourceFile *resourceFile = m_aliasItemToResourceFile.value(item);
1317 QtResourcePrefix *resourcePrefix = m_prefixItemToResourcePrefix.value(item);
1318 if (resourcePrefix) {
1323 resourcePrefix = m_languageItemToResourcePrefix.value(item);
1324 if (resourcePrefix) {
1331 const QString &title, QString dir,
const QString &filter,
const QString &extension)
const
1335 saveFile = m_dlgGui->getSaveFileName(parent, title, dir, filter,
nullptr, QFileDialog::DontConfirmOverwrite);
1336 if (saveFile.isEmpty())
1339 const QFileInfo fInfo(saveFile);
1340 if (fInfo.suffix().isEmpty() && !fInfo.fileName().endsWith(u'.'))
1341 saveFile += u'.' + extension;
1343 const QFileInfo fi(saveFile);
1347 if (warning(title, msgOverwrite(fi.fileName()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
1359 const QDir dir = QFileInfo(m_currentQrcFile->path()).dir();
1360 return dir.exists() ? dir.absolutePath() : QString();
1365 const QString qrcPath = getSaveFileNameWithExtension(q_ptr,
1366 QCoreApplication::translate(
"QtResourceEditorDialog",
"New Resource File"),
1367 m_firstQrcFileDialog ? qrcStartDirectory() : QString(),
1368 QCoreApplication::translate(
"QtResourceEditorDialog",
"Resource files (*.qrc)"),
1370 if (qrcPath.isEmpty())
1374 if (QtQrcFile *sameQrcFile =
m_qrcManager->qrcFileOf(qrcPath)) {
1376 QListWidgetItem *item = m_qrcFileToItem.value(sameQrcFile);
1377 m_ui.qrcFileList->setCurrentItem(item);
1378 item->setSelected(
true);
1384 QtQrcFile *qrcFile =
m_qrcManager->insertQrcFile(qrcPath, nextQrcFile,
true);
1385 m_ui.qrcFileList->setCurrentItem(m_qrcFileToItem.value(qrcFile));
1390 const QString qrcPath = m_dlgGui->getOpenFileName(q_ptr,
1391 QCoreApplication::translate(
"QtResourceEditorDialog",
"Import Resource File"),
1392 m_firstQrcFileDialog ? qrcStartDirectory() : QString(),
1393 QCoreApplication::translate(
"QtResourceEditorDialog",
"Resource files (*.qrc)"));
1394 if (qrcPath.isEmpty())
1397 if (QtQrcFile *sameQrcFile =
m_qrcManager->qrcFileOf(qrcPath)) {
1399 QListWidgetItem *item = m_qrcFileToItem.value(sameQrcFile);
1400 m_ui.qrcFileList->setCurrentItem(item);
1401 item->setSelected(
true);
1407 QtQrcFileData qrcFileData;
1408 loadQrcFile(qrcPath, &qrcFileData);
1410 m_ui.qrcFileList->setCurrentItem(m_qrcFileToItem.value(qrcFile));
1419 if (!currentQrcFile)
1423 QListWidgetItem *item = m_qrcFileToItem.value(currentQrcFile);
1425 m_ui.qrcFileList->setCurrentItem(item);
1426 item->setSelected(
true);
1457 QStandardItem *currentItem = m_treeModel->itemFromIndex(m_treeSelection->currentIndex());
1460 QtResourceFile *currentResourceFile =
nullptr;
1462 currentResourceFile = m_pathItemToResourceFile.value(currentItem);
1463 if (!currentResourceFile)
1464 currentResourceFile = m_aliasItemToResourceFile.value(currentItem);
1466 return currentResourceFile;
1471 QStandardItem *currentItem = m_treeModel->itemFromIndex(m_treeSelection->currentIndex());
1473 QtResourcePrefix *currentResourcePrefix =
nullptr;
1475 currentResourcePrefix = m_prefixItemToResourcePrefix.value(currentItem);
1476 if (!currentResourcePrefix) {
1477 currentResourcePrefix = m_languageItemToResourcePrefix.value(currentItem);
1478 if (!currentResourcePrefix) {
1480 if (currentResourceFile)
1485 return currentResourcePrefix;
1490 const QModelIndex index = m_treeModel->indexFromItem(item);
1491 m_treeSelection->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
1492 m_treeSelection->setCurrentIndex(index, QItemSelectionModel::Select);
1502 QtResourcePrefix *newResourcePrefix = m_qrcManager->insertResourcePrefix(m_currentQrcFile,
1503 QCoreApplication::translate(
"QtResourceEditorDialog",
"newPrefix"),
1504 QString(), nextResourcePrefix);
1505 if (!newResourcePrefix)
1508 QStandardItem *newItem = m_resourcePrefixToPrefixItem.value(newResourcePrefix);
1512 const QModelIndex index = m_treeModel->indexFromItem(newItem);
1513 selectTreeRow(newItem);
1514 m_ui.resourceTreeView->edit(index);
1519 return QApplication::translate(
"QtResourceEditorDialog",
1520 "<p><b>Warning:</b> The file</p>"
1522 "<p>is outside of the current resource file's parent directory.</p>").arg(fname);
1527 return QApplication::translate(
"QtResourceEditorDialog",
1528 "<p>To resolve the issue, press:</p>"
1530 "<tr><th align=\"left\">Copy</th><td>to copy the file to the resource file's parent directory.</td></tr>"
1531 "<tr><th align=\"left\">Copy As...</th><td>to copy the file into a subdirectory of the resource file's parent directory.</td></tr>"
1532 "<tr><th align=\"left\">Keep</th><td>to use its current location.</td></tr></table>");
1542 if (!currentResourcePrefix)
1545 QString initialPath = m_currentQrcFile->path();
1546 if (currentResourceFile) {
1547 QFileInfo fi(currentResourceFile->fullPath());
1548 initialPath = fi.absolutePath();
1551 const QStringList resourcePaths = m_dlgGui->getOpenImageFileNames(q_ptr,
1552 QCoreApplication::translate(
"QtResourceEditorDialog",
"Add Files"),
1554 if (resourcePaths.isEmpty())
1558 if (!currentResourceFile) {
1559 const auto resourceFiles = currentResourcePrefix->resourceFiles();
1560 if (!resourceFiles.isEmpty())
1561 nextResourceFile = resourceFiles.first();
1564 const QFileInfo fi(m_currentQrcFile->path());
1565 const QString destDir = fi.absolutePath();
1566 const QDir dir(fi.absolutePath());
1567 for (QString resourcePath : resourcePaths) {
1568 QString relativePath = dir.relativeFilePath(resourcePath);
1569 if (relativePath.startsWith(
".."_L1)) {
1570 QMessageBox msgBox(QMessageBox::Warning,
1571 QCoreApplication::translate(
"QtResourceEditorDialog",
"Incorrect Path"),
1572 outOfPathWarning(relativePath), QMessageBox::Cancel);
1573 msgBox.setInformativeText(outOfPathWarningInfo());
1574 QPushButton *copyButton = msgBox.addButton(QCoreApplication::translate(
"QtResourceEditorDialog",
1575 "Copy"), QMessageBox::ActionRole);
1576 QPushButton *copyAsButton = msgBox.addButton(QCoreApplication::translate(
"QtResourceEditorDialog",
1577 "Copy As..."), QMessageBox::ActionRole);
1578 QPushButton *keepButton = msgBox.addButton(QCoreApplication::translate(
"QtResourceEditorDialog",
1579 "Keep"), QMessageBox::ActionRole);
1580 QPushButton *skipButton = msgBox.addButton(QCoreApplication::translate(
"QtResourceEditorDialog",
1581 "Skip"), QMessageBox::ActionRole);
1582 msgBox.setEscapeButton(QMessageBox::Cancel);
1583 msgBox.setDefaultButton(copyButton);
1586 if (msgBox.clickedButton() == keepButton) {
1588 }
else if (msgBox.clickedButton() == copyButton) {
1589 QFileInfo resInfo(resourcePath);
1591 destPath = dd.absoluteFilePath(resInfo.fileName());
1592 if (dd.exists(resInfo.fileName())) {
1593 if (warning(QCoreApplication::translate(
"QtResourceEditorDialog",
"Copy"),
1594 msgOverwrite(resInfo.fileName()),
1595 QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Yes)
1598 resourcePath = copyResourceFile(resourcePath, destPath);
1599 }
else if (msgBox.clickedButton() == copyAsButton) {
1600 destPath = browseForNewLocation(resourcePath, dir);
1601 if (destPath.isEmpty())
1603 resourcePath = copyResourceFile(resourcePath, destPath);
1604 }
else if (msgBox.clickedButton() == skipButton) {
1609 if (resourcePath.isEmpty())
1612 relativePath = dir.relativeFilePath(resourcePath);
1613 QtResourceFile *newResourceFile = m_qrcManager->insertResourceFile(currentResourcePrefix, relativePath, QString(), nextResourceFile);
1615 QStandardItem *newItem = m_resourceFileToPathItem.value(newResourceFile);
1617 selectTreeRow(newItem);
1624 if (!currentResourcePrefix)
1627 QStandardItem *item = m_resourcePrefixToPrefixItem.value(currentResourcePrefix);
1628 QModelIndex index = m_treeModel->indexFromItem(item);
1629 selectTreeRow(item);
1630 m_ui.resourceTreeView->scrollTo(index);
1631 m_ui.resourceTreeView->edit(index);
1637 if (!currentResourcePrefix)
1640 QStandardItem *item = m_resourcePrefixToLanguageItem.value(currentResourcePrefix);
1641 QModelIndex index = m_treeModel->indexFromItem(item);
1642 selectTreeRow(item);
1643 m_ui.resourceTreeView->scrollTo(index);
1644 m_ui.resourceTreeView->edit(index);
1650 if (!currentResourceFile)
1653 QStandardItem *item = m_resourceFileToAliasItem.value(currentResourceFile);
1654 QModelIndex index = m_treeModel->indexFromItem(item);
1655 selectTreeRow(item);
1656 m_ui.resourceTreeView->scrollTo(index);
1657 m_ui.resourceTreeView->edit(index);
1663 if (!currentResourcePrefix)
1667 QString suffix = QInputDialog::getText(q_ptr, QApplication::translate(
"QtResourceEditorDialog",
"Clone Prefix"),
1668 QCoreApplication::translate(
"QtResourceEditorDialog",
"Enter the suffix which you want to add to the names of the cloned files.\n"
1669 "This could for example be a language extension like \"_de\"."),
1670 QLineEdit::Normal, QString(), &ok);
1676 if (newResourcePrefix) {
1677 const auto files = currentResourcePrefix->resourceFiles();
1678 for (QtResourceFile *resourceFile : files) {
1679 QString path = resourceFile->path();
1682 QString oldSuffix = fi.completeSuffix();
1683 if (!oldSuffix.isEmpty())
1684 oldSuffix = u'.' + oldSuffix;
1685 const QString newBaseName = fi.baseName() + suffix + oldSuffix;
1686 const QString newPath = QDir::cleanPath(dir.filePath(newBaseName));
1687 m_qrcManager->insertResourceFile(newResourcePrefix, newPath,
1688 resourceFile->alias());
1695 QStandardItem *item = m_treeModel->itemFromIndex(m_treeSelection->currentIndex());
1699 QtResourceFile *resourceFile = m_pathItemToResourceFile.value(item);
1701 resourceFile = m_aliasItemToResourceFile.value(item);
1702 QtResourcePrefix *resourcePrefix = m_prefixItemToResourcePrefix.value(item);
1703 if (!resourcePrefix)
1704 resourcePrefix = m_languageItemToResourcePrefix.value(item);
1706 QStandardItem *newCurrentItem =
nullptr;
1712 newCurrentItem = m_resourceFileToPathItem.value(nextFile);
1713 if (!newCurrentItem)
1714 newCurrentItem = m_resourcePrefixToPrefixItem.value(m_qrcManager->resourcePrefixOf(resourceFile));
1716 if (!newCurrentItem) {
1720 newCurrentItem = m_resourcePrefixToPrefixItem.value(nextPrefix);
1723 selectTreeRow(newCurrentItem);
1727 else if (resourceFile)
1740 selectTreeRow(m_resourceFileToPathItem.value(resourceFile));
1748 selectTreeRow(m_resourcePrefixToPrefixItem.value(resourcePrefix));
1761 selectTreeRow(m_resourceFileToPathItem.value(resourceFile));
1769 selectTreeRow(m_resourcePrefixToPrefixItem.value(resourcePrefix));
1775 QFileInfo fi(resourceFile);
1776 const QString initialPath = rootDir.absoluteFilePath(fi.fileName());
1778 QString newPath = m_dlgGui->getSaveFileName(q_ptr,
1779 QCoreApplication::translate(
"QtResourceEditorDialog",
"Copy As"),
1781 QString relativePath = rootDir.relativeFilePath(newPath);
1782 if (relativePath.startsWith(
".."_L1)) {
1783 if (warning(QCoreApplication::translate(
"QtResourceEditorDialog",
"Copy As"),
1784 QCoreApplication::translate(
"QtResourceEditorDialog",
"<p>The selected file:</p>"
1785 "<p>%1</p><p>is outside of the current resource file's directory:</p><p>%2</p>"
1786 "<p>Please select another path within this directory.<p>").
1787 arg(relativePath, rootDir.absolutePath()),
1788 QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok) != QMessageBox::Ok)
1800 QFileInfo fi(destPath);
1802 while (fi.exists() && !QFile::remove(destPath)) {
1803 if (warning(QCoreApplication::translate(
"QtResourceEditorDialog",
"Copy"),
1804 QCoreApplication::translate(
"QtResourceEditorDialog",
"Could not overwrite %1.").arg(fi.fileName()),
1805 QMessageBox::Retry | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Retry)
1809 while (!QFile::copy(resourceFile, destPath)) {
1810 if (warning(QCoreApplication::translate(
"QtResourceEditorDialog",
"Copy"),
1811 QCoreApplication::translate(
"QtResourceEditorDialog",
"Could not copy\n%1\nto\n%2")
1812 .arg(resourceFile, destPath),
1813 QMessageBox::Retry | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Retry)
1820 QString errorMessage;
1821 const bool rc = loadQrcFile(path, qrcFileData, &errorMessage);
1831 qrcFileData->qrcPath = path;
1834 if (!file.open(QIODevice::ReadOnly)) {
1840 QByteArray dataArray = file.readAll();
1844 if (QDomDocument::ParseResult result = doc.setContent(dataArray)) {
1845 return loadQrcFileData(doc, path, qrcFileData, errorMessage);
1848 QCoreApplication::translate(
"QtResourceEditorDialog",
1849 "A parse error occurred at line %1, column %2 of %3:\n%4")
1850 .arg(result.errorLine).arg(result.errorColumn).arg(path, result.errorMessage);
1857 QFile file(qrcFileData.qrcPath);
1858 while (!file.open(QIODevice::WriteOnly)) {
1859 QMessageBox msgBox(QMessageBox::Warning,
1860 QCoreApplication::translate(
"QtResourceEditorDialog",
1861 "Save Resource File"),
1862 QCoreApplication::translate(
"QtResourceEditorDialog",
1863 "Could not write %1: %2")
1864 .arg(qrcFileData.qrcPath,
1865 file.errorString()),
1866 QMessageBox::Cancel|QMessageBox::Ignore|QMessageBox::Retry);
1867 msgBox.setEscapeButton(QMessageBox::Cancel);
1868 msgBox.setDefaultButton(QMessageBox::Ignore);
1869 switch (msgBox.exec()) {
1870 case QMessageBox::Retry:
1872 case QMessageBox::Ignore:
1879 QDomDocument doc = saveQrcFileData(qrcFileData);
1881 QByteArray dataArray = doc.toByteArray(2);
1882 file.write(dataArray);
1889 : QDialog(parent), d_ptr(
new QtResourceEditorDialogPrivate())
1891 d_ptr->q_ptr =
this;
1892 d_ptr->m_ui.setupUi(
this);
1893 d_ptr->m_qrcManager =
new QtQrcManager(
this);
1894 d_ptr->m_dlgGui = dlgGui;
1895 d_ptr->m_core = core;
1897 setWindowTitle(tr(
"Edit Resources"));
1899 connect(d_ptr->m_qrcManager, &QtQrcManager::qrcFileInserted,
1900 this, [
this](QtQrcFile *file) { d_ptr->slotQrcFileInserted(file); });
1901 connect(d_ptr->m_qrcManager, &QtQrcManager::qrcFileMoved,
1902 this, [
this](QtQrcFile *file) { d_ptr->slotQrcFileMoved(file); });
1903 connect(d_ptr->m_qrcManager, &QtQrcManager::qrcFileRemoved,
1904 this, [
this](QtQrcFile *file) { d_ptr->slotQrcFileRemoved(file); });
1906 connect(d_ptr->m_qrcManager, &QtQrcManager::resourcePrefixInserted,
1907 this, [
this](QtResourcePrefix *prefix) { d_ptr->slotResourcePrefixInserted(prefix); });
1908 connect(d_ptr->m_qrcManager, &QtQrcManager::resourcePrefixMoved,
1909 this, [
this](QtResourcePrefix *prefix) { d_ptr->slotResourcePrefixMoved(prefix); });
1910 connect(d_ptr->m_qrcManager, &QtQrcManager::resourcePrefixChanged,
1911 this, [
this](QtResourcePrefix *prefix) { d_ptr->slotResourcePrefixChanged(prefix); });
1912 connect(d_ptr->m_qrcManager, &QtQrcManager::resourceLanguageChanged,
1913 this, [
this](QtResourcePrefix *prefix) { d_ptr->slotResourceLanguageChanged(prefix); });
1914 connect(d_ptr->m_qrcManager, &QtQrcManager::resourcePrefixRemoved,
1915 this, [
this](QtResourcePrefix *prefix) { d_ptr->slotResourcePrefixRemoved(prefix); });
1917 connect(d_ptr->m_qrcManager, &QtQrcManager::resourceFileInserted,
1918 this, [
this](QtResourceFile *file) { d_ptr->slotResourceFileInserted(file); });
1919 connect(d_ptr->m_qrcManager, &QtQrcManager::resourceFileMoved,
1920 this, [
this](QtResourceFile *file) { d_ptr->slotResourceFileMoved(file); });
1921 connect(d_ptr->m_qrcManager, &QtQrcManager::resourceAliasChanged,
1922 this, [
this](QtResourceFile *file) { d_ptr->slotResourceAliasChanged(file); });
1923 connect(d_ptr->m_qrcManager, &QtQrcManager::resourceFileRemoved,
1924 this, [
this](QtResourceFile *file) { d_ptr->slotResourceFileRemoved(file); });
1926 QIcon upIcon = qdesigner_internal::createIconSet(
"up.png"_L1);
1927 QIcon downIcon = qdesigner_internal::createIconSet(
"down.png"_L1);
1928 QIcon minusIcon = qdesigner_internal::createIconSet(
"minus-16.png"_L1);
1929 QIcon newIcon = qdesigner_internal::createIconSet(
"filenew-16.png"_L1);
1930 QIcon openIcon = qdesigner_internal::createIconSet(
"fileopen-16.png"_L1);
1931 QIcon removeIcon = qdesigner_internal::createIconSet(
"editdelete-16.png"_L1);
1932 QIcon addPrefixIcon = qdesigner_internal::createIconSet(
"prefix-add.png"_L1);
1934 d_ptr->m_newQrcFileAction =
new QAction(newIcon, tr(
"New..."),
this);
1935 d_ptr->m_newQrcFileAction->setToolTip(tr(
"New Resource File"));
1936 d_ptr->m_importQrcFileAction =
new QAction(openIcon, tr(
"Open..."),
this);
1937 d_ptr->m_importQrcFileAction->setToolTip(tr(
"Open Resource File"));
1938 d_ptr->m_removeQrcFileAction =
new QAction(removeIcon, tr(
"Remove"),
this);
1939 d_ptr->m_moveUpQrcFileAction =
new QAction(upIcon, tr(
"Move Up"),
this);
1940 d_ptr->m_moveDownQrcFileAction =
new QAction(downIcon, tr(
"Move Down"),
this);
1942 d_ptr->m_newPrefixAction =
new QAction(addPrefixIcon, tr(
"Add Prefix"),
this);
1943 d_ptr->m_newPrefixAction->setToolTip(tr(
"Add Prefix"));
1944 d_ptr->m_addResourceFileAction =
new QAction(openIcon, tr(
"Add Files..."),
this);
1945 d_ptr->m_changePrefixAction =
new QAction(tr(
"Change Prefix"),
this);
1946 d_ptr->m_changeLanguageAction =
new QAction(tr(
"Change Language"),
this);
1947 d_ptr->m_changeAliasAction =
new QAction(tr(
"Change Alias"),
this);
1948 d_ptr->m_clonePrefixAction =
new QAction(tr(
"Clone Prefix..."),
this);
1949 d_ptr->m_removeAction =
new QAction(minusIcon, tr(
"Remove"),
this);
1950 d_ptr->m_moveUpAction =
new QAction(upIcon, tr(
"Move Up"),
this);
1951 d_ptr->m_moveDownAction =
new QAction(downIcon, tr(
"Move Down"),
this);
1953 d_ptr->m_ui.newQrcButton->setDefaultAction(d_ptr->m_newQrcFileAction);
1954 d_ptr->m_ui.importQrcButton->setDefaultAction(d_ptr->m_importQrcFileAction);
1955 d_ptr->m_ui.removeQrcButton->setDefaultAction(d_ptr->m_removeQrcFileAction);
1957 d_ptr->m_ui.newResourceButton->setDefaultAction(d_ptr->m_newPrefixAction);
1958 d_ptr->m_ui.addResourceButton->setDefaultAction(d_ptr->m_addResourceFileAction);
1959 d_ptr->m_ui.removeResourceButton->setDefaultAction(d_ptr->m_removeAction);
1961 connect(d_ptr->m_newQrcFileAction, &QAction::triggered,
1962 this, [
this] { d_ptr->slotNewQrcFile(); });
1963 connect(d_ptr->m_importQrcFileAction, &QAction::triggered,
1964 this, [
this] { d_ptr->slotImportQrcFile(); });
1965 connect(d_ptr->m_removeQrcFileAction, &QAction::triggered,
1966 this, [
this] { d_ptr->slotRemoveQrcFile(); });
1967 connect(d_ptr->m_moveUpQrcFileAction, &QAction::triggered,
1968 this, [
this] { d_ptr->slotMoveUpQrcFile(); });
1969 connect(d_ptr->m_moveDownQrcFileAction, &QAction::triggered,
1970 this, [
this] { d_ptr->slotMoveDownQrcFile(); });
1972 connect(d_ptr->m_newPrefixAction, &QAction::triggered,
1973 this, [
this] { d_ptr->slotNewPrefix(); });
1974 connect(d_ptr->m_addResourceFileAction, &QAction::triggered,
1975 this, [
this] { d_ptr->slotAddFiles(); });
1976 connect(d_ptr->m_changePrefixAction, &QAction::triggered,
1977 this, [
this] { d_ptr->slotChangePrefix(); });
1978 connect(d_ptr->m_changeLanguageAction, &QAction::triggered,
1979 this, [
this] { d_ptr->slotChangeLanguage(); });
1980 connect(d_ptr->m_changeAliasAction, &QAction::triggered,
1981 this, [
this] { d_ptr->slotChangeAlias(); });
1982 connect(d_ptr->m_clonePrefixAction, &QAction::triggered,
1983 this, [
this] { d_ptr->slotClonePrefix(); });
1984 connect(d_ptr->m_removeAction, &QAction::triggered,
1985 this, [
this] { d_ptr->slotRemove(); });
1986 connect(d_ptr->m_moveUpAction, &QAction::triggered,
1987 this, [
this] { d_ptr->slotMoveUp(); });
1988 connect(d_ptr->m_moveDownAction, &QAction::triggered,
1989 this, [
this] { d_ptr->slotMoveDown(); });
1991 d_ptr->m_ui.qrcFileList->setContextMenuPolicy(Qt::CustomContextMenu);
1992 connect(d_ptr->m_ui.qrcFileList, &QListWidget::customContextMenuRequested,
1993 this, [
this](
const QPoint &point) { d_ptr->slotListWidgetContextMenuRequested(point); });
1994 connect(d_ptr->m_ui.qrcFileList, &QListWidget::currentItemChanged,
1995 this, [
this](QListWidgetItem *item) { d_ptr->slotCurrentQrcFileChanged(item); });
1997 d_ptr->m_treeModel =
new QStandardItemModel(
this);
1998 d_ptr->m_treeModel->setColumnCount(2);
1999 d_ptr->m_treeModel->setHorizontalHeaderItem(0,
new QStandardItem(tr(
"Prefix / Path")));
2000 d_ptr->m_treeModel->setHorizontalHeaderItem(1,
new QStandardItem(tr(
"Language / Alias")));
2001 d_ptr->m_ui.resourceTreeView->setModel(d_ptr->m_treeModel);
2002 d_ptr->m_ui.resourceTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
2003 d_ptr->m_treeSelection = d_ptr->m_ui.resourceTreeView->selectionModel();
2004 connect(d_ptr->m_ui.resourceTreeView->header(), &QHeaderView::sectionDoubleClicked,
2005 d_ptr->m_ui.resourceTreeView, &QTreeView::resizeColumnToContents);
2006 d_ptr->m_ui.resourceTreeView->setTextElideMode(Qt::ElideLeft);
2008 connect(d_ptr->m_ui.resourceTreeView, &QTreeView::customContextMenuRequested,
2009 this, [
this](
const QPoint &point) { d_ptr->slotTreeViewContextMenuRequested(point); });
2010 connect(d_ptr->m_treeModel, &QStandardItemModel::itemChanged,
2011 this, [
this](QStandardItem *item) { d_ptr->slotTreeViewItemChanged(item); });
2012 connect(d_ptr->m_treeSelection, &QItemSelectionModel::currentChanged,
2013 this, [
this](
const QModelIndex &index) { d_ptr->slotCurrentTreeViewItemChanged(index); });
2015 d_ptr->m_ui.resourceTreeView->setColumnWidth(0, 200);
2017 d_ptr->slotCurrentTreeViewItemChanged(QModelIndex());
2018 d_ptr->m_removeQrcFileAction->setEnabled(
false);
2019 d_ptr->m_moveUpQrcFileAction->setEnabled(
false);
2020 d_ptr->m_moveDownQrcFileAction->setEnabled(
false);
2022 QDesignerSettingsInterface *settings = core->settingsManager();
2023 settings->beginGroup(QrcDialogC);
2025 d_ptr->m_ui.splitter->restoreState(settings->value(SplitterPosition).toByteArray());
2026 const QVariant geometry = settings->value(ResourceEditorGeometry);
2027 if (geometry.metaType().id() == QMetaType::QByteArray)
2028 restoreGeometry(geometry.toByteArray());
2030 settings->endGroup();
2035 QDesignerSettingsInterface *settings = d_ptr->m_core->settingsManager();
2036 settings->beginGroup(QrcDialogC);
2038 settings->setValue(SplitterPosition, d_ptr->m_ui.splitter->saveState());
2039 settings->setValue(ResourceEditorGeometry, saveGeometry());
2040 settings->endGroup();
2042 disconnect(d_ptr->m_qrcManager,
nullptr,
this,
nullptr);
2047 return d_ptr->m_resourceModel;
2052 d_ptr->m_resourceModel = model;
2054 QtResourceSet *resourceSet = d_ptr->m_resourceModel->currentResourceSet();
2060 d_ptr->m_initialState.clear();
2064 const QStringList paths = resourceSet->activeResourceFilePaths();
2065 for (
const QString &path : paths) {
2066 QtQrcFileData qrcFileData;
2067 d_ptr->loadQrcFile(path, &qrcFileData);
2068 d_ptr->m_initialState << qrcFileData;
2069 d_ptr->m_qrcManager->importQrcFile(qrcFileData);
2071 if (d_ptr->m_ui.qrcFileList->count() > 0) {
2072 d_ptr->m_ui.qrcFileList->item(0)->setSelected(
true);
2079 QtResourcePrefix *currentResourcePrefix = d_ptr->getCurrentResourcePrefix();
2080 if (!currentResourcePrefix)
2083 const QChar slash(u'/');
2084 QString resource = currentResourcePrefix->prefix();
2085 if (!resource.startsWith(slash))
2086 resource.prepend(slash);
2087 if (!resource.endsWith(slash))
2088 resource.append(slash);
2089 resource.prepend(u':');
2091 QtResourceFile *currentResourceFile = d_ptr->getCurrentResourceFile();
2092 if (!currentResourceFile)
2095 QString resourceEnding = currentResourceFile->path();
2096 if (!currentResourceFile->alias().isEmpty())
2097 resourceEnding = currentResourceFile->alias();
2099 const auto dotSlash =
"./"_L1;
2100 const auto dotDotSlash =
"../"_L1;
2102 if (resourceEnding.startsWith(slash))
2103 resourceEnding = resourceEnding.mid(1);
2104 else if (resourceEnding.startsWith(dotSlash))
2105 resourceEnding = resourceEnding.mid(dotSlash.size());
2106 else if (resourceEnding.startsWith(dotDotSlash))
2107 resourceEnding = resourceEnding.mid(dotDotSlash.size());
2112 resource.append(resourceEnding);
2119 const QString msg = tr(
"<html><p><b>Warning:</b> There have been problems while reloading the resources:</p><pre>%1</pre></html>").arg(logOutput);
2120 dlgGui->message(parent, QDesignerDialogGuiInterface::ResourceEditorMessage, QMessageBox::Warning,
2121 tr(
"Resource Warning"), msg);
2126 QStringList newQrcPaths;
2127 QList<QtQrcFileData> currentState;
2129 const auto qrcFiles = d_ptr->m_qrcManager->qrcFiles();
2130 for (QtQrcFile *qrcFile : qrcFiles) {
2131 QtQrcFileData qrcFileData;
2132 d_ptr->m_qrcManager->exportQrcFile(qrcFile, &qrcFileData);
2133 currentState << qrcFileData;
2134 if (qrcFileData == qrcFile->initialState()) {
2137 d_ptr->m_resourceModel->setWatcherEnabled(qrcFileData.qrcPath,
false);
2138 bool ok = d_ptr->saveQrcFile(qrcFileData);
2139 d_ptr->m_resourceModel->setWatcherEnabled(qrcFileData.qrcPath,
true);
2143 d_ptr->m_resourceModel->setModified(qrcFileData.qrcPath);
2145 newQrcPaths << qrcFileData.qrcPath;
2148 if (currentState == d_ptr->m_initialState) {
2152 QString errorMessages;
2153 d_ptr->m_resourceModel->currentResourceSet()->activateResourceFilePaths(newQrcPaths, &errorCount, &errorMessages);
2155 displayResourceFailures(errorMessages, d_ptr->m_dlgGui,
this);
2161 QtResourceModel *model,
2162 QDesignerDialogGuiInterface *dlgGui,
2167 if (dialog.exec() == QDialog::Accepted)
2168 return dialog.selectedResource();
2174#include "moc_qtresourceeditordialog_p.cpp"
2175#include "qtresourceeditordialog.moc"
QAction * m_importQrcFileAction
QHash< QListWidgetItem *, QtQrcFile * > m_itemToQrcFile
Ui::QtResourceEditorDialog m_ui
void slotQrcFileRemoved(QtQrcFile *qrcFile)
void selectTreeRow(QStandardItem *item)
void slotResourceAliasChanged(QtResourceFile *resourceFile)
void slotTreeViewContextMenuRequested(const QPoint &pos)
void slotResourcePrefixChanged(QtResourcePrefix *resourcePrefix)
bool loadQrcFile(const QString &path, QtQrcFileData *qrcFileData, QString *errorMessage)
QAction * m_newPrefixAction
QtResourceModel * m_resourceModel
QMessageBox::StandardButton warning(const QString &title, const QString &text, QMessageBox::StandardButtons buttons=QMessageBox::Ok, QMessageBox::StandardButton defaultButton=QMessageBox::NoButton) const
QtQrcFile * m_currentQrcFile
QString qrcStartDirectory() const
void slotTreeViewItemChanged(QStandardItem *item)
QHash< QStandardItem *, QtResourceFile * > m_pathItemToResourceFile
void slotResourcePrefixMoved(QtResourcePrefix *resourcePrefix)
void slotMoveDownQrcFile()
void slotResourceLanguageChanged(QtResourcePrefix *resourcePrefix)
void slotResourcePrefixRemoved(QtResourcePrefix *resourcePrefix)
QAction * m_changeLanguageAction
QAction * m_moveDownQrcFileAction
QHash< QtResourceFile *, QStandardItem * > m_resourceFileToAliasItem
QAction * m_moveDownAction
QAction * m_clonePrefixAction
void slotResourceFileMoved(QtResourceFile *resourceFile)
QAction * m_removeQrcFileAction
void slotChangeLanguage()
bool saveQrcFile(const QtQrcFileData &qrcFileData)
QAction * m_newQrcFileAction
QString copyResourceFile(const QString &resourceFile, const QString &destPath) const
QtResourcePrefix * getCurrentResourcePrefix() const
void slotQrcFileMoved(QtQrcFile *qrcFile)
void slotListWidgetContextMenuRequested(const QPoint &pos)
QAction * m_moveUpQrcFileAction
QAction * m_changeAliasAction
void slotCurrentQrcFileChanged(QListWidgetItem *item)
void slotResourceFileInserted(QtResourceFile *resourceFile)
QtQrcManager * m_qrcManager
QString getSaveFileNameWithExtension(QWidget *parent, const QString &title, QString dir, const QString &filter, const QString &extension) const
void slotResourceFileRemoved(QtResourceFile *resourceFile)
QAction * m_addResourceFileAction
bool loadQrcFile(const QString &path, QtQrcFileData *qrcFileData)
QDesignerFormEditorInterface * m_core
void slotQrcFileInserted(QtQrcFile *qrcFile)
QHash< QStandardItem *, QtResourcePrefix * > m_prefixItemToResourcePrefix
QAction * m_changePrefixAction
QList< QtQrcFileData > m_initialState
void slotCurrentTreeViewItemChanged(const QModelIndex &index)
void slotResourcePrefixInserted(QtResourcePrefix *resourcePrefix)
QHash< QtResourcePrefix *, QStandardItem * > m_resourcePrefixToPrefixItem
QStandardItemModel * m_treeModel
QtResourceFile * getCurrentResourceFile() const
QHash< QtQrcFile *, QListWidgetItem * > m_qrcFileToItem
QString browseForNewLocation(const QString &resourceFile, const QDir &rootDir) const
QDesignerDialogGuiInterface * m_dlgGui
QHash< QtResourceFile *, QStandardItem * > m_resourceFileToPathItem
QHash< QtResourcePrefix *, QStandardItem * > m_resourcePrefixToLanguageItem
bool m_firstQrcFileDialog
QString qrcFileText(QtQrcFile *qrcFile) const
QHash< QStandardItem *, QtResourcePrefix * > m_languageItemToResourcePrefix
QItemSelectionModel * m_treeSelection
QHash< QStandardItem *, QtResourceFile * > m_aliasItemToResourceFile
bool m_ignoreCurrentChanged
QStandardItem * insertResourcePrefix(QtResourcePrefix *resourcePrefix)
~QtResourceEditorDialog() override
QString selectedResource() const
void setResourceModel(QtResourceModel *model)
QtQrcFileData initialState() const
QList< QtResourcePrefix * > resourcePrefixList() const
QtQrcFile * qrcFileOf(const QString &path) const
QtQrcFile * qrcFileOf(QtResourcePrefix *resourcePrefix) const
void qrcFileMoved(qdesigner_internal::QtQrcFile *qrcFile, qdesigner_internal::QtQrcFile *oldBeforeQrcFile)
QtResourceFile * nextResourceFile(QtResourceFile *resourceFile) const
void resourcePrefixMoved(qdesigner_internal::QtResourcePrefix *resourcePrefix, qdesigner_internal::QtResourcePrefix *oldBeforeResourcePrefix)
QtResourcePrefix * resourcePrefixOf(QtResourceFile *resourceFile) const
void changeResourcePrefix(qdesigner_internal::QtResourcePrefix *resourcePrefix, const QString &newPrefix)
void changeResourceAlias(qdesigner_internal::QtResourceFile *resourceFile, const QString &newAlias)
bool exists(QtQrcFile *qrcFile) const
void exportQrcFile(QtQrcFile *qrcFile, QtQrcFileData *qrcFileData) const
QtQrcFile * nextQrcFile(QtQrcFile *qrcFile) const
QtResourceFile * insertResourceFile(qdesigner_internal::QtResourcePrefix *resourcePrefix, const QString &path, const QString &alias, qdesigner_internal::QtResourceFile *beforeResourceFile=nullptr)
QtQrcFile * importQrcFile(const QtQrcFileData &qrcFileData, QtQrcFile *beforeQrcFile=nullptr)
void removeResourcePrefix(qdesigner_internal::QtResourcePrefix *resourcePrefix)
void resourceAliasChanged(qdesigner_internal::QtResourceFile *resourceFile, const QString &oldAlias)
QtResourcePrefix * nextResourcePrefix(QtResourcePrefix *resourcePrefix) const
bool exists(const QString &resourceFullPath) const
void setInitialState(qdesigner_internal::QtQrcFile *qrcFile, const QtQrcFileData &initialState)
void resourceFileInserted(qdesigner_internal::QtResourceFile *resourceFile)
void resourcePrefixChanged(qdesigner_internal::QtResourcePrefix *resourcePrefix, const QString &oldPrefix)
void resourceLanguageChanged(qdesigner_internal::QtResourcePrefix *resourcePrefix, const QString &oldLanguage)
void resourceFileRemoved(qdesigner_internal::QtResourceFile *resourceFile)
void qrcFileRemoved(qdesigner_internal::QtQrcFile *qrcFile)
void removeQrcFile(qdesigner_internal::QtQrcFile *qrcFile)
void resourceFileMoved(qdesigner_internal::QtResourceFile *resourceFile, qdesigner_internal::QtResourceFile *oldBeforeResourceFile)
QtResourcePrefix * insertResourcePrefix(qdesigner_internal::QtQrcFile *qrcFile, const QString &prefix, const QString &language, QtResourcePrefix *beforeResourcePrefix=nullptr)
void removeResourceFile(qdesigner_internal::QtResourceFile *resourceFile)
void moveResourceFile(qdesigner_internal::QtResourceFile *resourceFile, qdesigner_internal::QtResourceFile *beforeResourceFile)
QIcon icon(const QString &resourceFullPath) const
void resourcePrefixInserted(qdesigner_internal::QtResourcePrefix *resourcePrefix)
void resourcePrefixRemoved(qdesigner_internal::QtResourcePrefix *resourcePrefix)
QtQrcFile * prevQrcFile(QtQrcFile *qrcFile) const
void moveResourcePrefix(qdesigner_internal::QtResourcePrefix *resourcePrefix, QtResourcePrefix *beforeResourcePrefix)
QtResourceFile * prevResourceFile(QtResourceFile *resourceFile) const
void changeResourceLanguage(qdesigner_internal::QtResourcePrefix *resourcePrefix, const QString &newLanguage)
QList< QtQrcFile * > qrcFiles() const
void moveQrcFile(QtQrcFile *qrcFile, qdesigner_internal::QtQrcFile *beforeQrcFile)
QtResourcePrefix * prevResourcePrefix(QtResourcePrefix *resourcePrefix) const
QList< QtResourceFile * > resourceFiles() const
Combined button and popup list for selecting options.
Auxiliary methods to store/retrieve settings.
static bool loadResourcePrefixData(const QDomElement &prefixElem, QtResourcePrefixData *prefixData, QString *errorMessage)
static QDomElement saveResourcePrefixData(QDomDocument &doc, const QtResourcePrefixData &prefixData)
static QDomElement saveResourceFileData(QDomDocument &doc, const QtResourceFileData &fileData)
static constexpr auto rccPrefixAttribute
static constexpr auto ResourceEditorGeometry
static QString outOfPathWarning(const QString &fname)
static bool loadQrcFileData(const QDomDocument &doc, const QString &path, QtQrcFileData *qrcFileData, QString *errorMessage)
static constexpr auto rccFileTag
static QString msgOverwrite(const QString &fname)
static bool loadResourceFileData(const QDomElement &fileElem, QtResourceFileData *fileData, QString *errorMessage)
static QString outOfPathWarningInfo()
static QString msgTagMismatch(const QString &got, const QString &expected)
static QDomDocument saveQrcFileData(const QtQrcFileData &qrcFileData)
static constexpr auto rccRootTag
static constexpr auto rccLangAttribute
static constexpr auto rccTag
static constexpr auto SplitterPosition
static constexpr auto rccAliasAttribute
static constexpr auto QrcDialogC
friend bool comparesEqual(const QtQrcFileData &lhs, const QtQrcFileData &rhs) noexcept
QList< QtResourcePrefixData > resourceList
friend bool comparesEqual(const QtResourceFileData &lhs, const QtResourceFileData &rhs) noexcept
friend bool comparesEqual(const QtResourcePrefixData &lhs, const QtResourcePrefixData &rhs) noexcept
QList< QtResourceFileData > resourceFileList