From cfdc19c4272804b9ed682704e8fa30d31a85a062 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 21 Sep 2013 23:06:29 -0500 Subject: [PATCH] Renamed esxSelector to contentSelector Fixed datafilespage model implementation in launcher Filtered addons in table view by selected game file --- apps/esmtool/esmtool.cpp | 4 +- apps/launcher/datafilespage.cpp | 195 ++++-- apps/launcher/datafilespage.hpp | 32 +- apps/launcher/graphicspage.cpp | 2 +- apps/launcher/utils/textinputdialog.cpp | 4 +- apps/launcher/utils/textinputdialog.hpp | 7 +- apps/opencs/editor.cpp | 4 +- apps/opencs/main.cpp | 2 +- apps/opencs/view/doc/filedialog.cpp | 12 +- apps/opencs/view/doc/filedialog.hpp | 6 +- apps/openmw/mwworld/esmstore.cpp | 2 +- components/CMakeLists.txt | 7 +- .../model/contentmodel.cpp | 137 ++-- .../model/contentmodel.hpp | 15 +- .../model/esmfile.cpp | 53 +- .../model/esmfile.hpp | 42 +- .../contentselector/model/modelitem.cpp | 69 ++ .../model/modelitem.hpp | 2 +- .../model/naturalsort.cpp | 0 .../model/naturalsort.hpp | 0 .../view/comboboxlineedit.cpp | 6 +- .../view/comboboxlineedit.hpp | 2 +- .../contentselector/view/contentselector.cpp | 134 ++++ .../view/contentselector.hpp | 32 +- .../view/lineedit.cpp | 6 +- .../view/lineedit.hpp | 2 +- .../view/profilescombobox.cpp | 14 +- .../view/profilescombobox.hpp | 2 +- components/esm/esmreader.hpp | 2 +- components/esm/loadcell.cpp | 4 +- .../esxselector/model/datafilesmodel.cpp | 608 ------------------ .../esxselector/model/datafilesmodel.hpp | 80 --- .../esxselector/model/masterproxymodel.cpp | 13 - .../esxselector/model/masterproxymodel.hpp | 25 - components/esxselector/model/modelitem.cpp | 69 -- .../esxselector/model/pluginsproxymodel.cpp | 14 - .../esxselector/model/pluginsproxymodel.hpp | 28 - components/esxselector/model/sourcemodel.cpp | 6 - components/esxselector/model/sourcemodel.h | 18 - .../esxselector/view/contentselector.cpp | 148 ----- files/ui/datafilespage.ui | 12 +- 41 files changed, 585 insertions(+), 1235 deletions(-) rename components/{esxselector => contentselector}/model/contentmodel.cpp (64%) rename components/{esxselector => contentselector}/model/contentmodel.hpp (86%) rename components/{esxselector => contentselector}/model/esmfile.cpp (54%) rename components/{esxselector => contentselector}/model/esmfile.hpp (58%) create mode 100644 components/contentselector/model/modelitem.cpp rename components/{esxselector => contentselector}/model/modelitem.hpp (96%) rename components/{esxselector => contentselector}/model/naturalsort.cpp (100%) rename components/{esxselector => contentselector}/model/naturalsort.hpp (100%) rename components/{esxselector => contentselector}/view/comboboxlineedit.cpp (83%) rename components/{esxselector => contentselector}/view/comboboxlineedit.hpp (96%) create mode 100644 components/contentselector/view/contentselector.cpp rename components/{esxselector => contentselector}/view/contentselector.hpp (51%) rename components/{esxselector => contentselector}/view/lineedit.cpp (87%) rename components/{esxselector => contentselector}/view/lineedit.hpp (96%) rename components/{esxselector => contentselector}/view/profilescombobox.cpp (83%) rename components/{esxselector => contentselector}/view/profilescombobox.hpp (96%) delete mode 100644 components/esxselector/model/datafilesmodel.cpp delete mode 100644 components/esxselector/model/datafilesmodel.hpp delete mode 100644 components/esxselector/model/masterproxymodel.cpp delete mode 100644 components/esxselector/model/masterproxymodel.hpp delete mode 100644 components/esxselector/model/modelitem.cpp delete mode 100644 components/esxselector/model/pluginsproxymodel.cpp delete mode 100644 components/esxselector/model/pluginsproxymodel.hpp delete mode 100644 components/esxselector/model/sourcemodel.cpp delete mode 100644 components/esxselector/model/sourcemodel.h delete mode 100644 components/esxselector/view/contentselector.cpp diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index a60e9f0e2..6ccf9c3f3 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -305,14 +305,14 @@ int load(Arguments& info) info.data.author = esm.getAuthor(); info.data.description = esm.getDesc(); - info.data.masters = esm.getMasters(); + info.data.masters = esm.getGameFiles(); if (!quiet) { std::cout << "Author: " << esm.getAuthor() << std::endl << "Description: " << esm.getDesc() << std::endl << "File format version: " << esm.getFVer() << std::endl; - std::vector m = esm.getMasters(); + std::vector m = esm.getGameFiles(); if (!m.empty()) { std::cout << "Masters:" << std::endl; diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 7069737ef..1526b705a 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -4,22 +4,22 @@ #include #include #include +#include #include -#include -#include +#include -#include -#include -#include +#include +#include +#include -#include "components/esxselector/model/masterproxymodel.hpp" #include "settings/gamesettings.hpp" #include "settings/launchersettings.hpp" #include "utils/textinputdialog.hpp" -#include "components/esxselector/view/contentselector.hpp" +#include "components/contentselector/view/contentselector.hpp" +#include "components/contentselector/model/contentmodel.hpp" #include @@ -28,8 +28,10 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam , mGameSettings(gameSettings) , mLauncherSettings(launcherSettings) { - mContentSelector.setParent(parent); - QMetaObject::connectSlotsByName(this); + setupUi(this); + // mContentSelector.setParent(parent); + + // QMetaObject::connectSlotsByName(this); projectGroupBox->hide(); @@ -38,8 +40,82 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString))); + + + buildContentModel(); + buildGameFileView(); + buildAddonView(); + buildProfilesView(); + + createActions(); setupDataFiles(); + + + updateViews(); +} + +void DataFilesPage::buildContentModel() +{ + mContentModel = new ContentSelectorModel::ContentModel(); + connect(mContentModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); +} + +void DataFilesPage::buildGameFileView() +{ + mGameFileProxyModel = new QSortFilterProxyModel(this); + mGameFileProxyModel->setFilterRegExp(QString::number((int)ContentSelectorModel::ContentType_GameFile)); + mGameFileProxyModel->setFilterRole (Qt::UserRole); + mGameFileProxyModel->setSourceModel (mContentModel); + + gameFileView->setPlaceholderText(QString("Select a game file...")); + gameFileView->setModel(mGameFileProxyModel); + + connect(gameFileView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentGameFileIndexChanged(int))); + + gameFileView->setCurrentIndex(-1); + gameFileView->setCurrentIndex(0); +} + +void DataFilesPage::buildAddonView() +{ + mAddonProxyModel = new QSortFilterProxyModel(this); + mAddonProxyModel->setFilterRegExp (QString::number((int)ContentSelectorModel::ContentType_Addon)); + mAddonProxyModel->setFilterRole (Qt::UserRole); + mAddonProxyModel->setDynamicSortFilter (true); + mAddonProxyModel->setSourceModel (mContentModel); + + addonView->setModel(mAddonProxyModel); + + connect(addonView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotAddonTableItemClicked(const QModelIndex &))); +} + +void DataFilesPage::buildProfilesView() +{ + profilesComboBox->setPlaceholderText(QString("Select a profile...")); + connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); +} + +void DataFilesPage::updateViews() +{ + // Ensure the columns are hidden because sort() re-enables them + addonView->setColumnHidden(1, true); + addonView->setColumnHidden(2, true); + addonView->setColumnHidden(3, true); + addonView->setColumnHidden(4, true); + addonView->setColumnHidden(5, true); + addonView->setColumnHidden(6, true); + addonView->setColumnHidden(7, true); + addonView->setColumnHidden(8, true); + addonView->resizeColumnsToContents(); +} + +void ContentSelectorView::ContentSelector::addFiles(const QString &path) +{ + mContentModel->addFiles(path); + //mContentModel->sort(3); // Sort by date accessed + gameFileView->setCurrentIndex(-1); + mContentModel->uncheckAll(); } void DataFilesPage::createActions() @@ -52,17 +128,19 @@ void DataFilesPage::createActions() void DataFilesPage::setupDataFiles() { // Set the encoding to the one found in openmw.cfg or the default - mContentSelector.setEncoding(mGameSettings.value(QString("encoding"), QString("win1252"))); + //mContentSelector.setEncoding(mGameSettings.value(QString("encoding"), QString("win1252"))); QStringList paths = mGameSettings.getDataDirs(); foreach (const QString &path, paths) { - mContentSelector.addFiles(path); + //mContentSelector. + mContentModel->addFiles(path); } QString dataLocal = mGameSettings.getDataLocal(); if (!dataLocal.isEmpty()) - mContentSelector.addFiles(dataLocal); + //mContentSelector. + mContentModel->addFiles(dataLocal); // Sort by date accessed for now //mContentSelector->sort(3); @@ -95,6 +173,7 @@ void DataFilesPage::setupDataFiles() loadSettings(); + gameFileView->setCurrentIndex(-1); } void DataFilesPage::loadSettings() @@ -104,29 +183,17 @@ void DataFilesPage::loadSettings() if (profile.isEmpty()) return; - // mContentSelector.uncheckAll(); - - QStringList masters = mLauncherSettings.values(QString("Profiles/") + profile + QString("/master"), Qt::MatchExactly); - QStringList plugins = mLauncherSettings.values(QString("Profiles/") + profile + QString("/plugin"), Qt::MatchExactly); -/* - foreach (const QString &master, masters) { - QModelIndex index = mDataFilesModel->indexFromItem(mDataFilesModel->findItem(master)); - if (index.isValid()) - mDataFilesModel->setCheckState(index, Qt::Checked); - } + // mContentSelector. + mContentModel->uncheckAll(); - foreach (const QString &plugin, plugins) { - QModelIndex index = mDataFilesModel->indexFromItem(mDataFilesModel->findItem(plugin)); - if (index.isValid()) - mDataFilesModel->setCheckState(index, Qt::Checked); - } - */ + QStringList gameFiles = mLauncherSettings.values(QString("Profiles/") + profile + QString("/master"), Qt::MatchExactly); + QStringList addons = mLauncherSettings.values(QString("Profiles/") + profile + QString("/plugin"), Qt::MatchExactly); } void DataFilesPage::saveSettings() { -// if (mDataFilesModel->rowCount() < 1) -// return; + if (mContentModel->rowCount() < 1) + return; QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); @@ -141,11 +208,11 @@ void DataFilesPage::saveSettings() mGameSettings.remove(QString("master")); mGameSettings.remove(QString("plugin")); - // EsxModel::EsmFileList items = mDataFilesModel->checkedItems(); -/* - foreach(const EsxModel::EsmFile *item, items) { + ContentSelectorModel::ContentFileList items = mContentModel->checkedItems(); + + foreach(const ContentSelectorModel::EsmFile *item, items) { - if (item->masters().size() == 0) { + if (item->gameFiles().size() == 0) { mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/master"), item->fileName()); mGameSettings.setMultiValue(QString("master"), item->fileName()); @@ -154,7 +221,7 @@ void DataFilesPage::saveSettings() mGameSettings.setMultiValue(QString("plugin"), item->fileName()); } } -*/ + } void DataFilesPage::updateOkButton(const QString &text) @@ -223,23 +290,25 @@ void DataFilesPage::on_deleteProfileAction_triggered() void DataFilesPage::setPluginsCheckstates(Qt::CheckState state) { - if (!pluginView->selectionModel()->hasSelection()) { + if (!addonView->selectionModel()->hasSelection()) { return; } - QModelIndexList indexes = pluginView->selectionModel()->selectedIndexes(); + QModelIndexList indexes = addonView->selectionModel()->selectedIndexes(); foreach (const QModelIndex &index, indexes) { if (!index.isValid()) return; - QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(index); + QModelIndex sourceIndex = mAddonProxyModel->mapToSource(index); if (!sourceIndex.isValid()) return; - //mDataFilesModel->setCheckState(sourceIndex, state); + bool isChecked = ( state == Qt::Checked ); + + mContentModel->setData(sourceIndex, state, Qt::CheckStateRole); } } @@ -287,3 +356,51 @@ void DataFilesPage::profileRenamed(const QString &previous, const QString &curre loadSettings(); } +//////////////////////////// + +QStringList DataFilesPage::checkedItemsPaths() +{ + QStringList itemPaths; + + foreach( const ContentSelectorModel::EsmFile *file, mContentModel->checkedItems()) + itemPaths << file->path(); + + return itemPaths; +} + +void DataFilesPage::slotCurrentProfileIndexChanged(int index) +{ + emit profileChanged(index); +} + +void DataFilesPage::slotCurrentGameFileIndexChanged(int index) +{ + static int oldIndex = -1; + + QAbstractItemModel *const model = gameFileView->model(); + QSortFilterProxyModel *proxy = dynamic_cast(model); + + if (proxy) + proxy->setDynamicSortFilter(false); + + if (oldIndex > -1) + model->setData(model->index(oldIndex, 0), false, Qt::UserRole + 1); + + oldIndex = index; + + model->setData(model->index(index, 0), true, Qt::UserRole + 1); + + if (proxy) + proxy->setDynamicSortFilter(true); +} + +void DataFilesPage::slotAddonTableItemClicked(const QModelIndex &index) +{ + QAbstractItemModel *const model = addonView->model(); + QSortFilterProxyModel *proxy = dynamic_cast(model); + + if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked) + model->setData(index, Qt::Checked, Qt::CheckStateRole); + else + model->setData(index, Qt::Unchecked, Qt::CheckStateRole); +} diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index ed92da749..9c7b0538e 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -5,24 +5,24 @@ #include #include "ui_datafilespage.h" -#include "components/esxselector/view/contentselector.hpp" +#include "components/contentselector/view/contentselector.hpp" class QSortFilterProxyModel; class QAbstractItemModel; class QAction; class QMenu; -class DataFilesModel; class TextInputDialog; class GameSettings; class LauncherSettings; -class PluginsProxyModel; + namespace Files { struct ConfigurationManager; } -class DataFilesPage : public EsxView::ContentSelector +class DataFilesPage : public QWidget, private Ui::DataFilesPage { Q_OBJECT + public: DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent = 0); @@ -42,7 +42,7 @@ public slots: void profileChanged(const QString &previous, const QString ¤t); void profileRenamed(const QString &previous, const QString ¤t); void updateOkButton(const QString &text); - + void updateViews(); // Action slots void on_newProfileAction_triggered(); void on_deleteProfileAction_triggered(); @@ -52,14 +52,16 @@ private slots: private: QMenu *mContextMenu; - ContentSelector mContentSelector; - + //ContentSelectorView::ContentSelector mContentSelector; + ContentSelectorModel::ContentModel *mContentModel; Files::ConfigurationManager &mCfgMgr; GameSettings &mGameSettings; LauncherSettings &mLauncherSettings; TextInputDialog *mNewProfileDialog; + QSortFilterProxyModel *mGameFileProxyModel; + QSortFilterProxyModel *mAddonProxyModel; void setPluginsCheckstates(Qt::CheckState state); @@ -70,6 +72,22 @@ private: void loadSettings(); + ////////////////////////////////////// + void buildContentModel(); + void buildGameFileView(); + void buildAddonView(); + void buildProfilesView(); + + //void addFiles(const QString &path); + + QStringList checkedItemsPaths(); + +private slots: + void slotCurrentProfileIndexChanged(int index); + void slotCurrentGameFileIndexChanged(int index); + void slotAddonTableItemClicked(const QModelIndex &index); + + }; #endif diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index e71fc429f..4d9ce14d6 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include "settings/graphicssettings.hpp" diff --git a/apps/launcher/utils/textinputdialog.cpp b/apps/launcher/utils/textinputdialog.cpp index 052fc58e4..51928c09a 100644 --- a/apps/launcher/utils/textinputdialog.cpp +++ b/apps/launcher/utils/textinputdialog.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWidget *parent) : QDialog(parent) @@ -19,7 +19,7 @@ TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWid // Line edit QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore - mLineEdit = new EsxView::LineEdit(this); + mLineEdit = new ContentSelectorView::LineEdit(this); mLineEdit->setValidator(validator); mLineEdit->setCompleter(0); diff --git a/apps/launcher/utils/textinputdialog.hpp b/apps/launcher/utils/textinputdialog.hpp index 2fb6e0f6b..de3a9fb72 100644 --- a/apps/launcher/utils/textinputdialog.hpp +++ b/apps/launcher/utils/textinputdialog.hpp @@ -2,11 +2,10 @@ #define TEXTINPUTDIALOG_HPP #include -//#include "lineedit.hpp" class QDialogButtonBox; -namespace EsxView { +namespace ContentSelectorView { class LineEdit; } @@ -16,10 +15,10 @@ class TextInputDialog : public QDialog Q_OBJECT public: explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0); - inline EsxView::LineEdit *lineEdit() { return mLineEdit; } + inline ContentSelectorView::LineEdit *lineEdit() { return mLineEdit; } void setOkButtonEnabled(bool enabled); - EsxView::LineEdit *mLineEdit; + ContentSelectorView::LineEdit *mLineEdit; int exec(); diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 9a6832ec0..ba1dfb57e 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -79,8 +79,8 @@ void CS::Editor::setupDataFiles() } // Set the charset for reading the esm/esp files - QString encoding = QString::fromStdString(variables["encoding"].as()); - mFileDialog.setEncoding(encoding); + // QString encoding = QString::fromStdString(variables["encoding"].as()); + //mFileDialog.setEncoding(encoding); dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end()); diff --git a/apps/opencs/main.cpp b/apps/opencs/main.cpp index ef7123c20..e5e7514ce 100644 --- a/apps/opencs/main.cpp +++ b/apps/opencs/main.cpp @@ -42,7 +42,7 @@ int main(int argc, char *argv[]) if(!editor.makeIPCServer()) { editor.connectToIPCServer(); - return 0; + // return 0; } return editor.run(); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index fb031fe5f..1d6bed7a7 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -10,24 +10,18 @@ #include #include -#include -#include -#include - -#include - -#include "components/esxselector/model/masterproxymodel.hpp" +#include +#include CSVDoc::FileDialog::FileDialog(QWidget *parent) : ContentSelector(parent) { // Hide the profile elements profileGroupBox->hide(); - pluginView->showColumn(2); + addonView->showColumn(2); resize(400, 400); - // connect(mDataFilesModel, SIGNAL(checkedItemsChanged(QStringList)), this, SLOT(updateOpenButton(QStringList))); connect(projectNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateCreateButton(QString))); connect(projectCreateButton, SIGNAL(clicked()), this, SIGNAL(createNewFile())); diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index c749099d4..d0c3461b9 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -4,7 +4,7 @@ #include #include -#include "components/esxselector/view/contentselector.hpp" +#include "components/contentselector/view/contentselector.hpp" #include "ui_datafilespage.h" class QDialogButtonBox; @@ -19,14 +19,14 @@ class QLabel; class DataFilesModel; class PluginsProxyModel; -namespace EsxView +namespace ContentSelectorView { class LineEdit; } namespace CSVDoc { - class FileDialog : public EsxView::ContentSelector + class FileDialog : public ContentSelectorView::ContentSelector { Q_OBJECT public: diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 7703f2d23..963316070 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -36,7 +36,7 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener) // all files/readers used by the engine. This will greaty accelerate // refnumber mangling, as required for handling moved references. int index = ~0; - const std::vector &masters = esm.getMasters(); + const std::vector &masters = esm.getGameFiles(); std::vector *allPlugins = esm.getGlobalReaderList(); for (size_t j = 0; j < masters.size(); j++) { ESM::Header::MasterData &mast = const_cast(masters[j]); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 34ef43ab5..7053bb973 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -79,10 +79,9 @@ set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/datafilespage.ui find_package(Qt4 COMPONENTS QtCore QtGui) if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) - add_component_qt_dir (esxselector - model/masterproxymodel model/modelitem - model/pluginsproxymodel model/esmfile model/naturalsort - model/contentmodel + add_component_qt_dir (contentselector + model/modelitem model/esmfile + model/naturalsort model/contentmodel view/profilescombobox view/comboboxlineedit view/lineedit view/contentselector ) diff --git a/components/esxselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp similarity index 64% rename from components/esxselector/model/contentmodel.cpp rename to components/contentselector/model/contentmodel.cpp index d23ea7801..b85da25c6 100644 --- a/components/esxselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -6,7 +6,7 @@ #include #include -EsxModel::ContentModel::ContentModel(QObject *parent) : +ContentSelectorModel::ContentModel::ContentModel(QObject *parent) : QAbstractTableModel(parent), mMimeType ("application/omwcontent"), mMimeTypes (QStringList() << mMimeType), @@ -15,11 +15,11 @@ EsxModel::ContentModel::ContentModel(QObject *parent) : mDefaultFlags (Qt::ItemIsDropEnabled | Qt::ItemIsSelectable), mDropActions (Qt::CopyAction | Qt::MoveAction) { - setEncoding ("win1252"); + // setEncoding ("win1252"); uncheckAll(); } - -void EsxModel::ContentModel::setEncoding(const QString &encoding) +/* +void ContentSelectorModel::ContentModel::setEncoding(const QString &encoding) { if (encoding == QLatin1String("win1252")) mCodec = QTextCodec::codecForName("windows-1252"); @@ -33,8 +33,8 @@ void EsxModel::ContentModel::setEncoding(const QString &encoding) else return; // This should never happen; } - -int EsxModel::ContentModel::columnCount(const QModelIndex &parent) const +*/ +int ContentSelectorModel::ContentModel::columnCount(const QModelIndex &parent) const { if (parent.isValid()) return 0; @@ -42,7 +42,7 @@ int EsxModel::ContentModel::columnCount(const QModelIndex &parent) const return mColumnCount; } -int EsxModel::ContentModel::rowCount(const QModelIndex &parent) const +int ContentSelectorModel::ContentModel::rowCount(const QModelIndex &parent) const { if(parent.isValid()) return 0; @@ -50,7 +50,7 @@ int EsxModel::ContentModel::rowCount(const QModelIndex &parent) const return mFiles.size(); } -const EsxModel::EsmFile* EsxModel::ContentModel::item(int row) const +const ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(int row) const { if (row >= 0 && row < mFiles.size()) return mFiles.at(row); @@ -58,14 +58,14 @@ const EsxModel::EsmFile* EsxModel::ContentModel::item(int row) const return 0; } -EsxModel::EsmFile *EsxModel::ContentModel::item(int row) +ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(int row) { if (row >= 0 && row < mFiles.count()) return mFiles.at(row); return 0; } -const EsxModel::EsmFile *EsxModel::ContentModel::findItem(const QString &name) const +const ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::findItem(const QString &name) const { foreach (const EsmFile *file, mFiles) { @@ -75,15 +75,18 @@ const EsxModel::EsmFile *EsxModel::ContentModel::findItem(const QString &name) c return 0; } -QModelIndex EsxModel::ContentModel::indexFromItem(EsmFile *item) const +QModelIndex ContentSelectorModel::ContentModel::indexFromItem(const EsmFile *item) const { + //workaround: non-const pointer cast for calls from outside contentmodel/contentselector + EsmFile *non_const_file_ptr = const_cast(item); + if (item) - return index(mFiles.indexOf(item),0); + return index(mFiles.indexOf(non_const_file_ptr),0); return QModelIndex(); } -Qt::ItemFlags EsxModel::ContentModel::flags(const QModelIndex &index) const +Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::NoItemFlags; @@ -99,7 +102,7 @@ Qt::ItemFlags EsxModel::ContentModel::flags(const QModelIndex &index) const return mDefaultFlags; } -QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const +QVariant ContentSelectorModel::ContentModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); @@ -119,7 +122,7 @@ QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const case Qt::EditRole: case Qt::DisplayRole: { - if (column >=0 && column <=EsmFile::FileProperty_Master) + if (column >=0 && column <=EsmFile::FileProperty_GameFile) return file->fileProperty(static_cast(column)); return QVariant(); @@ -154,17 +157,20 @@ QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const case Qt::CheckStateRole: { - if (!file->isMaster()) + if (!file->isGameFile()) return isChecked(file->fileName()); break; } case Qt::UserRole: { - if (file->isMaster()) - return "game"; + if (file->isGameFile()) + return ContentType_GameFile; else - return "addon"; + if (flags(index) & Qt::ItemIsEnabled) + return ContentType_Addon; + + break; } case Qt::UserRole + 1: @@ -174,7 +180,7 @@ QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const return QVariant(); } -bool EsxModel::ContentModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool ContentSelectorModel::ContentModel::setData(const QModelIndex &index, const QVariant &value, int role) { if(!index.isValid()) return false; @@ -189,11 +195,11 @@ bool EsxModel::ContentModel::setData(const QModelIndex &index, const QVariant &v { QStringList list = value.toStringList(); - for (int i = 0; i < EsmFile::FileProperty_Master; i++) + for (int i = 0; i < EsmFile::FileProperty_GameFile; i++) file->setFileProperty(static_cast(i), list.at(i)); - for (int i = EsmFile::FileProperty_Master; i < list.size(); i++) - file->setFileProperty (EsmFile::FileProperty_Master, list.at(i)); + for (int i = EsmFile::FileProperty_GameFile; i < list.size(); i++) + file->setFileProperty (EsmFile::FileProperty_GameFile, list.at(i)); emit dataChanged(index, index); @@ -209,7 +215,7 @@ bool EsxModel::ContentModel::setData(const QModelIndex &index, const QVariant &v foreach (EsmFile *file, mFiles) { - if (file->masters().contains(fileName)) + if (file->gameFiles().contains(fileName)) { QModelIndex idx = indexFromItem(file); emit dataChanged(idx, idx); @@ -222,15 +228,36 @@ bool EsxModel::ContentModel::setData(const QModelIndex &index, const QVariant &v case Qt::CheckStateRole: { int checkValue = value.toInt(); - + bool success = false; + bool setState = false; if ((checkValue==Qt::Checked) && !isChecked(fileName)) - setCheckState(fileName, true); + { + setState = true; + success = true; + } else if ((checkValue == Qt::Checked) && isChecked (fileName)) - setCheckState(fileName, false); + setState = true; else if (checkValue == Qt::Unchecked) - setCheckState(fileName, false); + setState = true; + + if (setState) + { + setCheckState(fileName, success); + emit dataChanged(index, index); + + } + else + return success; - emit dataChanged(index, index); + + foreach (EsmFile *file, mFiles) + { + if (file->gameFiles().contains(fileName)) + { + QModelIndex idx = indexFromItem(file); + emit dataChanged(idx, idx); + } + } success = true; } @@ -240,7 +267,7 @@ bool EsxModel::ContentModel::setData(const QModelIndex &index, const QVariant &v return success; } -bool EsxModel::ContentModel::insertRows(int position, int rows, const QModelIndex &parent) +bool ContentSelectorModel::ContentModel::insertRows(int position, int rows, const QModelIndex &parent) { if (parent.isValid()) return false; @@ -255,7 +282,7 @@ bool EsxModel::ContentModel::insertRows(int position, int rows, const QModelInde return true; } -bool EsxModel::ContentModel::removeRows(int position, int rows, const QModelIndex &parent) +bool ContentSelectorModel::ContentModel::removeRows(int position, int rows, const QModelIndex &parent) { if (parent.isValid()) return false; @@ -270,17 +297,17 @@ bool EsxModel::ContentModel::removeRows(int position, int rows, const QModelInde return true; } -Qt::DropActions EsxModel::ContentModel::supportedDropActions() const +Qt::DropActions ContentSelectorModel::ContentModel::supportedDropActions() const { return mDropActions; } -QStringList EsxModel::ContentModel::mimeTypes() const +QStringList ContentSelectorModel::ContentModel::mimeTypes() const { return mMimeTypes; } -QMimeData *EsxModel::ContentModel::mimeData(const QModelIndexList &indexes) const +QMimeData *ContentSelectorModel::ContentModel::mimeData(const QModelIndexList &indexes) const { QByteArray encodedData; @@ -298,7 +325,7 @@ QMimeData *EsxModel::ContentModel::mimeData(const QModelIndexList &indexes) cons return mimeData; } -bool EsxModel::ContentModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) +bool ContentSelectorModel::ContentModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { if (action == Qt::IgnoreAction) return true; @@ -325,51 +352,53 @@ bool EsxModel::ContentModel::dropMimeData(const QMimeData *data, Qt::DropAction QString value; QStringList values; - QStringList masters; + QStringList gamefiles; - for (int i = 0; i < EsmFile::FileProperty_Master; ++i) + for (int i = 0; i < EsmFile::FileProperty_GameFile; ++i) { stream >> value; values << value; } - stream >> masters; + stream >> gamefiles; insertRows(beginRow, 1); QModelIndex idx = index(beginRow++, 0, QModelIndex()); - setData(idx, QStringList() << values << masters, Qt::EditRole); + setData(idx, QStringList() << values << gamefiles, Qt::EditRole); } return true; } -bool EsxModel::ContentModel::canBeChecked(const EsmFile *file) const +bool ContentSelectorModel::ContentModel::canBeChecked(const EsmFile *file) const { //element can be checked if all its dependencies are - foreach (const QString &master, file->masters()) - if (!isChecked(master)) + foreach (const QString &gamefile, file->gameFiles()) + if (!isChecked(gamefile)) return false; return true; } -void EsxModel::ContentModel::addFile(EsmFile *file) +void ContentSelectorModel::ContentModel::addFile(EsmFile *file) { beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); mFiles.append(file); endInsertRows(); } -void EsxModel::ContentModel::addFiles(const QString &path) +void ContentSelectorModel::ContentModel::addFiles(const QString &path) { QDir dir(path); QStringList filters; filters << "*.esp" << "*.esm" << "*.omwgame" << "*.omwaddon"; dir.setNameFilters(filters); + QTextCodec *codec = QTextCodec::codecForName("UTF8"); + // Create a decoder for non-latin characters in esx metadata - QTextDecoder *decoder = mCodec->makeDecoder(); + QTextDecoder *decoder = codec->makeDecoder(); foreach (const QString &path, dir.entryList()) { @@ -378,16 +407,16 @@ void EsxModel::ContentModel::addFiles(const QString &path) try { ESM::ESMReader fileReader; - ToUTF8::Utf8Encoder encoder(ToUTF8::calculateEncoding(QString(mCodec->name()).toStdString())); - fileReader.setEncoder(&encoder); + ToUTF8::Utf8Encoder encoder(); //ToUTF8::calculateEncoding(QString(mCodec->name()).toStdString())); + //fileReader.setEncoder(&encoder); fileReader.open(dir.absoluteFilePath(path).toStdString()); - foreach (const ESM::Header::MasterData &item, fileReader.getMasters()) - file->addMaster(QString::fromStdString(item.name)); + foreach (const ESM::Header::MasterData &item, fileReader.getGameFiles()) + file->addGameFile(QString::fromStdString(item.name)); file->setAuthor (decoder->toUnicode(fileReader.getAuthor().c_str())); file->setDate (info.lastModified()); - file->setVersion (fileReader.getFVer()); + file->setFormat (fileReader.getFormat()); file->setPath (info.absoluteFilePath()); file->setDescription(decoder->toUnicode(fileReader.getDesc().c_str())); @@ -407,7 +436,7 @@ void EsxModel::ContentModel::addFiles(const QString &path) delete decoder; } -bool EsxModel::ContentModel::isChecked(const QString& name) const +bool ContentSelectorModel::ContentModel::isChecked(const QString& name) const { if (mCheckStates.contains(name)) return (mCheckStates[name] == Qt::Checked); @@ -415,7 +444,7 @@ bool EsxModel::ContentModel::isChecked(const QString& name) const return false; } -void EsxModel::ContentModel::setCheckState(const QString &name, bool isChecked) +void ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool isChecked) { if (name.isEmpty()) return; @@ -428,7 +457,7 @@ void EsxModel::ContentModel::setCheckState(const QString &name, bool isChecked) mCheckStates[name] = state; } -EsxModel::ContentFileList EsxModel::ContentModel::checkedItems() const +ContentSelectorModel::ContentFileList ContentSelectorModel::ContentModel::checkedItems() const { ContentFileList list; @@ -441,7 +470,7 @@ EsxModel::ContentFileList EsxModel::ContentModel::checkedItems() const return list; } -void EsxModel::ContentModel::uncheckAll() +void ContentSelectorModel::ContentModel::uncheckAll() { emit layoutAboutToBeChanged(); mCheckStates.clear(); diff --git a/components/esxselector/model/contentmodel.hpp b/components/contentselector/model/contentmodel.hpp similarity index 86% rename from components/esxselector/model/contentmodel.hpp rename to components/contentselector/model/contentmodel.hpp index 6a2dd88ca..a8ff103da 100644 --- a/components/esxselector/model/contentmodel.hpp +++ b/components/contentselector/model/contentmodel.hpp @@ -3,19 +3,26 @@ #include #include -namespace EsxModel + +namespace ContentSelectorModel { class EsmFile; typedef QList ContentFileList; + enum ContentType + { + ContentType_GameFile, + ContentType_Addon + }; + class ContentModel : public QAbstractTableModel { Q_OBJECT public: explicit ContentModel(QObject *parent = 0); - void setEncoding(const QString &encoding); + //void setEncoding(const QString &encoding); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; @@ -34,8 +41,8 @@ namespace EsxModel void addFiles(const QString &path); - QModelIndex indexFromItem(EsmFile *item) const; - const EsxModel::EsmFile *findItem(const QString &name) const; + QModelIndex indexFromItem(const EsmFile *item) const; + const EsmFile *findItem(const QString &name) const; bool isChecked(const QString &name) const; void setCheckState(const QString &name, bool isChecked); diff --git a/components/esxselector/model/esmfile.cpp b/components/contentselector/model/esmfile.cpp similarity index 54% rename from components/esxselector/model/esmfile.cpp rename to components/contentselector/model/esmfile.cpp index bd76dc4a0..9dfe49eba 100644 --- a/components/esxselector/model/esmfile.cpp +++ b/components/contentselector/model/esmfile.cpp @@ -3,64 +3,65 @@ #include #include -int EsxModel::EsmFile::sPropertyCount = 7; -QString EsxModel::EsmFile::sToolTip = QString("Author: %1
\ +int ContentSelectorModel::EsmFile::sPropertyCount = 7; +QString ContentSelectorModel::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) +ContentSelectorModel::EsmFile::EsmFile(QString fileName, ModelItem *parent) + : ModelItem(parent), mFileName(fileName), mFormat(0) {} -void EsxModel::EsmFile::setFileName(const QString &fileName) + +void ContentSelectorModel::EsmFile::setFileName(const QString &fileName) { mFileName = fileName; } -void EsxModel::EsmFile::setAuthor(const QString &author) +void ContentSelectorModel::EsmFile::setAuthor(const QString &author) { mAuthor = author; } -void EsxModel::EsmFile::setDate(const QDateTime &modified) +void ContentSelectorModel::EsmFile::setDate(const QDateTime &modified) { mModified = modified; } -void EsxModel::EsmFile::setVersion(float version) +void ContentSelectorModel::EsmFile::setFormat(int format) { - mVersion = version; + mFormat = format; } -void EsxModel::EsmFile::setPath(const QString &path) +void ContentSelectorModel::EsmFile::setPath(const QString &path) { mPath = path; } -void EsxModel::EsmFile::setMasters(const QStringList &masters) +void ContentSelectorModel::EsmFile::setGameFiles(const QStringList &gamefiles) { - mMasters = masters; + mGameFiles = gamefiles; } -void EsxModel::EsmFile::setDescription(const QString &description) +void ContentSelectorModel::EsmFile::setDescription(const QString &description) { mDescription = description; } -QByteArray EsxModel::EsmFile::encodedData() const +QByteArray ContentSelectorModel::EsmFile::encodedData() const { QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); - stream << mFileName << mAuthor << QString::number(mVersion) + stream << mFileName << mAuthor << QString::number(mFormat) << mModified.toString() << mPath << mDescription - << mMasters; + << mGameFiles; return encodedData; } -QVariant EsxModel::EsmFile::fileProperty(const FileProperty prop) const +QVariant ContentSelectorModel::EsmFile::fileProperty(const FileProperty prop) const { switch (prop) { @@ -72,8 +73,8 @@ QVariant EsxModel::EsmFile::fileProperty(const FileProperty prop) const return mAuthor; break; - case FileProperty_Version: - return mVersion; + case FileProperty_Format: + return mFormat; break; case FileProperty_DateModified: @@ -88,8 +89,8 @@ QVariant EsxModel::EsmFile::fileProperty(const FileProperty prop) const return mDescription; break; - case FileProperty_Master: - return mMasters; + case FileProperty_GameFile: + return mGameFiles; break; default: @@ -97,7 +98,7 @@ QVariant EsxModel::EsmFile::fileProperty(const FileProperty prop) const } return QVariant(); } -void EsxModel::EsmFile::setFileProperty (const FileProperty prop, const QString &value) +void ContentSelectorModel::EsmFile::setFileProperty (const FileProperty prop, const QString &value) { switch (prop) { @@ -109,8 +110,8 @@ void EsxModel::EsmFile::setFileProperty (const FileProperty prop, const QString mAuthor = value; break; - case FileProperty_Version: - mVersion = value.toFloat(); + case FileProperty_Format: + mFormat = value.toInt(); break; case FileProperty_DateModified: @@ -125,8 +126,8 @@ void EsxModel::EsmFile::setFileProperty (const FileProperty prop, const QString mDescription = value; break; - case FileProperty_Master: - mMasters << value; + case FileProperty_GameFile: + mGameFiles << value; break; default: diff --git a/components/esxselector/model/esmfile.hpp b/components/contentselector/model/esmfile.hpp similarity index 58% rename from components/esxselector/model/esmfile.hpp rename to components/contentselector/model/esmfile.hpp index 4f6d7a624..743b1c5a6 100644 --- a/components/esxselector/model/esmfile.hpp +++ b/components/contentselector/model/esmfile.hpp @@ -8,7 +8,7 @@ class QMimeData; -namespace EsxModel +namespace ContentSelectorModel { class EsmFile : public ModelItem { @@ -21,11 +21,11 @@ namespace EsxModel { FileProperty_FileName = 0, FileProperty_Author = 1, - FileProperty_Version = 2, + FileProperty_Format = 2, FileProperty_DateModified = 3, FileProperty_Path = 4, FileProperty_Description = 5, - FileProperty_Master = 6 + FileProperty_GameFile = 6 }; EsmFile(QString fileName = QString(), ModelItem *parent = 0); @@ -40,28 +40,28 @@ namespace EsxModel void setAuthor(const QString &author); void setSize(const int size); void setDate(const QDateTime &modified); - void setVersion(const float version); + void setFormat(const int format); void setPath(const QString &path); - void setMasters(const QStringList &masters); + void setGameFiles(const QStringList &gameFiles); void setDescription(const QString &description); - inline void addMaster (const QString &name) {mMasters.append(name); } + inline void addGameFile (const QString &name) {mGameFiles.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) + inline QString fileName() const { return mFileName; } + inline QString author() const { return mAuthor; } + inline QDateTime modified() const { return mModified; } + inline float format() const { return mFormat; } + inline QString path() const { return mPath; } + inline const QStringList &gameFiles() const { return mGameFiles; } + inline QString description() const { return mDescription; } + inline QString toolTip() const { return sToolTip.arg(mAuthor) + .arg(mFormat) .arg(mDescription) - .arg(mMasters.join(", ")); - } + .arg(mGameFiles.join(", ")); + } - inline bool isMaster() const { return (mMasters.size() == 0); } + inline bool isGameFile() const { return (mGameFiles.size() == 0); } QByteArray encodedData() const; public: @@ -73,15 +73,13 @@ namespace EsxModel QString mFileName; QString mAuthor; QDateTime mModified; - float mVersion; + int mFormat; QString mPath; - QStringList mMasters; + QStringList mGameFiles; QString mDescription; QString mToolTip; }; } -Q_DECLARE_METATYPE (EsxModel::EsmFile *) - #endif diff --git a/components/contentselector/model/modelitem.cpp b/components/contentselector/model/modelitem.cpp new file mode 100644 index 000000000..e1d737c2d --- /dev/null +++ b/components/contentselector/model/modelitem.cpp @@ -0,0 +1,69 @@ +#include "modelitem.hpp" + +ContentSelectorModel::ModelItem::ModelItem(ModelItem *parent) + : mParentItem(parent) +{ +} +/* +ContentSelectorModel::ModelItem::ModelItem(const ModelItem *parent) + // : mParentItem(parent) +{ +} +*/ + +ContentSelectorModel::ModelItem::~ModelItem() +{ + qDeleteAll(mChildItems); +} + + +ContentSelectorModel::ModelItem *ContentSelectorModel::ModelItem::parent() const +{ + return mParentItem; +} + +bool ContentSelectorModel::ModelItem::hasFormat(const QString &mimetype) const +{ + if (mimetype == "application/omwcontent") + return true; + + return QMimeData::hasFormat(mimetype); +} +int ContentSelectorModel::ModelItem::row() const +{ + if (mParentItem) + return 1; + //return mParentItem->childRow(const_cast(this)); + //return mParentItem->mChildItems.indexOf(const_cast(this)); + + return -1; +} + + +int ContentSelectorModel::ModelItem::childCount() const +{ + return mChildItems.count(); +} + +int ContentSelectorModel::ModelItem::childRow(ModelItem *child) const +{ + Q_ASSERT(child); + + return mChildItems.indexOf(child); +} + +ContentSelectorModel::ModelItem *ContentSelectorModel::ModelItem::child(int row) +{ + return mChildItems.value(row); +} + + +void ContentSelectorModel::ModelItem::appendChild(ModelItem *item) +{ + mChildItems.append(item); +} + +void ContentSelectorModel::ModelItem::removeChild(int row) +{ + mChildItems.removeAt(row); +} diff --git a/components/esxselector/model/modelitem.hpp b/components/contentselector/model/modelitem.hpp similarity index 96% rename from components/esxselector/model/modelitem.hpp rename to components/contentselector/model/modelitem.hpp index 5ee5e417e..57214b09c 100644 --- a/components/esxselector/model/modelitem.hpp +++ b/components/contentselector/model/modelitem.hpp @@ -4,7 +4,7 @@ #include #include -namespace EsxModel +namespace ContentSelectorModel { class ModelItem : public QMimeData { diff --git a/components/esxselector/model/naturalsort.cpp b/components/contentselector/model/naturalsort.cpp similarity index 100% rename from components/esxselector/model/naturalsort.cpp rename to components/contentselector/model/naturalsort.cpp diff --git a/components/esxselector/model/naturalsort.hpp b/components/contentselector/model/naturalsort.hpp similarity index 100% rename from components/esxselector/model/naturalsort.hpp rename to components/contentselector/model/naturalsort.hpp diff --git a/components/esxselector/view/comboboxlineedit.cpp b/components/contentselector/view/comboboxlineedit.cpp similarity index 83% rename from components/esxselector/view/comboboxlineedit.cpp rename to components/contentselector/view/comboboxlineedit.cpp index 815a1130b..df647a4a0 100644 --- a/components/esxselector/view/comboboxlineedit.cpp +++ b/components/contentselector/view/comboboxlineedit.cpp @@ -3,7 +3,7 @@ #include "comboboxlineedit.hpp" -EsxView::ComboBoxLineEdit::ComboBoxLineEdit(QWidget *parent) +ContentSelectorView::ComboBoxLineEdit::ComboBoxLineEdit(QWidget *parent) : QLineEdit(parent) { mClearButton = new QToolButton(this); @@ -21,7 +21,7 @@ EsxView::ComboBoxLineEdit::ComboBoxLineEdit(QWidget *parent) setStyleSheet(QString("ComboBoxLineEdit { background-color: transparent; padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1)); } -void EsxView::ComboBoxLineEdit::resizeEvent(QResizeEvent *) +void ContentSelectorView::ComboBoxLineEdit::resizeEvent(QResizeEvent *) { QSize sz = mClearButton->sizeHint(); int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); @@ -29,7 +29,7 @@ void EsxView::ComboBoxLineEdit::resizeEvent(QResizeEvent *) (rect().bottom() + 1 - sz.height())/2); } -void EsxView::ComboBoxLineEdit::updateClearButton(const QString& text) +void ContentSelectorView::ComboBoxLineEdit::updateClearButton(const QString& text) { mClearButton->setVisible(!text.isEmpty()); } diff --git a/components/esxselector/view/comboboxlineedit.hpp b/components/contentselector/view/comboboxlineedit.hpp similarity index 96% rename from components/esxselector/view/comboboxlineedit.hpp rename to components/contentselector/view/comboboxlineedit.hpp index f3b251955..1aef2f57b 100644 --- a/components/esxselector/view/comboboxlineedit.hpp +++ b/components/contentselector/view/comboboxlineedit.hpp @@ -14,7 +14,7 @@ class QToolButton; -namespace EsxView +namespace ContentSelectorView { class ComboBoxLineEdit : public QLineEdit { diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp new file mode 100644 index 000000000..615e9a846 --- /dev/null +++ b/components/contentselector/view/contentselector.cpp @@ -0,0 +1,134 @@ +#include "contentselector.hpp" + +#include "../model/contentmodel.hpp" +#include "../model/esmfile.hpp" + +#include + +#include +#include +#include + +ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) : + QDialog(parent) +{ + setupUi(this); + + buildContentModel(); + buildGameFileView(); + buildAddonView(); + buildProfilesView(); + + updateViews(); + +} + +void ContentSelectorView::ContentSelector::buildContentModel() +{ + mContentModel = new ContentSelectorModel::ContentModel(); + connect(mContentModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); +} + +void ContentSelectorView::ContentSelector::buildGameFileView() +{ + mGameFileProxyModel = new QSortFilterProxyModel(this); + mGameFileProxyModel->setFilterRegExp(QString::number((int)ContentSelectorModel::ContentType_GameFile)); + mGameFileProxyModel->setFilterRole (Qt::UserRole); + mGameFileProxyModel->setSourceModel (mContentModel); + + gameFileView->setPlaceholderText(QString("Select a game file...")); + gameFileView->setModel(mGameFileProxyModel); + + connect(gameFileView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentGameFileIndexChanged(int))); + + gameFileView->setCurrentIndex(-1); + gameFileView->setCurrentIndex(0); +} + +void ContentSelectorView::ContentSelector::buildAddonView() +{ + mAddonProxyModel = new QSortFilterProxyModel(this); + mAddonProxyModel->setFilterRegExp (QString::number((int)ContentSelectorModel::ContentType_Addon)); + mAddonProxyModel->setFilterRole (Qt::UserRole); + mAddonProxyModel->setDynamicSortFilter (true); + mAddonProxyModel->setSourceModel (mContentModel); + + addonView->setModel(mAddonProxyModel); + + connect(addonView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotAddonTableItemClicked(const QModelIndex &))); +} + +void ContentSelectorView::ContentSelector::buildProfilesView() +{ + profilesComboBox->setPlaceholderText(QString("Select a profile...")); + connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); +} + +void ContentSelectorView::ContentSelector::updateViews() +{ + // Ensure the columns are hidden because sort() re-enables them + addonView->setColumnHidden(1, true); + addonView->setColumnHidden(2, true); + addonView->setColumnHidden(3, true); + addonView->setColumnHidden(4, true); + addonView->setColumnHidden(5, true); + addonView->setColumnHidden(6, true); + addonView->setColumnHidden(7, true); + addonView->setColumnHidden(8, true); + addonView->resizeColumnsToContents(); +} + +void ContentSelectorView::ContentSelector::addFiles(const QString &path) +{ + mContentModel->addFiles(path); + //mContentModel->sort(3); // Sort by date accessed + gameFileView->setCurrentIndex(-1); + mContentModel->uncheckAll(); +} + +QStringList ContentSelectorView::ContentSelector::checkedItemsPaths() +{ + QStringList itemPaths; + + foreach( const ContentSelectorModel::EsmFile *file, mContentModel->checkedItems()) + itemPaths << file->path(); + + return itemPaths; +} + +void ContentSelectorView::ContentSelector::slotCurrentProfileIndexChanged(int index) +{ + emit profileChanged(index); +} + +void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int index) +{ + static int oldIndex = -1; + + QAbstractItemModel *const model = gameFileView->model(); + QSortFilterProxyModel *proxy = dynamic_cast(model); + + if (proxy) + proxy->setDynamicSortFilter(false); + + if (oldIndex > -1) + model->setData(model->index(oldIndex, 0), false, Qt::UserRole + 1); + + oldIndex = index; + + model->setData(model->index(index, 0), true, Qt::UserRole + 1); + + if (proxy) + proxy->setDynamicSortFilter(true); +} + +void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QModelIndex &index) +{ + QAbstractItemModel *const model = addonView->model(); + QSortFilterProxyModel *proxy = dynamic_cast(model); + + if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked) + model->setData(index, Qt::Checked, Qt::CheckStateRole); + else + model->setData(index, Qt::Unchecked, Qt::CheckStateRole); +} diff --git a/components/esxselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp similarity index 51% rename from components/esxselector/view/contentselector.hpp rename to components/contentselector/view/contentselector.hpp index e074fe688..8032b0449 100644 --- a/components/esxselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -5,15 +5,11 @@ #include "ui_datafilespage.h" -namespace EsxModel -{ - class ContentModel; - class DataFilesModel; -} +namespace ContentSelectorModel { class ContentModel; } class QSortFilterProxyModel; -namespace EsxView +namespace ContentSelectorView { class ContentSelector : public QDialog, protected Ui::DataFilesPage { @@ -21,27 +17,25 @@ namespace EsxView protected: - EsxModel::DataFilesModel *mDataFilesModel; - EsxModel::ContentModel *mContentModel; - QSortFilterProxyModel *mMasterProxyModel; - QSortFilterProxyModel *mPluginsProxyModel; + ContentSelectorModel::ContentModel *mContentModel; + QSortFilterProxyModel *mGameFileProxyModel; + QSortFilterProxyModel *mAddonProxyModel; public: + explicit ContentSelector(QWidget *parent = 0); - void buildModelsAndViews(); + static ContentSelector &cast(QWidget *subject); //static constructor function for singleton performance. void addFiles(const QString &path); - void setEncoding(const QString &encoding); - void setPluginCheckState(); void setCheckState(QModelIndex index, QSortFilterProxyModel *model); QStringList checkedItemsPaths(); - void on_checkAction_triggered(); private: - void buildSourceModel(); - void buildMasterView(); - void buildPluginsView(); + + void buildContentModel(); + void buildGameFileView(); + void buildAddonView(); void buildProfilesView(); signals: @@ -50,8 +44,8 @@ namespace EsxView private slots: void updateViews(); void slotCurrentProfileIndexChanged(int index); - void slotCurrentMasterIndexChanged(int index); - void slotPluginTableItemClicked(const QModelIndex &index); + void slotCurrentGameFileIndexChanged(int index); + void slotAddonTableItemClicked(const QModelIndex &index); }; } diff --git a/components/esxselector/view/lineedit.cpp b/components/contentselector/view/lineedit.cpp similarity index 87% rename from components/esxselector/view/lineedit.cpp rename to components/contentselector/view/lineedit.cpp index 48be2f022..b6fdfa805 100644 --- a/components/esxselector/view/lineedit.cpp +++ b/components/contentselector/view/lineedit.cpp @@ -4,7 +4,7 @@ #include "lineedit.hpp" -EsxView::LineEdit::LineEdit(QWidget *parent) +ContentSelectorView::LineEdit::LineEdit(QWidget *parent) : QLineEdit(parent) { mClearButton = new QToolButton(this); @@ -25,7 +25,7 @@ EsxView::LineEdit::LineEdit(QWidget *parent) qMax(msz.height(), mClearButton->sizeHint().height() + frameWidth * 2 + 2)); } -void EsxView::LineEdit::resizeEvent(QResizeEvent *) +void ContentSelectorView::LineEdit::resizeEvent(QResizeEvent *) { QSize sz = mClearButton->sizeHint(); int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); @@ -33,7 +33,7 @@ void EsxView::LineEdit::resizeEvent(QResizeEvent *) (rect().bottom() + 1 - sz.height())/2); } -void EsxView::LineEdit::updateClearButton(const QString& text) +void ContentSelectorView::LineEdit::updateClearButton(const QString& text) { mClearButton->setVisible(!text.isEmpty()); } diff --git a/components/esxselector/view/lineedit.hpp b/components/contentselector/view/lineedit.hpp similarity index 96% rename from components/esxselector/view/lineedit.hpp rename to components/contentselector/view/lineedit.hpp index 4e0cbe339..ab1c37203 100644 --- a/components/esxselector/view/lineedit.hpp +++ b/components/contentselector/view/lineedit.hpp @@ -14,7 +14,7 @@ class QToolButton; -namespace EsxView +namespace ContentSelectorView { class LineEdit : public QLineEdit { diff --git a/components/esxselector/view/profilescombobox.cpp b/components/contentselector/view/profilescombobox.cpp similarity index 83% rename from components/esxselector/view/profilescombobox.cpp rename to components/contentselector/view/profilescombobox.cpp index 0d709aa50..cb0ba7b77 100644 --- a/components/esxselector/view/profilescombobox.cpp +++ b/components/contentselector/view/profilescombobox.cpp @@ -7,7 +7,7 @@ #include "profilescombobox.hpp" #include "comboboxlineedit.hpp" -EsxView::ProfilesComboBox::ProfilesComboBox(QWidget *parent) : +ContentSelectorView::ProfilesComboBox::ProfilesComboBox(QWidget *parent) : QComboBox(parent) { mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore @@ -21,7 +21,7 @@ EsxView::ProfilesComboBox::ProfilesComboBox(QWidget *parent) : setInsertPolicy(QComboBox::NoInsert); } -void EsxView::ProfilesComboBox::setEditEnabled(bool editable) +void ContentSelectorView::ProfilesComboBox::setEditEnabled(bool editable) { if (isEditable() == editable) return; @@ -47,7 +47,7 @@ void EsxView::ProfilesComboBox::setEditEnabled(bool editable) SLOT(slotTextChanged(QString))); } -void EsxView::ProfilesComboBox::slotTextChanged(const QString &text) +void ContentSelectorView::ProfilesComboBox::slotTextChanged(const QString &text) { QPalette *palette = new QPalette(); palette->setColor(QPalette::Text,Qt::red); @@ -61,7 +61,7 @@ void EsxView::ProfilesComboBox::slotTextChanged(const QString &text) } } -void EsxView::ProfilesComboBox::slotEditingFinished() +void ContentSelectorView::ProfilesComboBox::slotEditingFinished() { QString current = currentText(); QString previous = itemText(currentIndex()); @@ -82,7 +82,7 @@ void EsxView::ProfilesComboBox::slotEditingFinished() emit(profileRenamed(previous, current)); } -void EsxView::ProfilesComboBox::slotIndexChanged(int index) +void ContentSelectorView::ProfilesComboBox::slotIndexChanged(int index) { if (index == -1) return; @@ -91,7 +91,7 @@ void EsxView::ProfilesComboBox::slotIndexChanged(int index) mOldProfile = itemText(index); } -void EsxView::ProfilesComboBox::paintEvent(QPaintEvent *) +void ContentSelectorView::ProfilesComboBox::paintEvent(QPaintEvent *) { QStylePainter painter(this); painter.setPen(palette().color(QPalette::Text)); @@ -107,7 +107,7 @@ void EsxView::ProfilesComboBox::paintEvent(QPaintEvent *) painter.drawControl(QStyle::CE_ComboBoxLabel, opt); } -void EsxView::ProfilesComboBox::setPlaceholderText(const QString &text) +void ContentSelectorView::ProfilesComboBox::setPlaceholderText(const QString &text) { mPlaceholderText = text; } diff --git a/components/esxselector/view/profilescombobox.hpp b/components/contentselector/view/profilescombobox.hpp similarity index 96% rename from components/esxselector/view/profilescombobox.hpp rename to components/contentselector/view/profilescombobox.hpp index 28740783b..d81c1e6a5 100644 --- a/components/esxselector/view/profilescombobox.hpp +++ b/components/contentselector/view/profilescombobox.hpp @@ -6,7 +6,7 @@ class QString; class QRegExpValidator; -namespace EsxView +namespace ContentSelectorView { class ProfilesComboBox : public QComboBox { diff --git a/components/esm/esmreader.hpp b/components/esm/esmreader.hpp index edc724cd2..3bf194c4e 100644 --- a/components/esm/esmreader.hpp +++ b/components/esm/esmreader.hpp @@ -34,7 +34,7 @@ public: float getFVer() const { if(mHeader.mData.version == VER_12) return 1.2; else return 1.3; } const std::string getAuthor() const { return mHeader.mData.author.toString(); } const std::string getDesc() const { return mHeader.mData.desc.toString(); } - const std::vector &getMasters() const { return mHeader.mMaster; } + const std::vector &getGameFiles() const { return mHeader.mMaster; } int getFormat() const; const NAME &retSubName() const { return mCtx.subName; } uint32_t getSubSize() const { return mCtx.leftSub; } diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index d8d0c1291..9793391ed 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -172,7 +172,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref) // If the most significant 8 bits are used, then this reference already exists. // In this case, do not spawn a new reference, but overwrite the old one. ref.mRefnum &= 0x00ffffff; // delete old plugin ID - const std::vector &masters = esm.getMasters(); + const std::vector &masters = esm.getGameFiles(); global = masters[local-1].index + 1; ref.mRefnum |= global << 24; // insert global plugin ID } @@ -276,7 +276,7 @@ bool Cell::getNextMVRF(ESMReader &esm, MovedCellRef &mref) int local = (mref.mRefnum & 0xff000000) >> 24; size_t global = esm.getIndex() + 1; mref.mRefnum &= 0x00ffffff; // delete old plugin ID - const std::vector &masters = esm.getMasters(); + const std::vector &masters = esm.getGameFiles(); global = masters[local-1].index + 1; mref.mRefnum |= global << 24; // insert global plugin ID diff --git a/components/esxselector/model/datafilesmodel.cpp b/components/esxselector/model/datafilesmodel.cpp deleted file mode 100644 index c98f70b16..000000000 --- a/components/esxselector/model/datafilesmodel.cpp +++ /dev/null @@ -1,608 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include - -#include "esmfile.hpp" - -#include "datafilesmodel.hpp" - -#include - -EsxModel::DataFilesModel::DataFilesModel(QObject *parent) : - QAbstractTableModel(parent) -{ - mEncoding = QString("win1252"); -} - -EsxModel::DataFilesModel::~DataFilesModel() -{ -} - -int EsxModel::DataFilesModel::rowCount(const QModelIndex &parent) const -{ - return parent.isValid() ? 0 : mFiles.count(); -} - -int EsxModel::DataFilesModel::columnCount(const QModelIndex &parent) const -{ - return parent.isValid() ? 0 : 1; -} - -const EsxModel::EsmFile* EsxModel::DataFilesModel::findItem(const QString &name) -{ - for (int i = 0; i < mFiles.size(); ++i) - { - const EsmFile *file = item(i); - - if (name == file->fileName()) - return file; - } - - return 0; -} - -const EsxModel::EsmFile* EsxModel::DataFilesModel::item(int row) const -{ - if (row >= 0 && row < mFiles.count()) - return mFiles.at(row); - - return 0; -} - -Qt::ItemFlags EsxModel::DataFilesModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - return Qt::NoItemFlags; - - const EsmFile *file = item(index.row()); - - if (!file) - return Qt::NoItemFlags; - - Qt::ItemFlags dragDropFlags = Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; - Qt::ItemFlags checkFlags = Qt::ItemIsUserCheckable | Qt::ItemIsEditable; - Qt::ItemFlags defaultFlags = Qt::ItemIsDropEnabled | Qt::ItemIsSelectable; - - if (canBeChecked(file)) - return defaultFlags | dragDropFlags | checkFlags | Qt::ItemIsEnabled; - else - return defaultFlags; -} - -QVariant EsxModel::DataFilesModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if (index.row() >= mFiles.size()) - return QVariant(); - - const EsmFile *file = item(index.row()); - - if (!file) - return QVariant(); - - const int column = index.column(); - - switch (role) - { - 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(); - } - break; - } - - case Qt::TextAlignmentRole: - { - switch (column) - { - case 0: - case 1: - return Qt::AlignLeft + Qt::AlignVCenter; - case 2: - case 3: - return Qt::AlignRight + Qt::AlignVCenter; - default: - return Qt::AlignLeft + Qt::AlignVCenter; - } - break; - } - - case Qt::ToolTipRole: - { - if (column != 0) - return QVariant(); - - if (file->version() == 0.0f) - return QVariant(); // Data not set - - QString tooltip = - 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 tooltip; - break; - } - - case Qt::UserRole: - { - if (file->masters().size() == 0) - return "game"; - else - return "addon"; - - break; - } - - case Qt::UserRole + 1: - //return check state here - break; - - default: - return QVariant(); - break; - } - -} - -bool EsxModel::DataFilesModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (!index.isValid()) - return false; - - switch (role) - { - case Qt::EditRole: - { - const EsmFile *file = item(index.row()); - - // iterate loop to repopulate file pointer with data in string list. - QStringList list = value.toStringList(); - for (int i = 0; i <999; ++i) - { - file->setProperty(i, value.at(i)); - } - - //populate master list here (emit data changed for each master and - //each item (other than the dropped item) which share each of the masters - file->masters().append(masterList); - - emit dataChanged(index, index); - return true; - } - break; - - case Qt::UserRole + 1: - { - EsmFile *file = item(index.row()); - //set file's checkstate to the passed checkstate - emit dataChanged(index, index); - - for (int i = 0; i < mFiles.size(); ++i) - if (mFiles.at(i)->getMasters().contains(file->fileName())) - emit dataChanged(QAbstractTableModel::index(i,0), QAbstractTableModel::index(i,0)); - - return true; - } - break; - - case Qt::CheckStateRole: - { - EsmFile *file = item(index.row()); - - if ((value.toInt() == Qt::Checked) && !file->isChecked()) - file->setChecked(true); - else if (value.toInt() == Qt::Checked && file->isChecked()) - file->setChecked(false); - else if (value.toInt() == Qt::UnChecked) - file->setChecked(false); - - emit dataChanged(index, index); - - return true; - } - break; - } - return false; -} - -bool EsxModel::DataFilesModel::insertRows(int row, int count, const QModelIndex &parent) -{ - if (parent.isValid()) - return false; - - beginInsertRows(QModelIndex(),row, row+count-1); - { - for (int i = 0; i < count; ++i) - mFiles.insert(row, new EsmFile()); - } endInsertRows(); - - return true; -} - -bool EsxModel::DataFilesModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (parent.isValid()) - return false; - - beginRemoveRows(QModelIndex(), row, row+count-1); - { - for (int i = 0; i < count; ++i) - delete mFiles.takeAt(row); - } endRemoveRows(); - - return true; -} - -Qt::DropActions EsxModel::DataFilesModel::supportedDropActions() const -{ - return Qt::CopyAction | Qt::MoveAction; -} - -QStringList EsxModel::DataFilesModel::mimeTypes() const -{ - QStringList types; - types << "application/omwcontent"; - return types; -} - -QMimeData *EsxModel::DataFilesModel::mimeData(const QModelIndexList &indexes) const -{ - QMimeData *mimeData = new QMimeData(); - QByteArray encodedData; - - QDataStream stream (&encodedData, QIODevice::WriteOnly); - - foreach (const QModelIndex &index, indexes) - { - if (index.isValid()) - { - EsmFile *file = item (index.row()); - - for (int i = 0; i < file->propertyCount(); ++i) - stream << data(index, Qt::DisplayRole).toString(); - - EsmFile *file = item(index.row()); - stream << file->getMasters(); - } - } - - mimeData->setData("application/omwcontent", encodedData); - - return mimeData; -} - -bool EsxModel::DataFilesModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) -{ - if (action == Qt::IgnoreAction) - return true; - - if (action != Qt::MoveAction) - return false; - - if (!data->hasFormat("application/omwcontent")) - return false; - - int dropRow = row; - - if (dropRow == -1) - { - if (parent.isValid()) - dropRow = parent.row(); - else - dropRow = rowCount(QModelIndex()); - } - - if (parent.isValid()) - qDebug() << "parent: " << parent.data().toString(); - qDebug() << "dragged file: " << (qobject_cast(data))->fileName(); -// qDebug() << "inserting file: " << droppedfile->fileName() << " ahead of " << file->fileName(); - insertRows (dropRow, 1, QModelIndex()); - - - const EsmFile *draggedFile = qobject_cast(data); - - int dragRow = -1; - - for (int i = 0; i < mFiles.size(); ++i) - if (draggedFile->fileName() == mFiles.at(i)->fileName()) - { - dragRow = i; - break; - } - - for (int i = 0; i < mFiles.count(); ++i) - { - qDebug() << "index: " << i << "file: " << item(i)->fileName(); - qDebug() << mFiles.at(i)->fileName(); - } - - qDebug() << "drop row: " << dropRow << "; drag row: " << dragRow; -// const EsmFile *file = qobject_cast(data); - // int index = mFiles.indexOf(file); - //qDebug() << "file name: " << file->fileName() << "; index: " << index; - mFiles.swap(dropRow, dragRow); - //setData(index(startRow, 0), varFile); - emit dataChanged(index(0,0), index(rowCount(),0)); - return true; -} - -void EsxModel::DataFilesModel::setEncoding(const QString &encoding) -{ - mEncoding = encoding; -} - -void EsxModel::DataFilesModel::setCheckState(const QModelIndex &index, Qt::CheckState state) -{ - if (!index.isValid()) - return; - - QString name = item(index.row())->fileName(); - mCheckStates[name] = state; - - // Force a redraw of the view since unchecking one item can affect another - QModelIndex firstIndex = indexFromItem(mFiles.first()); - QModelIndex lastIndex = indexFromItem(mFiles.last()); - - emit dataChanged(firstIndex, lastIndex); - emit checkedItemsChanged(checkedItems()); - -} - -Qt::CheckState EsxModel::DataFilesModel::checkState(const QModelIndex &index) -{ - return mCheckStates[item(index.row())->fileName()]; -} - -bool EsxModel::DataFilesModel::moveRow(int oldrow, int row, const QModelIndex &parent) -{ - if (oldrow < 0 || row < 0 || oldrow == row) - return false; - - emit layoutAboutToBeChanged(); - //emit beginMoveRows(parent, oldrow, oldrow, parent, row); - mFiles.swap(oldrow, row); - //emit endInsertRows(); - emit layoutChanged(); - - return true; -} - -QVariant EsxModel::DataFilesModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role != Qt::DisplayRole) - return QVariant(); - - if (orientation == Qt::Horizontal) { - switch (section) { - case 0: return tr("Name"); - case 1: return tr("Author"); - case 2: return tr("Size"); - case 3: return tr("Modified"); - case 4: return tr("Accessed"); - case 5: return tr("Version"); - case 6: return tr("Path"); - case 7: return tr("Masters"); - case 8: return tr("Description"); - } - } - return QVariant(); -} - -//!!!!!!!!!!!!!!!!!!!!!!! -bool lessThanEsmFile(const EsxModel::EsmFile *e1, const EsxModel::EsmFile *e2) -{ - //Masters first then alphabetically - if (e1->fileName().endsWith(".esm") && !e2->fileName().endsWith(".esm")) - return true; - if (!e1->fileName().endsWith(".esm") && e2->fileName().endsWith(".esm")) - return false; - - return e1->fileName().toLower() < e2->fileName().toLower(); -} -//!!!!!!!!!!!!!!!!!!!!!!! -bool lessThanDate(const EsxModel::EsmFile *e1, const EsxModel::EsmFile *e2) -{ - if (e1->modified().toString(Qt::ISODate) < e2->modified().toString(Qt::ISODate)) - return true; - else - return false; -} -//!!!!!!!!!!!!!!!!!!!!!!! -void EsxModel::DataFilesModel::sort(int column, Qt::SortOrder order) -{ - emit layoutAboutToBeChanged(); - - if (column == 3) { - qSort(mFiles.begin(), mFiles.end(), lessThanDate); - } else { - qSort(mFiles.begin(), mFiles.end(), lessThanEsmFile); - } - - emit layoutChanged(); -} - -void EsxModel::DataFilesModel::addFile(const EsmFile *file) -{ - emit beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); - mFiles.append(file); - emit endInsertRows(); -} - -void EsxModel::DataFilesModel::addFiles(const QString &path) -{ - QDir dir(path); - QStringList filters; - filters << "*.esp" << "*.esm" << "*.omwgame" << "*.omwaddon"; - 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 = codec->makeDecoder(); - - 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())); - fileReader.setEncoder(&encoder); - fileReader.open(dir.absoluteFilePath(path).toStdString()); - - std::vector mlist = fileReader.getMasters(); - - QStringList masters; - - 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->setDates(info.lastModified(), info.lastRead()); - file->setVersion(fileReader.getFVer()); - file->setPath(info.absoluteFilePath()); - file->setMasters(masters); - file->setDescription(decoder->toUnicode(fileReader.getDesc().c_str())); - - - // Put the file in the table - if (findItem(path) == 0) - addFile(file); - - } catch(std::runtime_error &e) { - // An error occurred while reading the .esp - qWarning() << "Error reading addon file: " << e.what(); - continue; - } - - } - - delete decoder; -} - -QModelIndex EsxModel::DataFilesModel::indexFromItem(const EsmFile *item) const -{ - if (item) - //return createIndex(mFiles.indexOf(item), 0); - return index(mFiles.indexOf(item),0); - - return QModelIndex(); -} - -EsxModel::EsmFileList EsxModel::DataFilesModel::checkedItems() -{ - EsmFileList list; - - EsmFileList::ConstIterator it; - EsmFileList::ConstIterator itEnd = mFiles.constEnd(); - - for (it = mFiles.constBegin(); it != itEnd; ++it) - { - // Only add the items that are in the checked list and available - if (mCheckStates[(*it)->fileName()] == Qt::Checked && canBeChecked(*it)) - list << (*it); - } - - return list; -} - -QStringList EsxModel::DataFilesModel::checkedItemsPaths() -{ - QStringList list; - - EsmFileList::ConstIterator it; - EsmFileList::ConstIterator itEnd = mFiles.constEnd(); - - int i = 0; - for (it = mFiles.constBegin(); it != itEnd; ++it) { - const EsmFile *file = item(i); - ++i; - - if (mCheckStates[file->fileName()] == Qt::Checked && canBeChecked(file)) - list << file->path(); - } - - return list; -} -void EsxModel::DataFilesModel::uncheckAll() -{ - emit layoutAboutToBeChanged(); - mCheckStates.clear(); - emit layoutChanged(); -} - -/* -EsxModel::EsmFileList EsxModel::DataFilesModel::uncheckedItems() -{ - EsmFileList list; - EsmFileList checked = checkedItems(); - - EsmFileList::ConstIterator it; - - for (it = mFiles.constBegin(); it != mFiles.constEnd(); ++it) - { - const EsmFile *file = *it; - - // Add the items that are not in the checked list - if (!checked.contains(file)) - list << file; - } - - return list; -} -*/ -bool EsxModel::DataFilesModel::canBeChecked(const EsmFile *file) const -{ - //element can be checked if all its dependencies are - foreach (const QString &master, file->masters()) - { - if (!mCheckStates.contains(master) || mCheckStates[master] != Qt::Checked) - return false; - } - return true; -} diff --git a/components/esxselector/model/datafilesmodel.hpp b/components/esxselector/model/datafilesmodel.hpp deleted file mode 100644 index 4f23cd530..000000000 --- a/components/esxselector/model/datafilesmodel.hpp +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef DATAFILESMODEL_HPP -#define DATAFILESMODEL_HPP - -#include -#include -#include -#include - -namespace EsxModel -{ - class EsmFile; - - typedef QList EsmFileList; - - class DataFilesModel : public QAbstractTableModel - { - Q_OBJECT - - public: - explicit DataFilesModel(QObject *parent = 0); - virtual ~DataFilesModel(); - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent); - bool insertRows(int row, int count, const QModelIndex &parent); - - bool moveRow(int oldrow, int row, const QModelIndex &parent = QModelIndex()); - - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - - virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); - - inline QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const - { - QModelIndex idx = QAbstractTableModel::index(row, 0, parent); - return idx; - } - - void setEncoding(const QString &encoding); - - void addFiles(const QString &path); - - void uncheckAll(); - - Qt::DropActions supportedDropActions() const; - QStringList mimeTypes() const; - QMimeData *mimeData(const QModelIndexList &indexes) const; - bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); - - EsmFileList checkedItems(); - EsmFileList uncheckedItems(); - QStringList checkedItemsPaths(); - - Qt::CheckState checkState(const QModelIndex &index); - void setCheckState(const QModelIndex &index, Qt::CheckState state); - - QModelIndex indexFromItem(const EsmFile *item) const; - const EsmFile* findItem(const QString &name); - const EsmFile* item(int row) const; - - signals: - void checkedItemsChanged(const EsmFileList &items); - - private: - - bool canBeChecked(const EsmFile *file) const; - void addFile(const EsmFile *file); - - EsmFileList mFiles; - QHash mCheckStates; - - QString mEncoding; - - }; -} -#endif // DATAFILESMODEL_HPP diff --git a/components/esxselector/model/masterproxymodel.cpp b/components/esxselector/model/masterproxymodel.cpp deleted file mode 100644 index df74d0356..000000000 --- a/components/esxselector/model/masterproxymodel.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "masterproxymodel.hpp" -#include -#include - -EsxModel::MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableModel* model) : - QSortFilterProxyModel(parent) -{ - setFilterRegExp(QString("game")); - setFilterRole (Qt::UserRole); - - if (model) - setSourceModel (model); -} diff --git a/components/esxselector/model/masterproxymodel.hpp b/components/esxselector/model/masterproxymodel.hpp deleted file mode 100644 index 8a5c73032..000000000 --- a/components/esxselector/model/masterproxymodel.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef MASTERPROXYMODEL_HPP -#define MASTERPROXYMODEL_HPP - -#include -#include -#include - -class QAbstractTableModel; - -namespace EsxModel -{ - class MasterProxyModel : public QSortFilterProxyModel - { - Q_OBJECT - public: - explicit MasterProxyModel(QObject *parent = 0, QAbstractTableModel *model = 0); - // virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - - signals: - - public slots: - void slotSourceModelChanged(QModelIndex topLeft, QModelIndex botRight); - }; -} -#endif // MASTERPROXYMODEL_HPP diff --git a/components/esxselector/model/modelitem.cpp b/components/esxselector/model/modelitem.cpp deleted file mode 100644 index 03b19f691..000000000 --- a/components/esxselector/model/modelitem.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "modelitem.hpp" - -EsxModel::ModelItem::ModelItem(ModelItem *parent) - : mParentItem(parent) -{ -} -/* -EsxModel::ModelItem::ModelItem(const ModelItem *parent) - // : mParentItem(parent) -{ -} -*/ - -EsxModel::ModelItem::~ModelItem() -{ - qDeleteAll(mChildItems); -} - - -EsxModel::ModelItem *EsxModel::ModelItem::parent() const -{ - return mParentItem; -} - -bool EsxModel::ModelItem::hasFormat(const QString &mimetype) const -{ - if (mimetype == "application/omwcontent") - return true; - - return QMimeData::hasFormat(mimetype); -} -int EsxModel::ModelItem::row() const -{ - if (mParentItem) - return 1; - //return mParentItem->childRow(const_cast(this)); - //return mParentItem->mChildItems.indexOf(const_cast(this)); - - return -1; -} - - -int EsxModel::ModelItem::childCount() const -{ - return mChildItems.count(); -} - -int EsxModel::ModelItem::childRow(ModelItem *child) const -{ - Q_ASSERT(child); - - return mChildItems.indexOf(child); -} - -EsxModel::ModelItem *EsxModel::ModelItem::child(int row) -{ - return mChildItems.value(row); -} - - -void EsxModel::ModelItem::appendChild(ModelItem *item) -{ - mChildItems.append(item); -} - -void EsxModel::ModelItem::removeChild(int row) -{ - mChildItems.removeAt(row); -} diff --git a/components/esxselector/model/pluginsproxymodel.cpp b/components/esxselector/model/pluginsproxymodel.cpp deleted file mode 100644 index c543672b0..000000000 --- a/components/esxselector/model/pluginsproxymodel.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "pluginsproxymodel.hpp" -#include "contentmodel.hpp" -#include - -EsxModel::PluginsProxyModel::PluginsProxyModel(QObject *parent, ContentModel *model) : - QSortFilterProxyModel(parent) -{ - setFilterRegExp (QString("addon")); - setFilterRole (Qt::UserRole); - setDynamicSortFilter (true); - - if (model) - setSourceModel (model); -} diff --git a/components/esxselector/model/pluginsproxymodel.hpp b/components/esxselector/model/pluginsproxymodel.hpp deleted file mode 100644 index 4415df716..000000000 --- a/components/esxselector/model/pluginsproxymodel.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef PLUGINSPROXYMODEL_HPP -#define PLUGINSPROXYMODEL_HPP - -#include - -class QVariant; -class QAbstractTableModel; - -namespace EsxModel -{ - class ContentModel; - - class PluginsProxyModel : public QSortFilterProxyModel - { - Q_OBJECT - - public: - - explicit PluginsProxyModel(QObject *parent = 0, ContentModel *model = 0); - ~PluginsProxyModel(); - - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - - bool removeRows(int row, int count, const QModelIndex &parent); - }; -} - -#endif // PLUGINSPROXYMODEL_HPP diff --git a/components/esxselector/model/sourcemodel.cpp b/components/esxselector/model/sourcemodel.cpp deleted file mode 100644 index 7b54adba9..000000000 --- a/components/esxselector/model/sourcemodel.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "sourcemodel.h" - -SourceModel::SourceModel(QObject *parent) : - QAbstractTableClass(parent) -{ -} diff --git a/components/esxselector/model/sourcemodel.h b/components/esxselector/model/sourcemodel.h deleted file mode 100644 index cf5145675..000000000 --- a/components/esxselector/model/sourcemodel.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef SOURCEMODEL_H -#define SOURCEMODEL_H - -#include - -class SourceModel : public QAbstractTableClass -{ - Q_OBJECT -public: - explicit SourceModel(QObject *parent = 0); - -signals: - -public slots: - -}; - -#endif // SOURCEMODEL_H diff --git a/components/esxselector/view/contentselector.cpp b/components/esxselector/view/contentselector.cpp deleted file mode 100644 index 4f8ac7253..000000000 --- a/components/esxselector/view/contentselector.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include "contentselector.hpp" - -#include "../model/datafilesmodel.hpp" -#include "../model/contentmodel.hpp" -#include "../model/esmfile.hpp" - -#include - -#include -#include -#include - -EsxView::ContentSelector::ContentSelector(QWidget *parent) : - QDialog(parent) -{ - setupUi(this); - - buildSourceModel(); - buildMasterView(); - buildPluginsView(); - buildProfilesView(); - - updateViews(); - -} - -void EsxView::ContentSelector::buildSourceModel() -{ - mContentModel = new EsxModel::ContentModel(); - connect(mContentModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); -} - -void EsxView::ContentSelector::buildMasterView() -{ - mMasterProxyModel = new QSortFilterProxyModel(this); - mMasterProxyModel->setFilterRegExp(QString("game")); - mMasterProxyModel->setFilterRole (Qt::UserRole); - mMasterProxyModel->setSourceModel (mContentModel); - - masterView->setPlaceholderText(QString("Select a game file...")); - masterView->setModel(mMasterProxyModel); - - connect(masterView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentMasterIndexChanged(int))); - - masterView->setCurrentIndex(-1); - masterView->setCurrentIndex(0); -} - -void EsxView::ContentSelector::buildPluginsView() -{ - mPluginsProxyModel = new QSortFilterProxyModel(this); - mPluginsProxyModel->setFilterRegExp (QString("addon")); - mPluginsProxyModel->setFilterRole (Qt::UserRole); - mPluginsProxyModel->setDynamicSortFilter (true); - mPluginsProxyModel->setSourceModel (mContentModel); - - pluginView->setModel(mPluginsProxyModel); - - connect(pluginView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotPluginTableItemClicked(const QModelIndex &))); -} - -void EsxView::ContentSelector::buildProfilesView() -{ - profilesComboBox->setPlaceholderText(QString("Select a profile...")); - connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); -} - -void EsxView::ContentSelector::updateViews() -{ - // Ensure the columns are hidden because sort() re-enables them - pluginView->setColumnHidden(1, true); - pluginView->setColumnHidden(2, true); - pluginView->setColumnHidden(3, true); - pluginView->setColumnHidden(4, true); - pluginView->setColumnHidden(5, true); - pluginView->setColumnHidden(6, true); - pluginView->setColumnHidden(7, true); - pluginView->setColumnHidden(8, true); - pluginView->resizeColumnsToContents(); -} - -void EsxView::ContentSelector::addFiles(const QString &path) -{ - mContentModel->addFiles(path); - mContentModel->sort(3); // Sort by date accessed - masterView->setCurrentIndex(-1); - mContentModel->uncheckAll(); -} - -void EsxView::ContentSelector::setEncoding(const QString &encoding) -{ - mContentModel->setEncoding(encoding); -} - -QStringList EsxView::ContentSelector::checkedItemsPaths() -{ - QStringList itemPaths; - - foreach( const EsxModel::EsmFile *file, mContentModel->checkedItems()) - itemPaths << file->path(); - - return itemPaths; -} - -void EsxView::ContentSelector::slotCurrentProfileIndexChanged(int index) -{ - emit profileChanged(index); -} - -void EsxView::ContentSelector::slotCurrentMasterIndexChanged(int index) -{ - static int oldIndex = -1; - - QAbstractItemModel *const model = masterView->model(); - QSortFilterProxyModel *proxy = dynamic_cast(model); - - if (proxy) - 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) - proxy->setDynamicSortFilter(true); -} - -void EsxView::ContentSelector::slotPluginTableItemClicked(const QModelIndex &index) -{ - QAbstractItemModel *const model = pluginView->model(); - QSortFilterProxyModel *proxy = dynamic_cast(model); - - if (proxy) - proxy->setDynamicSortFilter(false); - - if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked) - model->setData(index, Qt::Checked, Qt::CheckStateRole); - else - model->setData(index, Qt::Unchecked, Qt::CheckStateRole); - - if (proxy) - proxy->setDynamicSortFilter(true); -} diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 5b0a6d229..82d00922b 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -23,7 +23,7 @@ - + false @@ -34,7 +34,7 @@ - + 0 @@ -102,7 +102,7 @@ - + Enter project name... @@ -159,7 +159,7 @@ 6 - + true @@ -251,12 +251,12 @@ EsxView::ProfilesComboBox QComboBox -
components/esxselector/view/profilescombobox.hpp
+
components/contentselector/view/profilescombobox.hpp
EsxView::LineEdit QLineEdit -
components/esxselector/view/lineedit.hpp
+
components/contentselector/view/lineedit.hpp