diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2012-06-04 14:10:34 +0400 |
---|---|---|
committer | Eike Ziller <eike.ziller@nokia.com> | 2012-07-18 15:39:49 +0200 |
commit | 2bf7271d5158e5b589959f7ed93268b4d71b0e07 (patch) | |
tree | 6f258634a40c626a87caf912a1b968c9cbe6e05f /src/plugins/resourceeditor/qrceditor/resourceview.cpp | |
parent | faf7ba6274f0bdbf32597eb837997aac29a832e2 (diff) |
Moved QrcEditor to ResourceEditor plugin.
Change-Id: I623b47ab4fdad7abf07e47abd99959f0326639c6
Reviewed-by: Eike Ziller <eike.ziller@nokia.com>
Diffstat (limited to 'src/plugins/resourceeditor/qrceditor/resourceview.cpp')
-rw-r--r-- | src/plugins/resourceeditor/qrceditor/resourceview.cpp | 540 |
1 files changed, 540 insertions, 0 deletions
diff --git a/src/plugins/resourceeditor/qrceditor/resourceview.cpp b/src/plugins/resourceeditor/qrceditor/resourceview.cpp new file mode 100644 index 0000000000..ff32b7dfb6 --- /dev/null +++ b/src/plugins/resourceeditor/qrceditor/resourceview.cpp @@ -0,0 +1,540 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + +#include "resourceview.h" + +#include "undocommands_p.h" + +#include <QDebug> + +#include <QAction> +#include <QApplication> +#include <QFileDialog> +#include <QHeaderView> +#include <QInputDialog> +#include <QMenu> +#include <QMouseEvent> +#include <QUndoStack> + +namespace ResourceEditor { + +/*! + \class FileEntryBackup + + Backups a file node. +*/ +class FileEntryBackup : public EntryBackup +{ +private: + int m_fileIndex; + QString m_alias; + +public: + FileEntryBackup(ResourceModel &model, int prefixIndex, int fileIndex, + const QString &fileName, const QString &alias) + : EntryBackup(model, prefixIndex, fileName), m_fileIndex(fileIndex), + m_alias(alias) { } + void restore() const; +}; + +void FileEntryBackup::restore() const +{ + m_model->insertFile(m_prefixIndex, m_fileIndex, m_name, m_alias); +} + +/*! + \class PrefixEntryBackup + + Backups a prefix node including children. +*/ +class PrefixEntryBackup : public EntryBackup +{ +private: + QString m_language; + QList<FileEntryBackup> m_files; + +public: + PrefixEntryBackup(ResourceModel &model, int prefixIndex, const QString &prefix, + const QString &language, const QList<FileEntryBackup> &files) + : EntryBackup(model, prefixIndex, prefix), m_language(language), m_files(files) { } + void restore() const; +}; + +void PrefixEntryBackup::restore() const +{ + m_model->insertPrefix(m_prefixIndex, m_name, m_language); + foreach (const FileEntryBackup &entry, m_files) { + entry.restore(); + } +} + +namespace Internal { + +class RelativeResourceModel : public ResourceModel +{ +public: + RelativeResourceModel(const ResourceFile &resource_file, QObject *parent = 0); + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const + { + if (!index.isValid()) + return QVariant(); +/* + void const * const internalPointer = index.internalPointer(); + + if ((role == Qt::DisplayRole) && (internalPointer != NULL)) + return ResourceModel::data(index, Qt::ToolTipRole); +*/ + return ResourceModel::data(index, role); + } + + void setResourceDragEnabled(bool e) { m_resourceDragEnabled = e; } + bool resourceDragEnabled() const { return m_resourceDragEnabled; } + + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + EntryBackup * removeEntry(const QModelIndex &index); + +private: + bool m_resourceDragEnabled; +}; + +RelativeResourceModel::RelativeResourceModel(const ResourceFile &resource_file, QObject *parent) : + ResourceModel(resource_file, parent), + m_resourceDragEnabled(false) +{ +} + +Qt::ItemFlags RelativeResourceModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags rc = ResourceModel::flags(index); + if ((rc & Qt::ItemIsEnabled) && m_resourceDragEnabled) + rc |= Qt::ItemIsDragEnabled; + return rc; +} + +EntryBackup * RelativeResourceModel::removeEntry(const QModelIndex &index) +{ + const QModelIndex prefixIndex = this->prefixIndex(index); + const bool isPrefixNode = (prefixIndex == index); + + // Create backup, remove, return backup + if (isPrefixNode) { + QString dummy; + QString prefixBackup; + getItem(index, prefixBackup, dummy); + const QString languageBackup = lang(index); + const int childCount = rowCount(index); + QList<FileEntryBackup> filesBackup; + for (int i = 0; i < childCount; i++) { + const QModelIndex childIndex = this->index(i, 0, index); + const QString fileNameBackup = file(childIndex); + const QString aliasBackup = alias(childIndex); + FileEntryBackup entry(*this, index.row(), i, fileNameBackup, aliasBackup); + filesBackup << entry; + } + deleteItem(index); + return new PrefixEntryBackup(*this, index.row(), prefixBackup, languageBackup, filesBackup); + } else { + const QString fileNameBackup = file(index); + const QString aliasBackup = alias(index); + deleteItem(index); + return new FileEntryBackup(*this, prefixIndex.row(), index.row(), fileNameBackup, aliasBackup); + } +} + +} // namespace Internal + +ResourceView::ResourceView(QUndoStack *history, QWidget *parent) : + QTreeView(parent), + m_qrcModel(new Internal::RelativeResourceModel(m_qrcFile, this)), + m_history(history), + m_mergeId(-1) +{ + advanceMergeId(); + setModel(m_qrcModel); + setContextMenuPolicy(Qt::CustomContextMenu); + setEditTriggers(EditKeyPressed); + + header()->hide(); + + connect(m_qrcModel, SIGNAL(dirtyChanged(bool)), + this, SIGNAL(dirtyChanged(bool))); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), + this, SLOT(showContextMenu(QPoint))); + connect(this, SIGNAL(activated(QModelIndex)), + this, SLOT(itemActivated(QModelIndex))); +} + +ResourceView::~ResourceView() +{ +} + +bool ResourceView::isDirty() const +{ + return m_qrcModel->dirty(); +} + +void ResourceView::setDirty(bool dirty) +{ + m_qrcModel->setDirty(dirty); +} + +void ResourceView::findSamePlacePostDeletionModelIndex(int &row, QModelIndex &parent) const +{ + // Concept: + // - Make selection stay on same Y level + // - Enable user to hit delete several times in row + const bool hasLowerBrother = m_qrcModel->hasIndex(row + 1, + 0, parent); + if (hasLowerBrother) { + // First or mid child -> lower brother + // o + // +--o + // +-[o] <-- deleted + // +--o <-- chosen + // o + // --> return unmodified + } else { + if (parent == QModelIndex()) { + // Last prefix node + if (row == 0) { + // Last and only prefix node + // [o] <-- deleted + // +--o + // +--o + row = -1; + parent = QModelIndex(); + } else { + const QModelIndex upperBrother = m_qrcModel->index(row - 1, + 0, parent); + if (m_qrcModel->hasChildren(upperBrother)) { + // o + // +--o <-- selected + // [o] <-- deleted + row = m_qrcModel->rowCount(upperBrother) - 1; + parent = upperBrother; + } else { + // o + // o <-- selected + // [o] <-- deleted + row--; + } + } + } else { + // Last file node + const bool hasPrefixBelow = m_qrcModel->hasIndex(parent.row() + 1, + parent.column(), QModelIndex()); + if (hasPrefixBelow) { + // Last child or parent with lower brother -> lower brother of parent + // o + // +--o + // +-[o] <-- deleted + // o <-- chosen + row = parent.row() + 1; + parent = QModelIndex(); + } else { + const bool onlyChild = row == 0; + if (onlyChild) { + // Last and only child of last parent -> parent + // o <-- chosen + // +-[o] <-- deleted + row = parent.row(); + parent = m_qrcModel->parent(parent); + } else { + // Last child of last parent -> upper brother + // o + // +--o <-- chosen + // +-[o] <-- deleted + row--; + } + } + } + } +} + +EntryBackup * ResourceView::removeEntry(const QModelIndex &index) +{ + Q_ASSERT(m_qrcModel); + return m_qrcModel->removeEntry(index); +} + +QStringList ResourceView::existingFilesSubtracted(int prefixIndex, const QStringList &fileNames) const +{ + return m_qrcModel->existingFilesSubtracted(prefixIndex, fileNames); +} + +void ResourceView::addFiles(int prefixIndex, const QStringList &fileNames, int cursorFile, + int &firstFile, int &lastFile) +{ + Q_ASSERT(m_qrcModel); + m_qrcModel->addFiles(prefixIndex, fileNames, cursorFile, firstFile, lastFile); + + // Expand prefix node + const QModelIndex prefixModelIndex = m_qrcModel->index(prefixIndex, 0, QModelIndex()); + if (prefixModelIndex.isValid()) { + this->setExpanded(prefixModelIndex, true); + } +} + +void ResourceView::removeFiles(int prefixIndex, int firstFileIndex, int lastFileIndex) +{ + Q_ASSERT(prefixIndex >= 0 && prefixIndex < m_qrcModel->rowCount(QModelIndex())); + const QModelIndex prefixModelIndex = m_qrcModel->index(prefixIndex, 0, QModelIndex()); + Q_ASSERT(prefixModelIndex != QModelIndex()); + Q_ASSERT(firstFileIndex >= 0 && firstFileIndex < m_qrcModel->rowCount(prefixModelIndex)); + Q_ASSERT(lastFileIndex >= 0 && lastFileIndex < m_qrcModel->rowCount(prefixModelIndex)); + + for (int i = lastFileIndex; i >= firstFileIndex; i--) { + const QModelIndex index = m_qrcModel->index(i, 0, prefixModelIndex); + delete removeEntry(index); + } +} + +void ResourceView::keyPressEvent(QKeyEvent *e) +{ + if (e->key() == Qt::Key_Delete) + removeItem(); + else + QTreeView::keyPressEvent(e); +} + +QModelIndex ResourceView::addPrefix() +{ + const QModelIndex idx = m_qrcModel->addNewPrefix(); + selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect); + return idx; +} + +void ResourceView::refresh() +{ + m_qrcModel->refresh(); + QModelIndex idx = currentIndex(); + setModel(0); + setModel(m_qrcModel); + setCurrentIndex(idx); + expandAll(); +} + +QStringList ResourceView::fileNamesToAdd() +{ + return QFileDialog::getOpenFileNames(this, tr("Open File"), + m_qrcModel->absolutePath(QString()), + tr("All files (*)")); +} + +void ResourceView::addFiles(QStringList fileList, const QModelIndex &index) +{ + if (fileList.isEmpty()) + return; + QModelIndex idx = index; + if (!m_qrcModel->hasChildren(QModelIndex())) { + idx = addPrefix(); + expand(idx); + } + + idx = m_qrcModel->addFiles(idx, fileList); + + if (idx.isValid()) { + const QModelIndex preindex = m_qrcModel->prefixIndex(index); + setExpanded(preindex, true); + selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect); + QString prefix, file; + m_qrcModel->getItem(preindex, prefix, file); +// XXX emit filesAdded(prefix, fileList); + } +} + +void ResourceView::addFile(const QString &prefix, const QString &file) +{ + const QModelIndex preindex = m_qrcModel->getIndex(prefix, QString()); + addFiles(QStringList(file), preindex); +} + +bool ResourceView::load(const QString &fileName) +{ + const QFileInfo fi(fileName); + m_qrcModel->setFileName(fi.absoluteFilePath()); + + if (!fi.exists()) + return false; + + return m_qrcModel->reload(); +} + +bool ResourceView::save() +{ + return m_qrcModel->save(); +} + +QString ResourceView::currentAlias() const +{ + const QModelIndex current = currentIndex(); + if (!current.isValid()) + return QString(); + return m_qrcModel->alias(current); +} + +QString ResourceView::currentPrefix() const +{ + const QModelIndex current = currentIndex(); + if (!current.isValid()) + return QString(); + const QModelIndex preindex = m_qrcModel->prefixIndex(current); + QString prefix, file; + m_qrcModel->getItem(preindex, prefix, file); + return prefix; +} + +QString ResourceView::currentLanguage() const +{ + const QModelIndex current = currentIndex(); + if (!current.isValid()) + return QString(); + const QModelIndex preindex = m_qrcModel->prefixIndex(current); + return m_qrcModel->lang(preindex); +} + +QString ResourceView::getCurrentValue(NodeProperty property) const +{ + switch (property) { + case AliasProperty: return currentAlias(); + case PrefixProperty: return currentPrefix(); + case LanguageProperty: return currentLanguage(); + default: Q_ASSERT(false); return QString(); // Kill warning + } +} + +void ResourceView::changeValue(const QModelIndex &nodeIndex, NodeProperty property, + const QString &value) +{ + switch (property) { + case AliasProperty: m_qrcModel->changeAlias(nodeIndex, value); return; + case PrefixProperty: m_qrcModel->changePrefix(nodeIndex, value); return; + case LanguageProperty: m_qrcModel->changeLang(nodeIndex, value); return; + default: Q_ASSERT(false); + } +} + +void ResourceView::itemActivated(const QModelIndex &index) +{ + const QString fileName = m_qrcModel->file(index); + if (fileName.isEmpty()) + return; + emit itemActivated(fileName); +} + +void ResourceView::showContextMenu(const QPoint &pos) +{ + const QModelIndex index = indexAt(pos); + const QString fileName = m_qrcModel->file(index); + if (fileName.isEmpty()) + return; + emit showContextMenu(mapToGlobal(pos), fileName); +} + +void ResourceView::advanceMergeId() +{ + m_mergeId++; + if (m_mergeId < 0) + m_mergeId = 0; +} + +void ResourceView::addUndoCommand(const QModelIndex &nodeIndex, NodeProperty property, + const QString &before, const QString &after) +{ + QUndoCommand * const command = new ModifyPropertyCommand(this, nodeIndex, property, + m_mergeId, before, after); + m_history->push(command); +} + +void ResourceView::setCurrentAlias(const QString &before, const QString &after) +{ + const QModelIndex current = currentIndex(); + if (!current.isValid()) + return; + + addUndoCommand(current, AliasProperty, before, after); +} + +void ResourceView::setCurrentPrefix(const QString &before, const QString &after) +{ + const QModelIndex current = currentIndex(); + if (!current.isValid()) + return; + const QModelIndex preindex = m_qrcModel->prefixIndex(current); + + addUndoCommand(preindex, PrefixProperty, before, after); +} + +void ResourceView::setCurrentLanguage(const QString &before, const QString &after) +{ + const QModelIndex current = currentIndex(); + if (!current.isValid()) + return; + const QModelIndex preindex = m_qrcModel->prefixIndex(current); + + addUndoCommand(preindex, LanguageProperty, before, after); +} + +bool ResourceView::isPrefix(const QModelIndex &index) const +{ + if (!index.isValid()) + return false; + const QModelIndex preindex = m_qrcModel->prefixIndex(index); + if (preindex == index) + return true; + return false; +} + +QString ResourceView::fileName() const +{ + return m_qrcModel->fileName(); +} + +void ResourceView::setFileName(const QString &fileName) +{ + m_qrcModel->setFileName(fileName); +} + +void ResourceView::setResourceDragEnabled(bool e) +{ + setDragEnabled(e); + m_qrcModel->setResourceDragEnabled(e); +} + +bool ResourceView::resourceDragEnabled() const +{ + return m_qrcModel->resourceDragEnabled(); +} + +} // namespace SharedTools |