diff --git a/components/esxselector/model/contentmodel.cpp b/components/esxselector/model/contentmodel.cpp index bfbb1bef7..d23ea7801 100644 --- a/components/esxselector/model/contentmodel.cpp +++ b/components/esxselector/model/contentmodel.cpp @@ -1,17 +1,37 @@ #include "contentmodel.hpp" #include "esmfile.hpp" -#include + #include #include #include +#include EsxModel::ContentModel::ContentModel(QObject *parent) : - QAbstractTableModel(parent), mEncoding("win1252") -{} + QAbstractTableModel(parent), + mMimeType ("application/omwcontent"), + mMimeTypes (QStringList() << mMimeType), + mColumnCount (1), + mDragDropFlags (Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled), + mDefaultFlags (Qt::ItemIsDropEnabled | Qt::ItemIsSelectable), + mDropActions (Qt::CopyAction | Qt::MoveAction) +{ + setEncoding ("win1252"); + uncheckAll(); +} void EsxModel::ContentModel::setEncoding(const QString &encoding) { - mEncoding = encoding; + if (encoding == QLatin1String("win1252")) + mCodec = QTextCodec::codecForName("windows-1252"); + + else if (encoding == QLatin1String("win1251")) + mCodec = QTextCodec::codecForName("windows-1251"); + + else if (encoding == QLatin1String("win1250")) + mCodec = QTextCodec::codecForName("windows-1250"); + + else + return; // This should never happen; } int EsxModel::ContentModel::columnCount(const QModelIndex &parent) const @@ -19,7 +39,7 @@ int EsxModel::ContentModel::columnCount(const QModelIndex &parent) const if (parent.isValid()) return 0; - return 1; + return mColumnCount; } int EsxModel::ContentModel::rowCount(const QModelIndex &parent) const @@ -30,22 +50,28 @@ int EsxModel::ContentModel::rowCount(const QModelIndex &parent) const return mFiles.size(); } -EsxModel::EsmFile* EsxModel::ContentModel::item(int row) const +const EsxModel::EsmFile* EsxModel::ContentModel::item(int row) const { - if (row >= 0 && row < mFiles.count()) + if (row >= 0 && row < mFiles.size()) return mFiles.at(row); return 0; } -EsxModel::EsmFile* EsxModel::ContentModel::findItem(const QString &name) +EsxModel::EsmFile *EsxModel::ContentModel::item(int row) { - for (int i = 0; i < mFiles.size(); ++i) + if (row >= 0 && row < mFiles.count()) + return mFiles.at(row); + + return 0; +} +const EsxModel::EsmFile *EsxModel::ContentModel::findItem(const QString &name) const +{ + foreach (const EsmFile *file, mFiles) { - if (name == item(i)->fileName()) - return item(i); + if (name == file->fileName()) + return file; } - return 0; } @@ -62,19 +88,15 @@ Qt::ItemFlags EsxModel::ContentModel::flags(const QModelIndex &index) const if (!index.isValid()) return Qt::NoItemFlags; - EsmFile *file = item(index.row()); + const EsmFile *file = item(index.row()); if (!file) return Qt::NoItemFlags; - Qt::ItemFlags dragDropFlags = Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; - Qt::ItemFlags checkFlags = Qt::ItemIsUserCheckable; - Qt::ItemFlags defaultFlags = Qt::ItemIsDropEnabled | Qt::ItemIsSelectable; - if (canBeChecked(file)) - return Qt::ItemIsEnabled | dragDropFlags | checkFlags | defaultFlags; - else - return defaultFlags; + return Qt::ItemIsEnabled | mDragDropFlags | mDefaultFlags; + + return mDefaultFlags; } QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const @@ -85,7 +107,7 @@ QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const if (index.row() >= mFiles.size()) return QVariant(); - EsmFile *file = item(index.row()); + const EsmFile *file = item(index.row()); if (!file) return QVariant(); @@ -97,25 +119,11 @@ QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const case Qt::EditRole: case Qt::DisplayRole: { - switch (column) - { - case 0: - return file->fileName(); - case 1: - return file->author(); - case 2: - return file->modified().toString(Qt::ISODate); - case 3: - return file->version(); - case 4: - return file->path(); - case 5: - return file->masters().join(", "); - case 6: - return file->description(); - } + if (column >=0 && column <=EsmFile::FileProperty_Master) + return file->fileProperty(static_cast(column)); return QVariant(); + break; } case Qt::TextAlignmentRole: @@ -132,6 +140,7 @@ QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const return Qt::AlignLeft + Qt::AlignVCenter; } return QVariant(); + break; } case Qt::ToolTipRole: @@ -139,23 +148,16 @@ QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const if (column != 0) return QVariant(); - if (file->version() == 0.0f) - return QVariant(); // Data not set - - return QString("Author: %1
\ - Version: %2
\ -
Description:
%3
\ -
Dependencies: %4
") - .arg(file->author()) - .arg(QString::number(file->version())) - .arg(file->description()) - .arg(file->masters().join(", ")); + return file->toolTip(); + break; } case Qt::CheckStateRole: + { if (!file->isMaster()) return isChecked(file->fileName()); break; + } case Qt::UserRole: { @@ -179,64 +181,63 @@ bool EsxModel::ContentModel::setData(const QModelIndex &index, const QVariant &v EsmFile *file = item(index.row()); QString fileName = file->fileName(); + bool success = false; switch(role) { case Qt::EditRole: - { - QStringList list = value.toStringList(); + { + QStringList list = value.toStringList(); - //iterate the string list, assigning values to proeprties - //index-enum correspondence 1:1 - for (int i = 0; i < EsxModel::Property_Master; i++) - file->setProperty(static_cast(i), list.at(i)); + for (int i = 0; i < EsmFile::FileProperty_Master; i++) + file->setFileProperty(static_cast(i), list.at(i)); - //iterate the remainder of the string list, assifning everything - // as - for (int i = EsxModel::Property_Master; i < list.size(); i++) - file->setProperty (EsxModel::Property_Master, list.at(i)); + for (int i = EsmFile::FileProperty_Master; i < list.size(); i++) + file->setFileProperty (EsmFile::FileProperty_Master, list.at(i)); - //emit data changed for the item itself - emit dataChanged(index, index); + emit dataChanged(index, index); - return true; - } - break; + success = true; + } + break; case Qt::UserRole+1: - { - setCheckState(fileName, value.toBool()); + { + setCheckState(fileName, value.toBool()); - emit dataChanged(index, index); + emit dataChanged(index, index); - for(int i = 0; i < mFiles.size(); i++) + foreach (EsmFile *file, mFiles) + { + if (file->masters().contains(fileName)) { - - if (mFiles.at(i)->masters().contains(fileName)) - { - QModelIndex idx = QAbstractTableModel::index(i, 0); - emit dataChanged(idx, idx); - } + QModelIndex idx = indexFromItem(file); + emit dataChanged(idx, idx); } - - return true; } - break; + success = true; + } + break; case Qt::CheckStateRole: - { - bool checked = ((value.toInt() == Qt::Checked) && !isChecked(fileName)); + { + int checkValue = value.toInt(); - setCheckState(fileName, checked); + if ((checkValue==Qt::Checked) && !isChecked(fileName)) + setCheckState(fileName, true); + else if ((checkValue == Qt::Checked) && isChecked (fileName)) + setCheckState(fileName, false); + else if (checkValue == Qt::Unchecked) + setCheckState(fileName, false); - emit dataChanged(index, index); + emit dataChanged(index, index); - return true; - } - break; + success = true; + } + break; } - return false; + return success; } bool EsxModel::ContentModel::insertRows(int position, int rows, const QModelIndex &parent) @@ -271,16 +272,12 @@ bool EsxModel::ContentModel::removeRows(int position, int rows, const QModelInde Qt::DropActions EsxModel::ContentModel::supportedDropActions() const { - return Qt::CopyAction | Qt::MoveAction; + return mDropActions; } QStringList EsxModel::ContentModel::mimeTypes() const { - QStringList types; - - types << "application/omwcontent"; - - return types; + return mMimeTypes; } QMimeData *EsxModel::ContentModel::mimeData(const QModelIndexList &indexes) const @@ -292,14 +289,11 @@ QMimeData *EsxModel::ContentModel::mimeData(const QModelIndexList &indexes) cons if (!index.isValid()) continue; - QByteArray fileData = item(index.row())->encodedData(); - - foreach (const char c, fileData) - encodedData.append(c); + encodedData.append(item(index.row())->encodedData()); } QMimeData *mimeData = new QMimeData(); - mimeData->setData("application/omwcontent", encodedData); + mimeData->setData(mMimeType, encodedData); return mimeData; } @@ -309,13 +303,13 @@ bool EsxModel::ContentModel::dropMimeData(const QMimeData *data, Qt::DropAction if (action == Qt::IgnoreAction) return true; - if (!data->hasFormat("application/omwcontent")) + if (column > 0) return false; - if (column > 0) + if (!data->hasFormat(mMimeType)) return false; - int beginRow; + int beginRow = rowCount(); if (row != -1) beginRow = row; @@ -323,23 +317,28 @@ bool EsxModel::ContentModel::dropMimeData(const QMimeData *data, Qt::DropAction else if (parent.isValid()) beginRow = parent.row(); - else - beginRow = rowCount(); - - QByteArray encodedData = data->data("application/omwcontent"); + QByteArray encodedData = data->data(mMimeType); QDataStream stream(&encodedData, QIODevice::ReadOnly); while (!stream.atEnd()) { + + QString value; QStringList values; + QStringList masters; - for (int i = 0; i < EsmFile::sPropertyCount; ++i) - stream >> values; + for (int i = 0; i < EsmFile::FileProperty_Master; ++i) + { + stream >> value; + values << value; + } + + stream >> masters; insertRows(beginRow, 1); QModelIndex idx = index(beginRow++, 0, QModelIndex()); - setData(idx, values, Qt::EditRole); + setData(idx, QStringList() << values << masters, Qt::EditRole); } return true; @@ -349,37 +348,8 @@ bool EsxModel::ContentModel::canBeChecked(const EsmFile *file) const { //element can be checked if all its dependencies are foreach (const QString &master, file->masters()) - { - {// if the master is not found in checkstates - // or it is not specifically checked, return false - if (!mCheckStates.contains(master)) - return false; - - if (!isChecked(master)) - return false; - } - - bool found = false; - - //iterate each file, if it is not a master and - //does not have a master that is currently checked, - //return false. - foreach(const EsmFile *file, mFiles) - { - QString filename = file->fileName(); - - found = (filename == master); - - if (found) - { - if (!isChecked(filename)) - return false; - } - } - - if (!found) + if (!isChecked(master)) return false; - } return true; } @@ -387,9 +357,8 @@ bool EsxModel::ContentModel::canBeChecked(const EsmFile *file) const void EsxModel::ContentModel::addFile(EsmFile *file) { beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); - { mFiles.append(file); - } endInsertRows(); + endInsertRows(); } void EsxModel::ContentModel::addFiles(const QString &path) @@ -400,45 +369,26 @@ void EsxModel::ContentModel::addFiles(const QString &path) dir.setNameFilters(filters); // Create a decoder for non-latin characters in esx metadata - QTextCodec *codec; - - if (mEncoding == QLatin1String("win1252")) { - codec = QTextCodec::codecForName("windows-1252"); - } else if (mEncoding == QLatin1String("win1251")) { - codec = QTextCodec::codecForName("windows-1251"); - } else if (mEncoding == QLatin1String("win1250")) { - codec = QTextCodec::codecForName("windows-1250"); - } else { - return; // This should never happen; - } + QTextDecoder *decoder = mCodec->makeDecoder(); - QTextDecoder *decoder = codec->makeDecoder(); - - foreach (const QString &path, dir.entryList()) { + foreach (const QString &path, dir.entryList()) + { QFileInfo info(dir.absoluteFilePath(path)); EsmFile *file = new EsmFile(path); try { ESM::ESMReader fileReader; - ToUTF8::Utf8Encoder encoder(ToUTF8::calculateEncoding(mEncoding.toStdString())); + ToUTF8::Utf8Encoder encoder(ToUTF8::calculateEncoding(QString(mCodec->name()).toStdString())); fileReader.setEncoder(&encoder); fileReader.open(dir.absoluteFilePath(path).toStdString()); - std::vector mlist = fileReader.getMasters(); - - QStringList masters; + foreach (const ESM::Header::MasterData &item, fileReader.getMasters()) + file->addMaster(QString::fromStdString(item.name)); - for (unsigned int i = 0; i < mlist.size(); ++i) { - QString master = QString::fromStdString(mlist[i].name); - masters.append(master); - } - - file->setAuthor(decoder->toUnicode(fileReader.getAuthor().c_str())); - //file->setSize(info.size()); - file->setDate(info.lastModified()); - file->setVersion(0.0f); - file->setPath(info.absoluteFilePath()); - file->setMasters(masters); + file->setAuthor (decoder->toUnicode(fileReader.getAuthor().c_str())); + file->setDate (info.lastModified()); + file->setVersion (fileReader.getFVer()); + file->setPath (info.absoluteFilePath()); file->setDescription(decoder->toUnicode(fileReader.getDesc().c_str())); @@ -459,7 +409,10 @@ void EsxModel::ContentModel::addFiles(const QString &path) bool EsxModel::ContentModel::isChecked(const QString& name) const { - return (mCheckStates[name] == Qt::Checked); + if (mCheckStates.contains(name)) + return (mCheckStates[name] == Qt::Checked); + + return false; } void EsxModel::ContentModel::setCheckState(const QString &name, bool isChecked) @@ -479,12 +432,9 @@ EsxModel::ContentFileList EsxModel::ContentModel::checkedItems() const { ContentFileList list; - for (int i = 0; i < mFiles.size(); ++i) + foreach (EsmFile *file, mFiles) { - EsmFile *file = item(i); - - // Only add the items that are in the checked list and available - if (mCheckStates[file->fileName()] == Qt::Checked && canBeChecked(file)) + if (isChecked(file->fileName())) list << file; } diff --git a/components/esxselector/model/contentmodel.hpp b/components/esxselector/model/contentmodel.hpp index 61c823ab3..6a2dd88ca 100644 --- a/components/esxselector/model/contentmodel.hpp +++ b/components/esxselector/model/contentmodel.hpp @@ -2,7 +2,7 @@ #define CONTENTMODEL_HPP #include - +#include namespace EsxModel { class EsmFile; @@ -35,7 +35,7 @@ namespace EsxModel void addFiles(const QString &path); QModelIndex indexFromItem(EsmFile *item) const; - EsxModel::EsmFile *findItem(const QString &name); + const EsxModel::EsmFile *findItem(const QString &name) const; bool isChecked(const QString &name) const; void setCheckState(const QString &name, bool isChecked); @@ -45,16 +45,21 @@ namespace EsxModel private: void addFile(EsmFile *file); - EsmFile* item(int row) const; + const EsmFile *item(int row) const; + EsmFile *item(int row); bool canBeChecked(const EsmFile *file) const; ContentFileList mFiles; QHash mCheckStates; - QString mEncoding; - - signals: + QTextCodec *mCodec; - public slots: + public: + QString mMimeType; + QStringList mMimeTypes; + int mColumnCount; + Qt::ItemFlags mDragDropFlags; + Qt::ItemFlags mDefaultFlags; + Qt::DropActions mDropActions; }; } diff --git a/components/esxselector/model/esmfile.cpp b/components/esxselector/model/esmfile.cpp index 0e7f18373..bd76dc4a0 100644 --- a/components/esxselector/model/esmfile.cpp +++ b/components/esxselector/model/esmfile.cpp @@ -4,19 +4,15 @@ #include int EsxModel::EsmFile::sPropertyCount = 7; +QString EsxModel::EsmFile::sToolTip = QString("Author: %1
\ + Version: %2
\ +
Description:
%3
\ +
Dependencies: %4
"); + EsxModel::EsmFile::EsmFile(QString fileName, ModelItem *parent) : ModelItem(parent), mFileName(fileName), mVersion(0.0f) {} -/* -EsxModel::EsmFile::EsmFile(const EsmFile &file) - : ModelItem(file.parent()), mFileName(file.mFileName), mSize(file.mSize), - mVersion(file.mVersion), mAuthor(file.mAuthor), mModified(file.mModified), - mAccessed(file.mAccessed), mPath(file.mPath), mMasters(file.mMasters), - mDescription(file.mDescription) -{} - -*/ void EsxModel::EsmFile::setFileName(const QString &fileName) { mFileName = fileName; @@ -64,35 +60,72 @@ QByteArray EsxModel::EsmFile::encodedData() const return encodedData; } -void EsxModel::EsmFile::setProperty (const EsmFileProperty prop, const QString &value) +QVariant EsxModel::EsmFile::fileProperty(const FileProperty prop) const +{ + switch (prop) + { + case FileProperty_FileName: + return mFileName; + break; + + case FileProperty_Author: + return mAuthor; + break; + + case FileProperty_Version: + return mVersion; + break; + + case FileProperty_DateModified: + return mModified.toString(Qt::ISODate); + break; + + case FileProperty_Path: + return mPath; + break; + + case FileProperty_Description: + return mDescription; + break; + + case FileProperty_Master: + return mMasters; + break; + + default: + break; + } + return QVariant(); +} +void EsxModel::EsmFile::setFileProperty (const FileProperty prop, const QString &value) { switch (prop) { - case Property_FileName: + case FileProperty_FileName: mFileName = value; break; - case Property_Author: + case FileProperty_Author: mAuthor = value; break; - case Property_Version: + case FileProperty_Version: mVersion = value.toFloat(); break; - case Property_DateModified: + case FileProperty_DateModified: mModified = QDateTime::fromString(value); break; - case Property_Path: + case FileProperty_Path: mPath = value; break; - case Property_Description: + case FileProperty_Description: mDescription = value; break; - case Property_Master: + case FileProperty_Master: mMasters << value; break; diff --git a/components/esxselector/model/esmfile.hpp b/components/esxselector/model/esmfile.hpp index 9a1ea8af1..4f6d7a624 100644 --- a/components/esxselector/model/esmfile.hpp +++ b/components/esxselector/model/esmfile.hpp @@ -10,17 +10,6 @@ class QMimeData; namespace EsxModel { - enum EsmFileProperty - { - Property_FileName = 0, - Property_Author = 1, - Property_Version = 2, - Property_DateModified = 3, - Property_Path = 4, - Property_Description = 5, - Property_Master = 6 - }; - class EsmFile : public ModelItem { Q_OBJECT @@ -28,13 +17,24 @@ namespace EsxModel public: + enum FileProperty + { + FileProperty_FileName = 0, + FileProperty_Author = 1, + FileProperty_Version = 2, + FileProperty_DateModified = 3, + FileProperty_Path = 4, + FileProperty_Description = 5, + FileProperty_Master = 6 + }; + EsmFile(QString fileName = QString(), ModelItem *parent = 0); // EsmFile(const EsmFile &); ~EsmFile() {} - void setProperty (const EsmFileProperty prop, const QString &value); + void setFileProperty (const FileProperty prop, const QString &value); void setFileName(const QString &fileName); void setAuthor(const QString &author); @@ -45,19 +45,28 @@ namespace EsxModel void setMasters(const QStringList &masters); void setDescription(const QString &description); - inline QString fileName() const { return mFileName; } - inline QString author() const { return mAuthor; } - inline QDateTime modified() const { return mModified; } - inline float version() const { return mVersion; } - inline QString path() const { return mPath; } - inline QStringList masters() const { return mMasters; } - inline QString description() const { return mDescription; } - - inline bool isMaster() const { return (mMasters.size() == 0); } + inline void addMaster (const QString &name) {mMasters.append(name); } + QVariant fileProperty (const FileProperty prop) const; + + inline QString fileName() const { return mFileName; } + inline QString author() const { return mAuthor; } + inline QDateTime modified() const { return mModified; } + inline float version() const { return mVersion; } + inline QString path() const { return mPath; } + inline const QStringList &masters() const { return mMasters; } + inline QString description() const { return mDescription; } + inline QString toolTip() const { return sToolTip.arg(mAuthor) + .arg(mVersion) + .arg(mDescription) + .arg(mMasters.join(", ")); + } + + inline bool isMaster() const { return (mMasters.size() == 0); } QByteArray encodedData() const; public: static int sPropertyCount; + static QString sToolTip; private: @@ -68,6 +77,7 @@ namespace EsxModel QString mPath; QStringList mMasters; QString mDescription; + QString mToolTip; }; } diff --git a/components/esxselector/view/contentselector.cpp b/components/esxselector/view/contentselector.cpp index 1f5e36d65..4f8ac7253 100644 --- a/components/esxselector/view/contentselector.cpp +++ b/components/esxselector/view/contentselector.cpp @@ -54,11 +54,9 @@ void EsxView::ContentSelector::buildPluginsView() mPluginsProxyModel->setDynamicSortFilter (true); mPluginsProxyModel->setSourceModel (mContentModel); - tableView->setModel (mPluginsProxyModel); pluginView->setModel(mPluginsProxyModel); connect(pluginView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotPluginTableItemClicked(const QModelIndex &))); - connect(tableView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotPluginTableItemClicked(const QModelIndex &))); } void EsxView::ContentSelector::buildProfilesView() @@ -120,10 +118,12 @@ void EsxView::ContentSelector::slotCurrentMasterIndexChanged(int index) proxy->setDynamicSortFilter(false); if (oldIndex > -1) + qDebug() << "clearing old master check state"; model->setData(model->index(oldIndex, 0), false, Qt::UserRole + 1); oldIndex = index; + qDebug() << "setting new master check state"; model->setData(model->index(index, 0), true, Qt::UserRole + 1); if (proxy) @@ -132,8 +132,6 @@ void EsxView::ContentSelector::slotCurrentMasterIndexChanged(int index) void EsxView::ContentSelector::slotPluginTableItemClicked(const QModelIndex &index) { - qDebug() << "setting checkstate in plugin..."; - QAbstractItemModel *const model = pluginView->model(); QSortFilterProxyModel *proxy = dynamic_cast(model); diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 76689627b..5b0a6d229 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -7,7 +7,7 @@ 0 0 518 - 310 + 313 @@ -44,6 +44,9 @@ Qt::DefaultContextMenu + + true + QAbstractItemView::NoEditTriggers @@ -85,40 +88,6 @@ - - - - QAbstractItemView::NoEditTriggers - - - true - - - false - - - QAbstractItemView::DragDrop - - - Qt::MoveAction - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - false - - - false - - - false - - -