1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
33 #include "resourcefile_p.h"
35 #include <QtCore/QCoreApplication>
36 #include <QtCore/QDebug>
37 #include <QtCore/QDir>
38 #include <QtCore/QFile>
39 #include <QtCore/QMimeData>
40 #include <QtCore/QtAlgorithms>
41 #include <QtCore/QTextStream>
43 #include <QtGui/QIcon>
44 #include <QtGui/QImageReader>
46 #include <QtXml/QDomDocument>
52 TRANSLATOR qdesigner_internal::ResourceModel
55 static QString msgFileNameEmpty()
57 return QCoreApplication::translate("Designer", "The file name is empty.");
60 namespace qdesigner_internal {
63 /******************************************************************************
67 bool FileList::containsFile(File *file)
69 foreach (const File *tmpFile, *this)
70 if (tmpFile->name == file->name && tmpFile->prefix() == file->prefix())
75 /******************************************************************************
79 ResourceFile::ResourceFile(const QString &file_name)
81 setFileName(file_name);
84 ResourceFile::~ResourceFile()
89 bool ResourceFile::load()
91 m_error_message.clear();
93 if (m_file_name.isEmpty()) {
94 m_error_message = msgFileNameEmpty();
98 QFile file(m_file_name);
99 if (!file.open(QIODevice::ReadOnly)) {
100 m_error_message = file.errorString();
109 int error_line, error_col;
110 if (!doc.setContent(&file, &error_msg, &error_line, &error_col)) {
111 m_error_message = QCoreApplication::translate("Designer", "XML error on line %1, col %2: %3")
112 .arg(error_line).arg(error_col).arg(error_msg);
116 QDomElement root = doc.firstChildElement(QLatin1String("RCC"));
118 m_error_message = QCoreApplication::translate("Designer", "The <RCC> root element is missing.");
122 QDomElement relt = root.firstChildElement(QLatin1String("qresource"));
123 for (; !relt.isNull(); relt = relt.nextSiblingElement(QLatin1String("qresource"))) {
125 QString prefix = fixPrefix(relt.attribute(QLatin1String("prefix")));
126 if (prefix.isEmpty())
127 prefix = QString(QLatin1Char('/'));
128 const QString language = relt.attribute(QLatin1String("lang"));
130 const int idx = indexOfPrefix(prefix);
133 p = new Prefix(prefix, language);
134 m_prefix_list.append(p);
136 p = m_prefix_list[idx];
140 QDomElement felt = relt.firstChildElement(QLatin1String("file"));
141 for (; !felt.isNull(); felt = felt.nextSiblingElement(QLatin1String("file"))) {
142 const QString fileName = absolutePath(felt.text());
143 const QString alias = felt.attribute(QLatin1String("alias"));
144 File * const file = new File(p, fileName, alias);
145 p->file_list.append(file);
152 bool ResourceFile::save()
154 m_error_message.clear();
156 if (m_file_name.isEmpty()) {
157 m_error_message = msgFileNameEmpty();
161 QFile file(m_file_name);
162 if (!file.open(QIODevice::WriteOnly)) {
163 m_error_message = file.errorString();
168 QDomElement root = doc.createElement(QLatin1String("RCC"));
169 doc.appendChild(root);
171 const QStringList name_list = prefixList();
173 foreach (const QString &name, name_list) {
176 foreach (const Prefix *pref, m_prefix_list) {
177 if (pref->name == name){
178 file_list += pref->file_list;
183 QDomElement relt = doc.createElement(QLatin1String("qresource"));
184 root.appendChild(relt);
185 relt.setAttribute(QLatin1String("prefix"), name);
187 relt.setAttribute(QLatin1String("lang"), lang);
189 foreach (const File *f, file_list) {
190 const File &file = *f;
191 QDomElement felt = doc.createElement(QLatin1String("file"));
192 relt.appendChild(felt);
193 const QString conv_file = relativePath(file.name).replace(QDir::separator(), QLatin1Char('/'));
194 const QDomText text = doc.createTextNode(conv_file);
195 felt.appendChild(text);
196 if (!file.alias.isEmpty())
197 felt.setAttribute(QLatin1String("alias"), file.alias);
201 QTextStream stream(&file);
207 bool ResourceFile::split(const QString &_path, QString *prefix, QString *file) const
212 QString path = _path;
213 if (!path.startsWith(QLatin1Char(':')))
217 for (int i = 0; i < m_prefix_list.size(); ++i) {
218 Prefix const * const &pref = m_prefix_list.at(i);
219 if (!path.startsWith(pref->name))
222 *prefix = pref->name;
223 if (pref->name == QString(QLatin1Char('/')))
226 *file = path.mid(pref->name.size() + 1);
228 const QString filePath = absolutePath(*file);
230 for (int j = 0; j < pref->file_list.count(); j++) {
231 File const * const &f = pref->file_list.at(j);
232 if (!f->alias.isEmpty()) {
233 if (absolutePath(f->alias) == filePath) {
237 } else if (f->name == filePath)
245 QString ResourceFile::resolvePath(const QString &path) const
247 QString prefix, file;
248 if (split(path, &prefix, &file))
249 return absolutePath(file);
254 QStringList ResourceFile::prefixList() const
257 for (int i = 0; i < m_prefix_list.size(); ++i)
258 result.append(m_prefix_list.at(i)->name);
262 bool ResourceFile::isEmpty() const
264 return m_file_name.isEmpty() && m_prefix_list.isEmpty();
267 QStringList ResourceFile::fileList(int pref_idx) const
270 Q_ASSERT(pref_idx >= 0 && pref_idx < m_prefix_list.count());
271 const FileList &abs_file_list = m_prefix_list.at(pref_idx)->file_list;
272 foreach (const File *abs_file, abs_file_list)
273 result.append(relativePath(abs_file->name));
277 void ResourceFile::addFile(int prefix_idx, const QString &file, int file_idx)
279 Prefix * const p = m_prefix_list[prefix_idx];
281 FileList &files = p->file_list;
282 Q_ASSERT(file_idx >= -1 && file_idx <= files.size());
284 file_idx = files.size();
285 files.insert(file_idx, new File(p, absolutePath(file)));
288 void ResourceFile::addPrefix(const QString &prefix, int prefix_idx)
290 QString fixed_prefix = fixPrefix(prefix);
291 if (indexOfPrefix(fixed_prefix) != -1)
294 Q_ASSERT(prefix_idx >= -1 && prefix_idx <= m_prefix_list.size());
295 if (prefix_idx == -1)
296 prefix_idx = m_prefix_list.size();
297 m_prefix_list.insert(prefix_idx, new Prefix(fixed_prefix));
300 void ResourceFile::removePrefix(int prefix_idx)
302 Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
303 Prefix * const p = m_prefix_list.at(prefix_idx);
305 m_prefix_list.removeAt(prefix_idx);
308 void ResourceFile::removeFile(int prefix_idx, int file_idx)
310 Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
311 FileList &fileList = m_prefix_list[prefix_idx]->file_list;
312 Q_ASSERT(file_idx >= 0 && file_idx < fileList.count());
313 delete fileList.at(file_idx);
314 fileList.removeAt(file_idx);
317 void ResourceFile::replacePrefix(int prefix_idx, const QString &prefix)
319 Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
320 m_prefix_list[prefix_idx]->name = fixPrefix(prefix);
323 void ResourceFile::replaceLang(int prefix_idx, const QString &lang)
325 Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
326 m_prefix_list[prefix_idx]->lang = lang;
329 void ResourceFile::replaceAlias(int prefix_idx, int file_idx, const QString &alias)
331 Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
332 FileList &fileList = m_prefix_list.at(prefix_idx)->file_list;
333 Q_ASSERT(file_idx >= 0 && file_idx < fileList.count());
334 fileList[file_idx]->alias = alias;
338 void ResourceFile::replaceFile(int pref_idx, int file_idx, const QString &file)
340 Q_ASSERT(pref_idx >= 0 && pref_idx < m_prefix_list.count());
341 FileList &fileList = m_prefix_list.at(pref_idx)->file_list;
342 Q_ASSERT(file_idx >= 0 && file_idx < fileList.count());
343 fileList[file_idx]->name = file;
346 int ResourceFile::indexOfPrefix(const QString &prefix) const
348 QString fixed_prefix = fixPrefix(prefix);
349 for (int i = 0; i < m_prefix_list.size(); ++i) {
350 if (m_prefix_list.at(i)->name == fixed_prefix)
356 int ResourceFile::indexOfFile(int pref_idx, const QString &file) const
358 Q_ASSERT(pref_idx >= 0 && pref_idx < m_prefix_list.count());
359 Prefix * const p = m_prefix_list.at(pref_idx);
360 File equalFile(p, absolutePath(file));
361 return p->file_list.indexOf(&equalFile);
364 QString ResourceFile::relativePath(const QString &abs_path) const
366 if (m_file_name.isEmpty() || QFileInfo(abs_path).isRelative())
369 QFileInfo fileInfo(m_file_name);
370 return fileInfo.absoluteDir().relativeFilePath(abs_path);
373 QString ResourceFile::absolutePath(const QString &rel_path) const
375 const QFileInfo fi(rel_path);
379 QString rc = QFileInfo(m_file_name).path();
380 rc += QDir::separator();
382 return QDir::cleanPath(rc);
385 bool ResourceFile::contains(const QString &prefix, const QString &file) const
387 int pref_idx = indexOfPrefix(prefix);
392 Q_ASSERT(pref_idx >= 0 && pref_idx < m_prefix_list.count());
393 Prefix * const p = m_prefix_list.at(pref_idx);
395 File equalFile(p, absolutePath(file));
396 return p->file_list.containsFile(&equalFile);
399 bool ResourceFile::contains(int pref_idx, const QString &file) const
401 Q_ASSERT(pref_idx >= 0 && pref_idx < m_prefix_list.count());
402 Prefix * const p = m_prefix_list.at(pref_idx);
403 File equalFile(p, absolutePath(file));
404 return p->file_list.containsFile(&equalFile);
407 /*static*/ QString ResourceFile::fixPrefix(const QString &prefix)
409 const QChar slash = QLatin1Char('/');
410 QString result = QString(slash);
411 for (int i = 0; i < prefix.size(); ++i) {
412 const QChar c = prefix.at(i);
413 if (c == slash && result.at(result.size() - 1) == slash)
418 if (result.size() > 1 && result.endsWith(slash))
419 result = result.mid(0, result.size() - 1);
424 int ResourceFile::prefixCount() const
426 return m_prefix_list.size();
429 QString ResourceFile::prefix(int idx) const
431 Q_ASSERT((idx >= 0) && (idx < m_prefix_list.count()));
432 return m_prefix_list.at(idx)->name;
435 QString ResourceFile::lang(int idx) const
437 Q_ASSERT(idx >= 0 && idx < m_prefix_list.count());
438 return m_prefix_list.at(idx)->lang;
441 int ResourceFile::fileCount(int prefix_idx) const
443 Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
444 return m_prefix_list.at(prefix_idx)->file_list.size();
447 QString ResourceFile::file(int prefix_idx, int file_idx) const
449 Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
450 FileList &fileList = m_prefix_list.at(prefix_idx)->file_list;
451 Q_ASSERT(file_idx >= 0 && file_idx < fileList.count());
452 return fileList.at(file_idx)->name;
455 QString ResourceFile::alias(int prefix_idx, int file_idx) const
457 Q_ASSERT(prefix_idx >= 0 && prefix_idx < m_prefix_list.count());
458 FileList &fileList = m_prefix_list.at(prefix_idx)->file_list;
459 Q_ASSERT(file_idx >= 0 && file_idx < fileList.count());
460 return fileList.at(file_idx)->alias;
463 void * ResourceFile::prefixPointer(int prefixIndex) const
465 Q_ASSERT(prefixIndex >= 0 && prefixIndex < m_prefix_list.count());
466 return m_prefix_list.at(prefixIndex);
469 void * ResourceFile::filePointer(int prefixIndex, int fileIndex) const
471 Q_ASSERT(prefixIndex >= 0 && prefixIndex < m_prefix_list.count());
472 FileList &fileList = m_prefix_list.at(prefixIndex)->file_list;
473 Q_ASSERT(fileIndex >= 0 && fileIndex < fileList.count());
474 return fileList.at(fileIndex);
477 int ResourceFile::prefixPointerIndex(const Prefix *prefix) const
479 int const count = m_prefix_list.count();
480 for (int i = 0; i < count; i++) {
481 Prefix * const other = m_prefix_list.at(i);
482 if (*other == *prefix)
488 void ResourceFile::clearPrefixList()
490 qDeleteAll(m_prefix_list);
491 m_prefix_list.clear();
494 /******************************************************************************
498 ResourceModel::ResourceModel(const ResourceFile &resource_file, QObject *parent)
499 : QAbstractItemModel(parent), m_resource_file(resource_file), m_dirty(false)
501 // Only action that works for QListWidget and the like.
502 setSupportedDragActions(Qt::CopyAction);
505 void ResourceModel::setDirty(bool b)
511 emit dirtyChanged(b);
514 QModelIndex ResourceModel::index(int row, int column, const QModelIndex &parent) const
517 return QModelIndex();
519 void * internalPointer = 0;
520 if (parent.isValid()) {
521 void * const pip = parent.internalPointer();
523 return QModelIndex();
526 Node * const node = reinterpret_cast<Node *>(pip);
527 Prefix * const prefix = node->prefix();
529 if (row < 0 || row >= prefix->file_list.count())
530 return QModelIndex();
531 const int prefixIndex = m_resource_file.prefixPointerIndex(prefix);
532 const int fileIndex = row;
533 internalPointer = m_resource_file.filePointer(prefixIndex, fileIndex);
536 if (row < 0 || row >= m_resource_file.prefixCount())
537 return QModelIndex();
538 internalPointer = m_resource_file.prefixPointer(row);
540 Q_ASSERT(internalPointer);
541 return createIndex(row, 0, internalPointer);
544 QModelIndex ResourceModel::parent(const QModelIndex &index) const
546 if (!index.isValid())
547 return QModelIndex();
549 void * const internalPointer = index.internalPointer();
550 if (internalPointer == 0)
551 return QModelIndex();
552 Node * const node = reinterpret_cast<Node *>(internalPointer);
553 Prefix * const prefix = node->prefix();
555 bool const isFileNode = (prefix != node);
558 const int row = m_resource_file.prefixPointerIndex(prefix);
560 return createIndex(row, 0, prefix);
562 return QModelIndex();
566 int ResourceModel::rowCount(const QModelIndex &parent) const
568 if (parent.isValid()) {
569 void * const internalPointer = parent.internalPointer();
570 Node * const node = reinterpret_cast<Node *>(internalPointer);
571 Prefix * const prefix = node->prefix();
573 bool const isFileNode = (prefix != node);
578 return prefix->file_list.count();
581 return m_resource_file.prefixCount();
585 int ResourceModel::columnCount(const QModelIndex &) const
590 bool ResourceModel::hasChildren(const QModelIndex &parent) const
592 return rowCount(parent) != 0;
595 bool ResourceModel::iconFileExtension(const QString &path)
597 static QStringList ext_list;
598 if (ext_list.isEmpty()) {
599 const QList<QByteArray> _ext_list = QImageReader::supportedImageFormats();
600 foreach (const QByteArray &ext, _ext_list) {
601 QString dotExt = QString(QLatin1Char('.'));
602 dotExt += QString::fromAscii(ext);
603 ext_list.append(dotExt);
607 foreach (const QString &ext, ext_list) {
608 if (path.endsWith(ext, Qt::CaseInsensitive))
615 static inline void appendParenthesized(const QString &what, QString &s)
617 s += QLatin1String(" (");
619 s += QLatin1Char(')');
622 QVariant ResourceModel::data(const QModelIndex &index, int role) const
624 if (!index.isValid())
627 const void *internalPointer = index.internalPointer();
628 const Node *node = reinterpret_cast<const Node *>(internalPointer);
629 const Prefix *prefix = node->prefix();
630 File *file = node->file();
632 const bool isFileNode = (prefix != node);
637 case Qt::DisplayRole:
642 stringRes = prefix->name;
643 const QString &lang = prefix->lang;
645 appendParenthesized(lang, stringRes);
649 QString conv_file = m_resource_file.relativePath(file->name);
650 stringRes = conv_file.replace(QDir::separator(), QLatin1Char('/'));
651 const QString alias = file->alias;
652 if (!alias.isEmpty())
653 appendParenthesized(alias, stringRes);
658 case Qt::DecorationRole:
662 if (file->icon.isNull()) {
663 const QString path = m_resource_file.absolutePath(file->name);
664 if (iconFileExtension(path))
665 file->icon = QIcon(path);
667 if (!file->icon.isNull())
677 void ResourceModel::getItem(const QModelIndex &index, QString &prefix, QString &file) const
682 if (!index.isValid())
685 const void *internalPointer = index.internalPointer();
686 const Node *node = reinterpret_cast<const Node *>(internalPointer);
687 const Prefix *p = node->prefix();
689 const bool isFileNode = (p != node);
692 const File *f = node->file();
694 if (!f->alias.isEmpty())
703 QString ResourceModel::lang(const QModelIndex &index) const
705 if (!index.isValid())
708 return m_resource_file.lang(index.row());
711 QString ResourceModel::alias(const QModelIndex &index) const
713 if (!index.isValid() || !index.parent().isValid())
715 return m_resource_file.alias(index.parent().row(), index.row());
718 QString ResourceModel::file(const QModelIndex &index) const
720 if (!index.isValid() || !index.parent().isValid())
722 return m_resource_file.file(index.parent().row(), index.row());
725 QModelIndex ResourceModel::getIndex(const QString &prefixed_file)
727 QString prefix, file;
728 if (!m_resource_file.split(prefixed_file, &prefix, &file))
729 return QModelIndex();
730 return getIndex(prefix, file);
733 QModelIndex ResourceModel::getIndex(const QString &prefix, const QString &file)
735 if (prefix.isEmpty())
736 return QModelIndex();
738 const int pref_idx = m_resource_file.indexOfPrefix(prefix);
740 return QModelIndex();
742 const QModelIndex pref_model_idx = index(pref_idx, 0, QModelIndex());
744 return pref_model_idx;
746 const int file_idx = m_resource_file.indexOfFile(pref_idx, file);
748 return QModelIndex();
750 return index(file_idx, 0, pref_model_idx);
753 QModelIndex ResourceModel::prefixIndex(const QModelIndex &sel_idx) const
755 if (!sel_idx.isValid())
756 return QModelIndex();
757 const QModelIndex parentIndex = parent(sel_idx);
758 return parentIndex.isValid() ? parentIndex : sel_idx;
761 QModelIndex ResourceModel::addNewPrefix()
763 const QString format = QLatin1String("/new/prefix%1");
765 QString prefix = format.arg(i);
766 for ( ; m_resource_file.contains(prefix); i++)
767 prefix = format.arg(i);
769 i = rowCount(QModelIndex());
770 beginInsertRows(QModelIndex(), i, i);
771 m_resource_file.addPrefix(prefix);
776 return index(i, 0, QModelIndex());
779 QModelIndex ResourceModel::addFiles(const QModelIndex &model_idx, const QStringList &file_list)
781 const QModelIndex prefixModelIndex = prefixIndex(model_idx);
782 const int prefixArrayIndex = prefixModelIndex.row();
783 const int cursorFileArrayIndex = (prefixModelIndex == model_idx) ? 0 : model_idx.row();
785 int lastFileArrayIndex;
786 addFiles(prefixArrayIndex, file_list, cursorFileArrayIndex, dummy, lastFileArrayIndex);
787 return index(lastFileArrayIndex, 0, prefixModelIndex);
790 void ResourceModel::addFiles(int prefixIndex, const QStringList &fileNames, int cursorFile,
791 int &firstFile, int &lastFile)
794 const QModelIndex prefix_model_idx = index(prefixIndex, 0, QModelIndex());
795 const QStringList &file_list = fileNames;
799 if (!prefix_model_idx.isValid()) {
802 const int prefix_idx = prefixIndex;
804 QStringList unique_list;
805 foreach (const QString &file, file_list) {
806 if (!m_resource_file.contains(prefix_idx, file) && !unique_list.contains(file))
807 unique_list.append(file);
810 if (unique_list.isEmpty()) {
813 const int cnt = m_resource_file.fileCount(prefix_idx);
814 beginInsertRows(prefix_model_idx, cnt, cnt + unique_list.count() - 1); // ### FIXME
816 foreach (const QString &file, unique_list)
817 m_resource_file.addFile(prefix_idx, file);
819 const QFileInfo fi(file_list.last());
820 m_lastResourceDir = fi.absolutePath();
826 lastFile = cnt + unique_list.count() - 1;
830 void ResourceModel::insertPrefix(int prefixIndex, const QString &prefix,
833 beginInsertRows(QModelIndex(), prefixIndex, prefixIndex);
834 m_resource_file.addPrefix(prefix, prefixIndex);
835 m_resource_file.replaceLang(prefixIndex, lang);
840 void ResourceModel::insertFile(int prefixIndex, int fileIndex,
841 const QString &fileName, const QString &alias)
843 const QModelIndex parent = index(prefixIndex, 0, QModelIndex());
844 beginInsertRows(parent, fileIndex, fileIndex);
845 m_resource_file.addFile(prefixIndex, fileName, fileIndex);
846 m_resource_file.replaceAlias(prefixIndex, fileIndex, alias);
851 void ResourceModel::changePrefix(const QModelIndex &model_idx, const QString &prefix)
853 if (!model_idx.isValid())
856 const QModelIndex prefix_model_idx = prefixIndex(model_idx);
857 const int prefix_idx = model_idx.row();
858 if (m_resource_file.prefix(prefix_idx) == ResourceFile::fixPrefix(prefix))
861 if (m_resource_file.contains(prefix))
864 m_resource_file.replacePrefix(prefix_idx, prefix);
865 emit dataChanged(prefix_model_idx, prefix_model_idx);
869 void ResourceModel::changeLang(const QModelIndex &model_idx, const QString &lang)
871 if (!model_idx.isValid())
874 const QModelIndex prefix_model_idx = prefixIndex(model_idx);
875 const int prefix_idx = model_idx.row();
876 if (m_resource_file.lang(prefix_idx) == lang)
879 m_resource_file.replaceLang(prefix_idx, lang);
880 emit dataChanged(prefix_model_idx, prefix_model_idx);
884 void ResourceModel::changeAlias(const QModelIndex &index, const QString &alias)
886 if (!index.parent().isValid())
889 if (m_resource_file.alias(index.parent().row(), index.row()) == alias)
891 m_resource_file.replaceAlias(index.parent().row(), index.row(), alias);
892 emit dataChanged(index, index);
896 QModelIndex ResourceModel::deleteItem(const QModelIndex &idx)
899 return QModelIndex();
902 getItem(idx, dummy, file);
906 beginRemoveRows(parent(idx), idx.row(), idx.row());
907 if (file.isEmpty()) {
909 prefix_idx = idx.row();
910 m_resource_file.removePrefix(prefix_idx);
911 if (prefix_idx == m_resource_file.prefixCount())
915 prefix_idx = prefixIndex(idx).row();
916 file_idx = idx.row();
917 m_resource_file.removeFile(prefix_idx, file_idx);
918 if (file_idx == m_resource_file.fileCount(prefix_idx))
925 if (prefix_idx == -1)
926 return QModelIndex();
927 const QModelIndex prefix_model_idx = index(prefix_idx, 0, QModelIndex());
929 return prefix_model_idx;
930 return index(file_idx, 0, prefix_model_idx);
933 bool ResourceModel::reload()
935 const bool result = m_resource_file.load();
942 bool ResourceModel::save()
944 const bool result = m_resource_file.save();
950 QString ResourceModel::lastResourceOpenDirectory() const
952 if (m_lastResourceDir.isEmpty())
953 return absolutePath(QString());
954 return m_lastResourceDir;
957 // Create a resource path 'prefix:/file'
958 QString ResourceModel::resourcePath(const QString &prefix, const QString &file)
960 QString rc = QString(QLatin1Char(':'));
962 rc += QLatin1Char('/');
964 return QDir::cleanPath(rc);
967 QMimeData *ResourceModel::mimeData(const QModelIndexList &indexes) const
969 if (indexes.size() != 1)
972 QString prefix, file;
973 getItem(indexes.front(), prefix, file);
974 if (prefix.isEmpty() || file.isEmpty())
977 // DnD format of Designer 4.4
979 QDomElement elem = doc.createElement(QLatin1String("resource"));
980 elem.setAttribute(QLatin1String("type"), QLatin1String("image"));
981 elem.setAttribute(QLatin1String("file"), resourcePath(prefix, file));
982 doc.appendChild(elem);
984 QMimeData *rc = new QMimeData;
985 rc->setText(doc.toString());
989 } // namespace qdesigner_internal