From bfb71f23c9f2e1c3b9f6525ef1ed8b1185425c6d Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 16 Aug 2013 17:26:23 -0500 Subject: [PATCH 001/118] Changed filter mechanism for game / addons Filters by number of master references, regardless of extension --- apps/opencs/view/doc/filedialog.cpp | 8 ++++---- components/fileorderlist/model/datafilesmodel.cpp | 9 +++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index f956317a7..02421a788 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -25,13 +25,13 @@ FileDialog::FileDialog(QWidget *parent) : mDataFilesModel = new DataFilesModel(this); mMastersProxyModel = new QSortFilterProxyModel(); - mMastersProxyModel->setFilterRegExp(QString("^.*\\.esm")); - mMastersProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + mMastersProxyModel->setFilterRegExp("game"); //QString("^.*\\.esm")); + mMastersProxyModel->setFilterRole (Qt::UserRole); mMastersProxyModel->setSourceModel(mDataFilesModel); mPluginsProxyModel = new PluginsProxyModel(); - mPluginsProxyModel->setFilterRegExp(QString("^.*\\.esp")); - mPluginsProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + mPluginsProxyModel->setFilterRegExp("addon"); //QString("^.*\\.esp")); + mPluginsProxyModel->setFilterRole (Qt::UserRole); mPluginsProxyModel->setSourceModel(mDataFilesModel); mFilterProxyModel = new QSortFilterProxyModel(); diff --git a/components/fileorderlist/model/datafilesmodel.cpp b/components/fileorderlist/model/datafilesmodel.cpp index 02a6766b0..cf1fa1b0a 100644 --- a/components/fileorderlist/model/datafilesmodel.cpp +++ b/components/fileorderlist/model/datafilesmodel.cpp @@ -144,6 +144,15 @@ QVariant DataFilesModel::data(const QModelIndex &index, int role) const return tooltip; } + + case Qt::UserRole: + { + if (file->masters().size() == 0) + return "game"; + else + return "addon"; + } + default: return QVariant(); } From 84e5c2610ab0347127645e277f08dd83e11383fd Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 16 Aug 2013 18:00:23 -0500 Subject: [PATCH 002/118] Implemented combobox for game file selection --- apps/launcher/datafilespage.cpp | 2 +- apps/opencs/view/doc/filedialog.cpp | 20 +++++++------- apps/opencs/view/doc/filedialog.hpp | 2 +- .../fileorderlist/utils/profilescombobox.cpp | 16 +++++++++++ .../fileorderlist/utils/profilescombobox.hpp | 5 +++- files/ui/datafilespage.ui | 27 +++---------------- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index add3dea40..1fafd5922 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -101,7 +101,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); - connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); + //connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); connect(splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(updateSplitter())); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 02421a788..b06c97008 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -41,6 +41,8 @@ FileDialog::FileDialog(QWidget *parent) : QCheckBox checkBox; unsigned int height = checkBox.sizeHint().height() + 4; + masterView->setModel(mMastersProxyModel); + mastersTable->setModel(mMastersProxyModel); mastersTable->setObjectName("MastersTable"); mastersTable->setContextMenuPolicy(Qt::CustomContextMenu); @@ -83,12 +85,12 @@ FileDialog::FileDialog(QWidget *parent) : mNameLabel = new QLabel(tr("File Name:"), this); QRegExpValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9\\s]*$")); - mNameLineEdit = new LineEdit(this); - mNameLineEdit->setValidator(validator); + //mNameLineEdit = new LineEdit(this); + //mNameLineEdit->setValidator(validator); nameLayout->addSpacerItem(spacer); nameLayout->addWidget(mNameLabel); - nameLayout->addWidget(mNameLineEdit); + //nameLayout->addWidget(mNameLineEdit); mButtonBox = new QDialogButtonBox(this); @@ -109,9 +111,9 @@ FileDialog::FileDialog(QWidget *parent) : connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); connect(mDataFilesModel, SIGNAL(checkedItemsChanged(QStringList)), this, SLOT(updateOpenButton(QStringList))); - connect(mNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateCreateButton(QString))); + //connect(mNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateCreateButton(QString))); - connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); + //connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); connect(pluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); connect(mastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); @@ -223,7 +225,7 @@ QStringList FileDialog::checkedItemsPaths() QString FileDialog::fileName() { - return mNameLineEdit->text(); + //return mNameLineEdit->text(); } void FileDialog::openFile() @@ -231,7 +233,7 @@ void FileDialog::openFile() setWindowTitle(tr("Open")); mNameLabel->hide(); - mNameLineEdit->hide(); + //mNameLineEdit->hide(); mCreateButton->hide(); mButtonBox->removeButton(mCreateButton); @@ -249,8 +251,8 @@ void FileDialog::newFile() setWindowTitle(tr("New")); mNameLabel->show(); - mNameLineEdit->clear(); - mNameLineEdit->show(); + //mNameLineEdit->clear(); + //mNameLineEdit->show(); mCreateButton->show(); mButtonBox->setStandardButtons(QDialogButtonBox::Cancel); diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index b21618d5d..4c3fe9ffa 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -51,7 +51,7 @@ private slots: private: QLabel *mNameLabel; - LineEdit *mNameLineEdit; + //LineEdit *mNameLineEdit; QPushButton *mCreateButton; QDialogButtonBox *mButtonBox; diff --git a/components/fileorderlist/utils/profilescombobox.cpp b/components/fileorderlist/utils/profilescombobox.cpp index c3ff953ae..9346276da 100644 --- a/components/fileorderlist/utils/profilescombobox.cpp +++ b/components/fileorderlist/utils/profilescombobox.cpp @@ -90,3 +90,19 @@ void ProfilesComboBox::slotIndexChanged(int index) emit(profileChanged(mOldProfile, currentText())); mOldProfile = itemText(index); } + +void ProfilesComboBox::paintEvent(QPaintEvent *) +{ + QStylePainter painter(this); + painter.setPen(palette().color(QPalette::Text)); + + // draw the combobox frame, focusrect and selected etc. + QStyleOptionComboBox opt; + initStyleOption(&opt); + painter.drawComplexControl(QStyle::CC_ComboBox, opt); + + // draw the icon and text + if (!opt.editable && currentIndex() == -1) // <<< we adjust the text displayed when nothing is selected + opt.currentText = tr("Select a game file..."); + painter.drawControl(QStyle::CE_ComboBoxLabel, opt); +} diff --git a/components/fileorderlist/utils/profilescombobox.hpp b/components/fileorderlist/utils/profilescombobox.hpp index 08ead9a7a..55913d7fe 100644 --- a/components/fileorderlist/utils/profilescombobox.hpp +++ b/components/fileorderlist/utils/profilescombobox.hpp @@ -2,7 +2,7 @@ #define PROFILESCOMBOBOX_HPP #include - +#include class QString; class QRegExpValidator; @@ -25,6 +25,9 @@ private slots: private: QString mOldProfile; QRegExpValidator *mValidator; + +protected: + void paintEvent(QPaintEvent *); }; #endif // PROFILESCOMBOBOX_HPP diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 041a9576d..342e4d9e9 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -14,28 +14,12 @@ - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Filter: + + + false - - - @@ -151,11 +135,6 @@ - - LineEdit - QLineEdit -
components/fileorderlist/utils/lineedit.hpp
-
ProfilesComboBox QComboBox From 49c4e1bf9eccd1efd91c371a22e0810a5c8cb815 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 16 Aug 2013 18:23:02 -0500 Subject: [PATCH 003/118] Removed master table widget --- apps/launcher/datafilespage.cpp | 34 +++++++++++++++-------------- apps/opencs/view/doc/filedialog.cpp | 9 ++++---- files/ui/datafilespage.ui | 1 - 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 1fafd5922..077f3c292 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -47,7 +47,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam QCheckBox checkBox; unsigned int height = checkBox.sizeHint().height() + 4; - +/* mastersTable->setModel(mMastersProxyModel); mastersTable->setObjectName("MastersTable"); mastersTable->setContextMenuPolicy(Qt::CustomContextMenu); @@ -63,7 +63,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam mastersTable->verticalHeader()->setDefaultSectionSize(height); mastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); mastersTable->verticalHeader()->hide(); - +*/ pluginsTable->setModel(mFilterProxyModel); pluginsTable->setObjectName("PluginsTable"); pluginsTable->setContextMenuPolicy(Qt::CustomContextMenu); @@ -94,10 +94,10 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString))); connect(pluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); - connect(mastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); + //connect(mastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); connect(pluginsTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); - connect(mastersTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); + //connect(mastersTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); @@ -255,6 +255,7 @@ void DataFilesPage::updateSplitter() void DataFilesPage::updateViews() { // Ensure the columns are hidden because sort() re-enables them + /* mastersTable->setColumnHidden(1, true); mastersTable->setColumnHidden(2, true); mastersTable->setColumnHidden(3, true); @@ -263,7 +264,7 @@ void DataFilesPage::updateViews() mastersTable->setColumnHidden(6, true); mastersTable->setColumnHidden(7, true); mastersTable->setColumnHidden(8, true); - +*/ pluginsTable->setColumnHidden(1, true); pluginsTable->setColumnHidden(2, true); pluginsTable->setColumnHidden(3, true); @@ -335,8 +336,8 @@ void DataFilesPage::on_checkAction_triggered() if (pluginsTable->hasFocus()) setPluginsCheckstates(Qt::Checked); - if (mastersTable->hasFocus()) - setMastersCheckstates(Qt::Checked); + //if (mastersTable->hasFocus()) + // setMastersCheckstates(Qt::Checked); } @@ -345,17 +346,17 @@ void DataFilesPage::on_uncheckAction_triggered() if (pluginsTable->hasFocus()) setPluginsCheckstates(Qt::Unchecked); - if (mastersTable->hasFocus()) - setMastersCheckstates(Qt::Unchecked); + //if (mastersTable->hasFocus()) + // setMastersCheckstates(Qt::Unchecked); } void DataFilesPage::setMastersCheckstates(Qt::CheckState state) -{ - if (!mastersTable->selectionModel()->hasSelection()) { - return; - } +{/* + //if (!mastersTable->selectionModel()->hasSelection()) { + // return; + //} - QModelIndexList indexes = mastersTable->selectionModel()->selectedIndexes(); + //QModelIndexList indexes = mastersTable->selectionModel()->selectedIndexes(); foreach (const QModelIndex &index, indexes) { @@ -368,7 +369,7 @@ void DataFilesPage::setMastersCheckstates(Qt::CheckState state) return; mDataFilesModel->setCheckState(sourceIndex, state); - } + }*/ } void DataFilesPage::setPluginsCheckstates(Qt::CheckState state) @@ -519,7 +520,7 @@ void DataFilesPage::showContextMenu(const QPoint &point) // Show menu mContextMenu->exec(globalPos); } - +/* if (object->objectName() == QLatin1String("MastersTable")) { if (!mastersTable->selectionModel()->hasSelection()) return; @@ -548,4 +549,5 @@ void DataFilesPage::showContextMenu(const QPoint &point) mContextMenu->exec(globalPos); } + */ } diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index b06c97008..a07b854df 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -42,7 +42,7 @@ FileDialog::FileDialog(QWidget *parent) : unsigned int height = checkBox.sizeHint().height() + 4; masterView->setModel(mMastersProxyModel); - +/* mastersTable->setModel(mMastersProxyModel); mastersTable->setObjectName("MastersTable"); mastersTable->setContextMenuPolicy(Qt::CustomContextMenu); @@ -57,7 +57,7 @@ FileDialog::FileDialog(QWidget *parent) : mastersTable->verticalHeader()->setDefaultSectionSize(height); mastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); mastersTable->verticalHeader()->hide(); - +*/ pluginsTable->setModel(mFilterProxyModel); pluginsTable->setObjectName("PluginsTable"); pluginsTable->setContextMenuPolicy(Qt::CustomContextMenu); @@ -116,7 +116,7 @@ FileDialog::FileDialog(QWidget *parent) : //connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); connect(pluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); - connect(mastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); + //connect(mastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); connect(mCreateButton, SIGNAL(clicked()), this, SLOT(createButtonClicked())); @@ -127,6 +127,7 @@ FileDialog::FileDialog(QWidget *parent) : void FileDialog::updateViews() { // Ensure the columns are hidden because sort() re-enables them + /* mastersTable->setColumnHidden(1, true); mastersTable->setColumnHidden(3, true); mastersTable->setColumnHidden(4, true); @@ -135,7 +136,7 @@ void FileDialog::updateViews() mastersTable->setColumnHidden(7, true); mastersTable->setColumnHidden(8, true); mastersTable->resizeColumnsToContents(); - +*/ pluginsTable->setColumnHidden(1, true); pluginsTable->setColumnHidden(3, true); pluginsTable->setColumnHidden(4, true); diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 342e4d9e9..816d288a6 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -36,7 +36,6 @@ false -
From b850fe02895dca508685d1ebbabb647f1e71c048 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 16 Aug 2013 18:59:01 -0500 Subject: [PATCH 004/118] Removed vertical headers from plugin view --- apps/launcher/datafilespage.cpp | 6 ++++-- components/fileorderlist/model/datafilesmodel.cpp | 4 ++-- components/fileorderlist/model/pluginsproxymodel.cpp | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 077f3c292..fe2fe8255 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -32,12 +32,14 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam mDataFilesModel = new DataFilesModel(this); mMastersProxyModel = new QSortFilterProxyModel(); - mMastersProxyModel->setFilterRegExp(QString("^.*\\.esm")); + mMastersProxyModel->setFilterRegExp(QString("game")); //QString("^.*\\.esm")); + mMastersProxyModel->setFilterRole (Qt::UserRole); mMastersProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); mMastersProxyModel->setSourceModel(mDataFilesModel); mPluginsProxyModel = new PluginsProxyModel(); - mPluginsProxyModel->setFilterRegExp(QString("^.*\\.esp")); + mPluginsProxyModel->setFilterRegExp(QString("addon")); //^.*\\.esp")); + mPluginsProxyModel->setFilterRole (Qt::UserRole); mPluginsProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); mPluginsProxyModel->setSourceModel(mDataFilesModel); diff --git a/components/fileorderlist/model/datafilesmodel.cpp b/components/fileorderlist/model/datafilesmodel.cpp index cf1fa1b0a..99c1aaebf 100644 --- a/components/fileorderlist/model/datafilesmodel.cpp +++ b/components/fileorderlist/model/datafilesmodel.cpp @@ -202,11 +202,11 @@ QVariant DataFilesModel::headerData(int section, Qt::Orientation orientation, in case 7: return tr("Masters"); case 8: return tr("Description"); } - } else { + } /* else { // Show row numbers return ++section; } - +*/ return QVariant(); } diff --git a/components/fileorderlist/model/pluginsproxymodel.cpp b/components/fileorderlist/model/pluginsproxymodel.cpp index 6be152b55..726a3f158 100644 --- a/components/fileorderlist/model/pluginsproxymodel.cpp +++ b/components/fileorderlist/model/pluginsproxymodel.cpp @@ -11,7 +11,7 @@ PluginsProxyModel::~PluginsProxyModel() QVariant PluginsProxyModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation != Qt::Vertical || role != Qt::DisplayRole) + //if (orientation != Qt::Vertical || role != Qt::DisplayRole) return QSortFilterProxyModel::headerData(section, orientation, role); - return section + 1; + // return section + 1; } From 2bc56d0b5c092a2e230281d55da9bdcecbc7e81c Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 16 Aug 2013 20:59:58 -0500 Subject: [PATCH 005/118] Fixed missing item list in launcher combobox --- apps/launcher/datafilespage.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index fe2fe8255..ddeb43ab7 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -47,6 +47,8 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam mFilterProxyModel->setDynamicSortFilter(true); mFilterProxyModel->setSourceModel(mPluginsProxyModel); + masterView->setModel (mMastersProxyModel); + QCheckBox checkBox; unsigned int height = checkBox.sizeHint().height() + 4; /* From 7389507eb52d2dadda0eba4f52624eb2d6f63360 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 16 Aug 2013 21:12:30 -0500 Subject: [PATCH 006/118] Created masterproxylist class --- apps/launcher/datafilespage.cpp | 7 ++++--- apps/opencs/view/doc/filedialog.cpp | 4 +++- components/CMakeLists.txt | 1 + components/fileorderlist/masterproxymodel.cpp | 11 +++++++++++ components/fileorderlist/masterproxymodel.hpp | 19 +++++++++++++++++++ .../fileorderlist/model/pluginsproxymodel.cpp | 6 ++---- .../fileorderlist/model/pluginsproxymodel.hpp | 2 +- 7 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 components/fileorderlist/masterproxymodel.cpp create mode 100644 components/fileorderlist/masterproxymodel.hpp diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index ddeb43ab7..f674e9dc7 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -48,9 +48,10 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam mFilterProxyModel->setSourceModel(mPluginsProxyModel); masterView->setModel (mMastersProxyModel); - +/* QCheckBox checkBox; unsigned int height = checkBox.sizeHint().height() + 4; + */ /* mastersTable->setModel(mMastersProxyModel); mastersTable->setObjectName("MastersTable"); @@ -80,8 +81,8 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam pluginsTable->horizontalHeader()->setStretchLastSection(true); pluginsTable->horizontalHeader()->hide(); - pluginsTable->verticalHeader()->setDefaultSectionSize(height); - pluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); + //pluginsTable->verticalHeader()->setDefaultSectionSize(height); + //pluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); // Adjust the tableview widths inside the splitter QList sizeList; diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index a07b854df..d49906949 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -16,6 +16,8 @@ #include +#include "components/fileorderlist/masterproxymodel.hpp" + FileDialog::FileDialog(QWidget *parent) : QDialog(parent) { @@ -24,7 +26,7 @@ FileDialog::FileDialog(QWidget *parent) : // Models mDataFilesModel = new DataFilesModel(this); - mMastersProxyModel = new QSortFilterProxyModel(); + mMastersProxyModel = new MasterProxyModel(); mMastersProxyModel->setFilterRegExp("game"); //QString("^.*\\.esm")); mMastersProxyModel->setFilterRole (Qt::UserRole); mMastersProxyModel->setSourceModel(mDataFilesModel); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 529891b4c..bbaca4805 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -70,6 +70,7 @@ find_package(Qt4 COMPONENTS QtCore QtGui) if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) add_component_qt_dir (fileorderlist + masterproxymodel model/modelitem model/datafilesmodel model/pluginsproxymodel model/esm/esmfile utils/profilescombobox utils/comboboxlineedit utils/lineedit utils/naturalsort ) diff --git a/components/fileorderlist/masterproxymodel.cpp b/components/fileorderlist/masterproxymodel.cpp new file mode 100644 index 000000000..ce874318d --- /dev/null +++ b/components/fileorderlist/masterproxymodel.cpp @@ -0,0 +1,11 @@ +#include "masterproxymodel.hpp" + +MasterProxyModel::MasterProxyModel(QObject *parent) : + QSortFilterProxyModel(parent) +{ +} + +QVariant MasterProxyModel::data(const QModelIndex &index, int role) const +{ + return QSortFilterProxyModel::data (index, role); +} diff --git a/components/fileorderlist/masterproxymodel.hpp b/components/fileorderlist/masterproxymodel.hpp new file mode 100644 index 000000000..d0d288873 --- /dev/null +++ b/components/fileorderlist/masterproxymodel.hpp @@ -0,0 +1,19 @@ +#ifndef MASTERPROXYMODEL_HPP +#define MASTERPROXYMODEL_HPP + +#include + +class MasterProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + explicit MasterProxyModel(QObject *parent = 0); + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + +signals: + +public slots: + +}; + +#endif // MASTERPROXYMODEL_HPP diff --git a/components/fileorderlist/model/pluginsproxymodel.cpp b/components/fileorderlist/model/pluginsproxymodel.cpp index 726a3f158..4648d2833 100644 --- a/components/fileorderlist/model/pluginsproxymodel.cpp +++ b/components/fileorderlist/model/pluginsproxymodel.cpp @@ -9,9 +9,7 @@ PluginsProxyModel::~PluginsProxyModel() { } -QVariant PluginsProxyModel::headerData(int section, Qt::Orientation orientation, int role) const +QVariant PluginsProxyModel::data(const QModelIndex &index, int role) const { - //if (orientation != Qt::Vertical || role != Qt::DisplayRole) - return QSortFilterProxyModel::headerData(section, orientation, role); - // return section + 1; + return QSortFilterProxyModel::data (index, role); } diff --git a/components/fileorderlist/model/pluginsproxymodel.hpp b/components/fileorderlist/model/pluginsproxymodel.hpp index 8fde73236..08baa2338 100644 --- a/components/fileorderlist/model/pluginsproxymodel.hpp +++ b/components/fileorderlist/model/pluginsproxymodel.hpp @@ -12,7 +12,7 @@ public: explicit PluginsProxyModel(QObject *parent = 0); ~PluginsProxyModel(); - QVariant headerData(int section, Qt::Orientation orientation, int role) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; }; #endif // PLUGINSPROXYMODEL_HPP From 4c8c6d697119c84d6ac27233cb480483074d6f66 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 16 Aug 2013 21:20:48 -0500 Subject: [PATCH 007/118] Moved init code to master / plugin proxy classes --- apps/launcher/datafilespage.cpp | 19 ++++++------------ apps/opencs/view/doc/filedialog.cpp | 20 +++++++------------ components/fileorderlist/masterproxymodel.cpp | 7 ++++++- components/fileorderlist/masterproxymodel.hpp | 4 +++- .../fileorderlist/model/pluginsproxymodel.cpp | 7 ++++++- .../fileorderlist/model/pluginsproxymodel.hpp | 3 ++- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index f674e9dc7..42e10c76b 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -15,6 +15,7 @@ #include #include +#include "a.out.h" #include "settings/gamesettings.hpp" #include "settings/launchersettings.hpp" @@ -29,19 +30,11 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam setupUi(this); // Models - mDataFilesModel = new DataFilesModel(this); - - mMastersProxyModel = new QSortFilterProxyModel(); - mMastersProxyModel->setFilterRegExp(QString("game")); //QString("^.*\\.esm")); - mMastersProxyModel->setFilterRole (Qt::UserRole); - mMastersProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); - mMastersProxyModel->setSourceModel(mDataFilesModel); - - mPluginsProxyModel = new PluginsProxyModel(); - mPluginsProxyModel->setFilterRegExp(QString("addon")); //^.*\\.esp")); - mPluginsProxyModel->setFilterRole (Qt::UserRole); - mPluginsProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); - mPluginsProxyModel->setSourceModel(mDataFilesModel); + mDataFilesModel = new DataFilesModel (this); + + mMastersProxyModel = new MasterProxyModel (this, mDataFilesModel); + + mPluginsProxyModel = new PluginsProxyModel (this, mDataFilesModel); mFilterProxyModel = new QSortFilterProxyModel(); mFilterProxyModel->setDynamicSortFilter(true); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index d49906949..dd94b0571 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -24,25 +24,19 @@ FileDialog::FileDialog(QWidget *parent) : setupUi(this); // Models - mDataFilesModel = new DataFilesModel(this); + mDataFilesModel = new DataFilesModel (this); - mMastersProxyModel = new MasterProxyModel(); - mMastersProxyModel->setFilterRegExp("game"); //QString("^.*\\.esm")); - mMastersProxyModel->setFilterRole (Qt::UserRole); - mMastersProxyModel->setSourceModel(mDataFilesModel); + mMastersProxyModel = new MasterProxyModel (this, mDataFilesModel); + mPluginsProxyModel = new PluginsProxyModel (this, mDataFilesModel); - mPluginsProxyModel = new PluginsProxyModel(); - mPluginsProxyModel->setFilterRegExp("addon"); //QString("^.*\\.esp")); - mPluginsProxyModel->setFilterRole (Qt::UserRole); - mPluginsProxyModel->setSourceModel(mDataFilesModel); mFilterProxyModel = new QSortFilterProxyModel(); mFilterProxyModel->setDynamicSortFilter(true); mFilterProxyModel->setSourceModel(mPluginsProxyModel); - +/* QCheckBox checkBox; unsigned int height = checkBox.sizeHint().height() + 4; - +*/ masterView->setModel(mMastersProxyModel); /* mastersTable->setModel(mMastersProxyModel); @@ -70,10 +64,10 @@ FileDialog::FileDialog(QWidget *parent) : pluginsTable->setAlternatingRowColors(true); pluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); pluginsTable->horizontalHeader()->setStretchLastSection(true); - +/* pluginsTable->verticalHeader()->setDefaultSectionSize(height); pluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); - +*/ // Hide the profile elements profileLabel->hide(); profilesComboBox->hide(); diff --git a/components/fileorderlist/masterproxymodel.cpp b/components/fileorderlist/masterproxymodel.cpp index ce874318d..dc702e945 100644 --- a/components/fileorderlist/masterproxymodel.cpp +++ b/components/fileorderlist/masterproxymodel.cpp @@ -1,8 +1,13 @@ #include "masterproxymodel.hpp" -MasterProxyModel::MasterProxyModel(QObject *parent) : +MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableModel* model) : QSortFilterProxyModel(parent) { + setFilterRegExp(QString("game")); + setFilterRole (Qt::UserRole); + + if (model) + setSourceModel (model); } QVariant MasterProxyModel::data(const QModelIndex &index, int role) const diff --git a/components/fileorderlist/masterproxymodel.hpp b/components/fileorderlist/masterproxymodel.hpp index d0d288873..d9e12dada 100644 --- a/components/fileorderlist/masterproxymodel.hpp +++ b/components/fileorderlist/masterproxymodel.hpp @@ -3,11 +3,13 @@ #include +class QAbstractTableModel; + class MasterProxyModel : public QSortFilterProxyModel { Q_OBJECT public: - explicit MasterProxyModel(QObject *parent = 0); + explicit MasterProxyModel(QObject *parent = 0, QAbstractTableModel *model = 0); virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; signals: diff --git a/components/fileorderlist/model/pluginsproxymodel.cpp b/components/fileorderlist/model/pluginsproxymodel.cpp index 4648d2833..61ffb8894 100644 --- a/components/fileorderlist/model/pluginsproxymodel.cpp +++ b/components/fileorderlist/model/pluginsproxymodel.cpp @@ -1,8 +1,13 @@ #include "pluginsproxymodel.hpp" -PluginsProxyModel::PluginsProxyModel(QObject *parent) : +PluginsProxyModel::PluginsProxyModel(QObject *parent, QAbstractTableModel *model) : QSortFilterProxyModel(parent) { + setFilterRegExp(QString("addon")); + setFilterRole (Qt::UserRole); + + if (model) + setSourceModel (model); } PluginsProxyModel::~PluginsProxyModel() diff --git a/components/fileorderlist/model/pluginsproxymodel.hpp b/components/fileorderlist/model/pluginsproxymodel.hpp index 08baa2338..238d2aac7 100644 --- a/components/fileorderlist/model/pluginsproxymodel.hpp +++ b/components/fileorderlist/model/pluginsproxymodel.hpp @@ -4,12 +4,13 @@ #include class QVariant; +class QAbstractTableModel; class PluginsProxyModel : public QSortFilterProxyModel { Q_OBJECT public: - explicit PluginsProxyModel(QObject *parent = 0); + explicit PluginsProxyModel(QObject *parent = 0, QAbstractTableModel *model = 0); ~PluginsProxyModel(); virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; From 61602789e1092eb80bdcb677f03ce7a02fce6501 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 16 Aug 2013 22:23:21 -0500 Subject: [PATCH 008/118] Began migrating code to ContentSelector base --- apps/launcher/datafilespage.cpp | 21 +-- apps/launcher/datafilespage.hpp | 4 +- apps/opencs/view/doc/filedialog.cpp | 117 +++------------- apps/opencs/view/doc/filedialog.hpp | 12 +- components/CMakeLists.txt | 9 +- components/fileorderlist/contentselector.cpp | 132 ++++++++++++++++++ components/fileorderlist/contentselector.hpp | 40 ++++++ components/fileorderlist/masterproxymodel.cpp | 4 +- components/fileorderlist/masterproxymodel.hpp | 22 +-- 9 files changed, 232 insertions(+), 129 deletions(-) create mode 100644 components/fileorderlist/contentselector.cpp create mode 100644 components/fileorderlist/contentselector.hpp diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 42e10c76b..7a4890051 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -15,7 +15,7 @@ #include #include -#include "a.out.h" +#include "components/fileorderlist/masterproxymodel.hpp" #include "settings/gamesettings.hpp" #include "settings/launchersettings.hpp" @@ -25,10 +25,11 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam : mCfgMgr(cfg) , mGameSettings(gameSettings) , mLauncherSettings(launcherSettings) - , QWidget(parent) + , ContentSelector(parent) { setupUi(this); - + buildModelsAndViews(); + /* // Models mDataFilesModel = new DataFilesModel (this); @@ -41,11 +42,11 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam mFilterProxyModel->setSourceModel(mPluginsProxyModel); masterView->setModel (mMastersProxyModel); -/* - QCheckBox checkBox; - unsigned int height = checkBox.sizeHint().height() + 4; - */ -/* + + //QCheckBox checkBox; + // unsigned int height = checkBox.sizeHint().height() + 4; + + mastersTable->setModel(mMastersProxyModel); mastersTable->setObjectName("MastersTable"); mastersTable->setContextMenuPolicy(Qt::CustomContextMenu); @@ -61,7 +62,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam mastersTable->verticalHeader()->setDefaultSectionSize(height); mastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); mastersTable->verticalHeader()->hide(); -*/ + pluginsTable->setModel(mFilterProxyModel); pluginsTable->setObjectName("PluginsTable"); pluginsTable->setContextMenuPolicy(Qt::CustomContextMenu); @@ -76,7 +77,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam //pluginsTable->verticalHeader()->setDefaultSectionSize(height); //pluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); - +*/ // Adjust the tableview widths inside the splitter QList sizeList; sizeList << mLauncherSettings.value(QString("General/MastersTable/width"), QString("200")).toInt(); diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index a0b029330..99aa24ff3 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -5,6 +5,7 @@ #include #include "ui_datafilespage.h" +#include "components/fileorderlist/contentselector.hpp" class QSortFilterProxyModel; class QAbstractItemModel; @@ -19,10 +20,9 @@ class PluginsProxyModel; namespace Files { struct ConfigurationManager; } -class DataFilesPage : public QWidget, private Ui::DataFilesPage +class DataFilesPage : public FileOrderList::ContentSelector { Q_OBJECT - public: DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent = 0); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index dd94b0571..f770e80a1 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -19,10 +19,11 @@ #include "components/fileorderlist/masterproxymodel.hpp" FileDialog::FileDialog(QWidget *parent) : - QDialog(parent) + ContentSelector(parent) { setupUi(this); - + buildModelsAndViews(); + /* // Models mDataFilesModel = new DataFilesModel (this); @@ -33,12 +34,12 @@ FileDialog::FileDialog(QWidget *parent) : mFilterProxyModel = new QSortFilterProxyModel(); mFilterProxyModel->setDynamicSortFilter(true); mFilterProxyModel->setSourceModel(mPluginsProxyModel); -/* - QCheckBox checkBox; - unsigned int height = checkBox.sizeHint().height() + 4; -*/ + +// QCheckBox checkBox; +// unsigned int height = checkBox.sizeHint().height() + 4; + masterView->setModel(mMastersProxyModel); -/* + mastersTable->setModel(mMastersProxyModel); mastersTable->setObjectName("MastersTable"); mastersTable->setContextMenuPolicy(Qt::CustomContextMenu); @@ -53,7 +54,7 @@ FileDialog::FileDialog(QWidget *parent) : mastersTable->verticalHeader()->setDefaultSectionSize(height); mastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); mastersTable->verticalHeader()->hide(); -*/ + pluginsTable->setModel(mFilterProxyModel); pluginsTable->setObjectName("PluginsTable"); pluginsTable->setContextMenuPolicy(Qt::CustomContextMenu); @@ -64,10 +65,11 @@ FileDialog::FileDialog(QWidget *parent) : pluginsTable->setAlternatingRowColors(true); pluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); pluginsTable->horizontalHeader()->setStretchLastSection(true); -/* - pluginsTable->verticalHeader()->setDefaultSectionSize(height); - pluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); -*/ + +// pluginsTable->verticalHeader()->setDefaultSectionSize(height); +// pluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); + + */ // Hide the profile elements profileLabel->hide(); profilesComboBox->hide(); @@ -105,43 +107,19 @@ FileDialog::FileDialog(QWidget *parent) : resize(600, 400); - connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); - connect(mDataFilesModel, SIGNAL(checkedItemsChanged(QStringList)), this, SLOT(updateOpenButton(QStringList))); + // + // connect(mDataFilesModel, SIGNAL(checkedItemsChanged(QStringList)), this, SLOT(updateOpenButton(QStringList))); //connect(mNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateCreateButton(QString))); //connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); - connect(pluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); + // connect(pluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); //connect(mastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); - connect(mCreateButton, SIGNAL(clicked()), this, SLOT(createButtonClicked())); - - connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject())); -} - -void FileDialog::updateViews() -{ - // Ensure the columns are hidden because sort() re-enables them - /* - mastersTable->setColumnHidden(1, true); - mastersTable->setColumnHidden(3, true); - mastersTable->setColumnHidden(4, true); - mastersTable->setColumnHidden(5, true); - mastersTable->setColumnHidden(6, true); - mastersTable->setColumnHidden(7, true); - mastersTable->setColumnHidden(8, true); - mastersTable->resizeColumnsToContents(); -*/ - pluginsTable->setColumnHidden(1, true); - pluginsTable->setColumnHidden(3, true); - pluginsTable->setColumnHidden(4, true); - pluginsTable->setColumnHidden(5, true); - pluginsTable->setColumnHidden(6, true); - pluginsTable->setColumnHidden(7, true); - pluginsTable->setColumnHidden(8, true); - pluginsTable->resizeColumnsToContents(); + // connect(mCreateButton, SIGNAL(clicked()), this, SLOT(createButtonClicked())); + // connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept())); + // connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject())); } void FileDialog::updateOpenButton(const QStringList &items) @@ -161,64 +139,13 @@ void FileDialog::updateCreateButton(const QString &name) mCreateButton->setEnabled(!name.isEmpty()); } - +/* void FileDialog::filterChanged(const QString &filter) { QRegExp filterRe(filter, Qt::CaseInsensitive, QRegExp::FixedString); mFilterProxyModel->setFilterRegExp(filterRe); } - -void FileDialog::addFiles(const QString &path) -{ - mDataFilesModel->addFiles(path); - mDataFilesModel->sort(3); // Sort by date accessed -} - -void FileDialog::setEncoding(const QString &encoding) -{ - mDataFilesModel->setEncoding(encoding); -} - -void FileDialog::setCheckState(QModelIndex index) -{ - if (!index.isValid()) - return; - - QObject *object = QObject::sender(); - - // Not a signal-slot call - if (!object) - return; - - - if (object->objectName() == QLatin1String("PluginsTable")) { - QModelIndex sourceIndex = mPluginsProxyModel->mapToSource( - mFilterProxyModel->mapToSource(index)); - - if (sourceIndex.isValid()) { - (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) - ? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked) - : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); - } - } - - if (object->objectName() == QLatin1String("MastersTable")) { - QModelIndex sourceIndex = mMastersProxyModel->mapToSource(index); - - if (sourceIndex.isValid()) { - (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) - ? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked) - : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); - } - } - - return; -} - -QStringList FileDialog::checkedItemsPaths() -{ - return mDataFilesModel->checkedItemsPaths(); -} +*/ QString FileDialog::fileName() { diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 4c3fe9ffa..2f4d4e381 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -4,6 +4,7 @@ #include #include +#include "components/fileorderlist/contentselector.hpp" #include "ui_datafilespage.h" class QDialogButtonBox; @@ -17,19 +18,16 @@ class QMenu; class DataFilesModel; class PluginsProxyModel; -class FileDialog : public QDialog, private Ui::DataFilesPage +class FileDialog : public FileOrderList::ContentSelector { Q_OBJECT public: explicit FileDialog(QWidget *parent = 0); - void addFiles(const QString &path); - void setEncoding(const QString &encoding); void openFile(); void newFile(); void accepted(); - QStringList checkedItemsPaths(); QString fileName(); signals: @@ -40,12 +38,12 @@ public slots: void accept(); private slots: - void updateViews(); + //void updateViews(); void updateOpenButton(const QStringList &items); void updateCreateButton(const QString &name); - void setCheckState(QModelIndex index); - void filterChanged(const QString &filter); + + //void filterChanged(const QString &filter); void createButtonClicked(); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index bbaca4805..19af6c3b2 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -66,22 +66,25 @@ add_component_dir (translation translation ) +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 (fileorderlist - masterproxymodel + masterproxymodel contentselector model/modelitem model/datafilesmodel model/pluginsproxymodel model/esm/esmfile utils/profilescombobox utils/comboboxlineedit utils/lineedit utils/naturalsort ) include(${QT_USE_FILE}) + QT4_WRAP_UI(ESM_UI_HDR ${ESM_UI}) QT4_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES}) endif(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) -include_directories(${BULLET_INCLUDE_DIRS}) +include_directories(${BULLET_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) -add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS}) +add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS} ${ESM_UI_HDR}) target_link_libraries(components ${Boost_LIBRARIES} ${OGRE_LIBRARIES}) diff --git a/components/fileorderlist/contentselector.cpp b/components/fileorderlist/contentselector.cpp new file mode 100644 index 000000000..16e071891 --- /dev/null +++ b/components/fileorderlist/contentselector.cpp @@ -0,0 +1,132 @@ +#include "contentselector.hpp" + +#include "model/datafilesmodel.hpp" +#include "masterproxymodel.hpp" +#include "model/pluginsproxymodel.hpp" + +#include + +FileOrderList::ContentSelector::ContentSelector(QWidget *parent) : + QWidget(parent) +{ +} + +void FileOrderList::ContentSelector::buildModelsAndViews() +{ + // Models + mDataFilesModel = new DataFilesModel (this); + + mMasterProxyModel = new FileOrderList::MasterProxyModel (this, mDataFilesModel); + mPluginsProxyModel = new PluginsProxyModel (this, mDataFilesModel); + + + mFilterProxyModel = new QSortFilterProxyModel(); + mFilterProxyModel->setDynamicSortFilter(true); + mFilterProxyModel->setSourceModel(mPluginsProxyModel); + + masterView->setModel(mMasterProxyModel); +/* + mastersTable->setModel(mMastersProxyModel); + mastersTable->setObjectName("MastersTable"); + mastersTable->setContextMenuPolicy(Qt::CustomContextMenu); + mastersTable->setSortingEnabled(false); + mastersTable->setSelectionBehavior(QAbstractItemView::SelectRows); + mastersTable->setSelectionMode(QAbstractItemView::ExtendedSelection); + mastersTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + mastersTable->setAlternatingRowColors(true); + mastersTable->horizontalHeader()->setStretchLastSection(true); + + // Set the row height to the size of the checkboxes + mastersTable->verticalHeader()->setDefaultSectionSize(height); + mastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); + mastersTable->verticalHeader()->hide(); +*/ + pluginsTable->setModel(mFilterProxyModel); + pluginsTable->setObjectName("PluginsTable"); + pluginsTable->setContextMenuPolicy(Qt::CustomContextMenu); + pluginsTable->setSortingEnabled(false); + pluginsTable->setSelectionBehavior(QAbstractItemView::SelectRows); + pluginsTable->setSelectionMode(QAbstractItemView::ExtendedSelection); + pluginsTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + pluginsTable->setAlternatingRowColors(true); + pluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); + pluginsTable->horizontalHeader()->setStretchLastSection(true); + + connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); +} + +void FileOrderList::ContentSelector::addFiles(const QString &path) +{ + mDataFilesModel->addFiles(path); + mDataFilesModel->sort(3); // Sort by date accessed +} + +void FileOrderList::ContentSelector::setEncoding(const QString &encoding) +{ + mDataFilesModel->setEncoding(encoding); +} + +void FileOrderList::ContentSelector::setCheckState(QModelIndex index) +{ + if (!index.isValid()) + return; + + QObject *object = QObject::sender(); + + // Not a signal-slot call + if (!object) + return; + + + if (object->objectName() == QLatin1String("PluginsTable")) { + QModelIndex sourceIndex = mPluginsProxyModel->mapToSource( + mFilterProxyModel->mapToSource(index)); + + if (sourceIndex.isValid()) { + (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) + ? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked) + : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); + } + } +/* + if (object->objectName() == QLatin1String("MastersTable")) { + QModelIndex sourceIndex = mMasterProxyModel->mapToSource(index); + + if (sourceIndex.isValid()) { + (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) + ? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked) + : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); + } + } +*/ + return; +} + +QStringList FileOrderList::ContentSelector::checkedItemsPaths() +{ + return mDataFilesModel->checkedItemsPaths(); +} + +void FileOrderList::ContentSelector::updateViews() +{ + // Ensure the columns are hidden because sort() re-enables them + /* + mastersTable->setColumnHidden(1, true); + mastersTable->setColumnHidden(3, true); + mastersTable->setColumnHidden(4, true); + mastersTable->setColumnHidden(5, true); + mastersTable->setColumnHidden(6, true); + mastersTable->setColumnHidden(7, true); + mastersTable->setColumnHidden(8, true); + mastersTable->resizeColumnsToContents(); +*/ + pluginsTable->setColumnHidden(1, true); + pluginsTable->setColumnHidden(3, true); + pluginsTable->setColumnHidden(4, true); + pluginsTable->setColumnHidden(5, true); + pluginsTable->setColumnHidden(6, true); + pluginsTable->setColumnHidden(7, true); + pluginsTable->setColumnHidden(8, true); + pluginsTable->resizeColumnsToContents(); + +} diff --git a/components/fileorderlist/contentselector.hpp b/components/fileorderlist/contentselector.hpp new file mode 100644 index 000000000..f17e3a909 --- /dev/null +++ b/components/fileorderlist/contentselector.hpp @@ -0,0 +1,40 @@ +#ifndef CONTENTSELECTOR_HPP +#define CONTENTSELECTOR_HPP + +#include + +#include "ui_datafilespage.h" + +class DataFilesModel; +class PluginsProxyModel; +class QSortFilterProxyModel; + +namespace FileOrderList +{ + class MasterProxyModel; + + class ContentSelector : public QWidget, protected Ui::DataFilesPage + { + Q_OBJECT + + DataFilesModel *mDataFilesModel; + MasterProxyModel *mMasterProxyModel; + PluginsProxyModel *mPluginsProxyModel; + QSortFilterProxyModel *mFilterProxyModel; + + public: + explicit ContentSelector(QWidget *parent = 0); + + void buildModelsAndViews(); + + void addFiles(const QString &path); + void setEncoding(const QString &encoding); + void setCheckState(QModelIndex index); + QStringList checkedItemsPaths(); + + private slots: + void updateViews(); + }; +} + +#endif // CONTENTSELECTOR_HPP diff --git a/components/fileorderlist/masterproxymodel.cpp b/components/fileorderlist/masterproxymodel.cpp index dc702e945..7701d4f17 100644 --- a/components/fileorderlist/masterproxymodel.cpp +++ b/components/fileorderlist/masterproxymodel.cpp @@ -1,6 +1,6 @@ #include "masterproxymodel.hpp" -MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableModel* model) : +FileOrderList::MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableModel* model) : QSortFilterProxyModel(parent) { setFilterRegExp(QString("game")); @@ -10,7 +10,7 @@ MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableModel* model) setSourceModel (model); } -QVariant MasterProxyModel::data(const QModelIndex &index, int role) const +QVariant FileOrderList::MasterProxyModel::data(const QModelIndex &index, int role) const { return QSortFilterProxyModel::data (index, role); } diff --git a/components/fileorderlist/masterproxymodel.hpp b/components/fileorderlist/masterproxymodel.hpp index d9e12dada..49ca369de 100644 --- a/components/fileorderlist/masterproxymodel.hpp +++ b/components/fileorderlist/masterproxymodel.hpp @@ -5,17 +5,19 @@ class QAbstractTableModel; -class MasterProxyModel : public QSortFilterProxyModel +namespace FileOrderList { - Q_OBJECT -public: - explicit MasterProxyModel(QObject *parent = 0, QAbstractTableModel *model = 0); - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + 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: - -}; + signals: + public slots: + + }; +} #endif // MASTERPROXYMODEL_HPP From 0087b0d67c4b36cfb9e9e9ce5af5d282673d9419 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 17 Aug 2013 05:37:23 -0500 Subject: [PATCH 009/118] Removed checkboxes from master list Moved checkbox code from datafilesmodel to pluginsproxymodel --- .../fileorderlist/model/datafilesmodel.cpp | 5 ----- .../fileorderlist/model/pluginsproxymodel.cpp | 16 ++++++++++++++-- .../fileorderlist/model/pluginsproxymodel.hpp | 7 ++++++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/components/fileorderlist/model/datafilesmodel.cpp b/components/fileorderlist/model/datafilesmodel.cpp index 99c1aaebf..3f63e73cc 100644 --- a/components/fileorderlist/model/datafilesmodel.cpp +++ b/components/fileorderlist/model/datafilesmodel.cpp @@ -117,11 +117,6 @@ QVariant DataFilesModel::data(const QModelIndex &index, int role) const } } - case Qt::CheckStateRole: { - if (column != 0) - return QVariant(); - return mCheckStates[file->fileName()]; - } case Qt::ToolTipRole: { if (column != 0) diff --git a/components/fileorderlist/model/pluginsproxymodel.cpp b/components/fileorderlist/model/pluginsproxymodel.cpp index 61ffb8894..f6864d85c 100644 --- a/components/fileorderlist/model/pluginsproxymodel.cpp +++ b/components/fileorderlist/model/pluginsproxymodel.cpp @@ -1,7 +1,8 @@ #include "pluginsproxymodel.hpp" +#include "datafilesmodel.hpp" -PluginsProxyModel::PluginsProxyModel(QObject *parent, QAbstractTableModel *model) : - QSortFilterProxyModel(parent) +PluginsProxyModel::PluginsProxyModel(QObject *parent, DataFilesModel *model) : + QSortFilterProxyModel(parent), mSourceModel (model) { setFilterRegExp(QString("addon")); setFilterRole (Qt::UserRole); @@ -16,5 +17,16 @@ PluginsProxyModel::~PluginsProxyModel() QVariant PluginsProxyModel::data(const QModelIndex &index, int role) const { + switch (role) + { + case Qt::CheckStateRole: + { + if (index.column() != 0) + return QVariant(); + + return mSourceModel->checkState(index); + } + }; + return QSortFilterProxyModel::data (index, role); } diff --git a/components/fileorderlist/model/pluginsproxymodel.hpp b/components/fileorderlist/model/pluginsproxymodel.hpp index 238d2aac7..e148ea3b1 100644 --- a/components/fileorderlist/model/pluginsproxymodel.hpp +++ b/components/fileorderlist/model/pluginsproxymodel.hpp @@ -5,12 +5,17 @@ class QVariant; class QAbstractTableModel; +class DataFilesModel; class PluginsProxyModel : public QSortFilterProxyModel { Q_OBJECT + + DataFilesModel *mSourceModel; + public: - explicit PluginsProxyModel(QObject *parent = 0, QAbstractTableModel *model = 0); + + explicit PluginsProxyModel(QObject *parent = 0, DataFilesModel *model = 0); ~PluginsProxyModel(); virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; From b24dd5c6acf9985b34aa9af45c24d817cc211a0c Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 17 Aug 2013 05:55:43 -0500 Subject: [PATCH 010/118] Continued migration of code to ContentSelector --- apps/launcher/datafilespage.cpp | 106 ++---------------- apps/launcher/datafilespage.hpp | 8 -- apps/opencs/view/doc/filedialog.cpp | 50 --------- apps/opencs/view/doc/filedialog.hpp | 6 - components/fileorderlist/contentselector.cpp | 26 +---- components/fileorderlist/contentselector.hpp | 3 +- .../fileorderlist/model/pluginsproxymodel.cpp | 3 +- 7 files changed, 17 insertions(+), 185 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 7a4890051..d077c3e0e 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -21,63 +21,14 @@ #include "utils/textinputdialog.hpp" +#include + DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent) : mCfgMgr(cfg) , mGameSettings(gameSettings) , mLauncherSettings(launcherSettings) , ContentSelector(parent) { - setupUi(this); - buildModelsAndViews(); - /* - // Models - mDataFilesModel = new DataFilesModel (this); - - mMastersProxyModel = new MasterProxyModel (this, mDataFilesModel); - - mPluginsProxyModel = new PluginsProxyModel (this, mDataFilesModel); - - mFilterProxyModel = new QSortFilterProxyModel(); - mFilterProxyModel->setDynamicSortFilter(true); - mFilterProxyModel->setSourceModel(mPluginsProxyModel); - - masterView->setModel (mMastersProxyModel); - - //QCheckBox checkBox; - // unsigned int height = checkBox.sizeHint().height() + 4; - - - mastersTable->setModel(mMastersProxyModel); - mastersTable->setObjectName("MastersTable"); - mastersTable->setContextMenuPolicy(Qt::CustomContextMenu); - mastersTable->setSortingEnabled(false); - mastersTable->setSelectionBehavior(QAbstractItemView::SelectRows); - mastersTable->setSelectionMode(QAbstractItemView::ExtendedSelection); - mastersTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - mastersTable->setAlternatingRowColors(true); - mastersTable->horizontalHeader()->setStretchLastSection(true); - mastersTable->horizontalHeader()->hide(); - - // Set the row height to the size of the checkboxes - mastersTable->verticalHeader()->setDefaultSectionSize(height); - mastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); - mastersTable->verticalHeader()->hide(); - - pluginsTable->setModel(mFilterProxyModel); - pluginsTable->setObjectName("PluginsTable"); - pluginsTable->setContextMenuPolicy(Qt::CustomContextMenu); - pluginsTable->setSortingEnabled(false); - pluginsTable->setSelectionBehavior(QAbstractItemView::SelectRows); - pluginsTable->setSelectionMode(QAbstractItemView::ExtendedSelection); - pluginsTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - pluginsTable->setAlternatingRowColors(true); - pluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); - pluginsTable->horizontalHeader()->setStretchLastSection(true); - pluginsTable->horizontalHeader()->hide(); - - //pluginsTable->verticalHeader()->setDefaultSectionSize(height); - //pluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); -*/ // Adjust the tableview widths inside the splitter QList sizeList; sizeList << mLauncherSettings.value(QString("General/MastersTable/width"), QString("200")).toInt(); @@ -98,8 +49,6 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam connect(pluginsTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); //connect(mastersTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); - connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); - //connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); connect(splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(updateSplitter())); @@ -123,6 +72,9 @@ void DataFilesPage::createActions() void DataFilesPage::setupDataFiles() { + if (!mDataFilesModel) + qDebug() << "data files model undefined"; + // Set the encoding to the one found in openmw.cfg or the default mDataFilesModel->setEncoding(mGameSettings.value(QString("encoding"), QString("win1252"))); @@ -384,8 +336,7 @@ void DataFilesPage::setPluginsCheckstates(Qt::CheckState state) if (!index.isValid()) return; - QModelIndex sourceIndex = mPluginsProxyModel->mapToSource( - mFilterProxyModel->mapToSource(index)); + QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(index); if (!sourceIndex.isValid()) return; @@ -394,48 +345,6 @@ void DataFilesPage::setPluginsCheckstates(Qt::CheckState state) } } -void DataFilesPage::setCheckState(QModelIndex index) -{ - if (!index.isValid()) - return; - - QObject *object = QObject::sender(); - - // Not a signal-slot call - if (!object) - return; - - - if (object->objectName() == QLatin1String("PluginsTable")) { - QModelIndex sourceIndex = mPluginsProxyModel->mapToSource( - mFilterProxyModel->mapToSource(index)); - - if (sourceIndex.isValid()) { - (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) - ? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked) - : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); - } - } - - if (object->objectName() == QLatin1String("MastersTable")) { - QModelIndex sourceIndex = mMastersProxyModel->mapToSource(index); - - if (sourceIndex.isValid()) { - (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) - ? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked) - : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); - } - } - - return; -} - -void DataFilesPage::filterChanged(const QString filter) -{ - QRegExp regExp(filter, Qt::CaseInsensitive, QRegExp::FixedString); - mFilterProxyModel->setFilterRegExp(regExp); -} - void DataFilesPage::profileChanged(const QString &previous, const QString ¤t) { // Prevent the deletion of the default profile @@ -505,8 +414,7 @@ void DataFilesPage::showContextMenu(const QPoint &point) if (!index.isValid()) return; - QModelIndex sourceIndex = mPluginsProxyModel->mapToSource( - mFilterProxyModel->mapToSource(index)); + QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(index); if (!sourceIndex.isValid()) return; diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index 99aa24ff3..1c528ab26 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -36,10 +36,8 @@ signals: void profileChanged(int index); public slots: - void setCheckState(QModelIndex index); void setProfilesComboBoxIndex(int index); - void filterChanged(const QString filter); void showContextMenu(const QPoint &point); void profileChanged(const QString &previous, const QString ¤t); void profileRenamed(const QString &previous, const QString ¤t); @@ -57,12 +55,6 @@ private slots: void slotCurrentIndexChanged(int index); private: - DataFilesModel *mDataFilesModel; - - PluginsProxyModel *mPluginsProxyModel; - QSortFilterProxyModel *mMastersProxyModel; - - QSortFilterProxyModel *mFilterProxyModel; QMenu *mContextMenu; diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index f770e80a1..2f3a6dc21 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -21,55 +21,6 @@ FileDialog::FileDialog(QWidget *parent) : ContentSelector(parent) { - setupUi(this); - buildModelsAndViews(); - /* - // Models - mDataFilesModel = new DataFilesModel (this); - - mMastersProxyModel = new MasterProxyModel (this, mDataFilesModel); - mPluginsProxyModel = new PluginsProxyModel (this, mDataFilesModel); - - - mFilterProxyModel = new QSortFilterProxyModel(); - mFilterProxyModel->setDynamicSortFilter(true); - mFilterProxyModel->setSourceModel(mPluginsProxyModel); - -// QCheckBox checkBox; -// unsigned int height = checkBox.sizeHint().height() + 4; - - masterView->setModel(mMastersProxyModel); - - mastersTable->setModel(mMastersProxyModel); - mastersTable->setObjectName("MastersTable"); - mastersTable->setContextMenuPolicy(Qt::CustomContextMenu); - mastersTable->setSortingEnabled(false); - mastersTable->setSelectionBehavior(QAbstractItemView::SelectRows); - mastersTable->setSelectionMode(QAbstractItemView::ExtendedSelection); - mastersTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - mastersTable->setAlternatingRowColors(true); - mastersTable->horizontalHeader()->setStretchLastSection(true); - - // Set the row height to the size of the checkboxes - mastersTable->verticalHeader()->setDefaultSectionSize(height); - mastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); - mastersTable->verticalHeader()->hide(); - - pluginsTable->setModel(mFilterProxyModel); - pluginsTable->setObjectName("PluginsTable"); - pluginsTable->setContextMenuPolicy(Qt::CustomContextMenu); - pluginsTable->setSortingEnabled(false); - pluginsTable->setSelectionBehavior(QAbstractItemView::SelectRows); - pluginsTable->setSelectionMode(QAbstractItemView::ExtendedSelection); - pluginsTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - pluginsTable->setAlternatingRowColors(true); - pluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); - pluginsTable->horizontalHeader()->setStretchLastSection(true); - -// pluginsTable->verticalHeader()->setDefaultSectionSize(height); -// pluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); - - */ // Hide the profile elements profileLabel->hide(); profilesComboBox->hide(); @@ -107,7 +58,6 @@ FileDialog::FileDialog(QWidget *parent) : resize(600, 400); - // // connect(mDataFilesModel, SIGNAL(checkedItemsChanged(QStringList)), this, SLOT(updateOpenButton(QStringList))); //connect(mNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateCreateButton(QString))); diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 2f4d4e381..7944b7fb3 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -53,12 +53,6 @@ private: QPushButton *mCreateButton; QDialogButtonBox *mButtonBox; - - DataFilesModel *mDataFilesModel; - - PluginsProxyModel *mPluginsProxyModel; - QSortFilterProxyModel *mMastersProxyModel; - QSortFilterProxyModel *mFilterProxyModel; }; #endif // FILEDIALOG_HPP diff --git a/components/fileorderlist/contentselector.cpp b/components/fileorderlist/contentselector.cpp index 16e071891..6f8a86a49 100644 --- a/components/fileorderlist/contentselector.cpp +++ b/components/fileorderlist/contentselector.cpp @@ -9,6 +9,8 @@ FileOrderList::ContentSelector::ContentSelector(QWidget *parent) : QWidget(parent) { + setupUi(this); + buildModelsAndViews(); } void FileOrderList::ContentSelector::buildModelsAndViews() @@ -19,11 +21,6 @@ void FileOrderList::ContentSelector::buildModelsAndViews() mMasterProxyModel = new FileOrderList::MasterProxyModel (this, mDataFilesModel); mPluginsProxyModel = new PluginsProxyModel (this, mDataFilesModel); - - mFilterProxyModel = new QSortFilterProxyModel(); - mFilterProxyModel->setDynamicSortFilter(true); - mFilterProxyModel->setSourceModel(mPluginsProxyModel); - masterView->setModel(mMasterProxyModel); /* mastersTable->setModel(mMastersProxyModel); @@ -41,7 +38,7 @@ void FileOrderList::ContentSelector::buildModelsAndViews() mastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); mastersTable->verticalHeader()->hide(); */ - pluginsTable->setModel(mFilterProxyModel); + pluginsTable->setModel(mPluginsProxyModel); pluginsTable->setObjectName("PluginsTable"); pluginsTable->setContextMenuPolicy(Qt::CustomContextMenu); pluginsTable->setSortingEnabled(false); @@ -79,8 +76,7 @@ void FileOrderList::ContentSelector::setCheckState(QModelIndex index) if (object->objectName() == QLatin1String("PluginsTable")) { - QModelIndex sourceIndex = mPluginsProxyModel->mapToSource( - mFilterProxyModel->mapToSource(index)); + QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(index); if (sourceIndex.isValid()) { (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) @@ -88,7 +84,7 @@ void FileOrderList::ContentSelector::setCheckState(QModelIndex index) : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); } } -/* + if (object->objectName() == QLatin1String("MastersTable")) { QModelIndex sourceIndex = mMasterProxyModel->mapToSource(index); @@ -98,7 +94,7 @@ void FileOrderList::ContentSelector::setCheckState(QModelIndex index) : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); } } -*/ + return; } @@ -110,16 +106,6 @@ QStringList FileOrderList::ContentSelector::checkedItemsPaths() void FileOrderList::ContentSelector::updateViews() { // Ensure the columns are hidden because sort() re-enables them - /* - mastersTable->setColumnHidden(1, true); - mastersTable->setColumnHidden(3, true); - mastersTable->setColumnHidden(4, true); - mastersTable->setColumnHidden(5, true); - mastersTable->setColumnHidden(6, true); - mastersTable->setColumnHidden(7, true); - mastersTable->setColumnHidden(8, true); - mastersTable->resizeColumnsToContents(); -*/ pluginsTable->setColumnHidden(1, true); pluginsTable->setColumnHidden(3, true); pluginsTable->setColumnHidden(4, true); diff --git a/components/fileorderlist/contentselector.hpp b/components/fileorderlist/contentselector.hpp index f17e3a909..914e8bacb 100644 --- a/components/fileorderlist/contentselector.hpp +++ b/components/fileorderlist/contentselector.hpp @@ -17,10 +17,11 @@ namespace FileOrderList { Q_OBJECT + protected: + DataFilesModel *mDataFilesModel; MasterProxyModel *mMasterProxyModel; PluginsProxyModel *mPluginsProxyModel; - QSortFilterProxyModel *mFilterProxyModel; public: explicit ContentSelector(QWidget *parent = 0); diff --git a/components/fileorderlist/model/pluginsproxymodel.cpp b/components/fileorderlist/model/pluginsproxymodel.cpp index f6864d85c..9e3cdd730 100644 --- a/components/fileorderlist/model/pluginsproxymodel.cpp +++ b/components/fileorderlist/model/pluginsproxymodel.cpp @@ -4,8 +4,9 @@ PluginsProxyModel::PluginsProxyModel(QObject *parent, DataFilesModel *model) : QSortFilterProxyModel(parent), mSourceModel (model) { - setFilterRegExp(QString("addon")); + setFilterRegExp (QString("addon")); setFilterRole (Qt::UserRole); + setDynamicSortFilter (true); if (model) setSourceModel (model); From 2878f51cd324c0dcc605b54f00b927a3dafac31c Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 17 Aug 2013 19:40:28 -0500 Subject: [PATCH 011/118] Reimplemented dependency selection feature Moved more code to ContentSelector Added support for omwgame and omwaddon files --- apps/launcher/datafilespage.cpp | 125 +++--------------- apps/launcher/datafilespage.hpp | 8 +- apps/opencs/view/doc/filedialog.cpp | 19 --- apps/opencs/view/doc/filedialog.hpp | 3 - components/fileorderlist/contentselector.cpp | 99 ++++++-------- components/fileorderlist/contentselector.hpp | 7 +- .../fileorderlist/model/datafilesmodel.cpp | 15 +-- .../fileorderlist/model/pluginsproxymodel.cpp | 4 +- .../fileorderlist/model/pluginsproxymodel.hpp | 2 - files/ui/datafilespage.ui | 44 +++--- 10 files changed, 99 insertions(+), 227 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index d077c3e0e..5cbcae545 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -29,29 +29,14 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam , mLauncherSettings(launcherSettings) , ContentSelector(parent) { - // Adjust the tableview widths inside the splitter - QList sizeList; - sizeList << mLauncherSettings.value(QString("General/MastersTable/width"), QString("200")).toInt(); - sizeList << mLauncherSettings.value(QString("General/PluginTable/width"), QString("340")).toInt(); - - splitter->setSizes(sizeList); // Create a dialog for the new profile name input mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); - connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentIndexChanged(int))); - connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString))); - connect(pluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); - //connect(mastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); - - connect(pluginsTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); - //connect(mastersTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); - - //connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); - - connect(splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(updateSplitter())); + //connect(pluginView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); + //connect(masterView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); createActions(); setupDataFiles(); @@ -193,49 +178,11 @@ void DataFilesPage::updateOkButton(const QString &text) : mNewProfileDialog->setOkButtonEnabled(false); } -void DataFilesPage::updateSplitter() -{ - // Sigh, update the saved splitter size in settings only when moved - // Since getting mSplitter->sizes() if page is hidden returns invalid values - QList sizes = splitter->sizes(); - - mLauncherSettings.setValue(QString("General/MastersTable/width"), QString::number(sizes.at(0))); - mLauncherSettings.setValue(QString("General/PluginsTable/width"), QString::number(sizes.at(1))); -} - -void DataFilesPage::updateViews() -{ - // Ensure the columns are hidden because sort() re-enables them - /* - mastersTable->setColumnHidden(1, true); - mastersTable->setColumnHidden(2, true); - mastersTable->setColumnHidden(3, true); - mastersTable->setColumnHidden(4, true); - mastersTable->setColumnHidden(5, true); - mastersTable->setColumnHidden(6, true); - mastersTable->setColumnHidden(7, true); - mastersTable->setColumnHidden(8, true); -*/ - pluginsTable->setColumnHidden(1, true); - pluginsTable->setColumnHidden(2, true); - pluginsTable->setColumnHidden(3, true); - pluginsTable->setColumnHidden(4, true); - pluginsTable->setColumnHidden(5, true); - pluginsTable->setColumnHidden(6, true); - pluginsTable->setColumnHidden(7, true); - pluginsTable->setColumnHidden(8, true); -} - void DataFilesPage::setProfilesComboBoxIndex(int index) { profilesComboBox->setCurrentIndex(index); } -void DataFilesPage::slotCurrentIndexChanged(int index) -{ - emit profileChanged(index); -} - QAbstractItemModel* DataFilesPage::profilesComboBoxModel() { return profilesComboBox->model(); @@ -282,54 +229,13 @@ void DataFilesPage::on_deleteProfileAction_triggered() } } -void DataFilesPage::on_checkAction_triggered() -{ - if (pluginsTable->hasFocus()) - setPluginsCheckstates(Qt::Checked); - - //if (mastersTable->hasFocus()) - // setMastersCheckstates(Qt::Checked); - -} - -void DataFilesPage::on_uncheckAction_triggered() -{ - if (pluginsTable->hasFocus()) - setPluginsCheckstates(Qt::Unchecked); - - //if (mastersTable->hasFocus()) - // setMastersCheckstates(Qt::Unchecked); -} - -void DataFilesPage::setMastersCheckstates(Qt::CheckState state) -{/* - //if (!mastersTable->selectionModel()->hasSelection()) { - // return; - //} - - //QModelIndexList indexes = mastersTable->selectionModel()->selectedIndexes(); - - foreach (const QModelIndex &index, indexes) - { - if (!index.isValid()) - return; - - QModelIndex sourceIndex = mMastersProxyModel->mapToSource(index); - - if (!sourceIndex.isValid()) - return; - - mDataFilesModel->setCheckState(sourceIndex, state); - }*/ -} - void DataFilesPage::setPluginsCheckstates(Qt::CheckState state) { - if (!pluginsTable->selectionModel()->hasSelection()) { + if (!pluginView->selectionModel()->hasSelection()) { return; } - QModelIndexList indexes = pluginsTable->selectionModel()->selectedIndexes(); + QModelIndexList indexes = pluginView->selectionModel()->selectedIndexes(); foreach (const QModelIndex &index, indexes) { @@ -389,7 +295,7 @@ void DataFilesPage::profileRenamed(const QString &previous, const QString &curre loadSettings(); } - +/* void DataFilesPage::showContextMenu(const QPoint &point) { QObject *object = QObject::sender(); @@ -398,12 +304,12 @@ void DataFilesPage::showContextMenu(const QPoint &point) if (!object) return; - if (object->objectName() == QLatin1String("PluginsTable")) { - if (!pluginsTable->selectionModel()->hasSelection()) + if (object->objectName() == QLatin1String("PluginView")) { + if (!pluginView->selectionModel()->hasSelection()) return; - QPoint globalPos = pluginsTable->mapToGlobal(point); - QModelIndexList indexes = pluginsTable->selectionModel()->selectedIndexes(); + QPoint globalPos = pluginView->mapToGlobal(point); + QModelIndexList indexes = pluginView->selectionModel()->selectedIndexes(); // Show the check/uncheck actions depending on the state of the selected items uncheckAction->setEnabled(false); @@ -427,13 +333,13 @@ void DataFilesPage::showContextMenu(const QPoint &point) // Show menu mContextMenu->exec(globalPos); } -/* - if (object->objectName() == QLatin1String("MastersTable")) { - if (!mastersTable->selectionModel()->hasSelection()) + + if (object->objectName() == QLatin1String("MasterView")) { + if (!masterView->selectionModel()->hasSelection()) return; - QPoint globalPos = mastersTable->mapToGlobal(point); - QModelIndexList indexes = mastersTable->selectionModel()->selectedIndexes(); + QPoint globalPos = masterView->mapToGlobal(point); + QModelIndexList indexes = masterView->selectionModel()->selectedIndexes(); // Show the check/uncheck actions depending on the state of the selected items uncheckAction->setEnabled(false); @@ -456,5 +362,6 @@ void DataFilesPage::showContextMenu(const QPoint &point) mContextMenu->exec(globalPos); } - */ + } +*/ diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index 1c528ab26..db391519f 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -38,21 +38,16 @@ signals: public slots: void setProfilesComboBoxIndex(int index); - void showContextMenu(const QPoint &point); + //void showContextMenu(const QPoint &point); void profileChanged(const QString &previous, const QString ¤t); void profileRenamed(const QString &previous, const QString ¤t); void updateOkButton(const QString &text); - void updateSplitter(); - void updateViews(); // Action slots void on_newProfileAction_triggered(); void on_deleteProfileAction_triggered(); - void on_checkAction_triggered(); - void on_uncheckAction_triggered(); private slots: - void slotCurrentIndexChanged(int index); private: @@ -65,7 +60,6 @@ private: TextInputDialog *mNewProfileDialog; - void setMastersCheckstates(Qt::CheckState state); void setPluginsCheckstates(Qt::CheckState state); void createActions(); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 2f3a6dc21..9f1c72068 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -49,23 +49,11 @@ FileDialog::FileDialog(QWidget *parent) : verticalLayout->addLayout(nameLayout); verticalLayout->addWidget(mButtonBox); - // Set sizes - QList sizeList; - sizeList << 175; - sizeList << 200; - - splitter->setSizes(sizeList); - resize(600, 400); // connect(mDataFilesModel, SIGNAL(checkedItemsChanged(QStringList)), this, SLOT(updateOpenButton(QStringList))); //connect(mNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateCreateButton(QString))); - //connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); - - // connect(pluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); - //connect(mastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); - // connect(mCreateButton, SIGNAL(clicked()), this, SLOT(createButtonClicked())); // connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept())); @@ -89,13 +77,6 @@ void FileDialog::updateCreateButton(const QString &name) mCreateButton->setEnabled(!name.isEmpty()); } -/* -void FileDialog::filterChanged(const QString &filter) -{ - QRegExp filterRe(filter, Qt::CaseInsensitive, QRegExp::FixedString); - mFilterProxyModel->setFilterRegExp(filterRe); -} -*/ QString FileDialog::fileName() { diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 7944b7fb3..232f250be 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -42,9 +42,6 @@ private slots: void updateOpenButton(const QStringList &items); void updateCreateButton(const QString &name); - - //void filterChanged(const QString &filter); - void createButtonClicked(); private: diff --git a/components/fileorderlist/contentselector.cpp b/components/fileorderlist/contentselector.cpp index 6f8a86a49..e7ab9b0cf 100644 --- a/components/fileorderlist/contentselector.cpp +++ b/components/fileorderlist/contentselector.cpp @@ -6,6 +6,7 @@ #include +#include FileOrderList::ContentSelector::ContentSelector(QWidget *parent) : QWidget(parent) { @@ -22,40 +23,20 @@ void FileOrderList::ContentSelector::buildModelsAndViews() mPluginsProxyModel = new PluginsProxyModel (this, mDataFilesModel); masterView->setModel(mMasterProxyModel); -/* - mastersTable->setModel(mMastersProxyModel); - mastersTable->setObjectName("MastersTable"); - mastersTable->setContextMenuPolicy(Qt::CustomContextMenu); - mastersTable->setSortingEnabled(false); - mastersTable->setSelectionBehavior(QAbstractItemView::SelectRows); - mastersTable->setSelectionMode(QAbstractItemView::ExtendedSelection); - mastersTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - mastersTable->setAlternatingRowColors(true); - mastersTable->horizontalHeader()->setStretchLastSection(true); - - // Set the row height to the size of the checkboxes - mastersTable->verticalHeader()->setDefaultSectionSize(height); - mastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); - mastersTable->verticalHeader()->hide(); -*/ - pluginsTable->setModel(mPluginsProxyModel); - pluginsTable->setObjectName("PluginsTable"); - pluginsTable->setContextMenuPolicy(Qt::CustomContextMenu); - pluginsTable->setSortingEnabled(false); - pluginsTable->setSelectionBehavior(QAbstractItemView::SelectRows); - pluginsTable->setSelectionMode(QAbstractItemView::ExtendedSelection); - pluginsTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - pluginsTable->setAlternatingRowColors(true); - pluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); - pluginsTable->horizontalHeader()->setStretchLastSection(true); + pluginView->setModel(mPluginsProxyModel); connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); + connect(masterView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentMasterIndexChanged(int))); + + connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); } void FileOrderList::ContentSelector::addFiles(const QString &path) { mDataFilesModel->addFiles(path); mDataFilesModel->sort(3); // Sort by date accessed + masterView->setCurrentIndex(-1); + mDataFilesModel->uncheckAll(); } void FileOrderList::ContentSelector::setEncoding(const QString &encoding) @@ -63,39 +44,22 @@ void FileOrderList::ContentSelector::setEncoding(const QString &encoding) mDataFilesModel->setEncoding(encoding); } -void FileOrderList::ContentSelector::setCheckState(QModelIndex index) +void FileOrderList::ContentSelector::setCheckState(QModelIndex index, QSortFilterProxyModel *model) { if (!index.isValid()) return; - QObject *object = QObject::sender(); - - // Not a signal-slot call - if (!object) + if (!model) return; + QModelIndex sourceIndex = model->mapToSource(index); - if (object->objectName() == QLatin1String("PluginsTable")) { - QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(index); - - if (sourceIndex.isValid()) { - (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) - ? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked) - : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); - } + if (sourceIndex.isValid()) + { + (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) + ? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked) + : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); } - - if (object->objectName() == QLatin1String("MastersTable")) { - QModelIndex sourceIndex = mMasterProxyModel->mapToSource(index); - - if (sourceIndex.isValid()) { - (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) - ? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked) - : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); - } - } - - return; } QStringList FileOrderList::ContentSelector::checkedItemsPaths() @@ -106,13 +70,30 @@ QStringList FileOrderList::ContentSelector::checkedItemsPaths() void FileOrderList::ContentSelector::updateViews() { // Ensure the columns are hidden because sort() re-enables them - pluginsTable->setColumnHidden(1, true); - pluginsTable->setColumnHidden(3, true); - pluginsTable->setColumnHidden(4, true); - pluginsTable->setColumnHidden(5, true); - pluginsTable->setColumnHidden(6, true); - pluginsTable->setColumnHidden(7, true); - pluginsTable->setColumnHidden(8, true); - pluginsTable->resizeColumnsToContents(); + pluginView->setColumnHidden(1, 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 FileOrderList::ContentSelector::slotCurrentProfileIndexChanged(int index) +{ + emit profileChanged(index); +} + +void FileOrderList::ContentSelector::slotCurrentMasterIndexChanged(int index) +{ + qDebug() << "index Changed: " << index; + QObject *object = QObject::sender(); + + // Not a signal-slot call + if (!object) + return; + setCheckState(mMasterProxyModel->index(index, 0), mMasterProxyModel); } diff --git a/components/fileorderlist/contentselector.hpp b/components/fileorderlist/contentselector.hpp index 914e8bacb..138ffc629 100644 --- a/components/fileorderlist/contentselector.hpp +++ b/components/fileorderlist/contentselector.hpp @@ -30,11 +30,16 @@ namespace FileOrderList void addFiles(const QString &path); void setEncoding(const QString &encoding); - void setCheckState(QModelIndex index); + void setCheckState(QModelIndex index, QSortFilterProxyModel *model); QStringList checkedItemsPaths(); + signals: + void profileChanged(int index); + private slots: void updateViews(); + void slotCurrentProfileIndexChanged(int index); + void slotCurrentMasterIndexChanged(int index); }; } diff --git a/components/fileorderlist/model/datafilesmodel.cpp b/components/fileorderlist/model/datafilesmodel.cpp index 3f63e73cc..8e27f1f75 100644 --- a/components/fileorderlist/model/datafilesmodel.cpp +++ b/components/fileorderlist/model/datafilesmodel.cpp @@ -174,7 +174,7 @@ Qt::ItemFlags DataFilesModel::flags(const QModelIndex &index) const if (index.column() == 0) { return Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; } else { - return Qt::NoItemFlags | Qt::ItemIsSelectable; + return Qt::ItemIsSelectable; } } @@ -270,7 +270,7 @@ void DataFilesModel::addFiles(const QString &path) { QDir dir(path); QStringList filters; - filters << "*.esp" << "*.esm"; + filters << "*.esp" << "*.esm" << "*.omwgame" << "*.omwaddon"; dir.setNameFilters(filters); // Create a decoder for non-latin characters in esx metadata @@ -319,9 +319,10 @@ void DataFilesModel::addFiles(const QString &path) // 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 esp: " << e.what(); + qWarning() << "Error reading addon file: " << e.what(); continue; } @@ -436,14 +437,10 @@ QStringList DataFilesModel::uncheckedItems() bool DataFilesModel::canBeChecked(EsmFile *file) const { //element can be checked if all its dependencies are - bool canBeChecked = true; foreach (const QString &master, file->masters()) { if (!mCheckStates.contains(master) || mCheckStates[master] != Qt::Checked) - { - canBeChecked = false; - break; - } + return false; } - return canBeChecked; + return true; } diff --git a/components/fileorderlist/model/pluginsproxymodel.cpp b/components/fileorderlist/model/pluginsproxymodel.cpp index 9e3cdd730..18aebc6b6 100644 --- a/components/fileorderlist/model/pluginsproxymodel.cpp +++ b/components/fileorderlist/model/pluginsproxymodel.cpp @@ -2,7 +2,7 @@ #include "datafilesmodel.hpp" PluginsProxyModel::PluginsProxyModel(QObject *parent, DataFilesModel *model) : - QSortFilterProxyModel(parent), mSourceModel (model) + QSortFilterProxyModel(parent) { setFilterRegExp (QString("addon")); setFilterRole (Qt::UserRole); @@ -25,7 +25,7 @@ QVariant PluginsProxyModel::data(const QModelIndex &index, int role) const if (index.column() != 0) return QVariant(); - return mSourceModel->checkState(index); + return static_cast(sourceModel())->checkState(mapToSource(index)); } }; diff --git a/components/fileorderlist/model/pluginsproxymodel.hpp b/components/fileorderlist/model/pluginsproxymodel.hpp index e148ea3b1..cfade092e 100644 --- a/components/fileorderlist/model/pluginsproxymodel.hpp +++ b/components/fileorderlist/model/pluginsproxymodel.hpp @@ -11,8 +11,6 @@ class PluginsProxyModel : public QSortFilterProxyModel { Q_OBJECT - DataFilesModel *mSourceModel; - public: explicit PluginsProxyModel(QObject *parent = 0, DataFilesModel *model = 0); diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 816d288a6..87213c5cc 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -10,7 +10,7 @@ 304 - + @@ -23,21 +23,33 @@ - - - - 0 - 0 - - - - Qt::Horizontal - - - false - - - + + + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectItems + + + Qt::ElideLeft + + + false + + + false + + + false + + + + From a9db983233dde491c0b90b53ca427e4427d0188f Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 18 Aug 2013 07:29:48 -0500 Subject: [PATCH 012/118] Fixing row-click selection --- components/fileorderlist/contentselector.cpp | 2 +- files/ui/datafilespage.ui | 24 ++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/components/fileorderlist/contentselector.cpp b/components/fileorderlist/contentselector.cpp index e7ab9b0cf..6254601dc 100644 --- a/components/fileorderlist/contentselector.cpp +++ b/components/fileorderlist/contentselector.cpp @@ -26,8 +26,8 @@ void FileOrderList::ContentSelector::buildModelsAndViews() pluginView->setModel(mPluginsProxyModel); connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); + //connect(pluginView, SIGNAL()) connect(masterView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentMasterIndexChanged(int))); - connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); } diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 87213c5cc..cf6f30b99 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -29,11 +29,14 @@ QAbstractItemView::NoEditTriggers + + true + QAbstractItemView::SingleSelection - QAbstractItemView::SelectItems + QAbstractItemView::SelectRows Qt::ElideLeft @@ -153,5 +156,22 @@ - + + + pluginView + clicked(QModelIndex) + checkAction + toggle() + + + 258 + 151 + + + -1 + -1 + + + + From 66e50343adba0bfca059da804dee0b865eba84d9 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 18 Aug 2013 08:54:51 -0500 Subject: [PATCH 013/118] Fixed row-selection/check feature --- components/fileorderlist/contentselector.cpp | 11 ++++++-- components/fileorderlist/contentselector.hpp | 3 ++ .../fileorderlist/model/datafilesmodel.cpp | 27 +++++++++--------- files/ui/datafilespage.ui | 28 +++++++------------ 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/components/fileorderlist/contentselector.cpp b/components/fileorderlist/contentselector.cpp index 6254601dc..b2a5c5ba5 100644 --- a/components/fileorderlist/contentselector.cpp +++ b/components/fileorderlist/contentselector.cpp @@ -7,6 +7,9 @@ #include #include +#include +#include + FileOrderList::ContentSelector::ContentSelector(QWidget *parent) : QWidget(parent) { @@ -26,7 +29,7 @@ void FileOrderList::ContentSelector::buildModelsAndViews() pluginView->setModel(mPluginsProxyModel); connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); - //connect(pluginView, SIGNAL()) + connect(pluginView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotPluginTableItemClicked(const QModelIndex &))); connect(masterView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentMasterIndexChanged(int))); connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); } @@ -88,7 +91,6 @@ void FileOrderList::ContentSelector::slotCurrentProfileIndexChanged(int index) void FileOrderList::ContentSelector::slotCurrentMasterIndexChanged(int index) { - qDebug() << "index Changed: " << index; QObject *object = QObject::sender(); // Not a signal-slot call @@ -97,3 +99,8 @@ void FileOrderList::ContentSelector::slotCurrentMasterIndexChanged(int index) setCheckState(mMasterProxyModel->index(index, 0), mMasterProxyModel); } + +void FileOrderList::ContentSelector::slotPluginTableItemClicked(const QModelIndex &index) +{ + setCheckState(index, mPluginsProxyModel); +} diff --git a/components/fileorderlist/contentselector.hpp b/components/fileorderlist/contentselector.hpp index 138ffc629..f1d8f6927 100644 --- a/components/fileorderlist/contentselector.hpp +++ b/components/fileorderlist/contentselector.hpp @@ -30,8 +30,10 @@ namespace FileOrderList void addFiles(const QString &path); void setEncoding(const QString &encoding); + void setPluginCheckState(); void setCheckState(QModelIndex index, QSortFilterProxyModel *model); QStringList checkedItemsPaths(); + void on_checkAction_triggered(); signals: void profileChanged(int index); @@ -40,6 +42,7 @@ namespace FileOrderList void updateViews(); void slotCurrentProfileIndexChanged(int index); void slotCurrentMasterIndexChanged(int index); + void slotPluginTableItemClicked(const QModelIndex &index); }; } diff --git a/components/fileorderlist/model/datafilesmodel.cpp b/components/fileorderlist/model/datafilesmodel.cpp index 8e27f1f75..ae842381e 100644 --- a/components/fileorderlist/model/datafilesmodel.cpp +++ b/components/fileorderlist/model/datafilesmodel.cpp @@ -30,7 +30,19 @@ void DataFilesModel::setEncoding(const QString &encoding) void DataFilesModel::setCheckState(const QModelIndex &index, Qt::CheckState state) { - setData(index, state, Qt::CheckStateRole); + 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 DataFilesModel::checkState(const QModelIndex &index) @@ -210,19 +222,6 @@ bool DataFilesModel::setData(const QModelIndex &index, const QVariant &value, in if (!index.isValid()) return false; - if (role == Qt::CheckStateRole) { - QString name = item(index.row())->fileName(); - mCheckStates[name] = static_cast(value.toInt()); - - // 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()); - return true; - } - return false; } diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index cf6f30b99..a6c1768b5 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -10,6 +10,9 @@ 304 + + Qt::DefaultContextMenu + @@ -26,6 +29,9 @@ + + Qt::DefaultContextMenu + QAbstractItemView::NoEditTriggers @@ -138,6 +144,9 @@ + + true + Check Selection @@ -156,22 +165,5 @@ - - - pluginView - clicked(QModelIndex) - checkAction - toggle() - - - 258 - 151 - - - -1 - -1 - - - - + From 45277c00825c759bb826a25e0e73cf940968086f Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 18 Aug 2013 09:34:33 -0500 Subject: [PATCH 014/118] Minor changes Stretched table columns to fit widget width Reduced width of opencs file dialog Hid the file size column for launcher Added alternating row colors in table view --- apps/launcher/datafilespage.cpp | 1 + apps/opencs/view/doc/filedialog.cpp | 2 +- components/fileorderlist/contentselector.cpp | 1 + files/ui/datafilespage.ui | 9 +++++++++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 5cbcae545..44f92d7fe 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -30,6 +30,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam , ContentSelector(parent) { + pluginView->hideColumn(2); // Create a dialog for the new profile name input mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 9f1c72068..252c760fa 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -49,7 +49,7 @@ FileDialog::FileDialog(QWidget *parent) : verticalLayout->addLayout(nameLayout); verticalLayout->addWidget(mButtonBox); - resize(600, 400); + resize(400, 400); // connect(mDataFilesModel, SIGNAL(checkedItemsChanged(QStringList)), this, SLOT(updateOpenButton(QStringList))); //connect(mNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateCreateButton(QString))); diff --git a/components/fileorderlist/contentselector.cpp b/components/fileorderlist/contentselector.cpp index b2a5c5ba5..27be996fc 100644 --- a/components/fileorderlist/contentselector.cpp +++ b/components/fileorderlist/contentselector.cpp @@ -27,6 +27,7 @@ void FileOrderList::ContentSelector::buildModelsAndViews() masterView->setModel(mMasterProxyModel); pluginView->setModel(mPluginsProxyModel); + pluginView-> connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); connect(pluginView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotPluginTableItemClicked(const QModelIndex &))); diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index a6c1768b5..07ad9d3ba 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -29,6 +29,12 @@ + + + 0 + 0 + + Qt::DefaultContextMenu @@ -53,6 +59,9 @@ false + + true + false From d0363b037cc9716ceb5f7d03594a1a836e8724c1 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 18 Aug 2013 09:41:02 -0500 Subject: [PATCH 015/118] Renamed components/fileorderlist to components/esxselector --- components/CMakeLists.txt | 2 +- components/{fileorderlist => esxselector}/contentselector.cpp | 0 components/{fileorderlist => esxselector}/contentselector.hpp | 0 components/{fileorderlist => esxselector}/masterproxymodel.cpp | 0 components/{fileorderlist => esxselector}/masterproxymodel.hpp | 0 .../{fileorderlist => esxselector}/model/datafilesmodel.cpp | 0 .../{fileorderlist => esxselector}/model/datafilesmodel.hpp | 0 components/{fileorderlist => esxselector}/model/esm/esmfile.cpp | 0 components/{fileorderlist => esxselector}/model/esm/esmfile.hpp | 0 components/{fileorderlist => esxselector}/model/modelitem.cpp | 0 components/{fileorderlist => esxselector}/model/modelitem.hpp | 0 .../{fileorderlist => esxselector}/model/pluginsproxymodel.cpp | 0 .../{fileorderlist => esxselector}/model/pluginsproxymodel.hpp | 0 .../{fileorderlist => esxselector}/utils/comboboxlineedit.cpp | 0 .../{fileorderlist => esxselector}/utils/comboboxlineedit.hpp | 0 components/{fileorderlist => esxselector}/utils/lineedit.cpp | 0 components/{fileorderlist => esxselector}/utils/lineedit.hpp | 0 components/{fileorderlist => esxselector}/utils/naturalsort.cpp | 0 components/{fileorderlist => esxselector}/utils/naturalsort.hpp | 0 .../{fileorderlist => esxselector}/utils/profilescombobox.cpp | 0 .../{fileorderlist => esxselector}/utils/profilescombobox.hpp | 0 21 files changed, 1 insertion(+), 1 deletion(-) rename components/{fileorderlist => esxselector}/contentselector.cpp (100%) rename components/{fileorderlist => esxselector}/contentselector.hpp (100%) rename components/{fileorderlist => esxselector}/masterproxymodel.cpp (100%) rename components/{fileorderlist => esxselector}/masterproxymodel.hpp (100%) rename components/{fileorderlist => esxselector}/model/datafilesmodel.cpp (100%) rename components/{fileorderlist => esxselector}/model/datafilesmodel.hpp (100%) rename components/{fileorderlist => esxselector}/model/esm/esmfile.cpp (100%) rename components/{fileorderlist => esxselector}/model/esm/esmfile.hpp (100%) rename components/{fileorderlist => esxselector}/model/modelitem.cpp (100%) rename components/{fileorderlist => esxselector}/model/modelitem.hpp (100%) rename components/{fileorderlist => esxselector}/model/pluginsproxymodel.cpp (100%) rename components/{fileorderlist => esxselector}/model/pluginsproxymodel.hpp (100%) rename components/{fileorderlist => esxselector}/utils/comboboxlineedit.cpp (100%) rename components/{fileorderlist => esxselector}/utils/comboboxlineedit.hpp (100%) rename components/{fileorderlist => esxselector}/utils/lineedit.cpp (100%) rename components/{fileorderlist => esxselector}/utils/lineedit.hpp (100%) rename components/{fileorderlist => esxselector}/utils/naturalsort.cpp (100%) rename components/{fileorderlist => esxselector}/utils/naturalsort.hpp (100%) rename components/{fileorderlist => esxselector}/utils/profilescombobox.cpp (100%) rename components/{fileorderlist => esxselector}/utils/profilescombobox.hpp (100%) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 19af6c3b2..85f1a3508 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -71,7 +71,7 @@ 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 (fileorderlist + add_component_qt_dir (esxselector masterproxymodel contentselector model/modelitem model/datafilesmodel model/pluginsproxymodel model/esm/esmfile utils/profilescombobox utils/comboboxlineedit utils/lineedit utils/naturalsort diff --git a/components/fileorderlist/contentselector.cpp b/components/esxselector/contentselector.cpp similarity index 100% rename from components/fileorderlist/contentselector.cpp rename to components/esxselector/contentselector.cpp diff --git a/components/fileorderlist/contentselector.hpp b/components/esxselector/contentselector.hpp similarity index 100% rename from components/fileorderlist/contentselector.hpp rename to components/esxselector/contentselector.hpp diff --git a/components/fileorderlist/masterproxymodel.cpp b/components/esxselector/masterproxymodel.cpp similarity index 100% rename from components/fileorderlist/masterproxymodel.cpp rename to components/esxselector/masterproxymodel.cpp diff --git a/components/fileorderlist/masterproxymodel.hpp b/components/esxselector/masterproxymodel.hpp similarity index 100% rename from components/fileorderlist/masterproxymodel.hpp rename to components/esxselector/masterproxymodel.hpp diff --git a/components/fileorderlist/model/datafilesmodel.cpp b/components/esxselector/model/datafilesmodel.cpp similarity index 100% rename from components/fileorderlist/model/datafilesmodel.cpp rename to components/esxselector/model/datafilesmodel.cpp diff --git a/components/fileorderlist/model/datafilesmodel.hpp b/components/esxselector/model/datafilesmodel.hpp similarity index 100% rename from components/fileorderlist/model/datafilesmodel.hpp rename to components/esxselector/model/datafilesmodel.hpp diff --git a/components/fileorderlist/model/esm/esmfile.cpp b/components/esxselector/model/esm/esmfile.cpp similarity index 100% rename from components/fileorderlist/model/esm/esmfile.cpp rename to components/esxselector/model/esm/esmfile.cpp diff --git a/components/fileorderlist/model/esm/esmfile.hpp b/components/esxselector/model/esm/esmfile.hpp similarity index 100% rename from components/fileorderlist/model/esm/esmfile.hpp rename to components/esxselector/model/esm/esmfile.hpp diff --git a/components/fileorderlist/model/modelitem.cpp b/components/esxselector/model/modelitem.cpp similarity index 100% rename from components/fileorderlist/model/modelitem.cpp rename to components/esxselector/model/modelitem.cpp diff --git a/components/fileorderlist/model/modelitem.hpp b/components/esxselector/model/modelitem.hpp similarity index 100% rename from components/fileorderlist/model/modelitem.hpp rename to components/esxselector/model/modelitem.hpp diff --git a/components/fileorderlist/model/pluginsproxymodel.cpp b/components/esxselector/model/pluginsproxymodel.cpp similarity index 100% rename from components/fileorderlist/model/pluginsproxymodel.cpp rename to components/esxselector/model/pluginsproxymodel.cpp diff --git a/components/fileorderlist/model/pluginsproxymodel.hpp b/components/esxselector/model/pluginsproxymodel.hpp similarity index 100% rename from components/fileorderlist/model/pluginsproxymodel.hpp rename to components/esxselector/model/pluginsproxymodel.hpp diff --git a/components/fileorderlist/utils/comboboxlineedit.cpp b/components/esxselector/utils/comboboxlineedit.cpp similarity index 100% rename from components/fileorderlist/utils/comboboxlineedit.cpp rename to components/esxselector/utils/comboboxlineedit.cpp diff --git a/components/fileorderlist/utils/comboboxlineedit.hpp b/components/esxselector/utils/comboboxlineedit.hpp similarity index 100% rename from components/fileorderlist/utils/comboboxlineedit.hpp rename to components/esxselector/utils/comboboxlineedit.hpp diff --git a/components/fileorderlist/utils/lineedit.cpp b/components/esxselector/utils/lineedit.cpp similarity index 100% rename from components/fileorderlist/utils/lineedit.cpp rename to components/esxselector/utils/lineedit.cpp diff --git a/components/fileorderlist/utils/lineedit.hpp b/components/esxselector/utils/lineedit.hpp similarity index 100% rename from components/fileorderlist/utils/lineedit.hpp rename to components/esxselector/utils/lineedit.hpp diff --git a/components/fileorderlist/utils/naturalsort.cpp b/components/esxselector/utils/naturalsort.cpp similarity index 100% rename from components/fileorderlist/utils/naturalsort.cpp rename to components/esxselector/utils/naturalsort.cpp diff --git a/components/fileorderlist/utils/naturalsort.hpp b/components/esxselector/utils/naturalsort.hpp similarity index 100% rename from components/fileorderlist/utils/naturalsort.hpp rename to components/esxselector/utils/naturalsort.hpp diff --git a/components/fileorderlist/utils/profilescombobox.cpp b/components/esxselector/utils/profilescombobox.cpp similarity index 100% rename from components/fileorderlist/utils/profilescombobox.cpp rename to components/esxselector/utils/profilescombobox.cpp diff --git a/components/fileorderlist/utils/profilescombobox.hpp b/components/esxselector/utils/profilescombobox.hpp similarity index 100% rename from components/fileorderlist/utils/profilescombobox.hpp rename to components/esxselector/utils/profilescombobox.hpp From a14e0b32d8daa1fad311d535a65bb14c5b123b91 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 18 Aug 2013 09:48:13 -0500 Subject: [PATCH 016/118] Restructured esxselector directory Added ./view Removed ./utils and ./model/esm Relocated code accordingly. --- apps/launcher/datafilespage.hpp | 2 +- apps/opencs/view/doc/filedialog.hpp | 2 +- components/CMakeLists.txt | 7 +-- components/esxselector/model/esm/esmfile.cpp | 50 ----------------- components/esxselector/model/esm/esmfile.hpp | 54 ------------------- .../{ => model}/masterproxymodel.cpp | 4 +- .../{ => model}/masterproxymodel.hpp | 2 +- .../{utils => model}/naturalsort.cpp | 0 .../{utils => model}/naturalsort.hpp | 0 .../{utils => view}/comboboxlineedit.cpp | 0 .../{utils => view}/comboboxlineedit.hpp | 0 .../{ => view}/contentselector.cpp | 22 ++++---- .../{ => view}/contentselector.hpp | 0 .../esxselector/{utils => view}/lineedit.cpp | 0 .../esxselector/{utils => view}/lineedit.hpp | 0 .../{utils => view}/profilescombobox.cpp | 0 .../{utils => view}/profilescombobox.hpp | 0 17 files changed, 20 insertions(+), 123 deletions(-) delete mode 100644 components/esxselector/model/esm/esmfile.cpp delete mode 100644 components/esxselector/model/esm/esmfile.hpp rename components/esxselector/{ => model}/masterproxymodel.cpp (57%) rename components/esxselector/{ => model}/masterproxymodel.hpp (95%) rename components/esxselector/{utils => model}/naturalsort.cpp (100%) rename components/esxselector/{utils => model}/naturalsort.hpp (100%) rename components/esxselector/{utils => view}/comboboxlineedit.cpp (100%) rename components/esxselector/{utils => view}/comboboxlineedit.hpp (100%) rename components/esxselector/{ => view}/contentselector.cpp (74%) rename components/esxselector/{ => view}/contentselector.hpp (100%) rename components/esxselector/{utils => view}/lineedit.cpp (100%) rename components/esxselector/{utils => view}/lineedit.hpp (100%) rename components/esxselector/{utils => view}/profilescombobox.cpp (100%) rename components/esxselector/{utils => view}/profilescombobox.hpp (100%) diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index db391519f..356cb88d6 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -20,7 +20,7 @@ class PluginsProxyModel; namespace Files { struct ConfigurationManager; } -class DataFilesPage : public FileOrderList::ContentSelector +class DataFilesPage : public EsxSelector::ContentSelector { Q_OBJECT public: diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 232f250be..1b4d09745 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -18,7 +18,7 @@ class QMenu; class DataFilesModel; class PluginsProxyModel; -class FileDialog : public FileOrderList::ContentSelector +class FileDialog : public EsxSelector::ContentSelector { Q_OBJECT public: diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 85f1a3508..4f14fa9d9 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -72,9 +72,10 @@ find_package(Qt4 COMPONENTS QtCore QtGui) if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) add_component_qt_dir (esxselector - masterproxymodel contentselector - model/modelitem model/datafilesmodel model/pluginsproxymodel model/esm/esmfile - utils/profilescombobox utils/comboboxlineedit utils/lineedit utils/naturalsort + model/masterproxymodel model/modelitem model/datafilesmodel + model/pluginsproxymodel model/esm/esmfile model/naturalsort + view/profilescombobox view/comboboxlineedit + view/lineedit view/contentselector ) include(${QT_USE_FILE}) diff --git a/components/esxselector/model/esm/esmfile.cpp b/components/esxselector/model/esm/esmfile.cpp deleted file mode 100644 index 93d83091e..000000000 --- a/components/esxselector/model/esm/esmfile.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "esmfile.hpp" - -EsmFile::EsmFile(QString fileName, ModelItem *parent) - : ModelItem(parent) -{ - mFileName = fileName; - mSize = 0; - mVersion = 0.0f; -} - -void EsmFile::setFileName(const QString &fileName) -{ - mFileName = fileName; -} - -void EsmFile::setAuthor(const QString &author) -{ - mAuthor = author; -} - -void EsmFile::setSize(const int size) -{ - mSize = size; -} - -void EsmFile::setDates(const QDateTime &modified, const QDateTime &accessed) -{ - mModified = modified; - mAccessed = accessed; -} - -void EsmFile::setVersion(float version) -{ - mVersion = version; -} - -void EsmFile::setPath(const QString &path) -{ - mPath = path; -} - -void EsmFile::setMasters(const QStringList &masters) -{ - mMasters = masters; -} - -void EsmFile::setDescription(const QString &description) -{ - mDescription = description; -} diff --git a/components/esxselector/model/esm/esmfile.hpp b/components/esxselector/model/esm/esmfile.hpp deleted file mode 100644 index 52b3fbd00..000000000 --- a/components/esxselector/model/esm/esmfile.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef ESMFILE_HPP -#define ESMFILE_HPP - -#include -#include - -#include "../modelitem.hpp" - -class EsmFile : public ModelItem -{ - Q_OBJECT - Q_PROPERTY(QString filename READ fileName) - -public: - EsmFile(QString fileName = QString(), ModelItem *parent = 0); - - ~EsmFile() - {} - - void setFileName(const QString &fileName); - void setAuthor(const QString &author); - void setSize(const int size); - void setDates(const QDateTime &modified, const QDateTime &accessed); - void setVersion(const float version); - void setPath(const QString &path); - void setMasters(const QStringList &masters); - void setDescription(const QString &description); - - inline QString fileName() const { return mFileName; } - inline QString author() const { return mAuthor; } - inline int size() const { return mSize; } - inline QDateTime modified() const { return mModified; } - inline QDateTime accessed() const { return mAccessed; } - inline float version() const { return mVersion; } - inline QString path() const { return mPath; } - inline QStringList masters() const { return mMasters; } - inline QString description() const { return mDescription; } - - -private: - QString mFileName; - QString mAuthor; - int mSize; - QDateTime mModified; - QDateTime mAccessed; - float mVersion; - QString mPath; - QStringList mMasters; - QString mDescription; - -}; - - -#endif diff --git a/components/esxselector/masterproxymodel.cpp b/components/esxselector/model/masterproxymodel.cpp similarity index 57% rename from components/esxselector/masterproxymodel.cpp rename to components/esxselector/model/masterproxymodel.cpp index 7701d4f17..04a7f0033 100644 --- a/components/esxselector/masterproxymodel.cpp +++ b/components/esxselector/model/masterproxymodel.cpp @@ -1,6 +1,6 @@ #include "masterproxymodel.hpp" -FileOrderList::MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableModel* model) : +EsxSelector::MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableModel* model) : QSortFilterProxyModel(parent) { setFilterRegExp(QString("game")); @@ -10,7 +10,7 @@ FileOrderList::MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTabl setSourceModel (model); } -QVariant FileOrderList::MasterProxyModel::data(const QModelIndex &index, int role) const +QVariant EsxSelector::MasterProxyModel::data(const QModelIndex &index, int role) const { return QSortFilterProxyModel::data (index, role); } diff --git a/components/esxselector/masterproxymodel.hpp b/components/esxselector/model/masterproxymodel.hpp similarity index 95% rename from components/esxselector/masterproxymodel.hpp rename to components/esxselector/model/masterproxymodel.hpp index 49ca369de..6fbdd3154 100644 --- a/components/esxselector/masterproxymodel.hpp +++ b/components/esxselector/model/masterproxymodel.hpp @@ -5,7 +5,7 @@ class QAbstractTableModel; -namespace FileOrderList +namespace EsxSelector { class MasterProxyModel : public QSortFilterProxyModel { diff --git a/components/esxselector/utils/naturalsort.cpp b/components/esxselector/model/naturalsort.cpp similarity index 100% rename from components/esxselector/utils/naturalsort.cpp rename to components/esxselector/model/naturalsort.cpp diff --git a/components/esxselector/utils/naturalsort.hpp b/components/esxselector/model/naturalsort.hpp similarity index 100% rename from components/esxselector/utils/naturalsort.hpp rename to components/esxselector/model/naturalsort.hpp diff --git a/components/esxselector/utils/comboboxlineedit.cpp b/components/esxselector/view/comboboxlineedit.cpp similarity index 100% rename from components/esxselector/utils/comboboxlineedit.cpp rename to components/esxselector/view/comboboxlineedit.cpp diff --git a/components/esxselector/utils/comboboxlineedit.hpp b/components/esxselector/view/comboboxlineedit.hpp similarity index 100% rename from components/esxselector/utils/comboboxlineedit.hpp rename to components/esxselector/view/comboboxlineedit.hpp diff --git a/components/esxselector/contentselector.cpp b/components/esxselector/view/contentselector.cpp similarity index 74% rename from components/esxselector/contentselector.cpp rename to components/esxselector/view/contentselector.cpp index 27be996fc..16139d9e6 100644 --- a/components/esxselector/contentselector.cpp +++ b/components/esxselector/view/contentselector.cpp @@ -10,19 +10,19 @@ #include #include -FileOrderList::ContentSelector::ContentSelector(QWidget *parent) : +EsxSelector::ContentSelector::ContentSelector(QWidget *parent) : QWidget(parent) { setupUi(this); buildModelsAndViews(); } -void FileOrderList::ContentSelector::buildModelsAndViews() +void EsxSelector::ContentSelector::buildModelsAndViews() { // Models mDataFilesModel = new DataFilesModel (this); - mMasterProxyModel = new FileOrderList::MasterProxyModel (this, mDataFilesModel); + mMasterProxyModel = new EsxSelector::MasterProxyModel (this, mDataFilesModel); mPluginsProxyModel = new PluginsProxyModel (this, mDataFilesModel); masterView->setModel(mMasterProxyModel); @@ -35,7 +35,7 @@ void FileOrderList::ContentSelector::buildModelsAndViews() connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); } -void FileOrderList::ContentSelector::addFiles(const QString &path) +void EsxSelector::ContentSelector::addFiles(const QString &path) { mDataFilesModel->addFiles(path); mDataFilesModel->sort(3); // Sort by date accessed @@ -43,12 +43,12 @@ void FileOrderList::ContentSelector::addFiles(const QString &path) mDataFilesModel->uncheckAll(); } -void FileOrderList::ContentSelector::setEncoding(const QString &encoding) +void EsxSelector::ContentSelector::setEncoding(const QString &encoding) { mDataFilesModel->setEncoding(encoding); } -void FileOrderList::ContentSelector::setCheckState(QModelIndex index, QSortFilterProxyModel *model) +void EsxSelector::ContentSelector::setCheckState(QModelIndex index, QSortFilterProxyModel *model) { if (!index.isValid()) return; @@ -66,12 +66,12 @@ void FileOrderList::ContentSelector::setCheckState(QModelIndex index, QSortFilte } } -QStringList FileOrderList::ContentSelector::checkedItemsPaths() +QStringList EsxSelector::ContentSelector::checkedItemsPaths() { return mDataFilesModel->checkedItemsPaths(); } -void FileOrderList::ContentSelector::updateViews() +void EsxSelector::ContentSelector::updateViews() { // Ensure the columns are hidden because sort() re-enables them pluginView->setColumnHidden(1, true); @@ -85,12 +85,12 @@ void FileOrderList::ContentSelector::updateViews() } -void FileOrderList::ContentSelector::slotCurrentProfileIndexChanged(int index) +void EsxSelector::ContentSelector::slotCurrentProfileIndexChanged(int index) { emit profileChanged(index); } -void FileOrderList::ContentSelector::slotCurrentMasterIndexChanged(int index) +void EsxSelector::ContentSelector::slotCurrentMasterIndexChanged(int index) { QObject *object = QObject::sender(); @@ -101,7 +101,7 @@ void FileOrderList::ContentSelector::slotCurrentMasterIndexChanged(int index) setCheckState(mMasterProxyModel->index(index, 0), mMasterProxyModel); } -void FileOrderList::ContentSelector::slotPluginTableItemClicked(const QModelIndex &index) +void EsxSelector::ContentSelector::slotPluginTableItemClicked(const QModelIndex &index) { setCheckState(index, mPluginsProxyModel); } diff --git a/components/esxselector/contentselector.hpp b/components/esxselector/view/contentselector.hpp similarity index 100% rename from components/esxselector/contentselector.hpp rename to components/esxselector/view/contentselector.hpp diff --git a/components/esxselector/utils/lineedit.cpp b/components/esxselector/view/lineedit.cpp similarity index 100% rename from components/esxselector/utils/lineedit.cpp rename to components/esxselector/view/lineedit.cpp diff --git a/components/esxselector/utils/lineedit.hpp b/components/esxselector/view/lineedit.hpp similarity index 100% rename from components/esxselector/utils/lineedit.hpp rename to components/esxselector/view/lineedit.hpp diff --git a/components/esxselector/utils/profilescombobox.cpp b/components/esxselector/view/profilescombobox.cpp similarity index 100% rename from components/esxselector/utils/profilescombobox.cpp rename to components/esxselector/view/profilescombobox.cpp diff --git a/components/esxselector/utils/profilescombobox.hpp b/components/esxselector/view/profilescombobox.hpp similarity index 100% rename from components/esxselector/utils/profilescombobox.hpp rename to components/esxselector/view/profilescombobox.hpp From f6217f9c6ac160d6372236698f1abcf24b3c785c Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 18 Aug 2013 15:11:29 -0500 Subject: [PATCH 017/118] Moved esx selector classes out of global namespace --- apps/launcher/datafilespage.cpp | 14 ++-- apps/launcher/datafilespage.hpp | 4 +- apps/launcher/graphicspage.cpp | 2 +- apps/launcher/utils/textinputdialog.cpp | 4 +- apps/launcher/utils/textinputdialog.hpp | 10 ++- apps/opencs/editor.hpp | 2 +- apps/opencs/view/doc/filedialog.cpp | 26 +++--- apps/opencs/view/doc/filedialog.hpp | 54 +++++++------ components/CMakeLists.txt | 2 +- .../esxselector/model/datafilesmodel.cpp | 53 +++++++------ .../esxselector/model/datafilesmodel.hpp | 79 ++++++++++--------- components/esxselector/model/esmfile.cpp | 50 ++++++++++++ components/esxselector/model/esmfile.hpp | 56 +++++++++++++ .../esxselector/model/masterproxymodel.cpp | 4 +- .../esxselector/model/masterproxymodel.hpp | 2 +- components/esxselector/model/modelitem.cpp | 18 ++--- components/esxselector/model/modelitem.hpp | 37 +++++---- components/esxselector/model/naturalsort.hpp | 8 +- .../esxselector/model/pluginsproxymodel.cpp | 6 +- .../esxselector/model/pluginsproxymodel.hpp | 20 +++-- .../esxselector/view/comboboxlineedit.cpp | 6 +- .../esxselector/view/comboboxlineedit.hpp | 26 +++--- .../esxselector/view/contentselector.cpp | 32 ++++---- .../esxselector/view/contentselector.hpp | 19 +++-- components/esxselector/view/lineedit.cpp | 6 +- components/esxselector/view/lineedit.hpp | 26 +++--- .../esxselector/view/profilescombobox.cpp | 12 +-- .../esxselector/view/profilescombobox.hpp | 43 +++++----- files/ui/datafilespage.ui | 8 +- 29 files changed, 380 insertions(+), 249 deletions(-) create mode 100644 components/esxselector/model/esmfile.cpp create mode 100644 components/esxselector/model/esmfile.hpp diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 44f92d7fe..2346a0b01 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -7,15 +7,15 @@ #include -#include -#include -#include +#include +#include +#include -#include -#include -#include +#include +#include +#include -#include "components/fileorderlist/masterproxymodel.hpp" +#include "components/esxselector/model/masterproxymodel.hpp" #include "settings/gamesettings.hpp" #include "settings/launchersettings.hpp" diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index 356cb88d6..f3792b1f1 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -5,7 +5,7 @@ #include #include "ui_datafilespage.h" -#include "components/fileorderlist/contentselector.hpp" +#include "components/esxselector/view/contentselector.hpp" class QSortFilterProxyModel; class QAbstractItemModel; @@ -20,7 +20,7 @@ class PluginsProxyModel; namespace Files { struct ConfigurationManager; } -class DataFilesPage : public EsxSelector::ContentSelector +class DataFilesPage : public EsxView::ContentSelector { Q_OBJECT public: diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 1bbf7f897..4d5975e58 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include "settings/graphicssettings.hpp" diff --git a/apps/launcher/utils/textinputdialog.cpp b/apps/launcher/utils/textinputdialog.cpp index a4b36b95e..052fc58e4 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 LineEdit(this); + mLineEdit = new EsxView::LineEdit(this); mLineEdit->setValidator(validator); mLineEdit->setCompleter(0); diff --git a/apps/launcher/utils/textinputdialog.hpp b/apps/launcher/utils/textinputdialog.hpp index cbb453ac8..2fb6e0f6b 100644 --- a/apps/launcher/utils/textinputdialog.hpp +++ b/apps/launcher/utils/textinputdialog.hpp @@ -5,17 +5,21 @@ //#include "lineedit.hpp" class QDialogButtonBox; -class LineEdit; + +namespace EsxView { + class LineEdit; +} + class TextInputDialog : public QDialog { Q_OBJECT public: explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0); - inline LineEdit *lineEdit() { return mLineEdit; } + inline EsxView::LineEdit *lineEdit() { return mLineEdit; } void setOkButtonEnabled(bool enabled); - LineEdit *mLineEdit; + EsxView::LineEdit *mLineEdit; int exec(); diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 380e434c2..c88efcfb9 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -22,7 +22,7 @@ namespace CS CSMDoc::DocumentManager mDocumentManager; CSVDoc::ViewManager mViewManager; CSVDoc::StartupDialogue mStartup; - FileDialog mFileDialog; + CSVDoc::FileDialog mFileDialog; Files::ConfigurationManager mCfgMgr; void setupDataFiles(); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 252c760fa..12849d6ee 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -10,15 +10,15 @@ #include #include -#include -#include -#include +#include +#include +#include -#include +#include -#include "components/fileorderlist/masterproxymodel.hpp" +#include "components/esxselector/model/masterproxymodel.hpp" -FileDialog::FileDialog(QWidget *parent) : +CSVDoc::FileDialog::FileDialog(QWidget *parent) : ContentSelector(parent) { // Hide the profile elements @@ -60,7 +60,7 @@ FileDialog::FileDialog(QWidget *parent) : // connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject())); } -void FileDialog::updateOpenButton(const QStringList &items) +void CSVDoc::FileDialog::updateOpenButton(const QStringList &items) { QPushButton *openButton = mButtonBox->button(QDialogButtonBox::Open); @@ -70,7 +70,7 @@ void FileDialog::updateOpenButton(const QStringList &items) openButton->setEnabled(!items.isEmpty()); } -void FileDialog::updateCreateButton(const QString &name) +void CSVDoc::FileDialog::updateCreateButton(const QString &name) { if (!mCreateButton->isVisible()) return; @@ -78,12 +78,12 @@ void FileDialog::updateCreateButton(const QString &name) mCreateButton->setEnabled(!name.isEmpty()); } -QString FileDialog::fileName() +QString CSVDoc::FileDialog::fileName() { //return mNameLineEdit->text(); } -void FileDialog::openFile() +void CSVDoc::FileDialog::openFile() { setWindowTitle(tr("Open")); @@ -101,7 +101,7 @@ void FileDialog::openFile() activateWindow(); } -void FileDialog::newFile() +void CSVDoc::FileDialog::newFile() { setWindowTitle(tr("New")); @@ -118,12 +118,12 @@ void FileDialog::newFile() activateWindow(); } -void FileDialog::accept() +void CSVDoc::FileDialog::accept() { emit openFiles(); } -void FileDialog::createButtonClicked() +void CSVDoc::FileDialog::createButtonClicked() { emit createNewFile(); } diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 1b4d09745..d016ad32d 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -4,7 +4,7 @@ #include #include -#include "components/fileorderlist/contentselector.hpp" +#include "components/esxselector/view/contentselector.hpp" #include "ui_datafilespage.h" class QDialogButtonBox; @@ -18,38 +18,40 @@ class QMenu; class DataFilesModel; class PluginsProxyModel; -class FileDialog : public EsxSelector::ContentSelector +namespace CSVDoc { - Q_OBJECT -public: - explicit FileDialog(QWidget *parent = 0); + class FileDialog : public EsxView::ContentSelector + { + Q_OBJECT + public: + explicit FileDialog(QWidget *parent = 0); - void openFile(); - void newFile(); - void accepted(); + void openFile(); + void newFile(); + void accepted(); - QString fileName(); + QString fileName(); -signals: - void openFiles(); - void createNewFile(); - -public slots: - void accept(); + signals: + void openFiles(); + void createNewFile(); -private slots: - //void updateViews(); - void updateOpenButton(const QStringList &items); - void updateCreateButton(const QString &name); + public slots: + void accept(); - void createButtonClicked(); + private slots: + //void updateViews(); + void updateOpenButton(const QStringList &items); + void updateCreateButton(const QString &name); -private: - QLabel *mNameLabel; - //LineEdit *mNameLineEdit; + void createButtonClicked(); - QPushButton *mCreateButton; - QDialogButtonBox *mButtonBox; -}; + private: + QLabel *mNameLabel; + //LineEdit *mNameLineEdit; + QPushButton *mCreateButton; + QDialogButtonBox *mButtonBox; + }; +} #endif // FILEDIALOG_HPP diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 4f14fa9d9..8b07a4e00 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -73,7 +73,7 @@ find_package(Qt4 COMPONENTS QtCore QtGui) if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) add_component_qt_dir (esxselector model/masterproxymodel model/modelitem model/datafilesmodel - model/pluginsproxymodel model/esm/esmfile model/naturalsort + model/pluginsproxymodel model/esmfile model/naturalsort view/profilescombobox view/comboboxlineedit view/lineedit view/contentselector ) diff --git a/components/esxselector/model/datafilesmodel.cpp b/components/esxselector/model/datafilesmodel.cpp index ae842381e..2980313f0 100644 --- a/components/esxselector/model/datafilesmodel.cpp +++ b/components/esxselector/model/datafilesmodel.cpp @@ -2,33 +2,34 @@ #include #include #include +#include #include #include -#include "esm/esmfile.hpp" +#include "esmfile.hpp" #include "datafilesmodel.hpp" #include -DataFilesModel::DataFilesModel(QObject *parent) : +EsxModel::DataFilesModel::DataFilesModel(QObject *parent) : QAbstractTableModel(parent) { mEncoding = QString("win1252"); } -DataFilesModel::~DataFilesModel() +EsxModel::DataFilesModel::~DataFilesModel() { } -void DataFilesModel::setEncoding(const QString &encoding) +void EsxModel::DataFilesModel::setEncoding(const QString &encoding) { mEncoding = encoding; } -void DataFilesModel::setCheckState(const QModelIndex &index, Qt::CheckState state) +void EsxModel::DataFilesModel::setCheckState(const QModelIndex &index, Qt::CheckState state) { if (!index.isValid()) return; @@ -45,24 +46,24 @@ void DataFilesModel::setCheckState(const QModelIndex &index, Qt::CheckState stat } -Qt::CheckState DataFilesModel::checkState(const QModelIndex &index) +Qt::CheckState EsxModel::DataFilesModel::checkState(const QModelIndex &index) { EsmFile *file = item(index.row()); return mCheckStates[file->fileName()]; } -int DataFilesModel::columnCount(const QModelIndex &parent) const +int EsxModel::DataFilesModel::columnCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : 9; } -int DataFilesModel::rowCount(const QModelIndex &parent) const +int EsxModel::DataFilesModel::rowCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : mFiles.count(); } -bool DataFilesModel::moveRow(int oldrow, int row, const QModelIndex &parent) +bool EsxModel::DataFilesModel::moveRow(int oldrow, int row, const QModelIndex &parent) { if (oldrow < 0 || row < 0 || oldrow == row) return false; @@ -76,7 +77,7 @@ bool DataFilesModel::moveRow(int oldrow, int row, const QModelIndex &parent) return true; } -QVariant DataFilesModel::data(const QModelIndex &index, int role) const +QVariant EsxModel::DataFilesModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); @@ -166,7 +167,7 @@ QVariant DataFilesModel::data(const QModelIndex &index, int role) const } -Qt::ItemFlags DataFilesModel::flags(const QModelIndex &index) const +Qt::ItemFlags EsxModel::DataFilesModel::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::NoItemFlags; @@ -192,7 +193,7 @@ Qt::ItemFlags DataFilesModel::flags(const QModelIndex &index) const } -QVariant DataFilesModel::headerData(int section, Qt::Orientation orientation, int role) const +QVariant EsxModel::DataFilesModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) return QVariant(); @@ -217,7 +218,7 @@ QVariant DataFilesModel::headerData(int section, Qt::Orientation orientation, in return QVariant(); } -bool DataFilesModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool EsxModel::DataFilesModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid()) return false; @@ -225,7 +226,7 @@ bool DataFilesModel::setData(const QModelIndex &index, const QVariant &value, in return false; } -bool lessThanEsmFile(const EsmFile *e1, const EsmFile *e2) +bool lessThanEsmFile(const EsxModel::EsmFile *e1, const EsxModel::EsmFile *e2) { //Masters first then alphabetically if (e1->fileName().endsWith(".esm") && !e2->fileName().endsWith(".esm")) @@ -236,7 +237,7 @@ bool lessThanEsmFile(const EsmFile *e1, const EsmFile *e2) return e1->fileName().toLower() < e2->fileName().toLower(); } -bool lessThanDate(const EsmFile *e1, const EsmFile *e2) +bool lessThanDate(const EsxModel::EsmFile *e1, const EsxModel::EsmFile *e2) { if (e1->modified().toString(Qt::ISODate) < e2->modified().toString(Qt::ISODate)) { return true; @@ -245,7 +246,7 @@ bool lessThanDate(const EsmFile *e1, const EsmFile *e2) } } -void DataFilesModel::sort(int column, Qt::SortOrder order) +void EsxModel::DataFilesModel::sort(int column, Qt::SortOrder order) { emit layoutAboutToBeChanged(); @@ -258,14 +259,14 @@ void DataFilesModel::sort(int column, Qt::SortOrder order) emit layoutChanged(); } -void DataFilesModel::addFile(EsmFile *file) +void EsxModel::DataFilesModel::addFile(EsmFile *file) { emit beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); mFiles.append(file); emit endInsertRows(); } -void DataFilesModel::addFiles(const QString &path) +void EsxModel::DataFilesModel::addFiles(const QString &path) { QDir dir(path); QStringList filters; @@ -330,7 +331,7 @@ void DataFilesModel::addFiles(const QString &path) delete decoder; } -QModelIndex DataFilesModel::indexFromItem(EsmFile *item) const +QModelIndex EsxModel::DataFilesModel::indexFromItem(EsmFile *item) const { if (item) return createIndex(mFiles.indexOf(item), 0); @@ -338,7 +339,7 @@ QModelIndex DataFilesModel::indexFromItem(EsmFile *item) const return QModelIndex(); } -EsmFile* DataFilesModel::findItem(const QString &name) +EsxModel::EsmFile* EsxModel::DataFilesModel::findItem(const QString &name) { QList::ConstIterator it; QList::ConstIterator itEnd = mFiles.constEnd(); @@ -356,7 +357,7 @@ EsmFile* DataFilesModel::findItem(const QString &name) return 0; } -EsmFile* DataFilesModel::item(int row) const +EsxModel::EsmFile* EsxModel::DataFilesModel::item(int row) const { if (row >= 0 && row < mFiles.count()) return mFiles.at(row); @@ -364,7 +365,7 @@ EsmFile* DataFilesModel::item(int row) const return 0; } -QStringList DataFilesModel::checkedItems() +QStringList EsxModel::DataFilesModel::checkedItems() { QStringList list; @@ -386,7 +387,7 @@ QStringList DataFilesModel::checkedItems() return list; } -QStringList DataFilesModel::checkedItemsPaths() +QStringList EsxModel::DataFilesModel::checkedItemsPaths() { QStringList list; @@ -405,14 +406,14 @@ QStringList DataFilesModel::checkedItemsPaths() return list; } -void DataFilesModel::uncheckAll() +void EsxModel::DataFilesModel::uncheckAll() { emit layoutAboutToBeChanged(); mCheckStates.clear(); emit layoutChanged(); } -QStringList DataFilesModel::uncheckedItems() +QStringList EsxModel::DataFilesModel::uncheckedItems() { QStringList list; QStringList checked = checkedItems(); @@ -433,7 +434,7 @@ QStringList DataFilesModel::uncheckedItems() return list; } -bool DataFilesModel::canBeChecked(EsmFile *file) const +bool EsxModel::DataFilesModel::canBeChecked(EsmFile *file) const { //element can be checked if all its dependencies are foreach (const QString &master, file->masters()) diff --git a/components/esxselector/model/datafilesmodel.hpp b/components/esxselector/model/datafilesmodel.hpp index 0a07a536f..bc55bb6cf 100644 --- a/components/esxselector/model/datafilesmodel.hpp +++ b/components/esxselector/model/datafilesmodel.hpp @@ -6,61 +6,62 @@ #include #include +namespace EsxModel +{ + class EsmFile; -class EsmFile; + class DataFilesModel : public QAbstractTableModel + { + Q_OBJECT -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; -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 moveRow(int oldrow, int row, const QModelIndex &parent = QModelIndex()); - bool moveRow(int oldrow, int row, const QModelIndex &parent = QModelIndex()); + virtual Qt::ItemFlags flags(const QModelIndex &index) const; - 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 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); - 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 + { return QAbstractTableModel::index(row, column, parent); } - inline QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const - { return QAbstractTableModel::index(row, column, parent); } + void setEncoding(const QString &encoding); - void setEncoding(const QString &encoding); + void addFiles(const QString &path); - void addFiles(const QString &path); + void uncheckAll(); - void uncheckAll(); + QStringList checkedItems(); + QStringList uncheckedItems(); + QStringList checkedItemsPaths(); - QStringList checkedItems(); - QStringList uncheckedItems(); - QStringList checkedItemsPaths(); + Qt::CheckState checkState(const QModelIndex &index); + void setCheckState(const QModelIndex &index, Qt::CheckState state); - Qt::CheckState checkState(const QModelIndex &index); - void setCheckState(const QModelIndex &index, Qt::CheckState state); + QModelIndex indexFromItem(EsmFile *item) const; + EsmFile* findItem(const QString &name); + EsmFile* item(int row) const; - QModelIndex indexFromItem(EsmFile *item) const; - EsmFile* findItem(const QString &name); - EsmFile* item(int row) const; + signals: + void checkedItemsChanged(const QStringList &items); -signals: - void checkedItemsChanged(const QStringList &items); - -private: - bool canBeChecked(EsmFile *file) const; - void addFile(EsmFile *file); - - QList mFiles; - QHash mCheckStates; + private: + bool canBeChecked(EsmFile *file) const; + void addFile(EsmFile *file); - QString mEncoding; + QList mFiles; + QHash mCheckStates; -}; + QString mEncoding; + }; +} #endif // DATAFILESMODEL_HPP diff --git a/components/esxselector/model/esmfile.cpp b/components/esxselector/model/esmfile.cpp new file mode 100644 index 000000000..96b90e44e --- /dev/null +++ b/components/esxselector/model/esmfile.cpp @@ -0,0 +1,50 @@ +#include "esmfile.hpp" + +EsxModel::EsmFile::EsmFile(QString fileName, ModelItem *parent) + : ModelItem(parent) +{ + mFileName = fileName; + mSize = 0; + mVersion = 0.0f; +} + +void EsxModel::EsmFile::setFileName(const QString &fileName) +{ + mFileName = fileName; +} + +void EsxModel::EsmFile::setAuthor(const QString &author) +{ + mAuthor = author; +} + +void EsxModel::EsmFile::setSize(const int size) +{ + mSize = size; +} + +void EsxModel::EsmFile::setDates(const QDateTime &modified, const QDateTime &accessed) +{ + mModified = modified; + mAccessed = accessed; +} + +void EsxModel::EsmFile::setVersion(float version) +{ + mVersion = version; +} + +void EsxModel::EsmFile::setPath(const QString &path) +{ + mPath = path; +} + +void EsxModel::EsmFile::setMasters(const QStringList &masters) +{ + mMasters = masters; +} + +void EsxModel::EsmFile::setDescription(const QString &description) +{ + mDescription = description; +} diff --git a/components/esxselector/model/esmfile.hpp b/components/esxselector/model/esmfile.hpp new file mode 100644 index 000000000..6a3e36b53 --- /dev/null +++ b/components/esxselector/model/esmfile.hpp @@ -0,0 +1,56 @@ +#ifndef ESMFILE_HPP +#define ESMFILE_HPP + +#include +#include + +#include "modelitem.hpp" + +namespace EsxModel +{ + class EsmFile : public ModelItem + { + Q_OBJECT + Q_PROPERTY(QString filename READ fileName) + + public: + EsmFile(QString fileName = QString(), ModelItem *parent = 0); + + ~EsmFile() + {} + + void setFileName(const QString &fileName); + void setAuthor(const QString &author); + void setSize(const int size); + void setDates(const QDateTime &modified, const QDateTime &accessed); + void setVersion(const float version); + void setPath(const QString &path); + void setMasters(const QStringList &masters); + void setDescription(const QString &description); + + inline QString fileName() const { return mFileName; } + inline QString author() const { return mAuthor; } + inline int size() const { return mSize; } + inline QDateTime modified() const { return mModified; } + inline QDateTime accessed() const { return mAccessed; } + inline float version() const { return mVersion; } + inline QString path() const { return mPath; } + inline QStringList masters() const { return mMasters; } + inline QString description() const { return mDescription; } + + + private: + QString mFileName; + QString mAuthor; + int mSize; + QDateTime mModified; + QDateTime mAccessed; + float mVersion; + QString mPath; + QStringList mMasters; + QString mDescription; + + }; +} + +#endif diff --git a/components/esxselector/model/masterproxymodel.cpp b/components/esxselector/model/masterproxymodel.cpp index 04a7f0033..011e5ebd5 100644 --- a/components/esxselector/model/masterproxymodel.cpp +++ b/components/esxselector/model/masterproxymodel.cpp @@ -1,6 +1,6 @@ #include "masterproxymodel.hpp" -EsxSelector::MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableModel* model) : +EsxModel::MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableModel* model) : QSortFilterProxyModel(parent) { setFilterRegExp(QString("game")); @@ -10,7 +10,7 @@ EsxSelector::MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableM setSourceModel (model); } -QVariant EsxSelector::MasterProxyModel::data(const QModelIndex &index, int role) const +QVariant EsxModel::MasterProxyModel::data(const QModelIndex &index, int role) const { return QSortFilterProxyModel::data (index, role); } diff --git a/components/esxselector/model/masterproxymodel.hpp b/components/esxselector/model/masterproxymodel.hpp index 6fbdd3154..fed01bdb1 100644 --- a/components/esxselector/model/masterproxymodel.hpp +++ b/components/esxselector/model/masterproxymodel.hpp @@ -5,7 +5,7 @@ class QAbstractTableModel; -namespace EsxSelector +namespace EsxModel { class MasterProxyModel : public QSortFilterProxyModel { diff --git a/components/esxselector/model/modelitem.cpp b/components/esxselector/model/modelitem.cpp index 0ff7e45cb..8c1e83695 100644 --- a/components/esxselector/model/modelitem.cpp +++ b/components/esxselector/model/modelitem.cpp @@ -1,23 +1,23 @@ #include "modelitem.hpp" -ModelItem::ModelItem(ModelItem *parent) +EsxModel::ModelItem::ModelItem(ModelItem *parent) : mParentItem(parent) , QObject(parent) { } -ModelItem::~ModelItem() +EsxModel::ModelItem::~ModelItem() { qDeleteAll(mChildItems); } -ModelItem *ModelItem::parent() +EsxModel::ModelItem *EsxModel::ModelItem::parent() { return mParentItem; } -int ModelItem::row() const +int EsxModel::ModelItem::row() const { if (mParentItem) return 1; @@ -28,30 +28,30 @@ int ModelItem::row() const } -int ModelItem::childCount() const +int EsxModel::ModelItem::childCount() const { return mChildItems.count(); } -int ModelItem::childRow(ModelItem *child) const +int EsxModel::ModelItem::childRow(ModelItem *child) const { Q_ASSERT(child); return mChildItems.indexOf(child); } -ModelItem *ModelItem::child(int row) +EsxModel::ModelItem *EsxModel::ModelItem::child(int row) { return mChildItems.value(row); } -void ModelItem::appendChild(ModelItem *item) +void EsxModel::ModelItem::appendChild(ModelItem *item) { mChildItems.append(item); } -void ModelItem::removeChild(int row) +void EsxModel::ModelItem::removeChild(int row) { mChildItems.removeAt(row); } diff --git a/components/esxselector/model/modelitem.hpp b/components/esxselector/model/modelitem.hpp index f4cb4322f..64596302c 100644 --- a/components/esxselector/model/modelitem.hpp +++ b/components/esxselector/model/modelitem.hpp @@ -4,29 +4,32 @@ #include #include -class ModelItem : public QObject +namespace EsxModel { - Q_OBJECT + class ModelItem : public QObject + { + Q_OBJECT -public: - ModelItem(ModelItem *parent = 0); - ~ModelItem(); + public: + ModelItem(ModelItem *parent = 0); + ~ModelItem(); - ModelItem *parent(); - int row() const; + ModelItem *parent(); + int row() const; - int childCount() const; - int childRow(ModelItem *child) const; - ModelItem *child(int row); + int childCount() const; + int childRow(ModelItem *child) const; + ModelItem *child(int row); - void appendChild(ModelItem *child); - void removeChild(int row); + void appendChild(ModelItem *child); + void removeChild(int row); - //virtual bool acceptChild(ModelItem *child); + //virtual bool acceptChild(ModelItem *child); -protected: - ModelItem *mParentItem; - QList mChildItems; -}; + protected: + ModelItem *mParentItem; + QList mChildItems; + }; +} #endif diff --git a/components/esxselector/model/naturalsort.hpp b/components/esxselector/model/naturalsort.hpp index 59271547a..8386e4e9f 100644 --- a/components/esxselector/model/naturalsort.hpp +++ b/components/esxselector/model/naturalsort.hpp @@ -3,9 +3,9 @@ #include -bool naturalSortLessThanCS( const QString &left, const QString &right ); -bool naturalSortLessThanCI( const QString &left, const QString &right ); -bool naturalSortGreaterThanCS( const QString &left, const QString &right ); -bool naturalSortGreaterThanCI( const QString &left, const QString &right ); + bool naturalSortLessThanCS( const QString &left, const QString &right ); + bool naturalSortLessThanCI( const QString &left, const QString &right ); + bool naturalSortGreaterThanCS( const QString &left, const QString &right ); + bool naturalSortGreaterThanCI( const QString &left, const QString &right ); #endif diff --git a/components/esxselector/model/pluginsproxymodel.cpp b/components/esxselector/model/pluginsproxymodel.cpp index 18aebc6b6..4fde11f47 100644 --- a/components/esxselector/model/pluginsproxymodel.cpp +++ b/components/esxselector/model/pluginsproxymodel.cpp @@ -1,7 +1,7 @@ #include "pluginsproxymodel.hpp" #include "datafilesmodel.hpp" -PluginsProxyModel::PluginsProxyModel(QObject *parent, DataFilesModel *model) : +EsxModel::PluginsProxyModel::PluginsProxyModel(QObject *parent, DataFilesModel *model) : QSortFilterProxyModel(parent) { setFilterRegExp (QString("addon")); @@ -12,11 +12,11 @@ PluginsProxyModel::PluginsProxyModel(QObject *parent, DataFilesModel *model) : setSourceModel (model); } -PluginsProxyModel::~PluginsProxyModel() +EsxModel::PluginsProxyModel::~PluginsProxyModel() { } -QVariant PluginsProxyModel::data(const QModelIndex &index, int role) const +QVariant EsxModel::PluginsProxyModel::data(const QModelIndex &index, int role) const { switch (role) { diff --git a/components/esxselector/model/pluginsproxymodel.hpp b/components/esxselector/model/pluginsproxymodel.hpp index cfade092e..04c18c2e2 100644 --- a/components/esxselector/model/pluginsproxymodel.hpp +++ b/components/esxselector/model/pluginsproxymodel.hpp @@ -5,18 +5,22 @@ class QVariant; class QAbstractTableModel; -class DataFilesModel; -class PluginsProxyModel : public QSortFilterProxyModel +namespace EsxModel { - Q_OBJECT + class DataFilesModel; -public: + class PluginsProxyModel : public QSortFilterProxyModel + { + Q_OBJECT - explicit PluginsProxyModel(QObject *parent = 0, DataFilesModel *model = 0); - ~PluginsProxyModel(); + public: - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; -}; + explicit PluginsProxyModel(QObject *parent = 0, DataFilesModel *model = 0); + ~PluginsProxyModel(); + + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + }; +} #endif // PLUGINSPROXYMODEL_HPP diff --git a/components/esxselector/view/comboboxlineedit.cpp b/components/esxselector/view/comboboxlineedit.cpp index 4d62e1399..815a1130b 100644 --- a/components/esxselector/view/comboboxlineedit.cpp +++ b/components/esxselector/view/comboboxlineedit.cpp @@ -3,7 +3,7 @@ #include "comboboxlineedit.hpp" -ComboBoxLineEdit::ComboBoxLineEdit(QWidget *parent) +EsxView::ComboBoxLineEdit::ComboBoxLineEdit(QWidget *parent) : QLineEdit(parent) { mClearButton = new QToolButton(this); @@ -21,7 +21,7 @@ ComboBoxLineEdit::ComboBoxLineEdit(QWidget *parent) setStyleSheet(QString("ComboBoxLineEdit { background-color: transparent; padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1)); } -void ComboBoxLineEdit::resizeEvent(QResizeEvent *) +void EsxView::ComboBoxLineEdit::resizeEvent(QResizeEvent *) { QSize sz = mClearButton->sizeHint(); int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); @@ -29,7 +29,7 @@ void ComboBoxLineEdit::resizeEvent(QResizeEvent *) (rect().bottom() + 1 - sz.height())/2); } -void ComboBoxLineEdit::updateClearButton(const QString& text) +void EsxView::ComboBoxLineEdit::updateClearButton(const QString& text) { mClearButton->setVisible(!text.isEmpty()); } diff --git a/components/esxselector/view/comboboxlineedit.hpp b/components/esxselector/view/comboboxlineedit.hpp index ba10731ae..f3b251955 100644 --- a/components/esxselector/view/comboboxlineedit.hpp +++ b/components/esxselector/view/comboboxlineedit.hpp @@ -14,22 +14,24 @@ class QToolButton; -class ComboBoxLineEdit : public QLineEdit +namespace EsxView { - Q_OBJECT + class ComboBoxLineEdit : public QLineEdit + { + Q_OBJECT -public: - ComboBoxLineEdit(QWidget *parent = 0); + public: + ComboBoxLineEdit(QWidget *parent = 0); -protected: - void resizeEvent(QResizeEvent *); + protected: + void resizeEvent(QResizeEvent *); -private slots: - void updateClearButton(const QString &text); - -private: - QToolButton *mClearButton; -}; + private slots: + void updateClearButton(const QString &text); + private: + QToolButton *mClearButton; + }; +} #endif // LIENEDIT_H diff --git a/components/esxselector/view/contentselector.cpp b/components/esxselector/view/contentselector.cpp index 16139d9e6..2de68e5bf 100644 --- a/components/esxselector/view/contentselector.cpp +++ b/components/esxselector/view/contentselector.cpp @@ -1,8 +1,8 @@ #include "contentselector.hpp" -#include "model/datafilesmodel.hpp" -#include "masterproxymodel.hpp" -#include "model/pluginsproxymodel.hpp" +#include "../model/datafilesmodel.hpp" +#include "../model/masterproxymodel.hpp" +#include "../model/pluginsproxymodel.hpp" #include @@ -10,20 +10,20 @@ #include #include -EsxSelector::ContentSelector::ContentSelector(QWidget *parent) : +EsxView::ContentSelector::ContentSelector(QWidget *parent) : QWidget(parent) { setupUi(this); buildModelsAndViews(); } -void EsxSelector::ContentSelector::buildModelsAndViews() +void EsxView::ContentSelector::buildModelsAndViews() { // Models - mDataFilesModel = new DataFilesModel (this); + mDataFilesModel = new EsxModel::DataFilesModel (this); - mMasterProxyModel = new EsxSelector::MasterProxyModel (this, mDataFilesModel); - mPluginsProxyModel = new PluginsProxyModel (this, mDataFilesModel); + mMasterProxyModel = new EsxModel::MasterProxyModel (this, mDataFilesModel); + mPluginsProxyModel = new EsxModel::PluginsProxyModel (this, mDataFilesModel); masterView->setModel(mMasterProxyModel); pluginView->setModel(mPluginsProxyModel); @@ -35,7 +35,7 @@ void EsxSelector::ContentSelector::buildModelsAndViews() connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); } -void EsxSelector::ContentSelector::addFiles(const QString &path) +void EsxView::ContentSelector::addFiles(const QString &path) { mDataFilesModel->addFiles(path); mDataFilesModel->sort(3); // Sort by date accessed @@ -43,12 +43,12 @@ void EsxSelector::ContentSelector::addFiles(const QString &path) mDataFilesModel->uncheckAll(); } -void EsxSelector::ContentSelector::setEncoding(const QString &encoding) +void EsxView::ContentSelector::setEncoding(const QString &encoding) { mDataFilesModel->setEncoding(encoding); } -void EsxSelector::ContentSelector::setCheckState(QModelIndex index, QSortFilterProxyModel *model) +void EsxView::ContentSelector::setCheckState(QModelIndex index, QSortFilterProxyModel *model) { if (!index.isValid()) return; @@ -66,12 +66,12 @@ void EsxSelector::ContentSelector::setCheckState(QModelIndex index, QSortFilterP } } -QStringList EsxSelector::ContentSelector::checkedItemsPaths() +QStringList EsxView::ContentSelector::checkedItemsPaths() { return mDataFilesModel->checkedItemsPaths(); } -void EsxSelector::ContentSelector::updateViews() +void EsxView::ContentSelector::updateViews() { // Ensure the columns are hidden because sort() re-enables them pluginView->setColumnHidden(1, true); @@ -85,12 +85,12 @@ void EsxSelector::ContentSelector::updateViews() } -void EsxSelector::ContentSelector::slotCurrentProfileIndexChanged(int index) +void EsxView::ContentSelector::slotCurrentProfileIndexChanged(int index) { emit profileChanged(index); } -void EsxSelector::ContentSelector::slotCurrentMasterIndexChanged(int index) +void EsxView::ContentSelector::slotCurrentMasterIndexChanged(int index) { QObject *object = QObject::sender(); @@ -101,7 +101,7 @@ void EsxSelector::ContentSelector::slotCurrentMasterIndexChanged(int index) setCheckState(mMasterProxyModel->index(index, 0), mMasterProxyModel); } -void EsxSelector::ContentSelector::slotPluginTableItemClicked(const QModelIndex &index) +void EsxView::ContentSelector::slotPluginTableItemClicked(const QModelIndex &index) { setCheckState(index, mPluginsProxyModel); } diff --git a/components/esxselector/view/contentselector.hpp b/components/esxselector/view/contentselector.hpp index f1d8f6927..35ef3a07c 100644 --- a/components/esxselector/view/contentselector.hpp +++ b/components/esxselector/view/contentselector.hpp @@ -5,23 +5,26 @@ #include "ui_datafilespage.h" -class DataFilesModel; -class PluginsProxyModel; -class QSortFilterProxyModel; - -namespace FileOrderList +namespace EsxModel { + class DataFilesModel; + class PluginsProxyModel; class MasterProxyModel; +} +class QSortFilterProxyModel; + +namespace EsxView +{ class ContentSelector : public QWidget, protected Ui::DataFilesPage { Q_OBJECT protected: - DataFilesModel *mDataFilesModel; - MasterProxyModel *mMasterProxyModel; - PluginsProxyModel *mPluginsProxyModel; + EsxModel::DataFilesModel *mDataFilesModel; + EsxModel::MasterProxyModel *mMasterProxyModel; + EsxModel::PluginsProxyModel *mPluginsProxyModel; public: explicit ContentSelector(QWidget *parent = 0); diff --git a/components/esxselector/view/lineedit.cpp b/components/esxselector/view/lineedit.cpp index b0f339589..8944251ae 100644 --- a/components/esxselector/view/lineedit.cpp +++ b/components/esxselector/view/lineedit.cpp @@ -3,7 +3,7 @@ #include "lineedit.hpp" -LineEdit::LineEdit(QWidget *parent) +EsxView::LineEdit::LineEdit(QWidget *parent) : QLineEdit(parent) { mClearButton = new QToolButton(this); @@ -24,7 +24,7 @@ LineEdit::LineEdit(QWidget *parent) qMax(msz.height(), mClearButton->sizeHint().height() + frameWidth * 2 + 2)); } -void LineEdit::resizeEvent(QResizeEvent *) +void EsxView::LineEdit::resizeEvent(QResizeEvent *) { QSize sz = mClearButton->sizeHint(); int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); @@ -32,7 +32,7 @@ void LineEdit::resizeEvent(QResizeEvent *) (rect().bottom() + 1 - sz.height())/2); } -void LineEdit::updateClearButton(const QString& text) +void EsxView::LineEdit::updateClearButton(const QString& text) { mClearButton->setVisible(!text.isEmpty()); } diff --git a/components/esxselector/view/lineedit.hpp b/components/esxselector/view/lineedit.hpp index 14bd7b1b4..e48392ba8 100644 --- a/components/esxselector/view/lineedit.hpp +++ b/components/esxselector/view/lineedit.hpp @@ -14,22 +14,24 @@ class QToolButton; -class LineEdit : public QLineEdit +namespace EsxView { - Q_OBJECT + class LineEdit : public QLineEdit + { + Q_OBJECT -public: - LineEdit(QWidget *parent = 0); + public: + LineEdit(QWidget *parent = 0); -protected: - void resizeEvent(QResizeEvent *); + protected: + void resizeEvent(QResizeEvent *); -private slots: - void updateClearButton(const QString &text); - -private: - QToolButton *mClearButton; -}; + private slots: + void updateClearButton(const QString &text); + private: + QToolButton *mClearButton; + }; +} #endif // LIENEDIT_H diff --git a/components/esxselector/view/profilescombobox.cpp b/components/esxselector/view/profilescombobox.cpp index 9346276da..b765f87ca 100644 --- a/components/esxselector/view/profilescombobox.cpp +++ b/components/esxselector/view/profilescombobox.cpp @@ -7,7 +7,7 @@ #include "profilescombobox.hpp" #include "comboboxlineedit.hpp" -ProfilesComboBox::ProfilesComboBox(QWidget *parent) : +EsxView::ProfilesComboBox::ProfilesComboBox(QWidget *parent) : QComboBox(parent) { mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore @@ -21,7 +21,7 @@ ProfilesComboBox::ProfilesComboBox(QWidget *parent) : setInsertPolicy(QComboBox::NoInsert); } -void ProfilesComboBox::setEditEnabled(bool editable) +void EsxView::ProfilesComboBox::setEditEnabled(bool editable) { if (isEditable() == editable) return; @@ -47,7 +47,7 @@ void ProfilesComboBox::setEditEnabled(bool editable) SLOT(slotTextChanged(QString))); } -void ProfilesComboBox::slotTextChanged(const QString &text) +void EsxView::ProfilesComboBox::slotTextChanged(const QString &text) { QPalette *palette = new QPalette(); palette->setColor(QPalette::Text,Qt::red); @@ -61,7 +61,7 @@ void ProfilesComboBox::slotTextChanged(const QString &text) } } -void ProfilesComboBox::slotEditingFinished() +void EsxView::ProfilesComboBox::slotEditingFinished() { QString current = currentText(); QString previous = itemText(currentIndex()); @@ -82,7 +82,7 @@ void ProfilesComboBox::slotEditingFinished() emit(profileRenamed(previous, current)); } -void ProfilesComboBox::slotIndexChanged(int index) +void EsxView::ProfilesComboBox::slotIndexChanged(int index) { if (index == -1) return; @@ -91,7 +91,7 @@ void ProfilesComboBox::slotIndexChanged(int index) mOldProfile = itemText(index); } -void ProfilesComboBox::paintEvent(QPaintEvent *) +void EsxView::ProfilesComboBox::paintEvent(QPaintEvent *) { QStylePainter painter(this); painter.setPen(palette().color(QPalette::Text)); diff --git a/components/esxselector/view/profilescombobox.hpp b/components/esxselector/view/profilescombobox.hpp index 55913d7fe..218948e7b 100644 --- a/components/esxselector/view/profilescombobox.hpp +++ b/components/esxselector/view/profilescombobox.hpp @@ -6,28 +6,31 @@ class QString; class QRegExpValidator; -class ProfilesComboBox : public QComboBox +namespace EsxView { - Q_OBJECT -public: - explicit ProfilesComboBox(QWidget *parent = 0); - void setEditEnabled(bool editable); - -signals: - void profileChanged(const QString &previous, const QString ¤t); - void profileRenamed(const QString &oldName, const QString &newName); - -private slots: - void slotEditingFinished(); - void slotIndexChanged(int index); - void slotTextChanged(const QString &text); + class ProfilesComboBox : public QComboBox + { + Q_OBJECT + public: + explicit ProfilesComboBox(QWidget *parent = 0); + void setEditEnabled(bool editable); -private: - QString mOldProfile; - QRegExpValidator *mValidator; + signals: + void profileChanged(const QString &previous, const QString ¤t); + void profileRenamed(const QString &oldName, const QString &newName); -protected: - void paintEvent(QPaintEvent *); -}; + private slots: + void slotEditingFinished(); + void slotIndexChanged(int index); + void slotTextChanged(const QString &text); + + private: + QString mOldProfile; + QRegExpValidator *mValidator; + + protected: + void paintEvent(QPaintEvent *); + }; +} #endif // PROFILESCOMBOBOX_HPP diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 07ad9d3ba..523ee69cc 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -17,7 +17,7 @@ - + false @@ -79,7 +79,7 @@ - + true @@ -168,9 +168,9 @@ - ProfilesComboBox + EsxView::ProfilesComboBox QComboBox -
components/fileorderlist/utils/profilescombobox.hpp
+
components/esxselector/view/profilescombobox.hpp
From e614ec335334d186dac0fba1147fa4c0e5bd6400 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 18 Aug 2013 17:11:23 -0500 Subject: [PATCH 018/118] Fixing profile code in progress... --- apps/opencs/view/doc/filedialog.cpp | 11 +- apps/opencs/view/doc/filedialog.hpp | 8 +- .../esxselector/view/contentselector.cpp | 4 +- .../esxselector/view/profilescombobox.cpp | 7 +- .../esxselector/view/profilescombobox.hpp | 2 + files/ui/datafilespage.ui | 257 +++++++++++------- 6 files changed, 175 insertions(+), 114 deletions(-) diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 12849d6ee..4f4aef4f2 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -22,10 +22,7 @@ CSVDoc::FileDialog::FileDialog(QWidget *parent) : ContentSelector(parent) { // Hide the profile elements - profileLabel->hide(); - profilesComboBox->hide(); - newProfileButton->hide(); - deleteProfileButton->hide(); + profileGroupBox->hide(); // Add some extra widgets QHBoxLayout *nameLayout = new QHBoxLayout(); @@ -34,12 +31,12 @@ CSVDoc::FileDialog::FileDialog(QWidget *parent) : mNameLabel = new QLabel(tr("File Name:"), this); QRegExpValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9\\s]*$")); - //mNameLineEdit = new LineEdit(this); - //mNameLineEdit->setValidator(validator); + mNameLineEdit = new EsxView::LineEdit(this); + mNameLineEdit->setValidator(validator); nameLayout->addSpacerItem(spacer); nameLayout->addWidget(mNameLabel); - //nameLayout->addWidget(mNameLineEdit); + nameLayout->addWidget(mNameLineEdit); mButtonBox = new QDialogButtonBox(this); diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index d016ad32d..0e2d8f32b 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -14,10 +14,16 @@ class QPushButton; class QStringList; class QString; class QMenu; +class QLabel; class DataFilesModel; class PluginsProxyModel; +namespace EsxView +{ + class LineEdit; +} + namespace CSVDoc { class FileDialog : public EsxView::ContentSelector @@ -48,7 +54,7 @@ namespace CSVDoc private: QLabel *mNameLabel; - //LineEdit *mNameLineEdit; + EsxView::LineEdit *mNameLineEdit; QPushButton *mCreateButton; QDialogButtonBox *mButtonBox; diff --git a/components/esxselector/view/contentselector.cpp b/components/esxselector/view/contentselector.cpp index 2de68e5bf..266fd76dc 100644 --- a/components/esxselector/view/contentselector.cpp +++ b/components/esxselector/view/contentselector.cpp @@ -25,9 +25,11 @@ void EsxView::ContentSelector::buildModelsAndViews() mMasterProxyModel = new EsxModel::MasterProxyModel (this, mDataFilesModel); mPluginsProxyModel = new EsxModel::PluginsProxyModel (this, mDataFilesModel); + masterView->setPlaceholderText(QString("Select a game file...")); masterView->setModel(mMasterProxyModel); pluginView->setModel(mPluginsProxyModel); - pluginView-> + profilesComboBox->setPlaceholderText(QString("Select a profile...")); + connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); connect(pluginView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotPluginTableItemClicked(const QModelIndex &))); diff --git a/components/esxselector/view/profilescombobox.cpp b/components/esxselector/view/profilescombobox.cpp index b765f87ca..0d709aa50 100644 --- a/components/esxselector/view/profilescombobox.cpp +++ b/components/esxselector/view/profilescombobox.cpp @@ -103,6 +103,11 @@ void EsxView::ProfilesComboBox::paintEvent(QPaintEvent *) // draw the icon and text if (!opt.editable && currentIndex() == -1) // <<< we adjust the text displayed when nothing is selected - opt.currentText = tr("Select a game file..."); + opt.currentText = mPlaceholderText; painter.drawControl(QStyle::CE_ComboBoxLabel, opt); } + +void EsxView::ProfilesComboBox::setPlaceholderText(const QString &text) +{ + mPlaceholderText = text; +} diff --git a/components/esxselector/view/profilescombobox.hpp b/components/esxselector/view/profilescombobox.hpp index 218948e7b..28740783b 100644 --- a/components/esxselector/view/profilescombobox.hpp +++ b/components/esxselector/view/profilescombobox.hpp @@ -14,6 +14,7 @@ namespace EsxView public: explicit ProfilesComboBox(QWidget *parent = 0); void setEditEnabled(bool editable); + void setPlaceholderText (const QString &text); signals: void profileChanged(const QString &previous, const QString ¤t); @@ -26,6 +27,7 @@ namespace EsxView private: QString mOldProfile; + QString mPlaceholderText; QRegExpValidator *mValidator; protected: diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 523ee69cc..6235f31af 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -14,113 +14,162 @@ Qt::DefaultContextMenu + + 6 + + + 6 + - - - - - false - - - - - - - - - - - - 0 - 0 - - - - Qt::DefaultContextMenu - - - QAbstractItemView::NoEditTriggers - - - true - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - Qt::ElideLeft - - - false - - - false - - - true - - - false - - - - + + + Content + + + + 9 + + + 6 + + + 6 + + + + + + + false + + + + + + + + + + + + 0 + 0 + + + + Qt::DefaultContextMenu + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + Qt::ElideLeft + + + false + + + false + + + true + + + false + + + + + + + pluginView + masterView + pluginView + masterView + + + - - - - - Current Profile: - - - - - - - true - - - - 0 - 0 - - - - - - - - New Profile - - - &New Profile - - - true - - - - - - - Delete Profile - - - Delete Profile - - - Ctrl+D - - - true - - - - + + + Qt::NoFocus + + + Profiles + + + false + + + + 6 + + + 9 + + + 9 + + + 0 + + + 6 + + + + + true + + + + 0 + 0 + + + + + + + + New Profile + + + &New Profile + + + true + + + + + + + Delete Profile + + + Delete Profile + + + Ctrl+D + + + true + + + + + From b52645bf2ac594b6762fabf2b79943fd3e42d8c7 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 20 Aug 2013 03:23:32 -0500 Subject: [PATCH 019/118] Fixes to accommodate master/plugin loading --- apps/launcher/datafilespage.cpp | 96 ++----------------- apps/opencs/view/doc/filedialog.cpp | 9 +- .../esxselector/model/datafilesmodel.cpp | 34 ++++--- .../esxselector/model/datafilesmodel.hpp | 10 +- .../esxselector/view/contentselector.cpp | 1 + files/ui/datafilespage.ui | 4 +- 6 files changed, 38 insertions(+), 116 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 2346a0b01..15f8d9ba2 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -29,16 +29,11 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam , mLauncherSettings(launcherSettings) , ContentSelector(parent) { - - pluginView->hideColumn(2); // Create a dialog for the new profile name input mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString))); - //connect(pluginView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); - //connect(masterView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); - createActions(); setupDataFiles(); } @@ -49,11 +44,6 @@ void DataFilesPage::createActions() // Add the actions to the toolbuttons newProfileButton->setDefaultAction(newProfileAction); deleteProfileButton->setDefaultAction(deleteProfileAction); - - // Context menu actions - mContextMenu = new QMenu(this); - mContextMenu->addAction(checkAction); - mContextMenu->addAction(uncheckAction); } void DataFilesPage::setupDataFiles() @@ -150,17 +140,17 @@ void DataFilesPage::saveSettings() mGameSettings.remove(QString("master")); mGameSettings.remove(QString("plugin")); - QStringList items = mDataFilesModel->checkedItems(); + EsxModel::EsmFileList items = mDataFilesModel->checkedItems(); - foreach(const QString &item, items) { + foreach(const EsxModel::EsmFile *item, items) { - if (item.endsWith(QString(".esm"), Qt::CaseInsensitive)) { - mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/master"), item); - mGameSettings.setMultiValue(QString("master"), item); + if (item->masters().size() == 0) { + mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/master"), item->fileName()); + mGameSettings.setMultiValue(QString("master"), item->fileName()); - } else if (item.endsWith(QString(".esp"), Qt::CaseInsensitive)) { - mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/plugin"), item); - mGameSettings.setMultiValue(QString("plugin"), item); + } else { + mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/plugin"), item->fileName()); + mGameSettings.setMultiValue(QString("plugin"), item->fileName()); } } @@ -296,73 +286,3 @@ void DataFilesPage::profileRenamed(const QString &previous, const QString &curre loadSettings(); } -/* -void DataFilesPage::showContextMenu(const QPoint &point) -{ - QObject *object = QObject::sender(); - - // Not a signal-slot call - if (!object) - return; - - if (object->objectName() == QLatin1String("PluginView")) { - if (!pluginView->selectionModel()->hasSelection()) - return; - - QPoint globalPos = pluginView->mapToGlobal(point); - QModelIndexList indexes = pluginView->selectionModel()->selectedIndexes(); - - // Show the check/uncheck actions depending on the state of the selected items - uncheckAction->setEnabled(false); - checkAction->setEnabled(false); - - foreach (const QModelIndex &index, indexes) - { - if (!index.isValid()) - return; - - QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(index); - - if (!sourceIndex.isValid()) - return; - - (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) - ? uncheckAction->setEnabled(true) - : checkAction->setEnabled(true); - } - - // Show menu - mContextMenu->exec(globalPos); - } - - if (object->objectName() == QLatin1String("MasterView")) { - if (!masterView->selectionModel()->hasSelection()) - return; - - QPoint globalPos = masterView->mapToGlobal(point); - QModelIndexList indexes = masterView->selectionModel()->selectedIndexes(); - - // Show the check/uncheck actions depending on the state of the selected items - uncheckAction->setEnabled(false); - checkAction->setEnabled(false); - - foreach (const QModelIndex &index, indexes) - { - if (!index.isValid()) - return; - - QModelIndex sourceIndex = mMastersProxyModel->mapToSource(index); - - if (!sourceIndex.isValid()) - return; - - (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) - ? uncheckAction->setEnabled(true) - : checkAction->setEnabled(true); - } - - mContextMenu->exec(globalPos); - } - -} -*/ diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 4f4aef4f2..69ed1c13a 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -23,6 +23,7 @@ CSVDoc::FileDialog::FileDialog(QWidget *parent) : { // Hide the profile elements profileGroupBox->hide(); + pluginView->showColumn(2); // Add some extra widgets QHBoxLayout *nameLayout = new QHBoxLayout(); @@ -77,7 +78,7 @@ void CSVDoc::FileDialog::updateCreateButton(const QString &name) QString CSVDoc::FileDialog::fileName() { - //return mNameLineEdit->text(); + return mNameLineEdit->text(); } void CSVDoc::FileDialog::openFile() @@ -85,7 +86,7 @@ void CSVDoc::FileDialog::openFile() setWindowTitle(tr("Open")); mNameLabel->hide(); - //mNameLineEdit->hide(); + mNameLineEdit->hide(); mCreateButton->hide(); mButtonBox->removeButton(mCreateButton); @@ -103,8 +104,8 @@ void CSVDoc::FileDialog::newFile() setWindowTitle(tr("New")); mNameLabel->show(); - //mNameLineEdit->clear(); - //mNameLineEdit->show(); + mNameLineEdit->clear(); + mNameLineEdit->show(); mCreateButton->show(); mButtonBox->setStandardButtons(QDialogButtonBox::Cancel); diff --git a/components/esxselector/model/datafilesmodel.cpp b/components/esxselector/model/datafilesmodel.cpp index 2980313f0..49d0d6132 100644 --- a/components/esxselector/model/datafilesmodel.cpp +++ b/components/esxselector/model/datafilesmodel.cpp @@ -365,23 +365,21 @@ EsxModel::EsmFile* EsxModel::DataFilesModel::item(int row) const return 0; } -QStringList EsxModel::DataFilesModel::checkedItems() +EsxModel::EsmFileList EsxModel::DataFilesModel::checkedItems() { - QStringList list; + EsmFileList list; - QList::ConstIterator it; - QList::ConstIterator itEnd = mFiles.constEnd(); + EsmFileList::ConstIterator it; + EsmFileList::ConstIterator itEnd = mFiles.constEnd(); int i = 0; - for (it = mFiles.constBegin(); it != itEnd; ++it) { - EsmFile *file = item(i); - ++i; - - QString name = file->fileName(); + for (it = mFiles.constBegin(); it != itEnd; ++it) + { + EsmFile *file = *it; // Only add the items that are in the checked list and available - if (mCheckStates[name] == Qt::Checked && canBeChecked(file)) - list << name; + if (mCheckStates[file->fileName()] == Qt::Checked && canBeChecked(file)) + list << file; } return list; @@ -413,13 +411,13 @@ void EsxModel::DataFilesModel::uncheckAll() emit layoutChanged(); } -QStringList EsxModel::DataFilesModel::uncheckedItems() +EsxModel::EsmFileList EsxModel::DataFilesModel::uncheckedItems() { - QStringList list; - QStringList checked = checkedItems(); + EsmFileList list; + EsmFileList checked = checkedItems(); - QList::ConstIterator it; - QList::ConstIterator itEnd = mFiles.constEnd(); + EsmFileList::ConstIterator it; + EsmFileList::ConstIterator itEnd = mFiles.constEnd(); int i = 0; for (it = mFiles.constBegin(); it != itEnd; ++it) { @@ -427,8 +425,8 @@ QStringList EsxModel::DataFilesModel::uncheckedItems() ++i; // Add the items that are not in the checked list - if (!checked.contains(file->fileName())) - list << file->fileName(); + if (!checked.contains(file)) + list << file; } return list; diff --git a/components/esxselector/model/datafilesmodel.hpp b/components/esxselector/model/datafilesmodel.hpp index bc55bb6cf..24b36aa88 100644 --- a/components/esxselector/model/datafilesmodel.hpp +++ b/components/esxselector/model/datafilesmodel.hpp @@ -10,6 +10,8 @@ namespace EsxModel { class EsmFile; + typedef QList EsmFileList; + class DataFilesModel : public QAbstractTableModel { Q_OBJECT @@ -39,8 +41,8 @@ namespace EsxModel void uncheckAll(); - QStringList checkedItems(); - QStringList uncheckedItems(); + EsmFileList checkedItems(); + EsmFileList uncheckedItems(); QStringList checkedItemsPaths(); Qt::CheckState checkState(const QModelIndex &index); @@ -51,13 +53,13 @@ namespace EsxModel EsmFile* item(int row) const; signals: - void checkedItemsChanged(const QStringList &items); + void checkedItemsChanged(const EsmFileList &items); private: bool canBeChecked(EsmFile *file) const; void addFile(EsmFile *file); - QList mFiles; + EsmFileList mFiles; QHash mCheckStates; QString mEncoding; diff --git a/components/esxselector/view/contentselector.cpp b/components/esxselector/view/contentselector.cpp index 266fd76dc..0b4780241 100644 --- a/components/esxselector/view/contentselector.cpp +++ b/components/esxselector/view/contentselector.cpp @@ -77,6 +77,7 @@ 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); diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 6235f31af..ecc70dfcb 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -27,7 +27,7 @@ - 9 + 3 6 @@ -115,7 +115,7 @@ 6 - 9 + 3 9 From 24e38846da6f96b79f722cdad989672dcbb99c21 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 20 Aug 2013 03:53:23 -0500 Subject: [PATCH 020/118] Fixed broken profile actions --- apps/launcher/datafilespage.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 15f8d9ba2..6f8d1dfac 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -29,6 +29,8 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam , mLauncherSettings(launcherSettings) , ContentSelector(parent) { + QMetaObject::connectSlotsByName(this); + // Create a dialog for the new profile name input mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); @@ -40,10 +42,13 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam void DataFilesPage::createActions() { - + qDebug () << "adding actions..."; // Add the actions to the toolbuttons newProfileButton->setDefaultAction(newProfileAction); deleteProfileButton->setDefaultAction(deleteProfileAction); + + for (int i = 0; i < newProfileButton->actions().size(); i++) + qDebug() << newProfileButton->actions().at(i)->objectName(); } void DataFilesPage::setupDataFiles() @@ -186,6 +191,7 @@ int DataFilesPage::profilesComboBoxIndex() void DataFilesPage::on_newProfileAction_triggered() { + qDebug() << "new_profile_action_triggered"; if (mNewProfileDialog->exec() == QDialog::Accepted) { QString profile = mNewProfileDialog->lineEdit()->text(); profilesComboBox->addItem(profile); From 6898321676e0841cd2dbc70bf93b57748199d924 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 20 Aug 2013 08:16:56 -0500 Subject: [PATCH 021/118] Reenabling features Profile functions enabled New/load file functions partially enabled Layout reorganized --- apps/launcher/datafilespage.cpp | 4 +- apps/opencs/view/doc/filedialog.cpp | 67 +++++------------------- apps/opencs/view/doc/filedialog.hpp | 11 ---- components/esxselector/view/lineedit.cpp | 1 + components/esxselector/view/lineedit.hpp | 2 + files/ui/datafilespage.ui | 53 +++++++++++++++---- 6 files changed, 60 insertions(+), 78 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 6f8d1dfac..d51952b11 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -31,6 +31,8 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam { QMetaObject::connectSlotsByName(this); + projectGroupBox->hide(); + // Create a dialog for the new profile name input mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); @@ -42,7 +44,6 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam void DataFilesPage::createActions() { - qDebug () << "adding actions..."; // Add the actions to the toolbuttons newProfileButton->setDefaultAction(newProfileAction); deleteProfileButton->setDefaultAction(deleteProfileAction); @@ -191,7 +192,6 @@ int DataFilesPage::profilesComboBoxIndex() void DataFilesPage::on_newProfileAction_triggered() { - qDebug() << "new_profile_action_triggered"; if (mNewProfileDialog->exec() == QDialog::Accepted) { QString profile = mNewProfileDialog->lineEdit()->text(); profilesComboBox->addItem(profile); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 69ed1c13a..a0360cc5e 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -25,42 +25,20 @@ CSVDoc::FileDialog::FileDialog(QWidget *parent) : profileGroupBox->hide(); pluginView->showColumn(2); - // Add some extra widgets - QHBoxLayout *nameLayout = new QHBoxLayout(); - QSpacerItem *spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - - mNameLabel = new QLabel(tr("File Name:"), this); - - QRegExpValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9\\s]*$")); - mNameLineEdit = new EsxView::LineEdit(this); - mNameLineEdit->setValidator(validator); - - nameLayout->addSpacerItem(spacer); - nameLayout->addWidget(mNameLabel); - nameLayout->addWidget(mNameLineEdit); - - mButtonBox = new QDialogButtonBox(this); - - mCreateButton = new QPushButton(tr("Create"), this); - mCreateButton->setEnabled(false); - - verticalLayout->addLayout(nameLayout); - verticalLayout->addWidget(mButtonBox); - resize(400, 400); // connect(mDataFilesModel, SIGNAL(checkedItemsChanged(QStringList)), this, SLOT(updateOpenButton(QStringList))); //connect(mNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateCreateButton(QString))); - // connect(mCreateButton, SIGNAL(clicked()), this, SLOT(createButtonClicked())); + connect(projectCreateButton, SIGNAL(clicked()), this, SIGNAL(createNewFile())); - // connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept())); - // connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(mButtonBox, SIGNAL(accepted()), this, SIGNAL(openFiles()); + // connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject())); } void CSVDoc::FileDialog::updateOpenButton(const QStringList &items) { - QPushButton *openButton = mButtonBox->button(QDialogButtonBox::Open); + QPushButton *openButton = projectButtonBox->button(QDialogButtonBox::Open); if (!openButton) return; @@ -70,29 +48,25 @@ void CSVDoc::FileDialog::updateOpenButton(const QStringList &items) void CSVDoc::FileDialog::updateCreateButton(const QString &name) { - if (!mCreateButton->isVisible()) + if (!projectCreateButton->isVisible()) return; - mCreateButton->setEnabled(!name.isEmpty()); + projectCreateButton->setEnabled(!name.isEmpty()); } QString CSVDoc::FileDialog::fileName() { - return mNameLineEdit->text(); + return projectNameLineEdit->text(); } void CSVDoc::FileDialog::openFile() { setWindowTitle(tr("Open")); - mNameLabel->hide(); - mNameLineEdit->hide(); - mCreateButton->hide(); - - mButtonBox->removeButton(mCreateButton); - mButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Open); - QPushButton *openButton = mButtonBox->button(QDialogButtonBox::Open); - openButton->setEnabled(false); + projectNameLineEdit->hide(); + projectCreateButton->hide(); + projectGroupBox->setTitle(tr("")); + projectButtonBox->button(QDialogButtonBox::Open)->setEnabled(false); show(); raise(); @@ -103,25 +77,10 @@ void CSVDoc::FileDialog::newFile() { setWindowTitle(tr("New")); - mNameLabel->show(); - mNameLineEdit->clear(); - mNameLineEdit->show(); - mCreateButton->show(); - - mButtonBox->setStandardButtons(QDialogButtonBox::Cancel); - mButtonBox->addButton(mCreateButton, QDialogButtonBox::ActionRole); + projectButtonBox->setStandardButtons(QDialogButtonBox::Cancel); + projectButtonBox->addButton(projectCreateButton, QDialogButtonBox::ActionRole); show(); raise(); activateWindow(); } - -void CSVDoc::FileDialog::accept() -{ - emit openFiles(); -} - -void CSVDoc::FileDialog::createButtonClicked() -{ - emit createNewFile(); -} diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 0e2d8f32b..c749099d4 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -34,7 +34,6 @@ namespace CSVDoc void openFile(); void newFile(); - void accepted(); QString fileName(); @@ -43,21 +42,11 @@ namespace CSVDoc void createNewFile(); public slots: - void accept(); private slots: //void updateViews(); void updateOpenButton(const QStringList &items); void updateCreateButton(const QString &name); - - void createButtonClicked(); - - private: - QLabel *mNameLabel; - EsxView::LineEdit *mNameLineEdit; - - QPushButton *mCreateButton; - QDialogButtonBox *mButtonBox; }; } #endif // FILEDIALOG_HPP diff --git a/components/esxselector/view/lineedit.cpp b/components/esxselector/view/lineedit.cpp index 8944251ae..48be2f022 100644 --- a/components/esxselector/view/lineedit.cpp +++ b/components/esxselector/view/lineedit.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "lineedit.hpp" diff --git a/components/esxselector/view/lineedit.hpp b/components/esxselector/view/lineedit.hpp index e48392ba8..4e0cbe339 100644 --- a/components/esxselector/view/lineedit.hpp +++ b/components/esxselector/view/lineedit.hpp @@ -20,6 +20,8 @@ namespace EsxView { Q_OBJECT + QString mPlaceholderText; + public: LineEdit(QWidget *parent = 0); diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index ecc70dfcb..60e8b8bf5 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -14,12 +14,6 @@ Qt::DefaultContextMenu - - 6 - - - 6 - @@ -91,21 +85,53 @@
- pluginView - masterView - pluginView - masterView
+ + + + Project + + + + + + Enter project name... + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Open + + + + + + + false + + + Create + + + + + projectButtonBox + projectCreateButton + projectNameLineEdit + + Qt::NoFocus - Profiles + Profile false @@ -221,6 +247,11 @@ QComboBox
components/esxselector/view/profilescombobox.hpp
+ + EsxView::LineEdit + QLineEdit +
components/esxselector/view/lineedit.hpp
+
From e6fdc7e7fdce784b2e540022087cc90b35a0bbc4 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 20 Aug 2013 12:34:39 -0500 Subject: [PATCH 022/118] ... --- apps/launcher/datafilespage.cpp | 3 --- apps/opencs/view/doc/filedialog.cpp | 8 ++++---- components/esxselector/view/contentselector.cpp | 2 +- components/esxselector/view/contentselector.hpp | 4 ++-- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index d51952b11..070f455e4 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -47,9 +47,6 @@ void DataFilesPage::createActions() // Add the actions to the toolbuttons newProfileButton->setDefaultAction(newProfileAction); deleteProfileButton->setDefaultAction(deleteProfileAction); - - for (int i = 0; i < newProfileButton->actions().size(); i++) - qDebug() << newProfileButton->actions().at(i)->objectName(); } void DataFilesPage::setupDataFiles() diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index a0360cc5e..561f7f5d7 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -27,13 +27,13 @@ CSVDoc::FileDialog::FileDialog(QWidget *parent) : resize(400, 400); - // connect(mDataFilesModel, SIGNAL(checkedItemsChanged(QStringList)), this, SLOT(updateOpenButton(QStringList))); - //connect(mNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateCreateButton(QString))); + 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())); - connect(mButtonBox, SIGNAL(accepted()), this, SIGNAL(openFiles()); - // connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(projectButtonBox, SIGNAL(accepted()), this, SIGNAL(openFiles())); + connect(projectButtonBox, SIGNAL(rejected()), this, SLOT(reject())); } void CSVDoc::FileDialog::updateOpenButton(const QStringList &items) diff --git a/components/esxselector/view/contentselector.cpp b/components/esxselector/view/contentselector.cpp index 0b4780241..6cba643d2 100644 --- a/components/esxselector/view/contentselector.cpp +++ b/components/esxselector/view/contentselector.cpp @@ -11,7 +11,7 @@ #include EsxView::ContentSelector::ContentSelector(QWidget *parent) : - QWidget(parent) + QDialog(parent) { setupUi(this); buildModelsAndViews(); diff --git a/components/esxselector/view/contentselector.hpp b/components/esxselector/view/contentselector.hpp index 35ef3a07c..658e0176c 100644 --- a/components/esxselector/view/contentselector.hpp +++ b/components/esxselector/view/contentselector.hpp @@ -1,7 +1,7 @@ #ifndef CONTENTSELECTOR_HPP #define CONTENTSELECTOR_HPP -#include +#include #include "ui_datafilespage.h" @@ -16,7 +16,7 @@ class QSortFilterProxyModel; namespace EsxView { - class ContentSelector : public QWidget, protected Ui::DataFilesPage + class ContentSelector : public QDialog, protected Ui::DataFilesPage { Q_OBJECT From a6e7cf9a8c795ffebd6c45e72f80b4650f1bbd7b Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 7 Sep 2013 15:57:40 -0500 Subject: [PATCH 023/118] Implementing drag and drop --- apps/opencs/view/doc/filedialog.cpp | 2 +- components/CMakeLists.txt | 3 +- components/esxselector/model/contentmodel.cpp | 428 ++++++++++++++++++ components/esxselector/model/contentmodel.hpp | 64 +++ .../esxselector/model/datafilesmodel.cpp | 216 ++++++--- .../esxselector/model/datafilesmodel.hpp | 25 +- components/esxselector/model/esmfile.cpp | 18 +- components/esxselector/model/esmfile.hpp | 5 + .../esxselector/model/masterproxymodel.cpp | 34 +- .../esxselector/model/masterproxymodel.hpp | 6 +- components/esxselector/model/modelitem.cpp | 16 +- components/esxselector/model/modelitem.hpp | 10 +- .../esxselector/model/pluginsproxymodel.cpp | 19 +- .../esxselector/model/pluginsproxymodel.hpp | 6 +- components/esxselector/model/sourcemodel.cpp | 6 + components/esxselector/model/sourcemodel.h | 18 + .../esxselector/view/contentselector.cpp | 58 ++- .../esxselector/view/contentselector.hpp | 3 + files/ui/datafilespage.ui | 63 ++- 19 files changed, 887 insertions(+), 113 deletions(-) create mode 100644 components/esxselector/model/contentmodel.cpp create mode 100644 components/esxselector/model/contentmodel.hpp create mode 100644 components/esxselector/model/sourcemodel.cpp create mode 100644 components/esxselector/model/sourcemodel.h diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 561f7f5d7..fb031fe5f 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -27,7 +27,7 @@ CSVDoc::FileDialog::FileDialog(QWidget *parent) : resize(400, 400); - connect(mDataFilesModel, SIGNAL(checkedItemsChanged(QStringList)), this, SLOT(updateOpenButton(QStringList))); + // 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/components/CMakeLists.txt b/components/CMakeLists.txt index 8b07a4e00..0f7c5017b 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -1,5 +1,5 @@ project (Components) - +set (CMAKE_BUILD_TYPE DEBUG) # source files add_component_dir (settings @@ -74,6 +74,7 @@ if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) add_component_qt_dir (esxselector model/masterproxymodel model/modelitem model/datafilesmodel model/pluginsproxymodel model/esmfile model/naturalsort + model/contentmodel view/profilescombobox view/comboboxlineedit view/lineedit view/contentselector ) diff --git a/components/esxselector/model/contentmodel.cpp b/components/esxselector/model/contentmodel.cpp new file mode 100644 index 000000000..673665775 --- /dev/null +++ b/components/esxselector/model/contentmodel.cpp @@ -0,0 +1,428 @@ +#include "contentmodel.hpp" +#include "esmfile.hpp" +#include +#include +#include +#include + +EsxModel::ContentModel::ContentModel(QObject *parent) : + QAbstractTableModel(parent), mEncoding("win1252") +{} + +void EsxModel::ContentModel::setEncoding(const QString &encoding) +{ + mEncoding = encoding; +} + +int EsxModel::ContentModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return 1; +} +/* +QModelIndex EsxModel::ContentModel::parent(const QModelIndex &child) const +{ + if(!child.isValid()) + return 0; + + return child.parent(); +} + +QModelIndex EsxModel::ContentModel::index(int row, int column, const QModelIndex &parent) const +{ + +} +*/ +int EsxModel::ContentModel::rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return mFiles.size(); +} + +QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (index.row() >= mFiles.size()) + return QVariant(); + + 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 QString("%1 kB").arg(int((file->size() + 1023) / 1024)); + case 3: + return file->modified().toString(Qt::ISODate); + case 4: + return file->accessed().toString(Qt::TextDate); + case 5: + return file->version(); + case 6: + return file->path(); + case 7: + return file->masters().join(", "); + case 8: + return file->description(); + } + + return QVariant(); + } + + case Qt::TextAlignmentRole: + { + switch (column) + { + case 0: + case 1: + return Qt::AlignLeft + Qt::AlignVCenter; + case 2: + case 3: + case 4: + case 5: + return Qt::AlignRight + Qt::AlignVCenter; + default: + return Qt::AlignLeft + Qt::AlignVCenter; + } + return QVariant(); + } + + case Qt::ToolTipRole: + { + 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(", ")); + } + + case Qt::UserRole: + { + if (file->masters().size() == 0) + return "game"; + else + return "addon"; + } + + default: + return QVariant(); + } +} + +Qt::ItemFlags EsxModel::ContentModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + + 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; +} + +bool EsxModel::ContentModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (index.isValid() && role == Qt::EditRole) + { + QString fname = value.value(); + mFiles.replace(index.row(), findItem(fname)); + emit dataChanged(index, index); + return true; + } + + return false; +} + +bool EsxModel::ContentModel::insertRows(int position, int rows, const QModelIndex &parent) +{ + beginInsertRows(parent, position, position+rows-1); + + for (int row = 0; row < rows; ++row) + mFiles.insert(position, new EsmFile); + + endInsertRows(); + return true; +} + +bool EsxModel::ContentModel::removeRows(int position, int rows, const QModelIndex &parent) +{ + beginRemoveRows(parent, position, position+rows-1); + + for (int row = 0; row < rows; ++row) + mFiles.removeAt(position); + + endRemoveRows(); + emit dataChanged(index(0,0,parent), index(rowCount()-1, 0, parent)); + return true; +} + +Qt::DropActions EsxModel::ContentModel::supportedDropActions() const +{ + return Qt::CopyAction | Qt::MoveAction; +} + +QStringList EsxModel::ContentModel::mimeTypes() const +{ + QStringList types; + types << "application/omwcontent"; + return types; +} + +QMimeData *EsxModel::ContentModel::mimeData(const QModelIndexList &indexes) const +{ + QMimeData *mimeData = new QMimeData(); + QByteArray encodedData; + + QDataStream stream(&encodedData, QIODevice::WriteOnly); + + foreach (const QModelIndex &index, indexes) + { + if (index.isValid()) + { + QString text = data(index, Qt::DisplayRole).toString(); + stream << text; + } + } + + mimeData->setData("application/omwcontent", encodedData); + return mimeData; +} + +bool EsxModel::ContentModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + if (action == Qt::IgnoreAction) + return true; + + if (!data->hasFormat("application/omwcontent")) + return false; + + if (column > 0) + return false; + + int beginRow; + + if (row != -1) + beginRow = row; + else if (parent.isValid()) + beginRow = parent.row(); + else + beginRow = rowCount(); + + QByteArray encodedData = data->data("application/omwcontent"); + QDataStream stream(&encodedData, QIODevice::ReadOnly); + QStringList newItems; + int rows = 0; + + while (!stream.atEnd()) + { + QString text; + stream >> text; + newItems << text; + ++rows; + } + + insertRows(beginRow, rows, QModelIndex()); + + foreach (const QString &text, newItems) + { + QModelIndex idx = index(beginRow, 0, QModelIndex()); + setData(idx, text); + beginRow++; + } + + return true; +} + +void EsxModel::ContentModel::addFile(EsmFile *file) +{ + emit beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); + mFiles.append(file); + emit endInsertRows(); +} + +void EsxModel::ContentModel::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; +} + +EsxModel::EsmFile* EsxModel::ContentModel::findItem(const QString &name) +{ + for (int i = 0; i < mFiles.size(); ++i) + { + if (name == item(i)->fileName()) + return item(i); + } + + // Not found + return 0; +} + +EsxModel::EsmFile* EsxModel::ContentModel::item(int row) const +{ + if (row >= 0 && row < mFiles.count()) + return mFiles.at(row); + + return 0; +} + +QModelIndex EsxModel::ContentModel::indexFromItem(EsmFile *item) const +{ + if (item) + //return createIndex(mFiles.indexOf(item), 0); + return index(mFiles.indexOf(item),0); + + return QModelIndex(); +} + +Qt::CheckState EsxModel::ContentModel::checkState(const QModelIndex &index) +{ + return mCheckStates[item(index.row())->fileName()]; +} + +void EsxModel::ContentModel::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()); + +} + +bool EsxModel::ContentModel::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; +} + +EsxModel::ContentFileList EsxModel::ContentModel::checkedItems() const +{ + ContentFileList list; + + for (int i = 0; i < mFiles.size(); ++i) + { + EsmFile *file = item(i); + + // Only add the items that are in the checked list and available + if (mCheckStates[file->fileName()] == Qt::Checked && canBeChecked(file)) + list << file; + } + + return list; +} + +void EsxModel::ContentModel::uncheckAll() +{ + emit layoutAboutToBeChanged(); + mCheckStates.clear(); + emit layoutChanged(); +} diff --git a/components/esxselector/model/contentmodel.hpp b/components/esxselector/model/contentmodel.hpp new file mode 100644 index 000000000..a585ab63b --- /dev/null +++ b/components/esxselector/model/contentmodel.hpp @@ -0,0 +1,64 @@ +#ifndef CONTENTMODEL_HPP +#define CONTENTMODEL_HPP + +#include + +namespace EsxModel +{ + class EsmFile; + + typedef QList ContentFileList; + + class ContentModel : public QAbstractTableModel + { + Q_OBJECT + public: + explicit ContentModel(QObject *parent = 0); + + void setEncoding(const QString &encoding); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()); + + 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); + + void addFiles(const QString &path); + + QModelIndex indexFromItem(EsmFile *item) const; + EsxModel::EsmFile *findItem(const QString &name); + + Qt::CheckState checkState(const QModelIndex &index); + void setCheckState(const QModelIndex &index, Qt::CheckState state); + ContentFileList checkedItems() const; + void uncheckAll(); +/* + QModelIndex index(int row, int column, const QModelIndex &parent) const; + QModelIndex parent(const QModelIndex &child) const; +*/ + private: + + void addFile(EsmFile *file); + EsmFile* item(int row) const; + bool canBeChecked(const EsmFile *file) const; + + ContentFileList mFiles; + QHash mCheckStates; + QString mEncoding; + + signals: + + public slots: + + }; +} +#endif // CONTENTMODEL_HPP diff --git a/components/esxselector/model/datafilesmodel.cpp b/components/esxselector/model/datafilesmodel.cpp index 49d0d6132..ee940bb27 100644 --- a/components/esxselector/model/datafilesmodel.cpp +++ b/components/esxselector/model/datafilesmodel.cpp @@ -48,13 +48,12 @@ void EsxModel::DataFilesModel::setCheckState(const QModelIndex &index, Qt::Check Qt::CheckState EsxModel::DataFilesModel::checkState(const QModelIndex &index) { - EsmFile *file = item(index.row()); - return mCheckStates[file->fileName()]; + return mCheckStates[item(index.row())->fileName()]; } int EsxModel::DataFilesModel::columnCount(const QModelIndex &parent) const { - return parent.isValid() ? 0 : 9; + return parent.isValid() ? 0 : 1; } int EsxModel::DataFilesModel::rowCount(const QModelIndex &parent) const @@ -82,7 +81,7 @@ QVariant EsxModel::DataFilesModel::data(const QModelIndex &index, int role) cons if (!index.isValid()) return QVariant(); - EsmFile *file = item(index.row()); + const EsmFile *file = item(index.row()); if (!file) return QVariant(); @@ -90,6 +89,7 @@ QVariant EsxModel::DataFilesModel::data(const QModelIndex &index, int role) cons const int column = index.column(); switch (role) { + case Qt::EditRole: case Qt::DisplayRole: { switch (column) { @@ -172,25 +172,26 @@ Qt::ItemFlags EsxModel::DataFilesModel::flags(const QModelIndex &index) const if (!index.isValid()) return Qt::NoItemFlags; - EsmFile *file = item(index.row()); + const EsmFile *file = item(index.row()); + + Qt::ItemFlags dragDropFlags = Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; + Qt::ItemFlags checkFlags = Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; if (!file) return Qt::NoItemFlags; - if (canBeChecked(file)) { - if (index.column() == 0) { - return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; - } else { - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; - } - } else { - if (index.column() == 0) { - return Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; - } else { - return Qt::ItemIsSelectable; - } + if (canBeChecked(file)) + { + if (index.column() == 0) + return dragDropFlags | checkFlags | Qt::ItemIsEnabled; + else + return Qt::ItemIsDropEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable; } + if (index.column() == 0) + return dragDropFlags | checkFlags; + + return Qt::ItemIsDropEnabled | Qt::ItemIsSelectable; } QVariant EsxModel::DataFilesModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -210,22 +211,27 @@ QVariant EsxModel::DataFilesModel::headerData(int section, Qt::Orientation orien case 7: return tr("Masters"); case 8: return tr("Description"); } - } /* else { - // Show row numbers - return ++section; } -*/ return QVariant(); } bool EsxModel::DataFilesModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid()) - return false; + return false; + + if (role == Qt::EditRole) + { + qDebug() << "replacing: " << mFiles.at(index.row())->fileName(); +// mFiles.replace(index.row(), value.value()); + qDebug() << "with: " << mFiles.at(index.row())->fileName(); + emit dataChanged(index, index); + return true; + } return false; } - +//!!!!!!!!!!!!!!!!!!!!!!! bool lessThanEsmFile(const EsxModel::EsmFile *e1, const EsxModel::EsmFile *e2) { //Masters first then alphabetically @@ -236,16 +242,15 @@ bool lessThanEsmFile(const EsxModel::EsmFile *e1, const EsxModel::EsmFile *e2) 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)) { + if (e1->modified().toString(Qt::ISODate) < e2->modified().toString(Qt::ISODate)) return true; - } else { + else return false; - } } - +//!!!!!!!!!!!!!!!!!!!!!!! void EsxModel::DataFilesModel::sort(int column, Qt::SortOrder order) { emit layoutAboutToBeChanged(); @@ -259,7 +264,7 @@ void EsxModel::DataFilesModel::sort(int column, Qt::SortOrder order) emit layoutChanged(); } -void EsxModel::DataFilesModel::addFile(EsmFile *file) +void EsxModel::DataFilesModel::addFile(const EsmFile *file) { emit beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); mFiles.append(file); @@ -331,22 +336,23 @@ void EsxModel::DataFilesModel::addFiles(const QString &path) delete decoder; } -QModelIndex EsxModel::DataFilesModel::indexFromItem(EsmFile *item) const +QModelIndex EsxModel::DataFilesModel::indexFromItem(const EsmFile *item) const { if (item) - return createIndex(mFiles.indexOf(item), 0); + //return createIndex(mFiles.indexOf(item), 0); + return index(mFiles.indexOf(item),0); return QModelIndex(); } -EsxModel::EsmFile* EsxModel::DataFilesModel::findItem(const QString &name) +const EsxModel::EsmFile* EsxModel::DataFilesModel::findItem(const QString &name) { - QList::ConstIterator it; - QList::ConstIterator itEnd = mFiles.constEnd(); + EsmFileList::ConstIterator it; + EsmFileList::ConstIterator itEnd = mFiles.constEnd(); int i = 0; for (it = mFiles.constBegin(); it != itEnd; ++it) { - EsmFile *file = item(i); + const EsmFile *file = item(i); ++i; if (name == file->fileName()) @@ -357,12 +363,12 @@ EsxModel::EsmFile* EsxModel::DataFilesModel::findItem(const QString &name) return 0; } -EsxModel::EsmFile* EsxModel::DataFilesModel::item(int row) const +const EsxModel::EsmFile* EsxModel::DataFilesModel::item(int row) const { if (row >= 0 && row < mFiles.count()) return mFiles.at(row); - else - return 0; + + return 0; } EsxModel::EsmFileList EsxModel::DataFilesModel::checkedItems() @@ -372,14 +378,11 @@ EsxModel::EsmFileList EsxModel::DataFilesModel::checkedItems() EsmFileList::ConstIterator it; EsmFileList::ConstIterator itEnd = mFiles.constEnd(); - int i = 0; for (it = mFiles.constBegin(); it != itEnd; ++it) { - EsmFile *file = *it; - // Only add the items that are in the checked list and available - if (mCheckStates[file->fileName()] == Qt::Checked && canBeChecked(file)) - list << file; + if (mCheckStates[(*it)->fileName()] == Qt::Checked && canBeChecked(*it)) + list << (*it); } return list; @@ -389,12 +392,12 @@ QStringList EsxModel::DataFilesModel::checkedItemsPaths() { QStringList list; - QList::ConstIterator it; - QList::ConstIterator itEnd = mFiles.constEnd(); + EsmFileList::ConstIterator it; + EsmFileList::ConstIterator itEnd = mFiles.constEnd(); int i = 0; for (it = mFiles.constBegin(); it != itEnd; ++it) { - EsmFile *file = item(i); + const EsmFile *file = item(i); ++i; if (mCheckStates[file->fileName()] == Qt::Checked && canBeChecked(file)) @@ -403,7 +406,6 @@ QStringList EsxModel::DataFilesModel::checkedItemsPaths() return list; } - void EsxModel::DataFilesModel::uncheckAll() { emit layoutAboutToBeChanged(); @@ -411,18 +413,17 @@ void EsxModel::DataFilesModel::uncheckAll() emit layoutChanged(); } +/* EsxModel::EsmFileList EsxModel::DataFilesModel::uncheckedItems() { EsmFileList list; EsmFileList checked = checkedItems(); EsmFileList::ConstIterator it; - EsmFileList::ConstIterator itEnd = mFiles.constEnd(); - int i = 0; - for (it = mFiles.constBegin(); it != itEnd; ++it) { - EsmFile *file = item(i); - ++i; + 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)) @@ -431,8 +432,8 @@ EsxModel::EsmFileList EsxModel::DataFilesModel::uncheckedItems() return list; } - -bool EsxModel::DataFilesModel::canBeChecked(EsmFile *file) const +*/ +bool EsxModel::DataFilesModel::canBeChecked(const EsmFile *file) const { //element can be checked if all its dependencies are foreach (const QString &master, file->masters()) @@ -442,3 +443,110 @@ bool EsxModel::DataFilesModel::canBeChecked(EsmFile *file) const } 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 +{ +// if (indexes.at(0).isValid()) +// return new EsmFile(*item(indexes.at(0).row())); + + return 0; +} + +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; +} + +bool EsxModel::DataFilesModel::insertRows(int row, int count, const QModelIndex &parent) +{ + qDebug() << "inserting row: " << row << " count: " << count; + beginInsertRows(QModelIndex(),row, row+count-1); + + EsmFile *file = new EsmFile(); + + for (int i = 0; i < count; ++i) + mFiles.insert(row + i, file); + + endInsertRows(); + return true; +} + +bool EsxModel::DataFilesModel::removeRows(int row, int count, const QModelIndex &parent) +{ + qDebug() << "removing row: " << row << " count: " << count; + beginRemoveRows(QModelIndex(), row, row+count-1); + + for (int i = 0; i < count; ++i) + { + mFiles.removeAt(i); + } + + endRemoveRows(); + qDebug() <<"remove success"; + + emit dataChanged(parent, index(rowCount()-1, 0, parent)); + return true; +} + diff --git a/components/esxselector/model/datafilesmodel.hpp b/components/esxselector/model/datafilesmodel.hpp index 24b36aa88..4f23cd530 100644 --- a/components/esxselector/model/datafilesmodel.hpp +++ b/components/esxselector/model/datafilesmodel.hpp @@ -10,7 +10,7 @@ namespace EsxModel { class EsmFile; - typedef QList EsmFileList; + typedef QList EsmFileList; class DataFilesModel : public QAbstractTableModel { @@ -21,6 +21,8 @@ namespace EsxModel 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()); @@ -33,7 +35,10 @@ namespace EsxModel void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); inline QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const - { return QAbstractTableModel::index(row, column, parent); } + { + QModelIndex idx = QAbstractTableModel::index(row, 0, parent); + return idx; + } void setEncoding(const QString &encoding); @@ -41,6 +46,11 @@ namespace EsxModel 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(); @@ -48,16 +58,17 @@ namespace EsxModel Qt::CheckState checkState(const QModelIndex &index); void setCheckState(const QModelIndex &index, Qt::CheckState state); - QModelIndex indexFromItem(EsmFile *item) const; - EsmFile* findItem(const QString &name); - EsmFile* item(int row) const; + 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(EsmFile *file) const; - void addFile(EsmFile *file); + + bool canBeChecked(const EsmFile *file) const; + void addFile(const EsmFile *file); EsmFileList mFiles; QHash mCheckStates; diff --git a/components/esxselector/model/esmfile.cpp b/components/esxselector/model/esmfile.cpp index 96b90e44e..95cf70312 100644 --- a/components/esxselector/model/esmfile.cpp +++ b/components/esxselector/model/esmfile.cpp @@ -1,13 +1,17 @@ #include "esmfile.hpp" EsxModel::EsmFile::EsmFile(QString fileName, ModelItem *parent) - : ModelItem(parent) -{ - mFileName = fileName; - mSize = 0; - mVersion = 0.0f; -} - + : ModelItem(parent), mFileName(fileName), mSize(0), 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; diff --git a/components/esxselector/model/esmfile.hpp b/components/esxselector/model/esmfile.hpp index 6a3e36b53..0cda018b3 100644 --- a/components/esxselector/model/esmfile.hpp +++ b/components/esxselector/model/esmfile.hpp @@ -14,7 +14,9 @@ namespace EsxModel Q_PROPERTY(QString filename READ fileName) public: + EsmFile(QString fileName = QString(), ModelItem *parent = 0); + // EsmFile(const EsmFile &); ~EsmFile() {} @@ -38,6 +40,7 @@ namespace EsxModel inline QStringList masters() const { return mMasters; } inline QString description() const { return mDescription; } + //inline ModelItem *parent() const { return ModelItem::parent(); this->} private: QString mFileName; @@ -53,4 +56,6 @@ namespace EsxModel }; } +Q_DECLARE_METATYPE (EsxModel::EsmFile *) + #endif diff --git a/components/esxselector/model/masterproxymodel.cpp b/components/esxselector/model/masterproxymodel.cpp index 011e5ebd5..46d68ca51 100644 --- a/components/esxselector/model/masterproxymodel.cpp +++ b/components/esxselector/model/masterproxymodel.cpp @@ -1,4 +1,6 @@ #include "masterproxymodel.hpp" +#include +#include EsxModel::MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableModel* model) : QSortFilterProxyModel(parent) @@ -7,10 +9,36 @@ EsxModel::MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableMode setFilterRole (Qt::UserRole); if (model) - setSourceModel (model); + setSourceModel (model); + //connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(slotSourceModelChanged(QModelIndex, QModelIndex))); } - +/* QVariant EsxModel::MasterProxyModel::data(const QModelIndex &index, int role) const { - return QSortFilterProxyModel::data (index, role); + if (index.isValid()) + return QSortFilterProxyModel::data (index, role); + + return 0; +} +*/ +void EsxModel::MasterProxyModel::slotSourceModelChanged(QModelIndex topLeft, QModelIndex botRight) +{ + qDebug() << "source data changed.. updating master proxy"; + emit dataChanged(index(0,0), index(rowCount()-1,0)); + + int curRow = -1; +/* + for (int i = 0; i < rowCount() - 1; ++i) + { + if (index(i,0).data(Qt::CheckState) == Qt::Checked) + { + curRow = i; + break; + } + } + + reset(); +*/ + if (curRow != -1); + // index(curRow, 0).setDataQt::CheckState) } diff --git a/components/esxselector/model/masterproxymodel.hpp b/components/esxselector/model/masterproxymodel.hpp index fed01bdb1..8a5c73032 100644 --- a/components/esxselector/model/masterproxymodel.hpp +++ b/components/esxselector/model/masterproxymodel.hpp @@ -2,6 +2,8 @@ #define MASTERPROXYMODEL_HPP #include +#include +#include class QAbstractTableModel; @@ -12,12 +14,12 @@ namespace EsxModel Q_OBJECT public: explicit MasterProxyModel(QObject *parent = 0, QAbstractTableModel *model = 0); - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + // 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 index 8c1e83695..03b19f691 100644 --- a/components/esxselector/model/modelitem.cpp +++ b/components/esxselector/model/modelitem.cpp @@ -2,9 +2,14 @@ EsxModel::ModelItem::ModelItem(ModelItem *parent) : mParentItem(parent) - , QObject(parent) { } +/* +EsxModel::ModelItem::ModelItem(const ModelItem *parent) + // : mParentItem(parent) +{ +} +*/ EsxModel::ModelItem::~ModelItem() { @@ -12,11 +17,18 @@ EsxModel::ModelItem::~ModelItem() } -EsxModel::ModelItem *EsxModel::ModelItem::parent() +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) diff --git a/components/esxselector/model/modelitem.hpp b/components/esxselector/model/modelitem.hpp index 64596302c..5ee5e417e 100644 --- a/components/esxselector/model/modelitem.hpp +++ b/components/esxselector/model/modelitem.hpp @@ -1,20 +1,22 @@ #ifndef MODELITEM_HPP #define MODELITEM_HPP -#include +#include #include namespace EsxModel { - class ModelItem : public QObject + class ModelItem : public QMimeData { Q_OBJECT public: ModelItem(ModelItem *parent = 0); + //ModelItem(const ModelItem *parent = 0); + ~ModelItem(); - ModelItem *parent(); + ModelItem *parent() const; int row() const; int childCount() const; @@ -24,6 +26,8 @@ namespace EsxModel void appendChild(ModelItem *child); void removeChild(int row); + bool hasFormat(const QString &mimetype) const; + //virtual bool acceptChild(ModelItem *child); protected: diff --git a/components/esxselector/model/pluginsproxymodel.cpp b/components/esxselector/model/pluginsproxymodel.cpp index 4fde11f47..412367b64 100644 --- a/components/esxselector/model/pluginsproxymodel.cpp +++ b/components/esxselector/model/pluginsproxymodel.cpp @@ -1,7 +1,8 @@ #include "pluginsproxymodel.hpp" -#include "datafilesmodel.hpp" +#include "contentmodel.hpp" +#include -EsxModel::PluginsProxyModel::PluginsProxyModel(QObject *parent, DataFilesModel *model) : +EsxModel::PluginsProxyModel::PluginsProxyModel(QObject *parent, ContentModel *model) : QSortFilterProxyModel(parent) { setFilterRegExp (QString("addon")); @@ -22,12 +23,18 @@ QVariant EsxModel::PluginsProxyModel::data(const QModelIndex &index, int role) c { case Qt::CheckStateRole: { - if (index.column() != 0) + if (index.column() != 0) return QVariant(); - return static_cast(sourceModel())->checkState(mapToSource(index)); + return static_cast(sourceModel())->checkState(mapToSource(index)); } - }; + } + return QSortFilterProxyModel::data(index, role); +} + +bool EsxModel::PluginsProxyModel::removeRows(int position, int rows, const QModelIndex &parent) +{ + bool success = QSortFilterProxyModel::removeRows(position, rows, parent); - return QSortFilterProxyModel::data (index, role); + return success; } diff --git a/components/esxselector/model/pluginsproxymodel.hpp b/components/esxselector/model/pluginsproxymodel.hpp index 04c18c2e2..4415df716 100644 --- a/components/esxselector/model/pluginsproxymodel.hpp +++ b/components/esxselector/model/pluginsproxymodel.hpp @@ -8,7 +8,7 @@ class QAbstractTableModel; namespace EsxModel { - class DataFilesModel; + class ContentModel; class PluginsProxyModel : public QSortFilterProxyModel { @@ -16,10 +16,12 @@ namespace EsxModel public: - explicit PluginsProxyModel(QObject *parent = 0, DataFilesModel *model = 0); + 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); }; } diff --git a/components/esxselector/model/sourcemodel.cpp b/components/esxselector/model/sourcemodel.cpp new file mode 100644 index 000000000..7b54adba9 --- /dev/null +++ b/components/esxselector/model/sourcemodel.cpp @@ -0,0 +1,6 @@ +#include "sourcemodel.h" + +SourceModel::SourceModel(QObject *parent) : + QAbstractTableClass(parent) +{ +} diff --git a/components/esxselector/model/sourcemodel.h b/components/esxselector/model/sourcemodel.h new file mode 100644 index 000000000..cf5145675 --- /dev/null +++ b/components/esxselector/model/sourcemodel.h @@ -0,0 +1,18 @@ +#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 index 6cba643d2..bc7cc2b8b 100644 --- a/components/esxselector/view/contentselector.cpp +++ b/components/esxselector/view/contentselector.cpp @@ -3,6 +3,8 @@ #include "../model/datafilesmodel.hpp" #include "../model/masterproxymodel.hpp" #include "../model/pluginsproxymodel.hpp" +#include "../model/contentmodel.hpp" +#include "../model/esmfile.hpp" #include @@ -14,7 +16,33 @@ EsxView::ContentSelector::ContentSelector(QWidget *parent) : QDialog(parent) { setupUi(this); - buildModelsAndViews(); + // buildModelsAndViews(); + buildDragDropModelView(); +} +void EsxView::ContentSelector::buildDragDropModelView() +{ + mContentModel = new EsxModel::ContentModel(); + + //mContentModel->addFiles("/home/joel/Projects/OpenMW/Data_Files"); + mMasterProxyModel = new EsxModel::MasterProxyModel(this, mContentModel); + mPluginsProxyModel = new EsxModel::PluginsProxyModel(this, mContentModel); + + tableView->setModel (mPluginsProxyModel); + + masterView->setPlaceholderText(QString("Select a game file...")); + masterView->setModel(mMasterProxyModel); + pluginView->setModel(mPluginsProxyModel); + + profilesComboBox->setPlaceholderText(QString("Select a profile...")); + + updateViews(); + connect(pluginView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotPluginTableItemClicked(const QModelIndex &))); + connect(masterView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentMasterIndexChanged(int))); + connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); + + + connect(mContentModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); + connect(tableView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotPluginTableItemClicked(const QModelIndex &))); } void EsxView::ContentSelector::buildModelsAndViews() @@ -22,15 +50,15 @@ void EsxView::ContentSelector::buildModelsAndViews() // Models mDataFilesModel = new EsxModel::DataFilesModel (this); - mMasterProxyModel = new EsxModel::MasterProxyModel (this, mDataFilesModel); - mPluginsProxyModel = new EsxModel::PluginsProxyModel (this, mDataFilesModel); + // mMasterProxyModel = new EsxModel::MasterProxyModel (this, mDataFilesModel); + // mPluginsProxyModel = new EsxModel::PluginsProxyModel (this, mDataFilesModel); masterView->setPlaceholderText(QString("Select a game file...")); masterView->setModel(mMasterProxyModel); pluginView->setModel(mPluginsProxyModel); profilesComboBox->setPlaceholderText(QString("Select a profile...")); - + updateViews(); connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); connect(pluginView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotPluginTableItemClicked(const QModelIndex &))); connect(masterView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentMasterIndexChanged(int))); @@ -39,15 +67,15 @@ void EsxView::ContentSelector::buildModelsAndViews() void EsxView::ContentSelector::addFiles(const QString &path) { - mDataFilesModel->addFiles(path); - mDataFilesModel->sort(3); // Sort by date accessed + mContentModel->addFiles(path); + mContentModel->sort(3); // Sort by date accessed masterView->setCurrentIndex(-1); - mDataFilesModel->uncheckAll(); + mContentModel->uncheckAll(); } void EsxView::ContentSelector::setEncoding(const QString &encoding) { - mDataFilesModel->setEncoding(encoding); + mContentModel->setEncoding(encoding); } void EsxView::ContentSelector::setCheckState(QModelIndex index, QSortFilterProxyModel *model) @@ -62,15 +90,20 @@ void EsxView::ContentSelector::setCheckState(QModelIndex index, QSortFilterProxy if (sourceIndex.isValid()) { - (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) - ? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked) - : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); + (mContentModel->checkState(sourceIndex) == Qt::Checked) + ? mContentModel->setCheckState(sourceIndex, Qt::Unchecked) + : mContentModel->setCheckState(sourceIndex, Qt::Checked); } } QStringList EsxView::ContentSelector::checkedItemsPaths() { - return mDataFilesModel->checkedItemsPaths(); + QStringList itemPaths; + + foreach( const EsxModel::EsmFile *file, mContentModel->checkedItems()) + itemPaths << file->path(); + + return itemPaths; } void EsxView::ContentSelector::updateViews() @@ -106,5 +139,6 @@ void EsxView::ContentSelector::slotCurrentMasterIndexChanged(int index) void EsxView::ContentSelector::slotPluginTableItemClicked(const QModelIndex &index) { + qDebug() << "setting checkstate in plugin..."; setCheckState(index, mPluginsProxyModel); } diff --git a/components/esxselector/view/contentselector.hpp b/components/esxselector/view/contentselector.hpp index 658e0176c..06cc8f3f0 100644 --- a/components/esxselector/view/contentselector.hpp +++ b/components/esxselector/view/contentselector.hpp @@ -7,6 +7,7 @@ namespace EsxModel { + class ContentModel; class DataFilesModel; class PluginsProxyModel; class MasterProxyModel; @@ -23,6 +24,7 @@ namespace EsxView protected: EsxModel::DataFilesModel *mDataFilesModel; + EsxModel::ContentModel *mContentModel; EsxModel::MasterProxyModel *mMasterProxyModel; EsxModel::PluginsProxyModel *mPluginsProxyModel; @@ -37,6 +39,7 @@ namespace EsxView void setCheckState(QModelIndex index, QSortFilterProxyModel *model); QStringList checkedItemsPaths(); void on_checkAction_triggered(); + void buildDragDropModelView(); signals: void profileChanged(int index); diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 60e8b8bf5..76689627b 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -7,28 +7,19 @@ 0 0 518 - 304 + 310
Qt::DefaultContextMenu - + Content - - - 3 - - - 6 - - - 6 - + @@ -41,7 +32,7 @@ - + @@ -56,6 +47,18 @@ QAbstractItemView::NoEditTriggers + + true + + + false + + + QAbstractItemView::DragDrop + + + Qt::MoveAction + true @@ -82,6 +85,40 @@ + + + + QAbstractItemView::NoEditTriggers + + + true + + + false + + + QAbstractItemView::DragDrop + + + Qt::MoveAction + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + false + + + false + + + From c961abce963d4d9681861510dad796c0fb65dd7a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 14 Sep 2013 14:00:07 +0200 Subject: [PATCH 024/118] added warning message to startup window --- apps/opencs/view/doc/startup.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/opencs/view/doc/startup.cpp b/apps/opencs/view/doc/startup.cpp index 4cc64f2df..5d59492c6 100644 --- a/apps/opencs/view/doc/startup.cpp +++ b/apps/opencs/view/doc/startup.cpp @@ -104,6 +104,17 @@ CSVDoc::StartupDialogue::StartupDialogue() : mWidth (0), mColumn (2) layout->addWidget (createButtons()); layout->addWidget (createTools()); + /// \todo remove this label once loading and saving are fully implemented + QLabel *warning = new QLabel ("WARNING:

OpenCS is in alpha stage.
The code for loading and saving is incomplete.
This version of OpenCS is only a preview.
Do NOT use it for real editing!
You will lose records both on loading and on saving.

Please note:
If you lose data and come to the OpenMW forum to complain,
we will mock you.
"); + + QFont font; + font.setPointSize (12); + font.setBold (true); + + warning->setFont (font); + + layout->addWidget (warning, 1); + setLayout (layout); QRect scr = QApplication::desktop()->screenGeometry(); From 077a157841a59bf8bb3ed7e4e7dbfd5bf745b9ff Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 14 Sep 2013 14:56:23 +0200 Subject: [PATCH 025/118] moved Operation and Stage from model/tools to model/doc --- apps/opencs/CMakeLists.txt | 8 ++++---- apps/opencs/model/{tools => doc}/operation.cpp | 17 ++++++++--------- apps/opencs/model/{tools => doc}/operation.hpp | 6 +++--- apps/opencs/model/doc/stage.cpp | 4 ++++ apps/opencs/model/{tools => doc}/stage.hpp | 8 ++++---- apps/opencs/model/tools/birthsigncheck.hpp | 4 ++-- apps/opencs/model/tools/classcheck.hpp | 4 ++-- apps/opencs/model/tools/factioncheck.hpp | 4 ++-- apps/opencs/model/tools/mandatoryid.hpp | 4 ++-- apps/opencs/model/tools/racecheck.hpp | 4 ++-- apps/opencs/model/tools/regioncheck.hpp | 4 ++-- apps/opencs/model/tools/skillcheck.hpp | 4 ++-- apps/opencs/model/tools/soundcheck.hpp | 4 ++-- apps/opencs/model/tools/spellcheck.hpp | 4 ++-- apps/opencs/model/tools/stage.cpp | 4 ---- apps/opencs/model/tools/tools.cpp | 8 ++++---- apps/opencs/model/tools/tools.hpp | 10 +++++++--- apps/opencs/model/tools/verifier.hpp | 4 ++-- 18 files changed, 54 insertions(+), 51 deletions(-) rename apps/opencs/model/{tools => doc}/operation.cpp (82%) rename apps/opencs/model/{tools => doc}/operation.hpp (92%) create mode 100644 apps/opencs/model/doc/stage.cpp rename apps/opencs/model/{tools => doc}/stage.hpp (65%) delete mode 100644 apps/opencs/model/tools/stage.cpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index aa6f6ba76..367c43eb7 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -5,11 +5,11 @@ opencs_units (. editor) set (CMAKE_BUILD_TYPE DEBUG) opencs_units (model/doc - document + document operation ) opencs_units_noqt (model/doc - documentmanager + documentmanager stage ) opencs_hdrs_noqt (model/doc @@ -33,11 +33,11 @@ opencs_hdrs_noqt (model/world opencs_units (model/tools - tools operation reportmodel + tools reportmodel ) opencs_units_noqt (model/tools - stage verifier mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck + verifier mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck birthsigncheck spellcheck ) diff --git a/apps/opencs/model/tools/operation.cpp b/apps/opencs/model/doc/operation.cpp similarity index 82% rename from apps/opencs/model/tools/operation.cpp rename to apps/opencs/model/doc/operation.cpp index 71761cdae..8f7472c5f 100644 --- a/apps/opencs/model/tools/operation.cpp +++ b/apps/opencs/model/doc/operation.cpp @@ -6,11 +6,10 @@ #include -#include "../doc/state.hpp" - +#include "state.hpp" #include "stage.hpp" -void CSMTools::Operation::prepareStages() +void CSMDoc::Operation::prepareStages() { mCurrentStage = mStages.begin(); mCurrentStep = 0; @@ -24,15 +23,15 @@ void CSMTools::Operation::prepareStages() } } -CSMTools::Operation::Operation (int type) : mType (type) {} +CSMDoc::Operation::Operation (int type) : mType (type) {} -CSMTools::Operation::~Operation() +CSMDoc::Operation::~Operation() { for (std::vector >::iterator iter (mStages.begin()); iter!=mStages.end(); ++iter) delete iter->first; } -void CSMTools::Operation::run() +void CSMDoc::Operation::run() { prepareStages(); @@ -45,17 +44,17 @@ void CSMTools::Operation::run() exec(); } -void CSMTools::Operation::appendStage (Stage *stage) +void CSMDoc::Operation::appendStage (Stage *stage) { mStages.push_back (std::make_pair (stage, 0)); } -void CSMTools::Operation::abort() +void CSMDoc::Operation::abort() { exit(); } -void CSMTools::Operation::verify() +void CSMDoc::Operation::verify() { std::vector messages; diff --git a/apps/opencs/model/tools/operation.hpp b/apps/opencs/model/doc/operation.hpp similarity index 92% rename from apps/opencs/model/tools/operation.hpp rename to apps/opencs/model/doc/operation.hpp index 4731c58fa..703098852 100644 --- a/apps/opencs/model/tools/operation.hpp +++ b/apps/opencs/model/doc/operation.hpp @@ -1,11 +1,11 @@ -#ifndef CSM_TOOLS_OPERATION_H -#define CSM_TOOLS_OPERATION_H +#ifndef CSM_DOC_OPERATION_H +#define CSM_DOC_OPERATION_H #include #include -namespace CSMTools +namespace CSMDoc { class Stage; diff --git a/apps/opencs/model/doc/stage.cpp b/apps/opencs/model/doc/stage.cpp new file mode 100644 index 000000000..99b765770 --- /dev/null +++ b/apps/opencs/model/doc/stage.cpp @@ -0,0 +1,4 @@ + +#include "stage.hpp" + +CSMDoc::Stage::~Stage() {} \ No newline at end of file diff --git a/apps/opencs/model/tools/stage.hpp b/apps/opencs/model/doc/stage.hpp similarity index 65% rename from apps/opencs/model/tools/stage.hpp rename to apps/opencs/model/doc/stage.hpp index 3020936f3..1f96c60b4 100644 --- a/apps/opencs/model/tools/stage.hpp +++ b/apps/opencs/model/doc/stage.hpp @@ -1,10 +1,10 @@ -#ifndef CSM_TOOLS_STAGE_H -#define CSM_TOOLS_STAGE_H +#ifndef CSM_DOC_STAGE_H +#define CSM_DOC_STAGE_H #include #include -namespace CSMTools +namespace CSMDoc { class Stage { @@ -16,7 +16,7 @@ namespace CSMTools ///< \return number of steps virtual void perform (int stage, std::vector& messages) = 0; - ///< Messages resulting from this tage will be appended to \a messages. + ///< Messages resulting from this stage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/birthsigncheck.hpp b/apps/opencs/model/tools/birthsigncheck.hpp index 42b5a6b24..bdd65b44a 100644 --- a/apps/opencs/model/tools/birthsigncheck.hpp +++ b/apps/opencs/model/tools/birthsigncheck.hpp @@ -5,12 +5,12 @@ #include "../world/idcollection.hpp" -#include "stage.hpp" +#include "../doc/stage.hpp" namespace CSMTools { /// \brief VerifyStage: make sure that birthsign records are internally consistent - class BirthsignCheckStage : public Stage + class BirthsignCheckStage : public CSMDoc::Stage { const CSMWorld::IdCollection& mBirthsigns; diff --git a/apps/opencs/model/tools/classcheck.hpp b/apps/opencs/model/tools/classcheck.hpp index a29d7c8b7..3604b451c 100644 --- a/apps/opencs/model/tools/classcheck.hpp +++ b/apps/opencs/model/tools/classcheck.hpp @@ -5,12 +5,12 @@ #include "../world/idcollection.hpp" -#include "stage.hpp" +#include "../doc/stage.hpp" namespace CSMTools { /// \brief VerifyStage: make sure that class records are internally consistent - class ClassCheckStage : public Stage + class ClassCheckStage : public CSMDoc::Stage { const CSMWorld::IdCollection& mClasses; diff --git a/apps/opencs/model/tools/factioncheck.hpp b/apps/opencs/model/tools/factioncheck.hpp index 868650572..7cd80347d 100644 --- a/apps/opencs/model/tools/factioncheck.hpp +++ b/apps/opencs/model/tools/factioncheck.hpp @@ -5,12 +5,12 @@ #include "../world/idcollection.hpp" -#include "stage.hpp" +#include "../doc/stage.hpp" namespace CSMTools { /// \brief VerifyStage: make sure that faction records are internally consistent - class FactionCheckStage : public Stage + class FactionCheckStage : public CSMDoc::Stage { const CSMWorld::IdCollection& mFactions; diff --git a/apps/opencs/model/tools/mandatoryid.hpp b/apps/opencs/model/tools/mandatoryid.hpp index 342e2d754..5fddf08d3 100644 --- a/apps/opencs/model/tools/mandatoryid.hpp +++ b/apps/opencs/model/tools/mandatoryid.hpp @@ -6,7 +6,7 @@ #include "../world/universalid.hpp" -#include "stage.hpp" +#include "../doc/stage.hpp" namespace CSMWorld { @@ -16,7 +16,7 @@ namespace CSMWorld namespace CSMTools { /// \brief Verify stage: make sure that records with specific IDs exist. - class MandatoryIdStage : public Stage + class MandatoryIdStage : public CSMDoc::Stage { const CSMWorld::CollectionBase& mIdCollection; CSMWorld::UniversalId mCollectionId; diff --git a/apps/opencs/model/tools/racecheck.hpp b/apps/opencs/model/tools/racecheck.hpp index 155f79902..ff9948bf6 100644 --- a/apps/opencs/model/tools/racecheck.hpp +++ b/apps/opencs/model/tools/racecheck.hpp @@ -5,12 +5,12 @@ #include "../world/idcollection.hpp" -#include "stage.hpp" +#include "../doc/stage.hpp" namespace CSMTools { /// \brief VerifyStage: make sure that race records are internally consistent - class RaceCheckStage : public Stage + class RaceCheckStage : public CSMDoc::Stage { const CSMWorld::IdCollection& mRaces; bool mPlayable; diff --git a/apps/opencs/model/tools/regioncheck.hpp b/apps/opencs/model/tools/regioncheck.hpp index b42135651..c8c437cbd 100644 --- a/apps/opencs/model/tools/regioncheck.hpp +++ b/apps/opencs/model/tools/regioncheck.hpp @@ -5,12 +5,12 @@ #include "../world/idcollection.hpp" -#include "stage.hpp" +#include "../doc/stage.hpp" namespace CSMTools { /// \brief VerifyStage: make sure that region records are internally consistent - class RegionCheckStage : public Stage + class RegionCheckStage : public CSMDoc::Stage { const CSMWorld::IdCollection& mRegions; diff --git a/apps/opencs/model/tools/skillcheck.hpp b/apps/opencs/model/tools/skillcheck.hpp index 30a3f01ca..662bdadee 100644 --- a/apps/opencs/model/tools/skillcheck.hpp +++ b/apps/opencs/model/tools/skillcheck.hpp @@ -5,12 +5,12 @@ #include "../world/idcollection.hpp" -#include "stage.hpp" +#include "../doc/stage.hpp" namespace CSMTools { /// \brief VerifyStage: make sure that skill records are internally consistent - class SkillCheckStage : public Stage + class SkillCheckStage : public CSMDoc::Stage { const CSMWorld::IdCollection& mSkills; diff --git a/apps/opencs/model/tools/soundcheck.hpp b/apps/opencs/model/tools/soundcheck.hpp index a309763a1..00b45cd93 100644 --- a/apps/opencs/model/tools/soundcheck.hpp +++ b/apps/opencs/model/tools/soundcheck.hpp @@ -5,12 +5,12 @@ #include "../world/idcollection.hpp" -#include "stage.hpp" +#include "../doc/stage.hpp" namespace CSMTools { /// \brief VerifyStage: make sure that sound records are internally consistent - class SoundCheckStage : public Stage + class SoundCheckStage : public CSMDoc::Stage { const CSMWorld::IdCollection& mSounds; diff --git a/apps/opencs/model/tools/spellcheck.hpp b/apps/opencs/model/tools/spellcheck.hpp index 056639219..880ddafcd 100644 --- a/apps/opencs/model/tools/spellcheck.hpp +++ b/apps/opencs/model/tools/spellcheck.hpp @@ -5,12 +5,12 @@ #include "../world/idcollection.hpp" -#include "stage.hpp" +#include "../doc/stage.hpp" namespace CSMTools { /// \brief VerifyStage: make sure that spell records are internally consistent - class SpellCheckStage : public Stage + class SpellCheckStage : public CSMDoc::Stage { const CSMWorld::IdCollection& mSpells; diff --git a/apps/opencs/model/tools/stage.cpp b/apps/opencs/model/tools/stage.cpp deleted file mode 100644 index 6f4567e57..000000000 --- a/apps/opencs/model/tools/stage.cpp +++ /dev/null @@ -1,4 +0,0 @@ - -#include "stage.hpp" - -CSMTools::Stage::~Stage() {} \ No newline at end of file diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 803861203..1d49028ed 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -21,7 +21,7 @@ #include "birthsigncheck.hpp" #include "spellcheck.hpp" -CSMTools::Operation *CSMTools::Tools::get (int type) +CSMDoc::Operation *CSMTools::Tools::get (int type) { switch (type) { @@ -31,7 +31,7 @@ CSMTools::Operation *CSMTools::Tools::get (int type) return 0; } -const CSMTools::Operation *CSMTools::Tools::get (int type) const +const CSMDoc::Operation *CSMTools::Tools::get (int type) const { return const_cast (this)->get (type); } @@ -103,7 +103,7 @@ CSMWorld::UniversalId CSMTools::Tools::runVerifier() void CSMTools::Tools::abortOperation (int type) { - if (Operation *operation = get (type)) + if (CSMDoc::Operation *operation = get (type)) operation->abort(); } @@ -118,7 +118,7 @@ int CSMTools::Tools::getRunningOperations() const int result = 0; for (int i=0; sOperations[i]!=-1; ++i) - if (const Operation *operation = get (sOperations[i])) + if (const CSMDoc::Operation *operation = get (sOperations[i])) if (operation->isRunning()) result |= sOperations[i]; diff --git a/apps/opencs/model/tools/tools.hpp b/apps/opencs/model/tools/tools.hpp index 652345c6d..693bdaa59 100644 --- a/apps/opencs/model/tools/tools.hpp +++ b/apps/opencs/model/tools/tools.hpp @@ -11,10 +11,14 @@ namespace CSMWorld class UniversalId; } +namespace CSMDoc +{ + class Operation; +} + namespace CSMTools { class Verifier; - class Operation; class ReportModel; class Tools : public QObject @@ -33,10 +37,10 @@ namespace CSMTools Verifier *getVerifier(); - Operation *get (int type); + CSMDoc::Operation *get (int type); ///< Returns a 0-pointer, if operation hasn't been used yet. - const Operation *get (int type) const; + const CSMDoc::Operation *get (int type) const; ///< Returns a 0-pointer, if operation hasn't been used yet. public: diff --git a/apps/opencs/model/tools/verifier.hpp b/apps/opencs/model/tools/verifier.hpp index 054f87169..59edbc41b 100644 --- a/apps/opencs/model/tools/verifier.hpp +++ b/apps/opencs/model/tools/verifier.hpp @@ -1,11 +1,11 @@ #ifndef CSM_TOOLS_VERIFIER_H #define CSM_TOOLS_VERIFIER_H -#include "operation.hpp" +#include "../doc/operation.hpp" namespace CSMTools { - class Verifier : public Operation + class Verifier : public CSMDoc::Operation { public: From f4c03c6a299cc5938aaa4c85e074aacb7c261c2b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 14 Sep 2013 15:12:24 +0200 Subject: [PATCH 026/118] added ordered-flag to Operation (currently ignored) --- apps/opencs/model/doc/operation.cpp | 2 +- apps/opencs/model/doc/operation.hpp | 4 +++- apps/opencs/model/tools/verifier.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/doc/operation.cpp b/apps/opencs/model/doc/operation.cpp index 8f7472c5f..83a374eb2 100644 --- a/apps/opencs/model/doc/operation.cpp +++ b/apps/opencs/model/doc/operation.cpp @@ -23,7 +23,7 @@ void CSMDoc::Operation::prepareStages() } } -CSMDoc::Operation::Operation (int type) : mType (type) {} +CSMDoc::Operation::Operation (int type, bool ordered) : mType (type), mOrdered (ordered) {} CSMDoc::Operation::~Operation() { diff --git a/apps/opencs/model/doc/operation.hpp b/apps/opencs/model/doc/operation.hpp index 703098852..c7d9a038e 100644 --- a/apps/opencs/model/doc/operation.hpp +++ b/apps/opencs/model/doc/operation.hpp @@ -19,12 +19,14 @@ namespace CSMDoc int mCurrentStep; int mCurrentStepTotal; int mTotalSteps; + int mOrdered; void prepareStages(); public: - Operation (int type); + Operation (int type, bool ordered); + ///< \param parallel Stages must be executed in the given order. virtual ~Operation(); diff --git a/apps/opencs/model/tools/verifier.cpp b/apps/opencs/model/tools/verifier.cpp index 9c00d4ea7..d5f2071c4 100644 --- a/apps/opencs/model/tools/verifier.cpp +++ b/apps/opencs/model/tools/verifier.cpp @@ -3,5 +3,5 @@ #include "../doc/state.hpp" -CSMTools::Verifier::Verifier() : Operation (CSMDoc::State_Verifying) +CSMTools::Verifier::Verifier() : Operation (CSMDoc::State_Verifying, false) {} From b7bffc8a7917d1b8fe1cf6009b4b6fc8726a8c6c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 14 Sep 2013 15:16:31 +0200 Subject: [PATCH 027/118] removed Verifier class (using Operation class without subclassing now) --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/tools/tools.cpp | 7 +++---- apps/opencs/model/tools/tools.hpp | 5 ++--- apps/opencs/model/tools/verifier.cpp | 7 ------- apps/opencs/model/tools/verifier.hpp | 17 ----------------- 5 files changed, 6 insertions(+), 32 deletions(-) delete mode 100644 apps/opencs/model/tools/verifier.cpp delete mode 100644 apps/opencs/model/tools/verifier.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 367c43eb7..8d09eb645 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -37,7 +37,7 @@ opencs_units (model/tools ) opencs_units_noqt (model/tools - verifier mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck + mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck birthsigncheck spellcheck ) diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 1d49028ed..1e8f4def5 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -3,9 +3,8 @@ #include -#include "verifier.hpp" - #include "../doc/state.hpp" +#include "../doc/operation.hpp" #include "../world/data.hpp" #include "../world/universalid.hpp" @@ -36,11 +35,11 @@ const CSMDoc::Operation *CSMTools::Tools::get (int type) const return const_cast (this)->get (type); } -CSMTools::Verifier *CSMTools::Tools::getVerifier() +CSMDoc::Operation *CSMTools::Tools::getVerifier() { if (!mVerifier) { - mVerifier = new Verifier; + mVerifier = new CSMDoc::Operation (CSMDoc::State_Verifying, false); connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); connect (mVerifier, SIGNAL (finished()), this, SLOT (verifierDone())); diff --git a/apps/opencs/model/tools/tools.hpp b/apps/opencs/model/tools/tools.hpp index 693bdaa59..79c909724 100644 --- a/apps/opencs/model/tools/tools.hpp +++ b/apps/opencs/model/tools/tools.hpp @@ -18,7 +18,6 @@ namespace CSMDoc namespace CSMTools { - class Verifier; class ReportModel; class Tools : public QObject @@ -26,7 +25,7 @@ namespace CSMTools Q_OBJECT CSMWorld::Data& mData; - Verifier *mVerifier; + CSMDoc::Operation *mVerifier; std::map mReports; int mNextReportNumber; std::map mActiveReports; // type, report number @@ -35,7 +34,7 @@ namespace CSMTools Tools (const Tools&); Tools& operator= (const Tools&); - Verifier *getVerifier(); + CSMDoc::Operation *getVerifier(); CSMDoc::Operation *get (int type); ///< Returns a 0-pointer, if operation hasn't been used yet. diff --git a/apps/opencs/model/tools/verifier.cpp b/apps/opencs/model/tools/verifier.cpp deleted file mode 100644 index d5f2071c4..000000000 --- a/apps/opencs/model/tools/verifier.cpp +++ /dev/null @@ -1,7 +0,0 @@ - -#include "verifier.hpp" - -#include "../doc/state.hpp" - -CSMTools::Verifier::Verifier() : Operation (CSMDoc::State_Verifying, false) -{} diff --git a/apps/opencs/model/tools/verifier.hpp b/apps/opencs/model/tools/verifier.hpp deleted file mode 100644 index 59edbc41b..000000000 --- a/apps/opencs/model/tools/verifier.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CSM_TOOLS_VERIFIER_H -#define CSM_TOOLS_VERIFIER_H - -#include "../doc/operation.hpp" - -namespace CSMTools -{ - class Verifier : public CSMDoc::Operation - { - public: - - Verifier(); - - }; -} - -#endif From a5aebfb76026d6e139e0ec636430031679481ea1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 15 Sep 2013 09:32:20 +0200 Subject: [PATCH 028/118] minor cleanup --- apps/opencs/model/doc/operation.cpp | 4 ++-- apps/opencs/model/doc/operation.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/doc/operation.cpp b/apps/opencs/model/doc/operation.cpp index 83a374eb2..d5c310b8d 100644 --- a/apps/opencs/model/doc/operation.cpp +++ b/apps/opencs/model/doc/operation.cpp @@ -37,7 +37,7 @@ void CSMDoc::Operation::run() QTimer timer; - timer.connect (&timer, SIGNAL (timeout()), this, SLOT (verify())); + timer.connect (&timer, SIGNAL (timeout()), this, SLOT (executeStage())); timer.start (0); @@ -54,7 +54,7 @@ void CSMDoc::Operation::abort() exit(); } -void CSMDoc::Operation::verify() +void CSMDoc::Operation::executeStage() { std::vector messages; diff --git a/apps/opencs/model/doc/operation.hpp b/apps/opencs/model/doc/operation.hpp index c7d9a038e..7b8114ecc 100644 --- a/apps/opencs/model/doc/operation.hpp +++ b/apps/opencs/model/doc/operation.hpp @@ -49,7 +49,7 @@ namespace CSMDoc private slots: - void verify(); + void executeStage(); }; } From 414e6abb9575258dc0654082aee694cff8e86f3a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 15 Sep 2013 11:35:12 +0200 Subject: [PATCH 029/118] more signal cleanup --- apps/opencs/model/doc/operation.cpp | 10 +++++++++- apps/opencs/model/doc/operation.hpp | 4 ++++ apps/opencs/model/tools/tools.cpp | 7 +------ apps/opencs/model/tools/tools.hpp | 2 -- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/apps/opencs/model/doc/operation.cpp b/apps/opencs/model/doc/operation.cpp index d5c310b8d..7f47e8c70 100644 --- a/apps/opencs/model/doc/operation.cpp +++ b/apps/opencs/model/doc/operation.cpp @@ -23,7 +23,10 @@ void CSMDoc::Operation::prepareStages() } } -CSMDoc::Operation::Operation (int type, bool ordered) : mType (type), mOrdered (ordered) {} +CSMDoc::Operation::Operation (int type, bool ordered) : mType (type), mOrdered (ordered) +{ + connect (this, SIGNAL (finished()), this, SLOT (operationDone())); +} CSMDoc::Operation::~Operation() { @@ -80,4 +83,9 @@ void CSMDoc::Operation::executeStage() if (mCurrentStage==mStages.end()) exit(); +} + +void CSMDoc::Operation::operationDone() +{ + emit done (mType); } \ No newline at end of file diff --git a/apps/opencs/model/doc/operation.hpp b/apps/opencs/model/doc/operation.hpp index 7b8114ecc..2fadbda55 100644 --- a/apps/opencs/model/doc/operation.hpp +++ b/apps/opencs/model/doc/operation.hpp @@ -43,6 +43,8 @@ namespace CSMDoc void reportMessage (const QString& message, int type); + void done (int type); + public slots: void abort(); @@ -50,6 +52,8 @@ namespace CSMDoc private slots: void executeStage(); + + void operationDone(); }; } diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 1e8f4def5..cd4653280 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -42,7 +42,7 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier() mVerifier = new CSMDoc::Operation (CSMDoc::State_Verifying, false); connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); - connect (mVerifier, SIGNAL (finished()), this, SLOT (verifierDone())); + connect (mVerifier, SIGNAL (done (int)), this, SIGNAL (done (int))); connect (mVerifier, SIGNAL (reportMessage (const QString&, int)), this, SLOT (verifierMessage (const QString&, int))); @@ -132,11 +132,6 @@ CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& return mReports.at (id.getIndex()); } -void CSMTools::Tools::verifierDone() -{ - emit done (CSMDoc::State_Verifying); -} - void CSMTools::Tools::verifierMessage (const QString& message, int type) { std::map::iterator iter = mActiveReports.find (type); diff --git a/apps/opencs/model/tools/tools.hpp b/apps/opencs/model/tools/tools.hpp index 79c909724..0079fab34 100644 --- a/apps/opencs/model/tools/tools.hpp +++ b/apps/opencs/model/tools/tools.hpp @@ -61,8 +61,6 @@ namespace CSMTools private slots: - void verifierDone(); - void verifierMessage (const QString& message, int type); signals: From d71d2829527dc61ba19084b0e3c891c69ec81e86 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 15 Sep 2013 12:03:36 +0200 Subject: [PATCH 030/118] more Operation enhancements in preparation for save operation --- apps/opencs/model/doc/operation.cpp | 35 ++++++++++++++++++++++++++--- apps/opencs/model/doc/operation.hpp | 9 ++++++-- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/doc/operation.cpp b/apps/opencs/model/doc/operation.cpp index 7f47e8c70..8af5a2c0d 100644 --- a/apps/opencs/model/doc/operation.cpp +++ b/apps/opencs/model/doc/operation.cpp @@ -15,6 +15,7 @@ void CSMDoc::Operation::prepareStages() mCurrentStep = 0; mCurrentStepTotal = 0; mTotalSteps = 0; + mError = false; for (std::vector >::iterator iter (mStages.begin()); iter!=mStages.end(); ++iter) { @@ -23,7 +24,8 @@ void CSMDoc::Operation::prepareStages() } } -CSMDoc::Operation::Operation (int type, bool ordered) : mType (type), mOrdered (ordered) +CSMDoc::Operation::Operation (int type, bool ordered, bool finalAlways) +: mType (type), mOrdered (ordered), mFinalAlways (finalAlways) { connect (this, SIGNAL (finished()), this, SLOT (operationDone())); } @@ -52,9 +54,28 @@ void CSMDoc::Operation::appendStage (Stage *stage) mStages.push_back (std::make_pair (stage, 0)); } +bool CSMDoc::Operation::hasError() const +{ + return mError; +} + void CSMDoc::Operation::abort() { - exit(); + if (!isRunning()) + return; + + mError = true; + + if (mFinalAlways) + { + if (mStages.begin()!=mStages.end() && mCurrentStage!=--mStages.end()) + { + mCurrentStep = 0; + mCurrentStage = --mStages.end(); + } + } + else + mCurrentStage = mStages.end(); } void CSMDoc::Operation::executeStage() @@ -70,7 +91,15 @@ void CSMDoc::Operation::executeStage() } else { - mCurrentStage->first->perform (mCurrentStep++, messages); + try + { + mCurrentStage->first->perform (mCurrentStep++, messages); + } + catch (const std::exception&) + { + abort(); + } + ++mCurrentStepTotal; break; } diff --git a/apps/opencs/model/doc/operation.hpp b/apps/opencs/model/doc/operation.hpp index 2fadbda55..316eda78f 100644 --- a/apps/opencs/model/doc/operation.hpp +++ b/apps/opencs/model/doc/operation.hpp @@ -20,13 +20,16 @@ namespace CSMDoc int mCurrentStepTotal; int mTotalSteps; int mOrdered; + bool mFinalAlways; + bool mError; void prepareStages(); public: - Operation (int type, bool ordered); - ///< \param parallel Stages must be executed in the given order. + Operation (int type, bool ordered, bool finalAlways = false); + ///< \param ordered Stages must be executed in the given order. + /// \param finalAlways Execute last stage even if an error occurred during earlier stages. virtual ~Operation(); @@ -37,6 +40,8 @@ namespace CSMDoc /// /// \attention Do no call this function while this Operation is running. + bool hasError() const; + signals: void progress (int current, int max, int type); From 8326ac9b6f271d18d7f5ff0af0b49435e2bba5f4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 15 Sep 2013 12:48:57 +0200 Subject: [PATCH 031/118] replaced dummy save implementation with a threaded dummy save implementation --- apps/opencs/CMakeLists.txt | 4 +-- apps/opencs/model/doc/document.cpp | 47 +++++++------------------- apps/opencs/model/doc/document.hpp | 8 ++--- apps/opencs/model/doc/saving.cpp | 14 ++++++++ apps/opencs/model/doc/saving.hpp | 25 ++++++++++++++ apps/opencs/model/doc/savingstages.cpp | 30 ++++++++++++++++ apps/opencs/model/doc/savingstages.hpp | 28 +++++++++++++++ apps/opencs/model/doc/savingstate.cpp | 13 +++++++ apps/opencs/model/doc/savingstate.hpp | 22 ++++++++++++ 9 files changed, 149 insertions(+), 42 deletions(-) create mode 100644 apps/opencs/model/doc/saving.cpp create mode 100644 apps/opencs/model/doc/saving.hpp create mode 100644 apps/opencs/model/doc/savingstages.cpp create mode 100644 apps/opencs/model/doc/savingstages.hpp create mode 100644 apps/opencs/model/doc/savingstate.cpp create mode 100644 apps/opencs/model/doc/savingstate.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 8d09eb645..b6de9295d 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -5,11 +5,11 @@ opencs_units (. editor) set (CMAKE_BUILD_TYPE DEBUG) opencs_units (model/doc - document operation + document operation saving ) opencs_units_noqt (model/doc - documentmanager stage + documentmanager stage savingstate savingstages ) opencs_hdrs_noqt (model/doc diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index d7138f671..9b2217559 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2141,7 +2141,7 @@ void CSMDoc::Document::createBase() CSMDoc::Document::Document (const std::vector& files, const boost::filesystem::path& savePath, bool new_) -: mSavePath (savePath), mTools (mData) +: mSavePath (savePath), mTools (mData), mSaving (*this) { if (files.empty()) throw std::runtime_error ("Empty content file sequence"); @@ -2166,9 +2166,8 @@ CSMDoc::Document::Document (const std::vector& files, connect (&mTools, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); connect (&mTools, SIGNAL (done (int)), this, SLOT (operationDone (int))); - // dummy implementation -> remove when proper save is implemented. - mSaveCount = 0; - connect (&mSaveTimer, SIGNAL(timeout()), this, SLOT (saving())); + connect (&mSaving, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); + connect (&mSaving, SIGNAL (done (int)), this, SLOT (operationDone (int))); } CSMDoc::Document::~Document() @@ -2187,7 +2186,7 @@ int CSMDoc::Document::getState() const if (!mUndoStack.isClean()) state |= State_Modified; - if (mSaveCount) + if (mSaving.isRunning()) state |= State_Locked | State_Saving | State_Operation; if (int operations = mTools.getRunningOperations()) @@ -2203,10 +2202,13 @@ const boost::filesystem::path& CSMDoc::Document::getSavePath() const void CSMDoc::Document::save() { - mSaveCount = 1; - mSaveTimer.start (500); + if (mSaving.isRunning()) + throw std::logic_error ( + "Failed to initiate save, because a save operation is already running."); + + mSaving.start(); + emit stateChanged (getState(), this); - emit progress (1, 16, State_Saving, 1, this); } CSMWorld::UniversalId CSMDoc::Document::verify() @@ -2218,17 +2220,12 @@ CSMWorld::UniversalId CSMDoc::Document::verify() void CSMDoc::Document::abortOperation (int type) { - mTools.abortOperation (type); - if (type==State_Saving) - { - mSaveCount=0; - mSaveTimer.stop(); - emit stateChanged (getState(), this); - } + mSaving.abort(); + else + mTools.abortOperation (type); } - void CSMDoc::Document::modificationStateChanged (bool clean) { emit stateChanged (getState(), this); @@ -2240,24 +2237,6 @@ void CSMDoc::Document::operationDone (int type) emit stateChanged (getState(), this); } -void CSMDoc::Document::saving() -{ - ++mSaveCount; - - emit progress (mSaveCount, 16, State_Saving, 1, this); - - if (mSaveCount>15) - { - //clear the stack before resetting the save state - //to avoid emitting incorrect states - mUndoStack.setClean(); - - mSaveCount = 0; - mSaveTimer.stop(); - emit stateChanged (getState(), this); - } -} - const CSMWorld::Data& CSMDoc::Document::getData() const { return mData; diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 3532721ea..5a0395510 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -14,6 +14,7 @@ #include "../tools/tools.hpp" #include "state.hpp" +#include "saving.hpp" class QAbstractItemModel; @@ -34,14 +35,12 @@ namespace CSMDoc boost::filesystem::path mSavePath; CSMWorld::Data mData; CSMTools::Tools mTools; + Saving mSaving; // It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is // using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late. QUndoStack mUndoStack; - int mSaveCount; ///< dummy implementation -> remove when proper save is implemented. - QTimer mSaveTimer; ///< dummy implementation -> remove when proper save is implemented. - // not implemented Document (const Document&); Document& operator= (const Document&); @@ -100,9 +99,6 @@ namespace CSMDoc void operationDone (int type); - void saving(); - ///< dummy implementation -> remove when proper save is implemented. - public slots: void progress (int current, int max, int type); diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp new file mode 100644 index 000000000..dda4ad12a --- /dev/null +++ b/apps/opencs/model/doc/saving.cpp @@ -0,0 +1,14 @@ + +#include "saving.hpp" + +#include "state.hpp" + +#include "savingstages.hpp" + +CSMDoc::Saving::Saving (Document& document) +: Operation (State_Saving, true, true), mDocument (document), mState (*this) +{ + + + appendStage (new FinalSavingStage (mDocument, mState)); +} \ No newline at end of file diff --git a/apps/opencs/model/doc/saving.hpp b/apps/opencs/model/doc/saving.hpp new file mode 100644 index 000000000..b89ba5f6d --- /dev/null +++ b/apps/opencs/model/doc/saving.hpp @@ -0,0 +1,25 @@ +#ifndef CSM_DOC_SAVING_H +#define CSM_DOC_SAVING_H + +#include "operation.hpp" +#include "savingstate.hpp" + +namespace CSMDoc +{ + class Document; + + class Saving : public Operation + { + Q_OBJECT + + Document& mDocument; + SavingState mState; + + public: + + Saving (Document& document); + + }; +} + +#endif diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp new file mode 100644 index 000000000..97facf612 --- /dev/null +++ b/apps/opencs/model/doc/savingstages.cpp @@ -0,0 +1,30 @@ + +#include "savingstages.hpp" + +#include + +#include "document.hpp" +#include "savingstate.hpp" + +CSMDoc::FinalSavingStage::FinalSavingStage (Document& document, SavingState& state) +: mDocument (document), mState (state) +{} + +int CSMDoc::FinalSavingStage::setup() +{ + return 1; +} + +void CSMDoc::FinalSavingStage::perform (int stage, std::vector& messages) +{ + if (mState.hasError()) + { + /// \todo close stream + /// \todo delete tmp file + } + else + { + /// \todo delete file, rename tmp file + mDocument.getUndoStack().setClean(); + } +} \ No newline at end of file diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp new file mode 100644 index 000000000..1549c9640 --- /dev/null +++ b/apps/opencs/model/doc/savingstages.hpp @@ -0,0 +1,28 @@ +#ifndef CSM_DOC_SAVINGSTAGES_H +#define CSM_DOC_SAVINGSTAGES_H + +#include "stage.hpp" + +namespace CSMDoc +{ + class Document; + class SavingState; + + class FinalSavingStage : public Stage + { + Document& mDocument; + SavingState& mState; + + public: + + FinalSavingStage (Document& document, SavingState& state); + + virtual int setup(); + ///< \return number of steps + + virtual void perform (int stage, std::vector& messages); + ///< Messages resulting from this stage will be appended to \a messages. + }; +} + +#endif diff --git a/apps/opencs/model/doc/savingstate.cpp b/apps/opencs/model/doc/savingstate.cpp new file mode 100644 index 000000000..379870859 --- /dev/null +++ b/apps/opencs/model/doc/savingstate.cpp @@ -0,0 +1,13 @@ + +#include "savingstate.hpp" + +#include "operation.hpp" + +CSMDoc::SavingState::SavingState (Operation& operation) +: mOperation (operation) +{} + +bool CSMDoc::SavingState::hasError() const +{ + return mOperation.hasError(); +} \ No newline at end of file diff --git a/apps/opencs/model/doc/savingstate.hpp b/apps/opencs/model/doc/savingstate.hpp new file mode 100644 index 000000000..b8b6f3878 --- /dev/null +++ b/apps/opencs/model/doc/savingstate.hpp @@ -0,0 +1,22 @@ +#ifndef CSM_DOC_SAVINGSTATE_H +#define CSM_DOC_SAVINGSTATE_H + +namespace CSMDoc +{ + class Operation; + + class SavingState + { + Operation& mOperation; + + public: + + SavingState (Operation& operation); + + bool hasError() const; + }; + + +} + +#endif \ No newline at end of file From bcd36bd37843404257f1cdf65c66efbb248ef309 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 15 Sep 2013 14:55:40 +0200 Subject: [PATCH 032/118] various ESMWriter fixes --- components/esm/esmwriter.cpp | 283 +++++++++++++++++------------------ components/esm/esmwriter.hpp | 181 +++++++++++----------- components/esm/loadtes3.hpp | 2 +- 3 files changed, 236 insertions(+), 230 deletions(-) diff --git a/components/esm/esmwriter.cpp b/components/esm/esmwriter.cpp index 3ea6bd350..a6aa82665 100644 --- a/components/esm/esmwriter.cpp +++ b/components/esm/esmwriter.cpp @@ -2,185 +2,182 @@ #include #include -#include - -bool count = true; +#include namespace ESM { + ESMWriter::ESMWriter() : mRecordCount (0), mCounting (false) {} -int ESMWriter::getVersion() -{ - return mHeader.mData.version; -} - -void ESMWriter::setVersion(int ver) -{ - mHeader.mData.version = ver; -} - -void ESMWriter::setAuthor(const std::string& auth) -{ - mHeader.mData.author.assign (auth); -} - -void ESMWriter::setDescription(const std::string& desc) -{ - mHeader.mData.desc.assign (desc); -} + unsigned int ESMWriter::getVersion() const + { + return mHeader.mData.version; + } -void ESMWriter::setRecordCount (int count) -{ - mHeader.mData.records = count; -} + void ESMWriter::setVersion(unsigned int ver) + { + mHeader.mData.version = ver; + } -void ESMWriter::setFormat (int format) -{ - mHeader.mFormat = format; -} + void ESMWriter::setAuthor(const std::string& auth) + { + mHeader.mData.author.assign (auth); + } -void ESMWriter::addMaster(const std::string& name, uint64_t size) -{ - Header::MasterData d; - d.name = name; - d.size = size; - mHeader.mMaster.push_back(d); -} + void ESMWriter::setDescription(const std::string& desc) + { + mHeader.mData.desc.assign (desc); + } -void ESMWriter::save(const std::string& file) -{ - std::ofstream fs(file.c_str(), std::ios_base::out | std::ios_base::trunc); - save(fs); -} + void ESMWriter::setRecordCount (int count) + { + mHeader.mData.records = count; + } -void ESMWriter::save(std::ostream& file) -{ - m_recordCount = 0; - m_stream = &file; + void ESMWriter::setFormat (int format) + { + mHeader.mFormat = format; + } - startRecord("TES3", 0); + void ESMWriter::addMaster(const std::string& name, uint64_t size) + { + Header::MasterData d; + d.name = name; + d.size = size; + mHeader.mMaster.push_back(d); + } - mHeader.save (*this); + void ESMWriter::save(const std::string& file) + { + std::ofstream fs(file.c_str(), std::ios_base::out | std::ios_base::trunc); + save(fs); + } - endRecord("TES3"); -} + void ESMWriter::save(std::ostream& file) + { + mRecordCount = 0; + mRecords.clear(); + mStream = &file; -void ESMWriter::close() -{ - m_stream->flush(); + startRecord("TES3", 0); - if (!m_records.empty()) - throw "Unclosed record remaining"; -} + mHeader.save (*this); -void ESMWriter::startRecord(const std::string& name, uint32_t flags) -{ - m_recordCount++; - - writeName(name); - RecordData rec; - rec.name = name; - rec.position = m_stream->tellp(); - rec.size = 0; - writeT(0); // Size goes here - writeT(0); // Unused header? - writeT(flags); - m_records.push_back(rec); - - assert(m_records.back().size == 0); -} + endRecord("TES3"); + } -void ESMWriter::startSubRecord(const std::string& name) -{ - writeName(name); - RecordData rec; - rec.name = name; - rec.position = m_stream->tellp(); - rec.size = 0; - writeT(0); // Size goes here - m_records.push_back(rec); - - assert(m_records.back().size == 0); -} + void ESMWriter::close() + { + if (!mRecords.empty()) + throw std::runtime_error ("Unclosed record remaining"); + } -void ESMWriter::endRecord(const std::string& name) -{ - RecordData rec = m_records.back(); - assert(rec.name == name); - m_records.pop_back(); + void ESMWriter::startRecord(const std::string& name, uint32_t flags) + { + mRecordCount++; + + writeName(name); + RecordData rec; + rec.name = name; + rec.position = mStream->tellp(); + rec.size = 0; + writeT(0); // Size goes here + writeT(0); // Unused header? + writeT(flags); + mRecords.push_back(rec); + + assert(mRecords.back().size == 0); + } - m_stream->seekp(rec.position); + void ESMWriter::startSubRecord(const std::string& name) + { + writeName(name); + RecordData rec; + rec.name = name; + rec.position = mStream->tellp(); + rec.size = 0; + writeT(0); // Size goes here + mRecords.push_back(rec); + + assert(mRecords.back().size == 0); + } - count = false; - write((char*)&rec.size, sizeof(int)); - count = true; + void ESMWriter::endRecord(const std::string& name) + { + RecordData rec = mRecords.back(); + assert(rec.name == name); + mRecords.pop_back(); - m_stream->seekp(0, std::ios::end); + mStream->seekp(rec.position); -} + mCounting = false; + write (reinterpret_cast (&rec.size), sizeof(int)); + mCounting = true; -void ESMWriter::writeHNString(const std::string& name, const std::string& data) -{ - startSubRecord(name); - writeHString(data); - endRecord(name); -} + mStream->seekp(0, std::ios::end); -void ESMWriter::writeHNString(const std::string& name, const std::string& data, size_t size) -{ - assert(data.size() <= size); - startSubRecord(name); - writeHString(data); + } - if (data.size() < size) + void ESMWriter::writeHNString(const std::string& name, const std::string& data) { - for (size_t i = data.size(); i < size; ++i) - write("\0",1); + startSubRecord(name); + writeHString(data); + endRecord(name); } - endRecord(name); -} - -void ESMWriter::writeHString(const std::string& data) -{ - if (data.size() == 0) - write("\0", 1); - else + void ESMWriter::writeHNString(const std::string& name, const std::string& data, size_t size) { - // Convert to UTF8 and return - std::string ascii = m_encoder->getLegacyEnc(data); + assert(data.size() <= size); + startSubRecord(name); + writeHString(data); + + if (data.size() < size) + { + for (size_t i = data.size(); i < size; ++i) + write("\0",1); + } - write(ascii.c_str(), ascii.size()); + endRecord(name); } -} -void ESMWriter::writeHCString(const std::string& data) -{ - writeHString(data); - if (data.size() > 0 && data[data.size()-1] != '\0') - write("\0", 1); -} + void ESMWriter::writeHString(const std::string& data) + { + if (data.size() == 0) + write("\0", 1); + else + { + // Convert to UTF8 and return + std::string ascii = mEncoder->getLegacyEnc(data); + + write(ascii.c_str(), ascii.size()); + } + } -void ESMWriter::writeName(const std::string& name) -{ - assert((name.size() == 4 && name[3] != '\0')); - write(name.c_str(), name.size()); -} + void ESMWriter::writeHCString(const std::string& data) + { + writeHString(data); + if (data.size() > 0 && data[data.size()-1] != '\0') + write("\0", 1); + } -void ESMWriter::write(const char* data, size_t size) -{ - if (count && !m_records.empty()) + void ESMWriter::writeName(const std::string& name) { - for (std::list::iterator it = m_records.begin(); it != m_records.end(); ++it) - it->size += size; + assert((name.size() == 4 && name[3] != '\0')); + write(name.c_str(), name.size()); } - m_stream->write(data, size); -} + void ESMWriter::write(const char* data, size_t size) + { + if (mCounting && !mRecords.empty()) + { + for (std::list::iterator it = mRecords.begin(); it != mRecords.end(); ++it) + it->size += size; + } -void ESMWriter::setEncoder(ToUTF8::Utf8Encoder* encoder) -{ - m_encoder = encoder; -} + mStream->write(data, size); + } + void ESMWriter::setEncoder(ToUTF8::Utf8Encoder* encoder) + { + mEncoder = encoder; + } } diff --git a/components/esm/esmwriter.hpp b/components/esm/esmwriter.hpp index be3ae33ab..b0925463a 100644 --- a/components/esm/esmwriter.hpp +++ b/components/esm/esmwriter.hpp @@ -13,92 +13,101 @@ namespace ESM { class ESMWriter { - struct RecordData - { - std::string name; - std::streampos position; - size_t size; + struct RecordData + { + std::string name; + std::streampos position; + size_t size; + }; + + public: + + ESMWriter(); + + unsigned int getVersion() const; + void setVersion(unsigned int ver = 0x3fa66666); + void setEncoder(ToUTF8::Utf8Encoder *encoding); + void setAuthor(const std::string& author); + void setDescription(const std::string& desc); + void setRecordCount (int count); + void setFormat (int format); + + void addMaster(const std::string& name, uint64_t size); + + void save(const std::string& file); + ///< Start saving a file by writing the TES3 header. + + void save(std::ostream& file); + ///< Start saving a file by writing the TES3 header. + + void close(); + ///< \note Does not close the stream. + + void writeHNString(const std::string& name, const std::string& data); + void writeHNString(const std::string& name, const std::string& data, size_t size); + void writeHNCString(const std::string& name, const std::string& data) + { + startSubRecord(name); + writeHCString(data); + endRecord(name); + } + void writeHNOString(const std::string& name, const std::string& data) + { + if (!data.empty()) + writeHNString(name, data); + } + void writeHNOCString(const std::string& name, const std::string& data) + { + if (!data.empty()) + writeHNCString(name, data); + } + + template + void writeHNT(const std::string& name, const T& data) + { + startSubRecord(name); + writeT(data); + endRecord(name); + } + + template + void writeHNT(const std::string& name, const T& data, int size) + { + startSubRecord(name); + writeT(data, size); + endRecord(name); + } + + template + void writeT(const T& data) + { + write((char*)&data, sizeof(T)); + } + + template + void writeT(const T& data, size_t size) + { + write((char*)&data, size); + } + + void startRecord(const std::string& name, uint32_t flags); + void startSubRecord(const std::string& name); + void endRecord(const std::string& name); + void writeHString(const std::string& data); + void writeHCString(const std::string& data); + void writeName(const std::string& data); + void write(const char* data, size_t size); + + private: + std::list mRecords; + std::ostream* mStream; + std::streampos mHeaderPos; + ToUTF8::Utf8Encoder* mEncoder; + int mRecordCount; + bool mCounting; + + Header mHeader; }; - -public: - int getVersion(); - void setVersion(int ver); - void setEncoder(ToUTF8::Utf8Encoder *encoding); // Write strings as UTF-8? - void setAuthor(const std::string& author); - void setDescription(const std::string& desc); - void setRecordCount (int count); - void setFormat (int format); - - void addMaster(const std::string& name, uint64_t size); - - void save(const std::string& file); - void save(std::ostream& file); - void close(); - - void writeHNString(const std::string& name, const std::string& data); - void writeHNString(const std::string& name, const std::string& data, size_t size); - void writeHNCString(const std::string& name, const std::string& data) - { - startSubRecord(name); - writeHCString(data); - endRecord(name); - } - void writeHNOString(const std::string& name, const std::string& data) - { - if (!data.empty()) - writeHNString(name, data); - } - void writeHNOCString(const std::string& name, const std::string& data) - { - if (!data.empty()) - writeHNCString(name, data); - } - - template - void writeHNT(const std::string& name, const T& data) - { - startSubRecord(name); - writeT(data); - endRecord(name); - } - - template - void writeHNT(const std::string& name, const T& data, int size) - { - startSubRecord(name); - writeT(data, size); - endRecord(name); - } - - template - void writeT(const T& data) - { - write((char*)&data, sizeof(T)); - } - - template - void writeT(const T& data, size_t size) - { - write((char*)&data, size); - } - - void startRecord(const std::string& name, uint32_t flags); - void startSubRecord(const std::string& name); - void endRecord(const std::string& name); - void writeHString(const std::string& data); - void writeHCString(const std::string& data); - void writeName(const std::string& data); - void write(const char* data, size_t size); - -private: - std::list m_records; - std::ostream* m_stream; - std::streampos m_headerPos; - ToUTF8::Utf8Encoder* m_encoder; - int m_recordCount; - - Header mHeader; -}; - } + #endif diff --git a/components/esm/loadtes3.hpp b/components/esm/loadtes3.hpp index b73a4c31e..5614d295f 100644 --- a/components/esm/loadtes3.hpp +++ b/components/esm/loadtes3.hpp @@ -24,7 +24,7 @@ namespace ESM versions are 1.2 and 1.3. These correspond to: 1.2 = 0x3f99999a and 1.3 = 0x3fa66666 */ - int version; + unsigned int version; int type; // 0=esp, 1=esm, 32=ess (unused) NAME32 author; // Author's name NAME256 desc; // File description From fa25a068a8681202a8327cde663273d9910fd838 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 15 Sep 2013 15:00:41 +0200 Subject: [PATCH 033/118] basic saving (no data is written to file yet) --- apps/opencs/model/doc/saving.cpp | 3 ++ apps/opencs/model/doc/savingstages.cpp | 53 ++++++++++++++++++++++++-- apps/opencs/model/doc/savingstages.hpp | 31 +++++++++++++++ apps/opencs/model/doc/savingstate.cpp | 45 +++++++++++++++++++++- apps/opencs/model/doc/savingstate.hpp | 22 +++++++++++ 5 files changed, 149 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index dda4ad12a..5607883ad 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -8,7 +8,10 @@ CSMDoc::Saving::Saving (Document& document) : Operation (State_Saving, true, true), mDocument (document), mState (*this) { + appendStage (new OpenSaveStage (mDocument, mState)); + appendStage (new CloseSaveStage (mState)); + appendStage (new FinalSavingStage (mDocument, mState)); } \ No newline at end of file diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 97facf612..078762992 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -1,11 +1,53 @@ #include "savingstages.hpp" +#include + +#include + #include #include "document.hpp" #include "savingstate.hpp" +CSMDoc::OpenSaveStage::OpenSaveStage (Document& document, SavingState& state) +: mDocument (document), mState (state) +{} + +int CSMDoc::OpenSaveStage::setup() +{ + return 1; +} + +void CSMDoc::OpenSaveStage::perform (int stage, std::vector& messages) +{ + mState.start (mDocument); + + mState.getStream().open (mState.getTmpPath().string().c_str()); + + if (!mState.getStream().is_open()) + throw std::runtime_error ("failed to open stream for saving"); +} + + +CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state) +: mState (state) +{} + +int CSMDoc::CloseSaveStage::setup() +{ + return 1; +} + +void CSMDoc::CloseSaveStage::perform (int stage, std::vector& messages) +{ + mState.getStream().close(); + + if (!mState.getStream()) + throw std::runtime_error ("saving failed"); +} + + CSMDoc::FinalSavingStage::FinalSavingStage (Document& document, SavingState& state) : mDocument (document), mState (state) {} @@ -19,12 +61,17 @@ void CSMDoc::FinalSavingStage::perform (int stage, std::vector& mes { if (mState.hasError()) { - /// \todo close stream - /// \todo delete tmp file + mState.getWriter().close(); + mState.getStream().close(); + + if (boost::filesystem::exists (mState.getTmpPath())) + boost::filesystem::remove (mState.getTmpPath()); } else { - /// \todo delete file, rename tmp file + boost::filesystem::remove (mState.getPath()); + boost::filesystem::rename (mState.getTmpPath(), mState.getPath()); + mDocument.getUndoStack().setClean(); } } \ No newline at end of file diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index 1549c9640..0b64896f7 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -8,6 +8,37 @@ namespace CSMDoc class Document; class SavingState; + class OpenSaveStage : public Stage + { + Document& mDocument; + SavingState& mState; + + public: + + OpenSaveStage (Document& document, SavingState& state); + + virtual int setup(); + ///< \return number of steps + + virtual void perform (int stage, std::vector& messages); + ///< Messages resulting from this stage will be appended to \a messages. + }; + + class CloseSaveStage : public Stage + { + SavingState& mState; + + public: + + CloseSaveStage (SavingState& state); + + virtual int setup(); + ///< \return number of steps + + virtual void perform (int stage, std::vector& messages); + ///< Messages resulting from this stage will be appended to \a messages. + }; + class FinalSavingStage : public Stage { Document& mDocument; diff --git a/apps/opencs/model/doc/savingstate.cpp b/apps/opencs/model/doc/savingstate.cpp index 379870859..a49a0699b 100644 --- a/apps/opencs/model/doc/savingstate.cpp +++ b/apps/opencs/model/doc/savingstate.cpp @@ -2,12 +2,53 @@ #include "savingstate.hpp" #include "operation.hpp" +#include "document.hpp" CSMDoc::SavingState::SavingState (Operation& operation) -: mOperation (operation) -{} +: mOperation (operation), + /// \todo set encoding properly, once config implementation has been fixed. + mEncoder (ToUTF8::calculateEncoding ("win1252")) +{ + mWriter.setEncoder (&mEncoder); +} bool CSMDoc::SavingState::hasError() const { return mOperation.hasError(); +} + +void CSMDoc::SavingState::start (Document& document) +{ + if (mStream.is_open()) + mStream.close(); + + mStream.clear(); + + mPath = document.getSavePath(); + + boost::filesystem::path file (mPath.filename().string() + ".tmp"); + + mTmpPath = mPath.parent_path(); + + mTmpPath /= file; +} + +const boost::filesystem::path& CSMDoc::SavingState::getPath() const +{ + return mPath; +} + +const boost::filesystem::path& CSMDoc::SavingState::getTmpPath() const +{ + return mTmpPath; +} + +std::ofstream& CSMDoc::SavingState::getStream() +{ + return mStream; +} + +ESM::ESMWriter& CSMDoc::SavingState::getWriter() +{ + return mWriter; } \ No newline at end of file diff --git a/apps/opencs/model/doc/savingstate.hpp b/apps/opencs/model/doc/savingstate.hpp index b8b6f3878..3f42b4653 100644 --- a/apps/opencs/model/doc/savingstate.hpp +++ b/apps/opencs/model/doc/savingstate.hpp @@ -1,19 +1,41 @@ #ifndef CSM_DOC_SAVINGSTATE_H #define CSM_DOC_SAVINGSTATE_H +#include + +#include + +#include + namespace CSMDoc { class Operation; + class Document; class SavingState { Operation& mOperation; + boost::filesystem::path mPath; + boost::filesystem::path mTmpPath; + ToUTF8::Utf8Encoder mEncoder; + std::ofstream mStream; + ESM::ESMWriter mWriter; public: SavingState (Operation& operation); bool hasError() const; + + void start (Document& document); + + const boost::filesystem::path& getPath() const; + + const boost::filesystem::path& getTmpPath() const; + + std::ofstream& getStream(); + + ESM::ESMWriter& getWriter(); }; From 231419028d7bdd83bc61e17fbed2ef25500bf0bd Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 15 Sep 2013 15:03:17 +0200 Subject: [PATCH 034/118] minor fix --- apps/opencs/model/doc/savingstages.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 078762992..e7c9799ec 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -69,7 +69,9 @@ void CSMDoc::FinalSavingStage::perform (int stage, std::vector& mes } else { - boost::filesystem::remove (mState.getPath()); + if (boost::filesystem::exists (mState.getPath())) + boost::filesystem::remove (mState.getPath()); + boost::filesystem::rename (mState.getTmpPath(), mState.getPath()); mDocument.getUndoStack().setClean(); From 1ee228a56614c0a512c2abf4fbb82ac235a1a2c5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 15 Sep 2013 15:30:17 +0200 Subject: [PATCH 035/118] fix for the ESMWriter fix --- components/esm/esmwriter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/esm/esmwriter.cpp b/components/esm/esmwriter.cpp index a6aa82665..95ad44811 100644 --- a/components/esm/esmwriter.cpp +++ b/components/esm/esmwriter.cpp @@ -6,7 +6,7 @@ namespace ESM { - ESMWriter::ESMWriter() : mRecordCount (0), mCounting (false) {} + ESMWriter::ESMWriter() : mRecordCount (0), mCounting (true) {} unsigned int ESMWriter::getVersion() const { @@ -56,6 +56,7 @@ namespace ESM { mRecordCount = 0; mRecords.clear(); + mCounting = true; mStream = &file; startRecord("TES3", 0); From db70095148a7df4c2c171fe58d51c907cc2c1492 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 15 Sep 2013 15:31:44 +0200 Subject: [PATCH 036/118] write TES3 header --- apps/opencs/model/doc/saving.cpp | 3 +++ apps/opencs/model/doc/savingstages.cpp | 26 ++++++++++++++++++++++++++ apps/opencs/model/doc/savingstages.hpp | 16 ++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index 5607883ad..67073ca43 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -10,6 +10,9 @@ CSMDoc::Saving::Saving (Document& document) { appendStage (new OpenSaveStage (mDocument, mState)); + appendStage (new WriteHeaderStage (mDocument, mState)); + + appendStage (new CloseSaveStage (mState)); diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index e7c9799ec..797b32eae 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -30,6 +30,32 @@ void CSMDoc::OpenSaveStage::perform (int stage, std::vector& messag } +CSMDoc::WriteHeaderStage::WriteHeaderStage (Document& document, SavingState& state) +: mDocument (document), mState (state) +{} + +int CSMDoc::WriteHeaderStage::setup() +{ + return 1; +} + +void CSMDoc::WriteHeaderStage::perform (int stage, std::vector& messages) +{ + mState.getWriter().setVersion(); + + mState.getWriter().setFormat (0); + + /// \todo fill in missing header information + mState.getWriter().setAuthor (""); + mState.getWriter().setDescription (""); + mState.getWriter().setRecordCount (0); + + /// \todo fill in dependency list + + mState.getWriter().save (mState.getStream()); +} + + CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state) : mState (state) {} diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index 0b64896f7..914a2d585 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -24,6 +24,22 @@ namespace CSMDoc ///< Messages resulting from this stage will be appended to \a messages. }; + class WriteHeaderStage : public Stage + { + Document& mDocument; + SavingState& mState; + + public: + + WriteHeaderStage (Document& document, SavingState& state); + + virtual int setup(); + ///< \return number of steps + + virtual void perform (int stage, std::vector& messages); + ///< Messages resulting from this stage will be appended to \a messages. + }; + class CloseSaveStage : public Stage { SavingState& mState; From 874ce26bef34ed6b14498b80aa1ec37a5120c377 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 16 Sep 2013 12:32:35 +0200 Subject: [PATCH 037/118] added missing consts to record save functions --- components/esm/aipackage.cpp | 4 ++-- components/esm/aipackage.hpp | 2 +- components/esm/cellref.cpp | 2 +- components/esm/cellref.hpp | 2 +- components/esm/effectlist.cpp | 4 ++-- components/esm/effectlist.hpp | 4 ++-- components/esm/filter.cpp | 2 +- components/esm/filter.hpp | 2 +- components/esm/loadacti.cpp | 2 +- components/esm/loadacti.hpp | 2 +- components/esm/loadalch.cpp | 2 +- components/esm/loadalch.hpp | 2 +- components/esm/loadappa.cpp | 2 +- components/esm/loadappa.hpp | 2 +- components/esm/loadarmo.cpp | 6 +++--- components/esm/loadarmo.hpp | 4 ++-- components/esm/loadbody.cpp | 2 +- components/esm/loadbody.hpp | 2 +- components/esm/loadbook.cpp | 2 +- components/esm/loadbook.hpp | 2 +- components/esm/loadbsgn.cpp | 2 +- components/esm/loadbsgn.hpp | 2 +- components/esm/loadcell.cpp | 2 +- components/esm/loadcell.hpp | 2 +- components/esm/loadclas.cpp | 2 +- components/esm/loadclas.hpp | 2 +- components/esm/loadclot.cpp | 2 +- components/esm/loadclot.hpp | 2 +- components/esm/loadcont.cpp | 6 +++--- components/esm/loadcont.hpp | 4 ++-- components/esm/loadcrea.cpp | 2 +- components/esm/loadcrea.hpp | 2 +- components/esm/loadcrec.hpp | 4 ++-- components/esm/loaddial.cpp | 2 +- components/esm/loaddial.hpp | 2 +- components/esm/loaddoor.cpp | 2 +- components/esm/loaddoor.hpp | 2 +- components/esm/loadench.cpp | 2 +- components/esm/loadench.hpp | 2 +- components/esm/loadfact.cpp | 4 ++-- components/esm/loadfact.hpp | 2 +- components/esm/loadglob.cpp | 2 +- components/esm/loadglob.hpp | 2 +- components/esm/loadgmst.cpp | 2 +- components/esm/loadgmst.hpp | 4 ++-- components/esm/loadinfo.cpp | 4 ++-- components/esm/loadinfo.hpp | 2 +- components/esm/loadingr.cpp | 2 +- components/esm/loadingr.hpp | 2 +- components/esm/loadland.cpp | 18 +++--------------- components/esm/loadland.hpp | 2 +- components/esm/loadlevlist.cpp | 4 ++-- components/esm/loadlevlist.hpp | 2 +- components/esm/loadligh.cpp | 2 +- components/esm/loadligh.hpp | 2 +- components/esm/loadlock.cpp | 2 +- components/esm/loadlock.hpp | 2 +- components/esm/loadltex.cpp | 2 +- components/esm/loadltex.hpp | 2 +- components/esm/loadmgef.cpp | 10 +++------- components/esm/loadmgef.hpp | 2 +- components/esm/loadmisc.cpp | 2 +- components/esm/loadmisc.hpp | 2 +- components/esm/loadnpc.cpp | 4 ++-- components/esm/loadnpc.hpp | 2 +- components/esm/loadnpcc.hpp | 2 +- components/esm/loadpgrd.cpp | 10 +++++----- components/esm/loadpgrd.hpp | 2 +- components/esm/loadprob.cpp | 2 +- components/esm/loadprob.hpp | 2 +- components/esm/loadrace.cpp | 2 +- components/esm/loadrace.hpp | 2 +- components/esm/loadregn.cpp | 4 ++-- components/esm/loadregn.hpp | 2 +- components/esm/loadrepa.cpp | 2 +- components/esm/loadrepa.hpp | 2 +- components/esm/loadscpt.cpp | 6 +++--- components/esm/loadscpt.hpp | 2 +- components/esm/loadskil.cpp | 2 +- components/esm/loadskil.hpp | 2 +- components/esm/loadsndg.cpp | 2 +- components/esm/loadsndg.hpp | 2 +- components/esm/loadsoun.cpp | 2 +- components/esm/loadsoun.hpp | 2 +- components/esm/loadspel.cpp | 2 +- components/esm/loadspel.hpp | 2 +- components/esm/loadsscr.cpp | 2 +- components/esm/loadsscr.hpp | 2 +- components/esm/loadstat.cpp | 2 +- components/esm/loadstat.hpp | 2 +- components/esm/loadweap.cpp | 2 +- components/esm/loadweap.hpp | 2 +- components/esm/spelllist.cpp | 4 ++-- components/esm/spelllist.hpp | 2 +- 94 files changed, 121 insertions(+), 137 deletions(-) diff --git a/components/esm/aipackage.cpp b/components/esm/aipackage.cpp index 1440dbd13..cf4951de7 100644 --- a/components/esm/aipackage.cpp +++ b/components/esm/aipackage.cpp @@ -44,9 +44,9 @@ namespace ESM } } - void AIPackageList::save(ESMWriter &esm) + void AIPackageList::save(ESMWriter &esm) const { - typedef std::vector::iterator PackageIter; + typedef std::vector::const_iterator PackageIter; for (PackageIter it = mList.begin(); it != mList.end(); ++it) { switch (it->mType) { case AI_Wander: diff --git a/components/esm/aipackage.hpp b/components/esm/aipackage.hpp index 38499b2dd..b06cb529a 100644 --- a/components/esm/aipackage.hpp +++ b/components/esm/aipackage.hpp @@ -93,7 +93,7 @@ namespace ESM /// it needs to use retSubName() if needed. But, hey, there /// is only one field left (XSCL) and only two records uses AI void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; } diff --git a/components/esm/cellref.cpp b/components/esm/cellref.cpp index 95cf24d33..e91059b26 100644 --- a/components/esm/cellref.cpp +++ b/components/esm/cellref.cpp @@ -3,7 +3,7 @@ #include "esmwriter.hpp" -void ESM::CellRef::save(ESMWriter &esm) +void ESM::CellRef::save(ESMWriter &esm) const { esm.writeHNT("FRMR", mRefnum); esm.writeHNCString("NAME", mRefID); diff --git a/components/esm/cellref.hpp b/components/esm/cellref.hpp index 31889914c..47cb0b99e 100644 --- a/components/esm/cellref.hpp +++ b/components/esm/cellref.hpp @@ -83,7 +83,7 @@ namespace ESM // Position and rotation of this object within the cell Position mPos; - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); }; diff --git a/components/esm/effectlist.cpp b/components/esm/effectlist.cpp index 88f87d6e2..bc126846b 100644 --- a/components/esm/effectlist.cpp +++ b/components/esm/effectlist.cpp @@ -14,9 +14,9 @@ void EffectList::load(ESMReader &esm) } } -void EffectList::save(ESMWriter &esm) +void EffectList::save(ESMWriter &esm) const { - for (std::vector::iterator it = mList.begin(); it != mList.end(); ++it) { + for (std::vector::const_iterator it = mList.begin(); it != mList.end(); ++it) { esm.writeHNT("ENAM", *it, 24); } } diff --git a/components/esm/effectlist.hpp b/components/esm/effectlist.hpp index 9f5b87aed..04adcc5cd 100644 --- a/components/esm/effectlist.hpp +++ b/components/esm/effectlist.hpp @@ -35,9 +35,9 @@ namespace ESM std::vector mList; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; - + } #endif diff --git a/components/esm/filter.cpp b/components/esm/filter.cpp index 7d4851a5f..96cc19d43 100644 --- a/components/esm/filter.cpp +++ b/components/esm/filter.cpp @@ -10,7 +10,7 @@ void ESM::Filter::load (ESMReader& esm) mDescription = esm.getHNString ("DESC"); } -void ESM::Filter::save (ESMWriter& esm) +void ESM::Filter::save (ESMWriter& esm) const { esm.writeHNCString ("FILT", mFilter); esm.writeHNCString ("DESC", mDescription); diff --git a/components/esm/filter.hpp b/components/esm/filter.hpp index 0fd564361..a44d1b198 100644 --- a/components/esm/filter.hpp +++ b/components/esm/filter.hpp @@ -17,7 +17,7 @@ namespace ESM std::string mFilter; void load (ESMReader& esm); - void save (ESMWriter& esm); + void save (ESMWriter& esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadacti.cpp b/components/esm/loadacti.cpp index fd022af7e..dcae845d0 100644 --- a/components/esm/loadacti.cpp +++ b/components/esm/loadacti.cpp @@ -11,7 +11,7 @@ void Activator::load(ESMReader &esm) mName = esm.getHNString("FNAM"); mScript = esm.getHNOString("SCRI"); } -void Activator::save(ESMWriter &esm) +void Activator::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNCString("FNAM", mName); diff --git a/components/esm/loadacti.hpp b/components/esm/loadacti.hpp index a62990590..6b072ee11 100644 --- a/components/esm/loadacti.hpp +++ b/components/esm/loadacti.hpp @@ -14,7 +14,7 @@ struct Activator std::string mId, mName, mScript, mModel; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadalch.cpp b/components/esm/loadalch.cpp index dbb69c066..187069c2e 100644 --- a/components/esm/loadalch.cpp +++ b/components/esm/loadalch.cpp @@ -14,7 +14,7 @@ void Potion::load(ESMReader &esm) esm.getHNT(mData, "ALDT", 12); mEffects.load(esm); } -void Potion::save(ESMWriter &esm) +void Potion::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNOCString("TEXT", mIcon); diff --git a/components/esm/loadalch.hpp b/components/esm/loadalch.hpp index 3ede85342..8f0435292 100644 --- a/components/esm/loadalch.hpp +++ b/components/esm/loadalch.hpp @@ -29,7 +29,7 @@ struct Potion EffectList mEffects; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadappa.cpp b/components/esm/loadappa.cpp index 4b8d2b763..01233a055 100644 --- a/components/esm/loadappa.cpp +++ b/components/esm/loadappa.cpp @@ -28,7 +28,7 @@ void Apparatus::load(ESMReader &esm) } } -void Apparatus::save(ESMWriter &esm) +void Apparatus::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNCString("FNAM", mName); diff --git a/components/esm/loadappa.hpp b/components/esm/loadappa.hpp index ed9d335be..d47643c6c 100644 --- a/components/esm/loadappa.hpp +++ b/components/esm/loadappa.hpp @@ -35,7 +35,7 @@ struct Apparatus std::string mId, mModel, mIcon, mScript, mName; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadarmo.cpp b/components/esm/loadarmo.cpp index e64c8705d..4dbdf1314 100644 --- a/components/esm/loadarmo.cpp +++ b/components/esm/loadarmo.cpp @@ -18,9 +18,9 @@ void PartReferenceList::load(ESMReader &esm) } } -void PartReferenceList::save(ESMWriter &esm) +void PartReferenceList::save(ESMWriter &esm) const { - for (std::vector::iterator it = mParts.begin(); it != mParts.end(); ++it) + for (std::vector::const_iterator it = mParts.begin(); it != mParts.end(); ++it) { esm.writeHNT("INDX", it->mPart); esm.writeHNOString("BNAM", it->mMale); @@ -39,7 +39,7 @@ void Armor::load(ESMReader &esm) mEnchant = esm.getHNOString("ENAM"); } -void Armor::save(ESMWriter &esm) +void Armor::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNCString("FNAM", mName); diff --git a/components/esm/loadarmo.hpp b/components/esm/loadarmo.hpp index eaef42be8..5a38605e3 100644 --- a/components/esm/loadarmo.hpp +++ b/components/esm/loadarmo.hpp @@ -56,7 +56,7 @@ struct PartReferenceList std::vector mParts; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; struct Armor @@ -89,7 +89,7 @@ struct Armor std::string mId, mName, mModel, mIcon, mScript, mEnchant; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadbody.cpp b/components/esm/loadbody.cpp index e95a8a860..a5d986f65 100644 --- a/components/esm/loadbody.cpp +++ b/components/esm/loadbody.cpp @@ -12,7 +12,7 @@ void BodyPart::load(ESMReader &esm) mRace = esm.getHNString("FNAM"); esm.getHNT(mData, "BYDT", 4); } -void BodyPart::save(ESMWriter &esm) +void BodyPart::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNCString("FNAM", mRace); diff --git a/components/esm/loadbody.hpp b/components/esm/loadbody.hpp index 3ad9b1b95..a8fd36aef 100644 --- a/components/esm/loadbody.hpp +++ b/components/esm/loadbody.hpp @@ -57,7 +57,7 @@ struct BodyPart std::string mId, mModel, mRace; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; } #endif diff --git a/components/esm/loadbook.cpp b/components/esm/loadbook.cpp index 3a70ac786..d9db11889 100644 --- a/components/esm/loadbook.cpp +++ b/components/esm/loadbook.cpp @@ -16,7 +16,7 @@ void Book::load(ESMReader &esm) mText = esm.getHNOString("TEXT"); mEnchant = esm.getHNOString("ENAM"); } -void Book::save(ESMWriter &esm) +void Book::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNOCString("FNAM", mName); diff --git a/components/esm/loadbook.hpp b/components/esm/loadbook.hpp index 68042e246..688e9dd75 100644 --- a/components/esm/loadbook.hpp +++ b/components/esm/loadbook.hpp @@ -25,7 +25,7 @@ struct Book std::string mId; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadbsgn.cpp b/components/esm/loadbsgn.cpp index cb500f674..9d19f02c7 100644 --- a/components/esm/loadbsgn.cpp +++ b/components/esm/loadbsgn.cpp @@ -15,7 +15,7 @@ void BirthSign::load(ESMReader &esm) mPowers.load(esm); } -void BirthSign::save(ESMWriter &esm) +void BirthSign::save(ESMWriter &esm) const { esm.writeHNCString("FNAM", mName); esm.writeHNOCString("TNAM", mTexture); diff --git a/components/esm/loadbsgn.hpp b/components/esm/loadbsgn.hpp index 434ddf68e..1ecb5e418 100644 --- a/components/esm/loadbsgn.hpp +++ b/components/esm/loadbsgn.hpp @@ -19,7 +19,7 @@ struct BirthSign SpellList mPowers; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID/index). diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index d8d0c1291..57d3278d8 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -89,7 +89,7 @@ void Cell::postLoad(ESMReader &esm) esm.skipRecord(); } -void Cell::save(ESMWriter &esm) +void Cell::save(ESMWriter &esm) const { esm.writeHNT("DATA", mData, 12); if (mData.mFlags & Interior) diff --git a/components/esm/loadcell.hpp b/components/esm/loadcell.hpp index 51288b291..c417fceab 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -102,7 +102,7 @@ struct Cell // This method is left in for compatibility with esmtool. Parsing moved references currently requires // passing ESMStore, bit it does not know about this parameter, so we do it this way. void load(ESMReader &esm, bool saveContext = true); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; bool isExterior() const { diff --git a/components/esm/loadclas.cpp b/components/esm/loadclas.cpp index bdc461462..ef07430c7 100644 --- a/components/esm/loadclas.cpp +++ b/components/esm/loadclas.cpp @@ -47,7 +47,7 @@ void Class::load(ESMReader &esm) mDescription = esm.getHNOString("DESC"); } -void Class::save(ESMWriter &esm) +void Class::save(ESMWriter &esm) const { esm.writeHNCString("FNAM", mName); esm.writeHNT("CLDT", mData, 60); diff --git a/components/esm/loadclas.hpp b/components/esm/loadclas.hpp index 4f85e6ee8..f241dca8d 100644 --- a/components/esm/loadclas.hpp +++ b/components/esm/loadclas.hpp @@ -70,7 +70,7 @@ struct Class CLDTstruct mData; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID/index). diff --git a/components/esm/loadclot.cpp b/components/esm/loadclot.cpp index 10b00970f..c623155df 100644 --- a/components/esm/loadclot.cpp +++ b/components/esm/loadclot.cpp @@ -20,7 +20,7 @@ void Clothing::load(ESMReader &esm) mEnchant = esm.getHNOString("ENAM"); } -void Clothing::save(ESMWriter &esm) +void Clothing::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNOCString("FNAM", mName); diff --git a/components/esm/loadclot.hpp b/components/esm/loadclot.hpp index 816d03cb2..13fae865b 100644 --- a/components/esm/loadclot.hpp +++ b/components/esm/loadclot.hpp @@ -45,7 +45,7 @@ struct Clothing std::string mId, mName, mModel, mIcon, mEnchant, mScript; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadcont.cpp b/components/esm/loadcont.cpp index 853c8bd50..0cbb4acd1 100644 --- a/components/esm/loadcont.cpp +++ b/components/esm/loadcont.cpp @@ -16,9 +16,9 @@ void InventoryList::load(ESMReader &esm) } } -void InventoryList::save(ESMWriter &esm) +void InventoryList::save(ESMWriter &esm) const { - for (std::vector::iterator it = mList.begin(); it != mList.end(); ++it) + for (std::vector::const_iterator it = mList.begin(); it != mList.end(); ++it) { esm.writeHNT("NPCO", *it, 36); } @@ -41,7 +41,7 @@ void Container::load(ESMReader &esm) mInventory.load(esm); } -void Container::save(ESMWriter &esm) +void Container::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNOCString("FNAM", mName); diff --git a/components/esm/loadcont.hpp b/components/esm/loadcont.hpp index b2bbab73d..c854b5290 100644 --- a/components/esm/loadcont.hpp +++ b/components/esm/loadcont.hpp @@ -27,7 +27,7 @@ struct InventoryList std::vector mList; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; struct Container @@ -46,7 +46,7 @@ struct Container InventoryList mInventory; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadcrea.cpp b/components/esm/loadcrea.cpp index 86d05b8a5..30b70b35b 100644 --- a/components/esm/loadcrea.cpp +++ b/components/esm/loadcrea.cpp @@ -35,7 +35,7 @@ void Creature::load(ESMReader &esm) esm.skipRecord(); } -void Creature::save(ESMWriter &esm) +void Creature::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNOCString("CNAM", mOriginal); diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index 279e2ea3f..80e0fbd1c 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -86,7 +86,7 @@ struct Creature AIPackageList mAiPackage; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadcrec.hpp b/components/esm/loadcrec.hpp index 6904df15a..2b840ccf4 100644 --- a/components/esm/loadcrec.hpp +++ b/components/esm/loadcrec.hpp @@ -24,7 +24,7 @@ struct LoadCREC esm.skipRecord(); } - void save(ESMWriter &esm) + void save(ESMWriter &esm) const { } }; @@ -39,7 +39,7 @@ struct LoadCNTC esm.skipRecord(); } - void save(ESMWriter &esm) + void save(ESMWriter &esm) const { } }; diff --git a/components/esm/loaddial.cpp b/components/esm/loaddial.cpp index fb50d5e9f..e014ca37e 100644 --- a/components/esm/loaddial.cpp +++ b/components/esm/loaddial.cpp @@ -25,7 +25,7 @@ void Dialogue::load(ESMReader &esm) esm.fail("Unknown sub record size"); } -void Dialogue::save(ESMWriter &esm) +void Dialogue::save(ESMWriter &esm) const { if (mType != Deleted) esm.writeHNT("DATA", mType); diff --git a/components/esm/loaddial.hpp b/components/esm/loaddial.hpp index 61f3f763d..0fe5027dc 100644 --- a/components/esm/loaddial.hpp +++ b/components/esm/loaddial.hpp @@ -34,7 +34,7 @@ struct Dialogue std::vector mInfo; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; } #endif diff --git a/components/esm/loaddoor.cpp b/components/esm/loaddoor.cpp index a4c7b7d58..f666ac67a 100644 --- a/components/esm/loaddoor.cpp +++ b/components/esm/loaddoor.cpp @@ -15,7 +15,7 @@ void Door::load(ESMReader &esm) mCloseSound = esm.getHNOString("ANAM"); } -void Door::save(ESMWriter &esm) +void Door::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNOCString("FNAM", mName); diff --git a/components/esm/loaddoor.hpp b/components/esm/loaddoor.hpp index 77ffc6489..2b927c56e 100644 --- a/components/esm/loaddoor.hpp +++ b/components/esm/loaddoor.hpp @@ -14,7 +14,7 @@ struct Door std::string mId, mName, mModel, mScript, mOpenSound, mCloseSound; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadench.cpp b/components/esm/loadench.cpp index c4e278368..4b4c3a1ec 100644 --- a/components/esm/loadench.cpp +++ b/components/esm/loadench.cpp @@ -12,7 +12,7 @@ void Enchantment::load(ESMReader &esm) mEffects.load(esm); } -void Enchantment::save(ESMWriter &esm) +void Enchantment::save(ESMWriter &esm) const { esm.writeHNT("ENDT", mData, 16); mEffects.save(esm); diff --git a/components/esm/loadench.hpp b/components/esm/loadench.hpp index 999f93ad9..3cdc3a0bd 100644 --- a/components/esm/loadench.hpp +++ b/components/esm/loadench.hpp @@ -39,7 +39,7 @@ struct Enchantment EffectList mEffects; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; } #endif diff --git a/components/esm/loadfact.cpp b/components/esm/loadfact.cpp index e2712d462..c8be51802 100644 --- a/components/esm/loadfact.cpp +++ b/components/esm/loadfact.cpp @@ -47,7 +47,7 @@ void Faction::load(ESMReader &esm) mReactions.push_back(r); } } -void Faction::save(ESMWriter &esm) +void Faction::save(ESMWriter &esm) const { esm.writeHNCString("FNAM", mName); @@ -61,7 +61,7 @@ void Faction::save(ESMWriter &esm) esm.writeHNT("FADT", mData, 240); - for (std::vector::iterator it = mReactions.begin(); it != mReactions.end(); ++it) + for (std::vector::const_iterator it = mReactions.begin(); it != mReactions.end(); ++it) { esm.writeHNString("ANAM", it->mFaction); esm.writeHNT("INTV", it->mReaction); diff --git a/components/esm/loadfact.hpp b/components/esm/loadfact.hpp index 891b99647..11f65a87f 100644 --- a/components/esm/loadfact.hpp +++ b/components/esm/loadfact.hpp @@ -63,7 +63,7 @@ struct Faction std::string mRanks[10]; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID/index). diff --git a/components/esm/loadglob.cpp b/components/esm/loadglob.cpp index ccb519acd..e1c2d4408 100644 --- a/components/esm/loadglob.cpp +++ b/components/esm/loadglob.cpp @@ -7,7 +7,7 @@ namespace ESM mValue.read (esm, ESM::Variant::Format_Global); } - void Global::save (ESMWriter &esm) + void Global::save (ESMWriter &esm) const { mValue.write (esm, ESM::Variant::Format_Global); } diff --git a/components/esm/loadglob.hpp b/components/esm/loadglob.hpp index 72e16c0ce..06ff97ef2 100644 --- a/components/esm/loadglob.hpp +++ b/components/esm/loadglob.hpp @@ -21,7 +21,7 @@ struct Global Variant mValue; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadgmst.cpp b/components/esm/loadgmst.cpp index fe1cc1b04..3a7df4506 100644 --- a/components/esm/loadgmst.cpp +++ b/components/esm/loadgmst.cpp @@ -7,7 +7,7 @@ namespace ESM mValue.read (esm, ESM::Variant::Format_Gmst); } - void GameSetting::save (ESMWriter &esm) + void GameSetting::save (ESMWriter &esm) const { mValue.write (esm, ESM::Variant::Format_Gmst); } diff --git a/components/esm/loadgmst.hpp b/components/esm/loadgmst.hpp index a6e0c2ecb..9c37c7da0 100644 --- a/components/esm/loadgmst.hpp +++ b/components/esm/loadgmst.hpp @@ -24,7 +24,7 @@ struct GameSetting void load(ESMReader &esm); - /// \todo remove the get* functions (redundant, since mValue as equivalent functions now). + /// \todo remove the get* functions (redundant, since mValue has equivalent functions now). int getInt() const; ///< Throws an exception if GMST is not of type int or float. @@ -35,7 +35,7 @@ struct GameSetting std::string getString() const; ///< Throwns an exception if GMST is not of type string. - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadinfo.cpp b/components/esm/loadinfo.cpp index 90f8fcf35..1985da2cd 100644 --- a/components/esm/loadinfo.cpp +++ b/components/esm/loadinfo.cpp @@ -120,7 +120,7 @@ void DialInfo::load(ESMReader &esm) esm.skipRecord(); } -void DialInfo::save(ESMWriter &esm) +void DialInfo::save(ESMWriter &esm) const { esm.writeHNCString("INAM", mId); esm.writeHNCString("PNAM", mPrev); @@ -135,7 +135,7 @@ void DialInfo::save(ESMWriter &esm) esm.writeHNOCString("SNAM", mSound); esm.writeHNOString("NAME", mResponse); - for (std::vector::iterator it = mSelects.begin(); it != mSelects.end(); ++it) + for (std::vector::const_iterator it = mSelects.begin(); it != mSelects.end(); ++it) { esm.writeHNString("SCVR", it->mSelectRule); it->mValue.write (esm, Variant::Format_Info); diff --git a/components/esm/loadinfo.hpp b/components/esm/loadinfo.hpp index 2361ed9eb..351768e96 100644 --- a/components/esm/loadinfo.hpp +++ b/components/esm/loadinfo.hpp @@ -99,7 +99,7 @@ struct DialInfo }; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; } diff --git a/components/esm/loadingr.cpp b/components/esm/loadingr.cpp index 7e31a4116..1bc9ae41c 100644 --- a/components/esm/loadingr.cpp +++ b/components/esm/loadingr.cpp @@ -37,7 +37,7 @@ void Ingredient::load(ESMReader &esm) } } -void Ingredient::save(ESMWriter &esm) +void Ingredient::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNCString("FNAM", mName); diff --git a/components/esm/loadingr.hpp b/components/esm/loadingr.hpp index 5e286535f..03e67924c 100644 --- a/components/esm/loadingr.hpp +++ b/components/esm/loadingr.hpp @@ -28,7 +28,7 @@ struct Ingredient std::string mId, mName, mModel, mIcon, mScript; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadland.cpp b/components/esm/loadland.cpp index 60c475040..8e54bcc5c 100644 --- a/components/esm/loadland.cpp +++ b/components/esm/loadland.cpp @@ -16,14 +16,14 @@ void Land::LandData::save(ESMWriter &esm) offsets.mHeightOffset = mHeights[0] / HEIGHT_SCALE; offsets.mUnk1 = mUnk1; offsets.mUnk2 = mUnk2; - + float prevY = mHeights[0], prevX; int number = 0; // avoid multiplication for (int i = 0; i < LAND_SIZE; ++i) { float diff = (mHeights[number] - prevY) / HEIGHT_SCALE; offsets.mHeightData[number] = (diff >= 0) ? (int8_t) (diff + 0.5) : (int8_t) (diff - 0.5); - + prevX = prevY = mHeights[number]; ++number; @@ -132,7 +132,7 @@ void Land::load(ESMReader &esm) mLandData = NULL; } -void Land::save(ESMWriter &esm) +void Land::save(ESMWriter &esm) const { esm.startSubRecord("INTV"); esm.writeT(mX); @@ -140,18 +140,6 @@ void Land::save(ESMWriter &esm) esm.endRecord("INTV"); esm.writeHNT("DATA", mFlags); - - // TODO: Land! - bool wasLoaded = mDataLoaded; - if (mDataTypes) { - // Try to load all available data before saving - loadData(mDataTypes); - } - if (mDataLoaded) - mLandData->save(esm); - - if (!wasLoaded) - unloadData(); // Don't need to keep the data loaded if it wasn't already } /// \todo remove memory allocation when only defaults needed diff --git a/components/esm/loadland.hpp b/components/esm/loadland.hpp index 9c1fd1f5c..3d3bcd67b 100644 --- a/components/esm/loadland.hpp +++ b/components/esm/loadland.hpp @@ -94,7 +94,7 @@ struct Land LandData *mLandData; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; /** * Actually loads data diff --git a/components/esm/loadlevlist.cpp b/components/esm/loadlevlist.cpp index b54a91276..ab3f5e9e6 100644 --- a/components/esm/loadlevlist.cpp +++ b/components/esm/loadlevlist.cpp @@ -33,13 +33,13 @@ void LeveledListBase::load(ESMReader &esm) esm.getHNT(li.mLevel, "INTV"); } } -void LeveledListBase::save(ESMWriter &esm) +void LeveledListBase::save(ESMWriter &esm) const { esm.writeHNT("DATA", mFlags); esm.writeHNT("NNAM", mChanceNone); esm.writeHNT("INDX", mList.size()); - for (std::vector::iterator it = mList.begin(); it != mList.end(); ++it) + for (std::vector::const_iterator it = mList.begin(); it != mList.end(); ++it) { esm.writeHNCString(mRecName, it->mId); esm.writeHNT("INTV", it->mLevel); diff --git a/components/esm/loadlevlist.hpp b/components/esm/loadlevlist.hpp index 7339cac56..f5fb7fd5b 100644 --- a/components/esm/loadlevlist.hpp +++ b/components/esm/loadlevlist.hpp @@ -51,7 +51,7 @@ struct LeveledListBase std::vector mList; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadligh.cpp b/components/esm/loadligh.cpp index 89a2b8c65..3f279c7c8 100644 --- a/components/esm/loadligh.cpp +++ b/components/esm/loadligh.cpp @@ -16,7 +16,7 @@ void Light::load(ESMReader &esm) mScript = esm.getHNOString("SCRI"); mSound = esm.getHNOString("SNAM"); } -void Light::save(ESMWriter &esm) +void Light::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNOCString("FNAM", mName); diff --git a/components/esm/loadligh.hpp b/components/esm/loadligh.hpp index 3f0b76d6e..9a341f0de 100644 --- a/components/esm/loadligh.hpp +++ b/components/esm/loadligh.hpp @@ -44,7 +44,7 @@ struct Light std::string mSound, mScript, mModel, mIcon, mName, mId; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadlock.cpp b/components/esm/loadlock.cpp index 03eac52bd..318769ec0 100644 --- a/components/esm/loadlock.cpp +++ b/components/esm/loadlock.cpp @@ -17,7 +17,7 @@ void Lockpick::load(ESMReader &esm) mIcon = esm.getHNOString("ITEX"); } -void Lockpick::save(ESMWriter &esm) +void Lockpick::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNCString("FNAM", mName); diff --git a/components/esm/loadlock.hpp b/components/esm/loadlock.hpp index 953066cb2..aea5a4f31 100644 --- a/components/esm/loadlock.hpp +++ b/components/esm/loadlock.hpp @@ -24,7 +24,7 @@ struct Lockpick std::string mId, mName, mModel, mIcon, mScript; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadltex.cpp b/components/esm/loadltex.cpp index e523e9fa7..dc1bc164b 100644 --- a/components/esm/loadltex.cpp +++ b/components/esm/loadltex.cpp @@ -11,7 +11,7 @@ void LandTexture::load(ESMReader &esm) esm.getHNT(mIndex, "INTV"); mTexture = esm.getHNString("DATA"); } -void LandTexture::save(ESMWriter &esm) +void LandTexture::save(ESMWriter &esm) const { esm.writeHNT("INTV", mIndex); esm.writeHNCString("DATA", mTexture); diff --git a/components/esm/loadltex.hpp b/components/esm/loadltex.hpp index 6e6d987d4..3d0816948 100644 --- a/components/esm/loadltex.hpp +++ b/components/esm/loadltex.hpp @@ -31,7 +31,7 @@ struct LandTexture int mIndex; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; } #endif diff --git a/components/esm/loadmgef.cpp b/components/esm/loadmgef.cpp index 060645b5f..9eaeff704 100644 --- a/components/esm/loadmgef.cpp +++ b/components/esm/loadmgef.cpp @@ -58,15 +58,11 @@ void MagicEffect::load(ESMReader &esm) mDescription = esm.getHNOString("DESC"); } -void MagicEffect::save(ESMWriter &esm) +void MagicEffect::save(ESMWriter &esm) const { esm.writeHNT("INDX", mIndex); - mData.mFlags &= 0xe00; esm.writeHNT("MEDT", mData, 36); - if (mIndex>=0 && mIndex::iterator DestIter; + typedef std::vector::const_iterator DestIter; for (DestIter it = mTransport.begin(); it != mTransport.end(); ++it) { esm.writeHNT("DODT", it->mPos, sizeof(it->mPos)); esm.writeHNOCString("DNAM", it->mCellName); diff --git a/components/esm/loadnpc.hpp b/components/esm/loadnpc.hpp index 009bc5ef3..009548c59 100644 --- a/components/esm/loadnpc.hpp +++ b/components/esm/loadnpc.hpp @@ -117,7 +117,7 @@ struct NPC std::string mHair, mHead; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; bool isMale() const; diff --git a/components/esm/loadnpcc.hpp b/components/esm/loadnpcc.hpp index 79d92397f..f023fd217 100644 --- a/components/esm/loadnpcc.hpp +++ b/components/esm/loadnpcc.hpp @@ -84,7 +84,7 @@ struct LoadNPCC { esm.skipRecord(); } - void save(ESMWriter &esm) + void save(ESMWriter &esm) const { } }; diff --git a/components/esm/loadpgrd.cpp b/components/esm/loadpgrd.cpp index 882addcb9..65d1f8055 100644 --- a/components/esm/loadpgrd.cpp +++ b/components/esm/loadpgrd.cpp @@ -70,25 +70,25 @@ void Pathgrid::load(ESMReader &esm) } } } -void Pathgrid::save(ESMWriter &esm) +void Pathgrid::save(ESMWriter &esm) const { esm.writeHNT("DATA", mData, 12); esm.writeHNCString("NAME", mCell); - + if (!mPoints.empty()) { esm.startSubRecord("PGRP"); - for (PointList::iterator it = mPoints.begin(); it != mPoints.end(); ++it) + for (PointList::const_iterator it = mPoints.begin(); it != mPoints.end(); ++it) { esm.writeT(*it); } esm.endRecord("PGRP"); } - + if (!mEdges.empty()) { esm.startSubRecord("PGRC"); - for (std::vector::iterator it = mEdges.begin(); it != mEdges.end(); ++it) + for (std::vector::const_iterator it = mEdges.begin(); it != mEdges.end(); ++it) { esm.writeT(it->mV1); } diff --git a/components/esm/loadpgrd.hpp b/components/esm/loadpgrd.hpp index c3f50fc4d..d14433a78 100644 --- a/components/esm/loadpgrd.hpp +++ b/components/esm/loadpgrd.hpp @@ -46,7 +46,7 @@ struct Pathgrid EdgeList mEdges; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; } #endif diff --git a/components/esm/loadprob.cpp b/components/esm/loadprob.cpp index 729f8404e..0fb4c9750 100644 --- a/components/esm/loadprob.cpp +++ b/components/esm/loadprob.cpp @@ -17,7 +17,7 @@ void Probe::load(ESMReader &esm) mIcon = esm.getHNOString("ITEX"); } -void Probe::save(ESMWriter &esm) +void Probe::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNCString("FNAM", mName); diff --git a/components/esm/loadprob.hpp b/components/esm/loadprob.hpp index 55b896bcd..d0a8256ab 100644 --- a/components/esm/loadprob.hpp +++ b/components/esm/loadprob.hpp @@ -24,7 +24,7 @@ struct Probe std::string mId, mName, mModel, mIcon, mScript; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadrace.cpp b/components/esm/loadrace.cpp index 955424e2b..e9e1d0d79 100644 --- a/components/esm/loadrace.cpp +++ b/components/esm/loadrace.cpp @@ -22,7 +22,7 @@ void Race::load(ESMReader &esm) mPowers.load(esm); mDescription = esm.getHNOString("DESC"); } -void Race::save(ESMWriter &esm) +void Race::save(ESMWriter &esm) const { esm.writeHNCString("FNAM", mName); esm.writeHNT("RADT", mData, 140); diff --git a/components/esm/loadrace.hpp b/components/esm/loadrace.hpp index 6ecec8ebb..a53a98070 100644 --- a/components/esm/loadrace.hpp +++ b/components/esm/loadrace.hpp @@ -65,7 +65,7 @@ struct Race SpellList mPowers; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID/index). diff --git a/components/esm/loadregn.cpp b/components/esm/loadregn.cpp index 41c7f507a..fd42b9ee8 100644 --- a/components/esm/loadregn.cpp +++ b/components/esm/loadregn.cpp @@ -28,7 +28,7 @@ void Region::load(ESMReader &esm) mSoundList.push_back(sr); } } -void Region::save(ESMWriter &esm) +void Region::save(ESMWriter &esm) const { esm.writeHNCString("FNAM", mName); @@ -40,7 +40,7 @@ void Region::save(ESMWriter &esm) esm.writeHNOCString("BNAM", mSleepList); esm.writeHNT("CNAM", mMapColor); - for (std::vector::iterator it = mSoundList.begin(); it != mSoundList.end(); ++it) + for (std::vector::const_iterator it = mSoundList.begin(); it != mSoundList.end(); ++it) { esm.writeHNT("SNAM", *it); } diff --git a/components/esm/loadregn.hpp b/components/esm/loadregn.hpp index f2a3d9a10..a6075d65a 100644 --- a/components/esm/loadregn.hpp +++ b/components/esm/loadregn.hpp @@ -47,7 +47,7 @@ struct Region std::vector mSoundList; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID/index). diff --git a/components/esm/loadrepa.cpp b/components/esm/loadrepa.cpp index ced6daa2e..59bfa0169 100644 --- a/components/esm/loadrepa.cpp +++ b/components/esm/loadrepa.cpp @@ -17,7 +17,7 @@ void Repair::load(ESMReader &esm) mIcon = esm.getHNOString("ITEX"); } -void Repair::save(ESMWriter &esm) +void Repair::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNCString("FNAM", mName); diff --git a/components/esm/loadrepa.hpp b/components/esm/loadrepa.hpp index 83812bad9..771e7ead0 100644 --- a/components/esm/loadrepa.hpp +++ b/components/esm/loadrepa.hpp @@ -24,7 +24,7 @@ struct Repair std::string mId, mName, mModel, mIcon, mScript; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadscpt.cpp b/components/esm/loadscpt.cpp index 2c1b018d9..8afb85602 100644 --- a/components/esm/loadscpt.cpp +++ b/components/esm/loadscpt.cpp @@ -50,11 +50,11 @@ void Script::load(ESMReader &esm) // Script text mScriptText = esm.getHNOString("SCTX"); } -void Script::save(ESMWriter &esm) +void Script::save(ESMWriter &esm) const { std::string varNameString; if (!mVarNames.empty()) - for (std::vector::iterator it = mVarNames.begin(); it != mVarNames.end(); ++it) + for (std::vector::const_iterator it = mVarNames.begin(); it != mVarNames.end(); ++it) varNameString.append(*it); SCHD data; @@ -68,7 +68,7 @@ void Script::save(ESMWriter &esm) if (!mVarNames.empty()) { esm.startSubRecord("SCVR"); - for (std::vector::iterator it = mVarNames.begin(); it != mVarNames.end(); ++it) + for (std::vector::const_iterator it = mVarNames.begin(); it != mVarNames.end(); ++it) { esm.writeHCString(*it); } diff --git a/components/esm/loadscpt.hpp b/components/esm/loadscpt.hpp index be7e83900..450224faa 100644 --- a/components/esm/loadscpt.hpp +++ b/components/esm/loadscpt.hpp @@ -56,7 +56,7 @@ public: std::string mScriptText; // Uncompiled script void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID/index). diff --git a/components/esm/loadskil.cpp b/components/esm/loadskil.cpp index 676a835c3..f6a2c4950 100644 --- a/components/esm/loadskil.cpp +++ b/components/esm/loadskil.cpp @@ -137,7 +137,7 @@ void Skill::load(ESMReader &esm) mId = indexToId (mIndex); } -void Skill::save(ESMWriter &esm) +void Skill::save(ESMWriter &esm) const { esm.writeHNT("INDX", mIndex); esm.writeHNT("SKDT", mData, 24); diff --git a/components/esm/loadskil.hpp b/components/esm/loadskil.hpp index 384f87454..2436173cb 100644 --- a/components/esm/loadskil.hpp +++ b/components/esm/loadskil.hpp @@ -75,7 +75,7 @@ struct Skill static const boost::array sSkillIds; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID/index). diff --git a/components/esm/loadsndg.cpp b/components/esm/loadsndg.cpp index 42d524226..9b992c960 100644 --- a/components/esm/loadsndg.cpp +++ b/components/esm/loadsndg.cpp @@ -13,7 +13,7 @@ void SoundGenerator::load(ESMReader &esm) mCreature = esm.getHNOString("CNAM"); mSound = esm.getHNOString("SNAM"); } -void SoundGenerator::save(ESMWriter &esm) +void SoundGenerator::save(ESMWriter &esm) const { esm.writeHNT("DATA", mType, 4); esm.writeHNOCString("CNAM", mCreature); diff --git a/components/esm/loadsndg.hpp b/components/esm/loadsndg.hpp index a6226c154..2756676ef 100644 --- a/components/esm/loadsndg.hpp +++ b/components/esm/loadsndg.hpp @@ -33,7 +33,7 @@ struct SoundGenerator std::string mId, mCreature, mSound; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; } #endif diff --git a/components/esm/loadsoun.cpp b/components/esm/loadsoun.cpp index 07af2b5e9..0f6b0f84a 100644 --- a/components/esm/loadsoun.cpp +++ b/components/esm/loadsoun.cpp @@ -17,7 +17,7 @@ void Sound::load(ESMReader &esm) << endl; */ } -void Sound::save(ESMWriter &esm) +void Sound::save(ESMWriter &esm) const { esm.writeHNCString("FNAM", mSound); esm.writeHNT("DATA", mData, 3); diff --git a/components/esm/loadsoun.hpp b/components/esm/loadsoun.hpp index f8e38ac09..6c9bb1fed 100644 --- a/components/esm/loadsoun.hpp +++ b/components/esm/loadsoun.hpp @@ -20,7 +20,7 @@ struct Sound std::string mId, mSound; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID/index). diff --git a/components/esm/loadspel.cpp b/components/esm/loadspel.cpp index 8149fe4ce..5c0bd956f 100644 --- a/components/esm/loadspel.cpp +++ b/components/esm/loadspel.cpp @@ -13,7 +13,7 @@ void Spell::load(ESMReader &esm) mEffects.load(esm); } -void Spell::save(ESMWriter &esm) +void Spell::save(ESMWriter &esm) const { esm.writeHNOCString("FNAM", mName); esm.writeHNT("SPDT", mData, 12); diff --git a/components/esm/loadspel.hpp b/components/esm/loadspel.hpp index 3a620962d..b34bd29f1 100644 --- a/components/esm/loadspel.hpp +++ b/components/esm/loadspel.hpp @@ -42,7 +42,7 @@ struct Spell EffectList mEffects; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID/index). diff --git a/components/esm/loadsscr.cpp b/components/esm/loadsscr.cpp index ae50de517..f51b7be47 100644 --- a/components/esm/loadsscr.cpp +++ b/components/esm/loadsscr.cpp @@ -11,7 +11,7 @@ void StartScript::load(ESMReader &esm) mData = esm.getHNString("DATA"); mScript = esm.getHNString("NAME"); } -void StartScript::save(ESMWriter &esm) +void StartScript::save(ESMWriter &esm) const { esm.writeHNString("DATA", mData); esm.writeHNString("NAME", mScript); diff --git a/components/esm/loadsscr.hpp b/components/esm/loadsscr.hpp index 713fe96b5..2326f00f4 100644 --- a/components/esm/loadsscr.hpp +++ b/components/esm/loadsscr.hpp @@ -24,7 +24,7 @@ struct StartScript // Load a record and add it to the list void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; } diff --git a/components/esm/loadstat.cpp b/components/esm/loadstat.cpp index c9346dafc..38206422b 100644 --- a/components/esm/loadstat.cpp +++ b/components/esm/loadstat.cpp @@ -10,7 +10,7 @@ void Static::load(ESMReader &esm) { mModel = esm.getHNString("MODL"); } -void Static::save(ESMWriter &esm) +void Static::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); } diff --git a/components/esm/loadstat.hpp b/components/esm/loadstat.hpp index 1adb7d05b..df42c0c49 100644 --- a/components/esm/loadstat.hpp +++ b/components/esm/loadstat.hpp @@ -25,7 +25,7 @@ struct Static std::string mId, mModel; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/loadweap.cpp b/components/esm/loadweap.cpp index 253712396..e21d8924a 100644 --- a/components/esm/loadweap.cpp +++ b/components/esm/loadweap.cpp @@ -15,7 +15,7 @@ void Weapon::load(ESMReader &esm) mIcon = esm.getHNOString("ITEX"); mEnchant = esm.getHNOString("ENAM"); } -void Weapon::save(ESMWriter &esm) +void Weapon::save(ESMWriter &esm) const { esm.writeHNCString("MODL", mModel); esm.writeHNOCString("FNAM", mName); diff --git a/components/esm/loadweap.hpp b/components/esm/loadweap.hpp index b62179ccb..42810d3af 100644 --- a/components/esm/loadweap.hpp +++ b/components/esm/loadweap.hpp @@ -59,7 +59,7 @@ struct Weapon std::string mId, mName, mModel, mIcon, mEnchant, mScript; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; void blank(); ///< Set record to default state (does not touch the ID). diff --git a/components/esm/spelllist.cpp b/components/esm/spelllist.cpp index dd886cf7f..24d3c3d0a 100644 --- a/components/esm/spelllist.cpp +++ b/components/esm/spelllist.cpp @@ -12,9 +12,9 @@ void SpellList::load(ESMReader &esm) } } -void SpellList::save(ESMWriter &esm) +void SpellList::save(ESMWriter &esm) const { - for (std::vector::iterator it = mList.begin(); it != mList.end(); ++it) { + for (std::vector::const_iterator it = mList.begin(); it != mList.end(); ++it) { esm.writeHNString("NPCS", *it, 32); } } diff --git a/components/esm/spelllist.hpp b/components/esm/spelllist.hpp index 52999270a..934bdda7a 100644 --- a/components/esm/spelllist.hpp +++ b/components/esm/spelllist.hpp @@ -17,7 +17,7 @@ namespace ESM std::vector mList; void load(ESMReader &esm); - void save(ESMWriter &esm); + void save(ESMWriter &esm) const; }; } From bf0fba68af5926ee3abd03ce77d43132315ba6f9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 16 Sep 2013 12:51:57 +0200 Subject: [PATCH 038/118] added save stage for globals --- apps/opencs/model/doc/document.cpp | 6 +-- apps/opencs/model/doc/saving.cpp | 9 +++- apps/opencs/model/doc/savingstages.hpp | 62 ++++++++++++++++++++++++++ components/esm/esmwriter.hpp | 2 +- 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 9b2217559..525f18a20 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2058,9 +2058,9 @@ void CSMDoc::Document::addOptionalGlobals() { static const char *sGlobals[] = { - "dayspassed", - "pcwerewolf", - "pcyear", + "DaysPassed", + "PCWerewolf", + "PCYear", 0 }; diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index 67073ca43..e0180bee4 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -1,9 +1,14 @@ #include "saving.hpp" -#include "state.hpp" +#include + +#include "../world/data.hpp" +#include "../world/idcollection.hpp" +#include "state.hpp" #include "savingstages.hpp" +#include "document.hpp" CSMDoc::Saving::Saving (Document& document) : Operation (State_Saving, true, true), mDocument (document), mState (*this) @@ -12,6 +17,8 @@ CSMDoc::Saving::Saving (Document& document) appendStage (new WriteHeaderStage (mDocument, mState)); + appendStage (new WriteCollectionStage > + (mDocument.getData().getGlobals(), mState, ESM::REC_GLOB)); appendStage (new CloseSaveStage (mState)); diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index 914a2d585..9787679c6 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -1,8 +1,14 @@ #ifndef CSM_DOC_SAVINGSTAGES_H #define CSM_DOC_SAVINGSTAGES_H +#include + #include "stage.hpp" +#include "savingstate.hpp" + +#include "../world/record.hpp" + namespace CSMDoc { class Document; @@ -40,6 +46,62 @@ namespace CSMDoc ///< Messages resulting from this stage will be appended to \a messages. }; + + template + class WriteCollectionStage : public Stage + { + const CollectionT& mCollection; + SavingState& mState; + ESM::RecNameInts mRecordType; + + public: + + WriteCollectionStage (const CollectionT& collection, SavingState& state, + ESM::RecNameInts recordType); + + virtual int setup(); + ///< \return number of steps + + virtual void perform (int stage, std::vector& messages); + ///< Messages resulting from this stage will be appended to \a messages. + }; + + template + WriteCollectionStage::WriteCollectionStage (const CollectionT& collection, + SavingState& state, ESM::RecNameInts recordType) + : mCollection (collection), mState (state), mRecordType (recordType) + {} + + template + int WriteCollectionStage::setup() + { + return mCollection.getSize(); + } + + template + void WriteCollectionStage::perform (int stage, std::vector& messages) + { + CSMWorld::RecordBase::State state = mCollection.getRecord (stage).mState; + + if (state==CSMWorld::RecordBase::State_Modified || + state==CSMWorld::RecordBase::State_ModifiedOnly) + { + std::string type; + for (int i=0; i<4; ++i) + /// \todo make endianess agnostic (change ESMWriter interface?) + type += reinterpret_cast (&mRecordType)[i]; + + mState.getWriter().startRecord (type); + mCollection.getRecord (stage).mModified.save (mState.getWriter()); + mState.getWriter().endRecord (type); + } + else if (state==CSMWorld::RecordBase::State_Deleted) + { + /// \todo write record with delete flag + } + } + + class CloseSaveStage : public Stage { SavingState& mState; diff --git a/components/esm/esmwriter.hpp b/components/esm/esmwriter.hpp index b0925463a..fc64c4a13 100644 --- a/components/esm/esmwriter.hpp +++ b/components/esm/esmwriter.hpp @@ -90,7 +90,7 @@ class ESMWriter write((char*)&data, size); } - void startRecord(const std::string& name, uint32_t flags); + void startRecord(const std::string& name, uint32_t flags = 0); void startSubRecord(const std::string& name); void endRecord(const std::string& name); void writeHString(const std::string& data); From 03054c816071bd53800d59c95170b18dcc8c8241 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 16 Sep 2013 14:10:05 +0200 Subject: [PATCH 039/118] forgot to write record ID --- apps/opencs/model/doc/savingstages.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index 9787679c6..96b1fe17f 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -92,6 +92,7 @@ namespace CSMDoc type += reinterpret_cast (&mRecordType)[i]; mState.getWriter().startRecord (type); + mState.getWriter().writeHNCString ("NAME", mCollection.getId (stage)); mCollection.getRecord (stage).mModified.save (mState.getWriter()); mState.getWriter().endRecord (type); } From acfd78c62ad6ee84c7160e1772dcdc19fd96d831 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 16 Sep 2013 14:17:04 +0200 Subject: [PATCH 040/118] implemented saving for all supported record types except cells, referencables and references --- apps/opencs/model/doc/saving.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index e0180bee4..7e0b10d66 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -20,6 +20,36 @@ CSMDoc::Saving::Saving (Document& document) appendStage (new WriteCollectionStage > (mDocument.getData().getGlobals(), mState, ESM::REC_GLOB)); + appendStage (new WriteCollectionStage > + (mDocument.getData().getGmsts(), mState, ESM::REC_GMST)); + + appendStage (new WriteCollectionStage > + (mDocument.getData().getSkills(), mState, ESM::REC_SKIL)); + + appendStage (new WriteCollectionStage > + (mDocument.getData().getClasses(), mState, ESM::REC_CLAS)); + + appendStage (new WriteCollectionStage > + (mDocument.getData().getFactions(), mState, ESM::REC_FACT)); + + appendStage (new WriteCollectionStage > + (mDocument.getData().getRaces(), mState, ESM::REC_RACE)); + + appendStage (new WriteCollectionStage > + (mDocument.getData().getSounds(), mState, ESM::REC_SOUN)); + + appendStage (new WriteCollectionStage > + (mDocument.getData().getScripts(), mState, ESM::REC_SCPT)); + + appendStage (new WriteCollectionStage > + (mDocument.getData().getRegions(), mState, ESM::REC_REGN)); + + appendStage (new WriteCollectionStage > + (mDocument.getData().getBirthsigns(), mState, ESM::REC_BSGN)); + + appendStage (new WriteCollectionStage > + (mDocument.getData().getSpells(), mState, ESM::REC_SPEL)); + appendStage (new CloseSaveStage (mState)); From 0eb06ada39ca9ca8857325e816b61048348d896c Mon Sep 17 00:00:00 2001 From: graffy76 Date: Wed, 18 Sep 2013 02:36:23 -0500 Subject: [PATCH 041/118] Implemneting drag and drop --- apps/launcher/datafilespage.cpp | 32 +- apps/launcher/datafilespage.hpp | 1 + components/CMakeLists.txt | 2 +- components/esxselector/model/contentmodel.cpp | 327 +++++++----- components/esxselector/model/contentmodel.hpp | 9 +- .../esxselector/model/datafilesmodel.cpp | 482 ++++++++++-------- components/esxselector/model/esmfile.cpp | 64 ++- components/esxselector/model/esmfile.hpp | 28 +- .../esxselector/model/masterproxymodel.cpp | 31 -- .../esxselector/model/pluginsproxymodel.cpp | 26 - .../esxselector/view/contentselector.cpp | 146 +++--- .../esxselector/view/contentselector.hpp | 13 +- 12 files changed, 650 insertions(+), 511 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 070f455e4..7069737ef 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -7,7 +7,6 @@ #include -#include #include #include @@ -20,6 +19,7 @@ #include "settings/launchersettings.hpp" #include "utils/textinputdialog.hpp" +#include "components/esxselector/view/contentselector.hpp" #include @@ -27,8 +27,8 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam : mCfgMgr(cfg) , mGameSettings(gameSettings) , mLauncherSettings(launcherSettings) - , ContentSelector(parent) { + mContentSelector.setParent(parent); QMetaObject::connectSlotsByName(this); projectGroupBox->hide(); @@ -51,24 +51,21 @@ void DataFilesPage::createActions() void DataFilesPage::setupDataFiles() { - if (!mDataFilesModel) - qDebug() << "data files model undefined"; - // Set the encoding to the one found in openmw.cfg or the default - mDataFilesModel->setEncoding(mGameSettings.value(QString("encoding"), QString("win1252"))); + mContentSelector.setEncoding(mGameSettings.value(QString("encoding"), QString("win1252"))); QStringList paths = mGameSettings.getDataDirs(); foreach (const QString &path, paths) { - mDataFilesModel->addFiles(path); + mContentSelector.addFiles(path); } QString dataLocal = mGameSettings.getDataLocal(); if (!dataLocal.isEmpty()) - mDataFilesModel->addFiles(dataLocal); + mContentSelector.addFiles(dataLocal); // Sort by date accessed for now - mDataFilesModel->sort(3); + //mContentSelector->sort(3); QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/")); QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); @@ -107,11 +104,11 @@ void DataFilesPage::loadSettings() if (profile.isEmpty()) return; - mDataFilesModel->uncheckAll(); + // 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()) @@ -123,12 +120,13 @@ void DataFilesPage::loadSettings() if (index.isValid()) mDataFilesModel->setCheckState(index, Qt::Checked); } + */ } void DataFilesPage::saveSettings() { - if (mDataFilesModel->rowCount() < 1) - return; +// if (mDataFilesModel->rowCount() < 1) +// return; QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); @@ -143,8 +141,8 @@ void DataFilesPage::saveSettings() mGameSettings.remove(QString("master")); mGameSettings.remove(QString("plugin")); - EsxModel::EsmFileList items = mDataFilesModel->checkedItems(); - + // EsxModel::EsmFileList items = mDataFilesModel->checkedItems(); +/* foreach(const EsxModel::EsmFile *item, items) { if (item->masters().size() == 0) { @@ -156,7 +154,7 @@ void DataFilesPage::saveSettings() mGameSettings.setMultiValue(QString("plugin"), item->fileName()); } } - +*/ } void DataFilesPage::updateOkButton(const QString &text) @@ -241,7 +239,7 @@ void DataFilesPage::setPluginsCheckstates(Qt::CheckState state) if (!sourceIndex.isValid()) return; - mDataFilesModel->setCheckState(sourceIndex, state); + //mDataFilesModel->setCheckState(sourceIndex, state); } } diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index f3792b1f1..ed92da749 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -52,6 +52,7 @@ private slots: private: QMenu *mContextMenu; + ContentSelector mContentSelector; Files::ConfigurationManager &mCfgMgr; diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 0f7c5017b..b79fa027e 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -72,7 +72,7 @@ find_package(Qt4 COMPONENTS QtCore QtGui) if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) add_component_qt_dir (esxselector - model/masterproxymodel model/modelitem model/datafilesmodel + model/masterproxymodel model/modelitem model/pluginsproxymodel model/esmfile model/naturalsort model/contentmodel view/profilescombobox view/comboboxlineedit diff --git a/components/esxselector/model/contentmodel.cpp b/components/esxselector/model/contentmodel.cpp index 673665775..bfbb1bef7 100644 --- a/components/esxselector/model/contentmodel.cpp +++ b/components/esxselector/model/contentmodel.cpp @@ -21,26 +21,60 @@ int EsxModel::ContentModel::columnCount(const QModelIndex &parent) const return 1; } -/* -QModelIndex EsxModel::ContentModel::parent(const QModelIndex &child) const + +int EsxModel::ContentModel::rowCount(const QModelIndex &parent) const { - if(!child.isValid()) + if(parent.isValid()) return 0; - return child.parent(); + return mFiles.size(); } -QModelIndex EsxModel::ContentModel::index(int row, int column, const QModelIndex &parent) const +EsxModel::EsmFile* EsxModel::ContentModel::item(int row) const { + if (row >= 0 && row < mFiles.count()) + return mFiles.at(row); + return 0; } -*/ -int EsxModel::ContentModel::rowCount(const QModelIndex &parent) const + +EsxModel::EsmFile* EsxModel::ContentModel::findItem(const QString &name) { - if(parent.isValid()) - return 0; + for (int i = 0; i < mFiles.size(); ++i) + { + if (name == item(i)->fileName()) + return item(i); + } - return mFiles.size(); + return 0; +} + +QModelIndex EsxModel::ContentModel::indexFromItem(EsmFile *item) const +{ + if (item) + return index(mFiles.indexOf(item),0); + + return QModelIndex(); +} + +Qt::ItemFlags EsxModel::ContentModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + + 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; } QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const @@ -70,18 +104,14 @@ QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const case 1: return file->author(); case 2: - return QString("%1 kB").arg(int((file->size() + 1023) / 1024)); - case 3: return file->modified().toString(Qt::ISODate); - case 4: - return file->accessed().toString(Qt::TextDate); - case 5: + case 3: return file->version(); - case 6: + case 4: return file->path(); - case 7: + case 5: return file->masters().join(", "); - case 8: + case 6: return file->description(); } @@ -97,8 +127,6 @@ QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const return Qt::AlignLeft + Qt::AlignVCenter; case 2: case 3: - case 4: - case 5: return Qt::AlignRight + Qt::AlignVCenter; default: return Qt::AlignLeft + Qt::AlignVCenter; @@ -124,47 +152,88 @@ QVariant EsxModel::ContentModel::data(const QModelIndex &index, int role) const .arg(file->masters().join(", ")); } + case Qt::CheckStateRole: + if (!file->isMaster()) + return isChecked(file->fileName()); + break; + case Qt::UserRole: { - if (file->masters().size() == 0) + if (file->isMaster()) return "game"; else return "addon"; } - default: - return QVariant(); + case Qt::UserRole + 1: + return isChecked(file->fileName()); + break; } + return QVariant(); } -Qt::ItemFlags EsxModel::ContentModel::flags(const QModelIndex &index) const +bool EsxModel::ContentModel::setData(const QModelIndex &index, const QVariant &value, int role) { - if (!index.isValid()) - return Qt::NoItemFlags; + if(!index.isValid()) + return false; EsmFile *file = item(index.row()); + QString fileName = file->fileName(); - if (!file) - return Qt::NoItemFlags; + switch(role) + { + case Qt::EditRole: + { + QStringList list = value.toStringList(); - Qt::ItemFlags dragDropFlags = Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; - Qt::ItemFlags checkFlags = Qt::ItemIsUserCheckable; - Qt::ItemFlags defaultFlags = Qt::ItemIsDropEnabled | Qt::ItemIsSelectable; + //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)); - if (canBeChecked(file)) - return Qt::ItemIsEnabled | dragDropFlags | checkFlags | defaultFlags; - else - return defaultFlags; -} + //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)); -bool EsxModel::ContentModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (index.isValid() && role == Qt::EditRole) - { - QString fname = value.value(); - mFiles.replace(index.row(), findItem(fname)); - emit dataChanged(index, index); - return true; + //emit data changed for the item itself + emit dataChanged(index, index); + + return true; + } + break; + + case Qt::UserRole+1: + { + setCheckState(fileName, value.toBool()); + + emit dataChanged(index, index); + + for(int i = 0; i < mFiles.size(); i++) + { + + if (mFiles.at(i)->masters().contains(fileName)) + { + QModelIndex idx = QAbstractTableModel::index(i, 0); + emit dataChanged(idx, idx); + } + } + + return true; + } + break; + + case Qt::CheckStateRole: + { + bool checked = ((value.toInt() == Qt::Checked) && !isChecked(fileName)); + + setCheckState(fileName, checked); + + emit dataChanged(index, index); + + return true; + } + break; } return false; @@ -172,24 +241,31 @@ bool EsxModel::ContentModel::setData(const QModelIndex &index, const QVariant &v bool EsxModel::ContentModel::insertRows(int position, int rows, const QModelIndex &parent) { + if (parent.isValid()) + return false; + beginInsertRows(parent, position, position+rows-1); + { + for (int row = 0; row < rows; ++row) + mFiles.insert(position, new EsmFile); - for (int row = 0; row < rows; ++row) - mFiles.insert(position, new EsmFile); + } endInsertRows(); - endInsertRows(); return true; } bool EsxModel::ContentModel::removeRows(int position, int rows, const QModelIndex &parent) { + if (parent.isValid()) + return false; + beginRemoveRows(parent, position, position+rows-1); + { + for (int row = 0; row < rows; ++row) + delete mFiles.takeAt(position); - for (int row = 0; row < rows; ++row) - mFiles.removeAt(position); + } endRemoveRows(); - endRemoveRows(); - emit dataChanged(index(0,0,parent), index(rowCount()-1, 0, parent)); return true; } @@ -201,27 +277,30 @@ Qt::DropActions EsxModel::ContentModel::supportedDropActions() const QStringList EsxModel::ContentModel::mimeTypes() const { QStringList types; + types << "application/omwcontent"; + return types; } QMimeData *EsxModel::ContentModel::mimeData(const QModelIndexList &indexes) const { - QMimeData *mimeData = new QMimeData(); QByteArray encodedData; - QDataStream stream(&encodedData, QIODevice::WriteOnly); - foreach (const QModelIndex &index, indexes) { - if (index.isValid()) - { - QString text = data(index, Qt::DisplayRole).toString(); - stream << text; - } + if (!index.isValid()) + continue; + + QByteArray fileData = item(index.row())->encodedData(); + + foreach (const char c, fileData) + encodedData.append(c); } + QMimeData *mimeData = new QMimeData(); mimeData->setData("application/omwcontent", encodedData); + return mimeData; } @@ -240,31 +319,66 @@ bool EsxModel::ContentModel::dropMimeData(const QMimeData *data, Qt::DropAction if (row != -1) beginRow = row; + else if (parent.isValid()) beginRow = parent.row(); + else beginRow = rowCount(); QByteArray encodedData = data->data("application/omwcontent"); QDataStream stream(&encodedData, QIODevice::ReadOnly); - QStringList newItems; - int rows = 0; while (!stream.atEnd()) { - QString text; - stream >> text; - newItems << text; - ++rows; + QStringList values; + + for (int i = 0; i < EsmFile::sPropertyCount; ++i) + stream >> values; + + insertRows(beginRow, 1); + + QModelIndex idx = index(beginRow++, 0, QModelIndex()); + setData(idx, values, Qt::EditRole); } - insertRows(beginRow, rows, QModelIndex()); + return true; +} - foreach (const QString &text, newItems) +bool EsxModel::ContentModel::canBeChecked(const EsmFile *file) const +{ + //element can be checked if all its dependencies are + foreach (const QString &master, file->masters()) { - QModelIndex idx = index(beginRow, 0, QModelIndex()); - setData(idx, text); - beginRow++; + {// 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) + return false; } return true; @@ -272,9 +386,10 @@ bool EsxModel::ContentModel::dropMimeData(const QMimeData *data, Qt::DropAction void EsxModel::ContentModel::addFile(EsmFile *file) { - emit beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); - mFiles.append(file); - emit endInsertRows(); + beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); + { + mFiles.append(file); + } endInsertRows(); } void EsxModel::ContentModel::addFiles(const QString &path) @@ -319,9 +434,9 @@ void EsxModel::ContentModel::addFiles(const QString &path) } file->setAuthor(decoder->toUnicode(fileReader.getAuthor().c_str())); - file->setSize(info.size()); - file->setDates(info.lastModified(), info.lastRead()); - file->setVersion(fileReader.getFVer()); + //file->setSize(info.size()); + file->setDate(info.lastModified()); + file->setVersion(0.0f); file->setPath(info.absoluteFilePath()); file->setMasters(masters); file->setDescription(decoder->toUnicode(fileReader.getDesc().c_str())); @@ -342,66 +457,22 @@ void EsxModel::ContentModel::addFiles(const QString &path) delete decoder; } -EsxModel::EsmFile* EsxModel::ContentModel::findItem(const QString &name) -{ - for (int i = 0; i < mFiles.size(); ++i) - { - if (name == item(i)->fileName()) - return item(i); - } - - // Not found - return 0; -} - -EsxModel::EsmFile* EsxModel::ContentModel::item(int row) const -{ - if (row >= 0 && row < mFiles.count()) - return mFiles.at(row); - - return 0; -} - -QModelIndex EsxModel::ContentModel::indexFromItem(EsmFile *item) const +bool EsxModel::ContentModel::isChecked(const QString& name) const { - if (item) - //return createIndex(mFiles.indexOf(item), 0); - return index(mFiles.indexOf(item),0); - - return QModelIndex(); + return (mCheckStates[name] == Qt::Checked); } -Qt::CheckState EsxModel::ContentModel::checkState(const QModelIndex &index) +void EsxModel::ContentModel::setCheckState(const QString &name, bool isChecked) { - return mCheckStates[item(index.row())->fileName()]; -} - -void EsxModel::ContentModel::setCheckState(const QModelIndex &index, Qt::CheckState state) -{ - if (!index.isValid()) + if (name.isEmpty()) 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()); + Qt::CheckState state = Qt::Unchecked; - emit dataChanged(firstIndex, lastIndex); - //emit checkedItemsChanged(checkedItems()); + if (isChecked) + state = Qt::Checked; -} - -bool EsxModel::ContentModel::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; + mCheckStates[name] = state; } EsxModel::ContentFileList EsxModel::ContentModel::checkedItems() const diff --git a/components/esxselector/model/contentmodel.hpp b/components/esxselector/model/contentmodel.hpp index a585ab63b..61c823ab3 100644 --- a/components/esxselector/model/contentmodel.hpp +++ b/components/esxselector/model/contentmodel.hpp @@ -37,14 +37,11 @@ namespace EsxModel QModelIndex indexFromItem(EsmFile *item) const; EsxModel::EsmFile *findItem(const QString &name); - Qt::CheckState checkState(const QModelIndex &index); - void setCheckState(const QModelIndex &index, Qt::CheckState state); + bool isChecked(const QString &name) const; + void setCheckState(const QString &name, bool isChecked); ContentFileList checkedItems() const; void uncheckAll(); -/* - QModelIndex index(int row, int column, const QModelIndex &parent) const; - QModelIndex parent(const QModelIndex &child) const; -*/ + private: void addFile(EsmFile *file); diff --git a/components/esxselector/model/datafilesmodel.cpp b/components/esxselector/model/datafilesmodel.cpp index ee940bb27..c98f70b16 100644 --- a/components/esxselector/model/datafilesmodel.cpp +++ b/components/esxselector/model/datafilesmodel.cpp @@ -24,56 +24,55 @@ EsxModel::DataFilesModel::~DataFilesModel() { } -void EsxModel::DataFilesModel::setEncoding(const QString &encoding) +int EsxModel::DataFilesModel::rowCount(const QModelIndex &parent) const { - mEncoding = encoding; + return parent.isValid() ? 0 : mFiles.count(); } -void EsxModel::DataFilesModel::setCheckState(const QModelIndex &index, Qt::CheckState state) +int EsxModel::DataFilesModel::columnCount(const QModelIndex &parent) const { - if (!index.isValid()) - return; - - QString name = item(index.row())->fileName(); - mCheckStates[name] = state; + return parent.isValid() ? 0 : 1; +} - // Force a redraw of the view since unchecking one item can affect another - QModelIndex firstIndex = indexFromItem(mFiles.first()); - QModelIndex lastIndex = indexFromItem(mFiles.last()); +const EsxModel::EsmFile* EsxModel::DataFilesModel::findItem(const QString &name) +{ + for (int i = 0; i < mFiles.size(); ++i) + { + const EsmFile *file = item(i); - emit dataChanged(firstIndex, lastIndex); - emit checkedItemsChanged(checkedItems()); + if (name == file->fileName()) + return file; + } + return 0; } -Qt::CheckState EsxModel::DataFilesModel::checkState(const QModelIndex &index) +const EsxModel::EsmFile* EsxModel::DataFilesModel::item(int row) const { - return mCheckStates[item(index.row())->fileName()]; -} + if (row >= 0 && row < mFiles.count()) + return mFiles.at(row); -int EsxModel::DataFilesModel::columnCount(const QModelIndex &parent) const -{ - return parent.isValid() ? 0 : 1; + return 0; } -int EsxModel::DataFilesModel::rowCount(const QModelIndex &parent) const +Qt::ItemFlags EsxModel::DataFilesModel::flags(const QModelIndex &index) const { - return parent.isValid() ? 0 : mFiles.count(); -} + if (!index.isValid()) + return Qt::NoItemFlags; + const EsmFile *file = item(index.row()); -bool EsxModel::DataFilesModel::moveRow(int oldrow, int row, const QModelIndex &parent) -{ - if (oldrow < 0 || row < 0 || oldrow == row) - return false; + if (!file) + return Qt::NoItemFlags; - emit layoutAboutToBeChanged(); - //emit beginMoveRows(parent, oldrow, oldrow, parent, row); - mFiles.swap(oldrow, row); - //emit endInsertRows(); - emit layoutChanged(); + Qt::ItemFlags dragDropFlags = Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; + Qt::ItemFlags checkFlags = Qt::ItemIsUserCheckable | Qt::ItemIsEditable; + Qt::ItemFlags defaultFlags = Qt::ItemIsDropEnabled | Qt::ItemIsSelectable; - return true; + if (canBeChecked(file)) + return defaultFlags | dragDropFlags | checkFlags | Qt::ItemIsEnabled; + else + return defaultFlags; } QVariant EsxModel::DataFilesModel::data(const QModelIndex &index, int role) const @@ -81,6 +80,9 @@ QVariant EsxModel::DataFilesModel::data(const QModelIndex &index, int role) cons if (!index.isValid()) return QVariant(); + if (index.row() >= mFiles.size()) + return QVariant(); + const EsmFile *file = item(index.row()); if (!file) @@ -88,46 +90,46 @@ QVariant EsxModel::DataFilesModel::data(const QModelIndex &index, int role) cons const int column = index.column(); - switch (role) { + switch (role) + { case Qt::EditRole: - case Qt::DisplayRole: { + case Qt::DisplayRole: + { - switch (column) { + switch (column) + { case 0: return file->fileName(); case 1: return file->author(); case 2: - return QString("%1 kB").arg(int((file->size() + 1023) / 1024)); - case 3: - //return file->modified().toString(Qt::TextDate); return file->modified().toString(Qt::ISODate); - case 4: - return file->accessed().toString(Qt::TextDate); - case 5: + case 3: return file->version(); - case 6: + case 4: return file->path(); - case 7: + case 5: return file->masters().join(", "); - case 8: + case 6: return file->description(); } + break; } - case Qt::TextAlignmentRole: { - switch (column) { + case Qt::TextAlignmentRole: + { + switch (column) + { case 0: case 1: return Qt::AlignLeft + Qt::AlignVCenter; case 2: case 3: - case 4: - case 5: - return Qt::AlignRight + Qt::AlignVCenter; + return Qt::AlignRight + Qt::AlignVCenter; default: return Qt::AlignLeft + Qt::AlignVCenter; } + break; } case Qt::ToolTipRole: @@ -150,7 +152,7 @@ QVariant EsxModel::DataFilesModel::data(const QModelIndex &index, int role) cons return tooltip; - + break; } case Qt::UserRole: @@ -159,39 +161,242 @@ QVariant EsxModel::DataFilesModel::data(const QModelIndex &index, int role) cons return "game"; else return "addon"; + + break; } + case Qt::UserRole + 1: + //return check state here + break; + default: return QVariant(); + break; } } -Qt::ItemFlags EsxModel::DataFilesModel::flags(const QModelIndex &index) const +bool EsxModel::DataFilesModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid()) - return Qt::NoItemFlags; + return false; - const EsmFile *file = item(index.row()); + switch (role) + { + case Qt::EditRole: + { + const EsmFile *file = item(index.row()); - Qt::ItemFlags dragDropFlags = Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; - Qt::ItemFlags checkFlags = Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; + // 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)); + } - if (!file) - return Qt::NoItemFlags; + //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); - if (canBeChecked(file)) + 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.column() == 0) - return dragDropFlags | checkFlags | Qt::ItemIsEnabled; + 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 - return Qt::ItemIsDropEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable; + dropRow = rowCount(QModelIndex()); } - if (index.column() == 0) - return dragDropFlags | checkFlags; + 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; - return Qt::ItemIsDropEnabled | Qt::ItemIsSelectable; + 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 @@ -215,22 +420,6 @@ QVariant EsxModel::DataFilesModel::headerData(int section, Qt::Orientation orien return QVariant(); } -bool EsxModel::DataFilesModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (!index.isValid()) - return false; - - if (role == Qt::EditRole) - { - qDebug() << "replacing: " << mFiles.at(index.row())->fileName(); -// mFiles.replace(index.row(), value.value()); - qDebug() << "with: " << mFiles.at(index.row())->fileName(); - emit dataChanged(index, index); - return true; - } - - return false; -} //!!!!!!!!!!!!!!!!!!!!!!! bool lessThanEsmFile(const EsxModel::EsmFile *e1, const EsxModel::EsmFile *e2) { @@ -345,32 +534,6 @@ QModelIndex EsxModel::DataFilesModel::indexFromItem(const EsmFile *item) const return QModelIndex(); } -const EsxModel::EsmFile* EsxModel::DataFilesModel::findItem(const QString &name) -{ - 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 (name == file->fileName()) - return file; - } - - // Not found - return 0; -} - -const EsxModel::EsmFile* EsxModel::DataFilesModel::item(int row) const -{ - if (row >= 0 && row < mFiles.count()) - return mFiles.at(row); - - return 0; -} - EsxModel::EsmFileList EsxModel::DataFilesModel::checkedItems() { EsmFileList list; @@ -443,110 +606,3 @@ bool EsxModel::DataFilesModel::canBeChecked(const EsmFile *file) const } 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 -{ -// if (indexes.at(0).isValid()) -// return new EsmFile(*item(indexes.at(0).row())); - - return 0; -} - -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; -} - -bool EsxModel::DataFilesModel::insertRows(int row, int count, const QModelIndex &parent) -{ - qDebug() << "inserting row: " << row << " count: " << count; - beginInsertRows(QModelIndex(),row, row+count-1); - - EsmFile *file = new EsmFile(); - - for (int i = 0; i < count; ++i) - mFiles.insert(row + i, file); - - endInsertRows(); - return true; -} - -bool EsxModel::DataFilesModel::removeRows(int row, int count, const QModelIndex &parent) -{ - qDebug() << "removing row: " << row << " count: " << count; - beginRemoveRows(QModelIndex(), row, row+count-1); - - for (int i = 0; i < count; ++i) - { - mFiles.removeAt(i); - } - - endRemoveRows(); - qDebug() <<"remove success"; - - emit dataChanged(parent, index(rowCount()-1, 0, parent)); - return true; -} - diff --git a/components/esxselector/model/esmfile.cpp b/components/esxselector/model/esmfile.cpp index 95cf70312..0e7f18373 100644 --- a/components/esxselector/model/esmfile.cpp +++ b/components/esxselector/model/esmfile.cpp @@ -1,7 +1,12 @@ #include "esmfile.hpp" +#include +#include + +int EsxModel::EsmFile::sPropertyCount = 7; + EsxModel::EsmFile::EsmFile(QString fileName, ModelItem *parent) - : ModelItem(parent), mFileName(fileName), mSize(0), mVersion(0.0f) + : ModelItem(parent), mFileName(fileName), mVersion(0.0f) {} /* EsxModel::EsmFile::EsmFile(const EsmFile &file) @@ -22,15 +27,9 @@ void EsxModel::EsmFile::setAuthor(const QString &author) mAuthor = author; } -void EsxModel::EsmFile::setSize(const int size) -{ - mSize = size; -} - -void EsxModel::EsmFile::setDates(const QDateTime &modified, const QDateTime &accessed) +void EsxModel::EsmFile::setDate(const QDateTime &modified) { mModified = modified; - mAccessed = accessed; } void EsxModel::EsmFile::setVersion(float version) @@ -52,3 +51,52 @@ void EsxModel::EsmFile::setDescription(const QString &description) { mDescription = description; } + +QByteArray EsxModel::EsmFile::encodedData() const +{ + QByteArray encodedData; + QDataStream stream(&encodedData, QIODevice::WriteOnly); + + stream << mFileName << mAuthor << QString::number(mVersion) + << mModified.toString() << mPath << mDescription + << mMasters; + + return encodedData; +} + +void EsxModel::EsmFile::setProperty (const EsmFileProperty prop, const QString &value) +{ + switch (prop) + { + case Property_FileName: + mFileName = value; + break; + + case Property_Author: + mAuthor = value; + break; + + case Property_Version: + mVersion = value.toFloat(); + break; + + case Property_DateModified: + mModified = QDateTime::fromString(value); + break; + + case Property_Path: + mPath = value; + break; + + case Property_Description: + mDescription = value; + break; + + case Property_Master: + mMasters << value; + break; + + default: + break; + } +} diff --git a/components/esxselector/model/esmfile.hpp b/components/esxselector/model/esmfile.hpp index 0cda018b3..9a1ea8af1 100644 --- a/components/esxselector/model/esmfile.hpp +++ b/components/esxselector/model/esmfile.hpp @@ -6,8 +6,21 @@ #include "modelitem.hpp" +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 @@ -21,10 +34,12 @@ namespace EsxModel ~EsmFile() {} + void setProperty (const EsmFileProperty prop, const QString &value); + void setFileName(const QString &fileName); void setAuthor(const QString &author); void setSize(const int size); - void setDates(const QDateTime &modified, const QDateTime &accessed); + void setDate(const QDateTime &modified); void setVersion(const float version); void setPath(const QString &path); void setMasters(const QStringList &masters); @@ -32,22 +47,23 @@ namespace EsxModel inline QString fileName() const { return mFileName; } inline QString author() const { return mAuthor; } - inline int size() const { return mSize; } inline QDateTime modified() const { return mModified; } - inline QDateTime accessed() const { return mAccessed; } 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 ModelItem *parent() const { return ModelItem::parent(); this->} + inline bool isMaster() const { return (mMasters.size() == 0); } + QByteArray encodedData() const; + + public: + static int sPropertyCount; private: + QString mFileName; QString mAuthor; - int mSize; QDateTime mModified; - QDateTime mAccessed; float mVersion; QString mPath; QStringList mMasters; diff --git a/components/esxselector/model/masterproxymodel.cpp b/components/esxselector/model/masterproxymodel.cpp index 46d68ca51..df74d0356 100644 --- a/components/esxselector/model/masterproxymodel.cpp +++ b/components/esxselector/model/masterproxymodel.cpp @@ -10,35 +10,4 @@ EsxModel::MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableMode if (model) setSourceModel (model); - //connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(slotSourceModelChanged(QModelIndex, QModelIndex))); -} -/* -QVariant EsxModel::MasterProxyModel::data(const QModelIndex &index, int role) const -{ - if (index.isValid()) - return QSortFilterProxyModel::data (index, role); - - return 0; -} -*/ -void EsxModel::MasterProxyModel::slotSourceModelChanged(QModelIndex topLeft, QModelIndex botRight) -{ - qDebug() << "source data changed.. updating master proxy"; - emit dataChanged(index(0,0), index(rowCount()-1,0)); - - int curRow = -1; -/* - for (int i = 0; i < rowCount() - 1; ++i) - { - if (index(i,0).data(Qt::CheckState) == Qt::Checked) - { - curRow = i; - break; - } - } - - reset(); -*/ - if (curRow != -1); - // index(curRow, 0).setDataQt::CheckState) } diff --git a/components/esxselector/model/pluginsproxymodel.cpp b/components/esxselector/model/pluginsproxymodel.cpp index 412367b64..c543672b0 100644 --- a/components/esxselector/model/pluginsproxymodel.cpp +++ b/components/esxselector/model/pluginsproxymodel.cpp @@ -12,29 +12,3 @@ EsxModel::PluginsProxyModel::PluginsProxyModel(QObject *parent, ContentModel *mo if (model) setSourceModel (model); } - -EsxModel::PluginsProxyModel::~PluginsProxyModel() -{ -} - -QVariant EsxModel::PluginsProxyModel::data(const QModelIndex &index, int role) const -{ - switch (role) - { - case Qt::CheckStateRole: - { - if (index.column() != 0) - return QVariant(); - - return static_cast(sourceModel())->checkState(mapToSource(index)); - } - } - return QSortFilterProxyModel::data(index, role); -} - -bool EsxModel::PluginsProxyModel::removeRows(int position, int rows, const QModelIndex &parent) -{ - bool success = QSortFilterProxyModel::removeRows(position, rows, parent); - - return success; -} diff --git a/components/esxselector/view/contentselector.cpp b/components/esxselector/view/contentselector.cpp index bc7cc2b8b..1f5e36d65 100644 --- a/components/esxselector/view/contentselector.cpp +++ b/components/esxselector/view/contentselector.cpp @@ -1,8 +1,6 @@ #include "contentselector.hpp" #include "../model/datafilesmodel.hpp" -#include "../model/masterproxymodel.hpp" -#include "../model/pluginsproxymodel.hpp" #include "../model/contentmodel.hpp" #include "../model/esmfile.hpp" @@ -16,55 +14,73 @@ EsxView::ContentSelector::ContentSelector(QWidget *parent) : QDialog(parent) { setupUi(this); - // buildModelsAndViews(); - buildDragDropModelView(); + + buildSourceModel(); + buildMasterView(); + buildPluginsView(); + buildProfilesView(); + + updateViews(); + } -void EsxView::ContentSelector::buildDragDropModelView() + +void EsxView::ContentSelector::buildSourceModel() { mContentModel = new EsxModel::ContentModel(); + connect(mContentModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); +} - //mContentModel->addFiles("/home/joel/Projects/OpenMW/Data_Files"); - mMasterProxyModel = new EsxModel::MasterProxyModel(this, mContentModel); - mPluginsProxyModel = new EsxModel::PluginsProxyModel(this, mContentModel); - - tableView->setModel (mPluginsProxyModel); +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); - pluginView->setModel(mPluginsProxyModel); - - profilesComboBox->setPlaceholderText(QString("Select a profile...")); - updateViews(); - connect(pluginView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotPluginTableItemClicked(const QModelIndex &))); connect(masterView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentMasterIndexChanged(int))); - connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); - - connect(mContentModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); - connect(tableView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotPluginTableItemClicked(const QModelIndex &))); + masterView->setCurrentIndex(-1); + masterView->setCurrentIndex(0); } -void EsxView::ContentSelector::buildModelsAndViews() +void EsxView::ContentSelector::buildPluginsView() { - // Models - mDataFilesModel = new EsxModel::DataFilesModel (this); - - // mMasterProxyModel = new EsxModel::MasterProxyModel (this, mDataFilesModel); - // mPluginsProxyModel = new EsxModel::PluginsProxyModel (this, mDataFilesModel); + mPluginsProxyModel = new QSortFilterProxyModel(this); + mPluginsProxyModel->setFilterRegExp (QString("addon")); + mPluginsProxyModel->setFilterRole (Qt::UserRole); + mPluginsProxyModel->setDynamicSortFilter (true); + mPluginsProxyModel->setSourceModel (mContentModel); - masterView->setPlaceholderText(QString("Select a game file...")); - masterView->setModel(mMasterProxyModel); + tableView->setModel (mPluginsProxyModel); pluginView->setModel(mPluginsProxyModel); - profilesComboBox->setPlaceholderText(QString("Select a profile...")); - updateViews(); - connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); connect(pluginView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotPluginTableItemClicked(const QModelIndex &))); - connect(masterView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentMasterIndexChanged(int))); + connect(tableView, 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); @@ -78,24 +94,6 @@ void EsxView::ContentSelector::setEncoding(const QString &encoding) mContentModel->setEncoding(encoding); } -void EsxView::ContentSelector::setCheckState(QModelIndex index, QSortFilterProxyModel *model) -{ - if (!index.isValid()) - return; - - if (!model) - return; - - QModelIndex sourceIndex = model->mapToSource(index); - - if (sourceIndex.isValid()) - { - (mContentModel->checkState(sourceIndex) == Qt::Checked) - ? mContentModel->setCheckState(sourceIndex, Qt::Unchecked) - : mContentModel->setCheckState(sourceIndex, Qt::Checked); - } -} - QStringList EsxView::ContentSelector::checkedItemsPaths() { QStringList itemPaths; @@ -106,21 +104,6 @@ QStringList EsxView::ContentSelector::checkedItemsPaths() return itemPaths; } -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::slotCurrentProfileIndexChanged(int index) { emit profileChanged(index); @@ -128,17 +111,40 @@ void EsxView::ContentSelector::slotCurrentProfileIndexChanged(int index) void EsxView::ContentSelector::slotCurrentMasterIndexChanged(int index) { - QObject *object = QObject::sender(); + static int oldIndex = -1; + + QAbstractItemModel *const model = masterView->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; - // Not a signal-slot call - if (!object) - return; + model->setData(model->index(index, 0), true, Qt::UserRole + 1); - setCheckState(mMasterProxyModel->index(index, 0), mMasterProxyModel); + if (proxy) + proxy->setDynamicSortFilter(true); } void EsxView::ContentSelector::slotPluginTableItemClicked(const QModelIndex &index) { qDebug() << "setting checkstate in plugin..."; - setCheckState(index, mPluginsProxyModel); + + 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/components/esxselector/view/contentselector.hpp b/components/esxselector/view/contentselector.hpp index 06cc8f3f0..e074fe688 100644 --- a/components/esxselector/view/contentselector.hpp +++ b/components/esxselector/view/contentselector.hpp @@ -9,8 +9,6 @@ namespace EsxModel { class ContentModel; class DataFilesModel; - class PluginsProxyModel; - class MasterProxyModel; } class QSortFilterProxyModel; @@ -25,8 +23,8 @@ namespace EsxView EsxModel::DataFilesModel *mDataFilesModel; EsxModel::ContentModel *mContentModel; - EsxModel::MasterProxyModel *mMasterProxyModel; - EsxModel::PluginsProxyModel *mPluginsProxyModel; + QSortFilterProxyModel *mMasterProxyModel; + QSortFilterProxyModel *mPluginsProxyModel; public: explicit ContentSelector(QWidget *parent = 0); @@ -39,7 +37,12 @@ namespace EsxView void setCheckState(QModelIndex index, QSortFilterProxyModel *model); QStringList checkedItemsPaths(); void on_checkAction_triggered(); - void buildDragDropModelView(); + + private: + void buildSourceModel(); + void buildMasterView(); + void buildPluginsView(); + void buildProfilesView(); signals: void profileChanged(int index); From 244e5819529e2be6e4c0a790442d228fc4a133fc Mon Sep 17 00:00:00 2001 From: graffy76 Date: Thu, 19 Sep 2013 06:53:09 -0500 Subject: [PATCH 042/118] Finished implementing drag / drop refactored datafilesmodel (now contentmodel) refactored esmfil --- components/esxselector/model/contentmodel.cpp | 296 ++++++++---------- components/esxselector/model/contentmodel.hpp | 19 +- components/esxselector/model/esmfile.cpp | 67 +++- components/esxselector/model/esmfile.hpp | 52 +-- .../esxselector/view/contentselector.cpp | 6 +- files/ui/datafilespage.ui | 39 +-- 6 files changed, 222 insertions(+), 257 deletions(-) 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 - - - From cfdc19c4272804b9ed682704e8fa30d31a85a062 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 21 Sep 2013 23:06:29 -0500 Subject: [PATCH 043/118] 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
From 513f0c4b3ef1d15160619b49eb95d6a23a411c59 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 22 Sep 2013 23:52:53 -0500 Subject: [PATCH 044/118] Implemented file/adjuster widgets into new addon creation dialog --- apps/launcher/datafilespage.cpp | 4 +- apps/opencs/view/doc/adjusterwidget.cpp | 6 +- apps/opencs/view/doc/adjusterwidget.hpp | 5 +- apps/opencs/view/doc/filedialog.cpp | 53 ++++++++++-- apps/opencs/view/doc/filedialog.hpp | 17 +++- apps/opencs/view/doc/filewidget.cpp | 7 +- apps/opencs/view/doc/filewidget.hpp | 2 + .../contentselector/view/contentselector.cpp | 5 +- .../contentselector/view/contentselector.hpp | 1 + files/ui/datafilespage.ui | 80 ++++++++++++++++--- 10 files changed, 152 insertions(+), 28 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 1526b705a..44392794b 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -306,7 +306,7 @@ void DataFilesPage::setPluginsCheckstates(Qt::CheckState state) if (!sourceIndex.isValid()) return; - bool isChecked = ( state == Qt::Checked ); + //bool isChecked = ( state == Qt::Checked ); mContentModel->setData(sourceIndex, state, Qt::CheckStateRole); } @@ -397,7 +397,7 @@ void DataFilesPage::slotCurrentGameFileIndexChanged(int index) void DataFilesPage::slotAddonTableItemClicked(const QModelIndex &index) { QAbstractItemModel *const model = addonView->model(); - QSortFilterProxyModel *proxy = dynamic_cast(model); + //QSortFilterProxyModel *proxy = dynamic_cast(model); if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked) model->setData(index, Qt::Checked, Qt::CheckStateRole); diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp index 910819700..2784bca8c 100644 --- a/apps/opencs/view/doc/adjusterwidget.cpp +++ b/apps/opencs/view/doc/adjusterwidget.cpp @@ -43,6 +43,10 @@ boost::filesystem::path CSVDoc::AdjusterWidget::getPath() const return mResultPath; } +bool CSVDoc::AdjusterWidget::isValid() const +{ + return mValid; +} void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) { QString message; @@ -88,4 +92,4 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) pixmap (QSize (16, 16))); emit stateChanged (mValid); -} \ No newline at end of file +} diff --git a/apps/opencs/view/doc/adjusterwidget.hpp b/apps/opencs/view/doc/adjusterwidget.hpp index f578dc4ae..d970cffee 100644 --- a/apps/opencs/view/doc/adjusterwidget.hpp +++ b/apps/opencs/view/doc/adjusterwidget.hpp @@ -25,6 +25,9 @@ namespace CSVDoc void setLocalData (const boost::filesystem::path& localData); + QString getText() const; + bool isValid() const; + boost::filesystem::path getPath() const; ///< This function must not be called if there is no valid path. @@ -38,4 +41,4 @@ namespace CSVDoc }; } -#endif \ No newline at end of file +#endif diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 1d6bed7a7..9dce090a1 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -9,12 +9,22 @@ #include #include #include +#include #include #include +#include "filewidget.hpp" +#include "adjusterwidget.hpp" + +#include + CSVDoc::FileDialog::FileDialog(QWidget *parent) : - ContentSelector(parent) + ContentSelector(parent), + mFileWidget (new FileWidget (this)), + mAdjusterWidget (new AdjusterWidget (this)), + mEnable_1(false), + mEnable_2(false) { // Hide the profile elements profileGroupBox->hide(); @@ -22,12 +32,20 @@ CSVDoc::FileDialog::FileDialog(QWidget *parent) : resize(400, 400); - connect(projectNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateCreateButton(QString))); + mFileWidget->setType(true); + mFileWidget->extensionLabelIsVisible(false); connect(projectCreateButton, SIGNAL(clicked()), this, SIGNAL(createNewFile())); connect(projectButtonBox, SIGNAL(accepted()), this, SIGNAL(openFiles())); connect(projectButtonBox, SIGNAL(rejected()), this, SLOT(reject())); + + connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)), + mAdjusterWidget, SLOT (setName (const QString&, bool))); + + connect (mAdjusterWidget, SIGNAL (stateChanged (bool)), this, SLOT (slotAdjusterChanged(bool))); + connect (this, SIGNAL (signalGameFileChanged(int)), this, SLOT (slotGameFileSelected(int))); + connect (this, SIGNAL (signalUpdateCreateButton(bool, int)), this, SLOT (slotEnableCreateButton(bool, int))); } void CSVDoc::FileDialog::updateOpenButton(const QStringList &items) @@ -40,24 +58,30 @@ void CSVDoc::FileDialog::updateOpenButton(const QStringList &items) openButton->setEnabled(!items.isEmpty()); } -void CSVDoc::FileDialog::updateCreateButton(const QString &name) +void CSVDoc::FileDialog::slotEnableCreateButton(bool enable, int widgetNumber) { - if (!projectCreateButton->isVisible()) - return; - projectCreateButton->setEnabled(!name.isEmpty()); + if (widgetNumber == 1) + mEnable_1 = enable; + + if (widgetNumber == 2) + mEnable_2 = enable; + + qDebug() << "update enabled" << mEnable_1 << mEnable_2 << enable; + projectCreateButton->setEnabled(mEnable_1 && mEnable_2); } QString CSVDoc::FileDialog::fileName() { - return projectNameLineEdit->text(); + return mFileWidget->getName(); } void CSVDoc::FileDialog::openFile() { setWindowTitle(tr("Open")); - projectNameLineEdit->hide(); + mFileWidget->hide(); + adjusterWidgetFrame->hide(); projectCreateButton->hide(); projectGroupBox->setTitle(tr("")); projectButtonBox->button(QDialogButtonBox::Open)->setEnabled(false); @@ -71,6 +95,9 @@ void CSVDoc::FileDialog::newFile() { setWindowTitle(tr("New")); + fileWidgetFrame->layout()->addWidget(mFileWidget); + adjusterWidgetFrame->layout()->addWidget(mAdjusterWidget); + projectButtonBox->setStandardButtons(QDialogButtonBox::Cancel); projectButtonBox->addButton(projectCreateButton, QDialogButtonBox::ActionRole); @@ -78,3 +105,13 @@ void CSVDoc::FileDialog::newFile() raise(); activateWindow(); } + +void CSVDoc::FileDialog::slotAdjusterChanged(bool value) +{ + emit signalUpdateCreateButton(mAdjusterWidget->isValid(), 2); +} + +void CSVDoc::FileDialog::slotGameFileSelected(int value) +{ + emit signalUpdateCreateButton(value > -1, 1); +} diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index d0c3461b9..7782dd94e 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -26,9 +26,19 @@ namespace ContentSelectorView namespace CSVDoc { + class FileWidget; + class AdjusterWidget; + class FileDialog : public ContentSelectorView::ContentSelector { Q_OBJECT + + FileWidget *mFileWidget; + AdjusterWidget *mAdjusterWidget; + + bool mEnable_1; + bool mEnable_2; + public: explicit FileDialog(QWidget *parent = 0); @@ -41,12 +51,17 @@ namespace CSVDoc void openFiles(); void createNewFile(); + void signalUpdateCreateButton (bool, int); + void signalUpdateCreateButtonFlags(int); + public slots: private slots: //void updateViews(); void updateOpenButton(const QStringList &items); - void updateCreateButton(const QString &name); + void slotEnableCreateButton(bool enable, int widgetNumber); + void slotAdjusterChanged(bool value); + void slotGameFileSelected(int value); }; } #endif // FILEDIALOG_HPP diff --git a/apps/opencs/view/doc/filewidget.cpp b/apps/opencs/view/doc/filewidget.cpp index c8f33e92d..9cd2fad42 100644 --- a/apps/opencs/view/doc/filewidget.cpp +++ b/apps/opencs/view/doc/filewidget.cpp @@ -50,4 +50,9 @@ QString CSVDoc::FileWidget::getName() const void CSVDoc::FileWidget::textChanged (const QString& text) { emit nameChanged (getName(), mAddon); -} \ No newline at end of file +} + +void CSVDoc::FileWidget::extensionLabelIsVisible(bool visible) +{ + mType->setVisible(visible); +} diff --git a/apps/opencs/view/doc/filewidget.hpp b/apps/opencs/view/doc/filewidget.hpp index c51c29632..ff09d71a3 100644 --- a/apps/opencs/view/doc/filewidget.hpp +++ b/apps/opencs/view/doc/filewidget.hpp @@ -27,6 +27,8 @@ namespace CSVDoc QString getName() const; + void extensionLabelIsVisible(bool visible); + private slots: void textChanged (const QString& text); diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index 615e9a846..e6ed0ec56 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -40,6 +40,7 @@ void ContentSelectorView::ContentSelector::buildGameFileView() gameFileView->setModel(mGameFileProxyModel); connect(gameFileView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentGameFileIndexChanged(int))); + connect(gameFileView, SIGNAL(currentIndexChanged(int)), this, SIGNAL(signalGameFileChanged(int))); gameFileView->setCurrentIndex(-1); gameFileView->setCurrentIndex(0); @@ -120,12 +121,14 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i if (proxy) proxy->setDynamicSortFilter(true); + + emit signalGameFileChanged(true); } void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QModelIndex &index) { QAbstractItemModel *const model = addonView->model(); - QSortFilterProxyModel *proxy = dynamic_cast(model); + //QSortFilterProxyModel *proxy = dynamic_cast(model); if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked) model->setData(index, Qt::Checked, Qt::CheckStateRole); diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index 8032b0449..5af53dc46 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -40,6 +40,7 @@ namespace ContentSelectorView signals: void profileChanged(int index); + void signalGameFileChanged(int value); private slots: void updateViews(); diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 82d00922b..949407759 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -10,6 +10,12 @@ 313 + + + 0 + 0 + + Qt::DefaultContextMenu @@ -97,15 +103,44 @@
+ + + 0 + 0 + + Project + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + - - - Enter project name... + + + + 0 + 0 + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + + 0 + + + 0 + + @@ -126,9 +161,33 @@
- projectButtonBox - projectCreateButton - projectNameLineEdit +
+
+ + + + + 1 + 0 + + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + + 0 + + + 0 + + @@ -249,14 +308,9 @@
- EsxView::ProfilesComboBox + ContentSelectorView::ProfilesComboBox QComboBox -
components/contentselector/view/profilescombobox.hpp
-
- - EsxView::LineEdit - QLineEdit -
components/contentselector/view/lineedit.hpp
+
components/contentselector/view/profilescombobox.hpp
From 63e0cf5154572f90b0c4234a64703d6056464123 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 23 Sep 2013 11:26:29 +0200 Subject: [PATCH 045/118] fixed missing initialisation of adjuster widget in file dialogue --- apps/opencs/editor.cpp | 1 + apps/opencs/view/doc/filedialog.cpp | 5 +++++ apps/opencs/view/doc/filedialog.hpp | 9 +++++++++ apps/opencs/view/doc/newgame.hpp | 3 +++ 4 files changed, 18 insertions(+) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index ba1dfb57e..104afa03b 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -17,6 +17,7 @@ CS::Editor::Editor() : mViewManager (mDocumentManager) setupDataFiles(); mNewGame.setLocalData (mLocal); + mFileDialog.setLocalData (mLocal); connect (&mViewManager, SIGNAL (newGameRequest ()), this, SLOT (createGame ())); connect (&mViewManager, SIGNAL (newAddonRequest ()), this, SLOT (createAddon ())); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 9dce090a1..4d7c5bc15 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -48,6 +48,11 @@ CSVDoc::FileDialog::FileDialog(QWidget *parent) : connect (this, SIGNAL (signalUpdateCreateButton(bool, int)), this, SLOT (slotEnableCreateButton(bool, int))); } +void CSVDoc::FileDialog::setLocalData (const boost::filesystem::path& localData) +{ + mAdjusterWidget->setLocalData (localData); +} + void CSVDoc::FileDialog::updateOpenButton(const QStringList &items) { QPushButton *openButton = projectButtonBox->button(QDialogButtonBox::Open); diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 7782dd94e..0c914b932 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -4,9 +4,16 @@ #include #include +#include + #include "components/contentselector/view/contentselector.hpp" #include "ui_datafilespage.h" +#ifndef CS_QT_BOOST_FILESYSTEM_PATH_DECLARED +#define CS_QT_BOOST_FILESYSTEM_PATH_DECLARED +Q_DECLARE_METATYPE (boost::filesystem::path) +#endif + class QDialogButtonBox; class QSortFilterProxyModel; class QAbstractItemModel; @@ -42,6 +49,8 @@ namespace CSVDoc public: explicit FileDialog(QWidget *parent = 0); + void setLocalData (const boost::filesystem::path& localData); + void openFile(); void newFile(); diff --git a/apps/opencs/view/doc/newgame.hpp b/apps/opencs/view/doc/newgame.hpp index aa97682ff..9ad7ea169 100644 --- a/apps/opencs/view/doc/newgame.hpp +++ b/apps/opencs/view/doc/newgame.hpp @@ -6,7 +6,10 @@ #include #include +#ifndef CS_QT_BOOST_FILESYSTEM_PATH_DECLARED +#define CS_QT_BOOST_FILESYSTEM_PATH_DECLARED Q_DECLARE_METATYPE (boost::filesystem::path) +#endif class QPushButton; From 74d683b5303e5b95a34fec6d082b9999aacecc3b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 23 Sep 2013 11:58:11 +0200 Subject: [PATCH 046/118] fixed save path for newly created addons --- apps/opencs/editor.cpp | 9 ++++----- apps/opencs/editor.hpp | 2 +- apps/opencs/view/doc/filedialog.cpp | 9 +++++++-- apps/opencs/view/doc/filedialog.hpp | 3 ++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 104afa03b..800f3984e 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -30,7 +30,8 @@ CS::Editor::Editor() : mViewManager (mDocumentManager) connect (&mStartup, SIGNAL (editConfig()), this, SLOT (showSettings ())); connect (&mFileDialog, SIGNAL(openFiles()), this, SLOT(openFiles())); - connect (&mFileDialog, SIGNAL(createNewFile()), this, SLOT(createNewFile())); + connect (&mFileDialog, SIGNAL(createNewFile (const boost::filesystem::path&)), + this, SLOT(createNewFile (const boost::filesystem::path&))); connect (&mNewGame, SIGNAL (createRequest (const boost::filesystem::path&)), this, SLOT (createNewGame (const boost::filesystem::path&))); @@ -138,7 +139,7 @@ void CS::Editor::openFiles() mFileDialog.hide(); } -void CS::Editor::createNewFile() +void CS::Editor::createNewFile (const boost::filesystem::path& savePath) { std::vector files; QStringList paths = mFileDialog.checkedItemsPaths(); @@ -149,9 +150,7 @@ void CS::Editor::createNewFile() files.push_back(mFileDialog.fileName().toStdString()); - /// \todo Get the save path from the file dialogue. - - CSMDoc::Document *document = mDocumentManager.addDocument (files, *files.rbegin(), true); + CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, true); mViewManager.addView (document); mFileDialog.hide(); diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 248ebf2c5..abf9496e4 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -60,7 +60,7 @@ namespace CS void loadDocument(); void openFiles(); - void createNewFile(); + void createNewFile (const boost::filesystem::path& savePath); void createNewGame (const boost::filesystem::path& file); void showStartup(); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 4d7c5bc15..4426d2e49 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -35,7 +35,7 @@ CSVDoc::FileDialog::FileDialog(QWidget *parent) : mFileWidget->setType(true); mFileWidget->extensionLabelIsVisible(false); - connect(projectCreateButton, SIGNAL(clicked()), this, SIGNAL(createNewFile())); + connect(projectCreateButton, SIGNAL(clicked()), this, SLOT(createNewFile())); connect(projectButtonBox, SIGNAL(accepted()), this, SIGNAL(openFiles())); connect(projectButtonBox, SIGNAL(rejected()), this, SLOT(reject())); @@ -118,5 +118,10 @@ void CSVDoc::FileDialog::slotAdjusterChanged(bool value) void CSVDoc::FileDialog::slotGameFileSelected(int value) { - emit signalUpdateCreateButton(value > -1, 1); + emit signalUpdateCreateButton(value > -1, 1); } + +void CSVDoc::FileDialog::createNewFile() +{ + emit createNewFile (mAdjusterWidget->getPath()); +} \ No newline at end of file diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 0c914b932..37119ff0d 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -58,7 +58,7 @@ namespace CSVDoc signals: void openFiles(); - void createNewFile(); + void createNewFile (const boost::filesystem::path& savePath); void signalUpdateCreateButton (bool, int); void signalUpdateCreateButtonFlags(int); @@ -71,6 +71,7 @@ namespace CSVDoc void slotEnableCreateButton(bool enable, int widgetNumber); void slotAdjusterChanged(bool value); void slotGameFileSelected(int value); + void createNewFile(); }; } #endif // FILEDIALOG_HPP From 6d9ff39390f5495535c2b18c2664554836cf83aa Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 23 Sep 2013 12:16:56 +0200 Subject: [PATCH 047/118] set dependencies when saving (requires further refinements) --- apps/opencs/model/doc/document.cpp | 7 ++++++- apps/opencs/model/doc/document.hpp | 5 +++++ apps/opencs/model/doc/savingstages.cpp | 13 ++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 525f18a20..37294bcd1 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2141,7 +2141,7 @@ void CSMDoc::Document::createBase() CSMDoc::Document::Document (const std::vector& files, const boost::filesystem::path& savePath, bool new_) -: mSavePath (savePath), mTools (mData), mSaving (*this) +: mSavePath (savePath), mContentFiles (files), mTools (mData), mSaving (*this) { if (files.empty()) throw std::runtime_error ("Empty content file sequence"); @@ -2200,6 +2200,11 @@ const boost::filesystem::path& CSMDoc::Document::getSavePath() const return mSavePath; } +const std::vector& CSMDoc::Document::getContentFiles() const +{ + return mContentFiles; +} + void CSMDoc::Document::save() { if (mSaving.isRunning()) diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 5a0395510..b1c6a0273 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -33,6 +33,7 @@ namespace CSMDoc private: boost::filesystem::path mSavePath; + std::vector mContentFiles; CSMWorld::Data mData; CSMTools::Tools mTools; Saving mSaving; @@ -74,6 +75,10 @@ namespace CSMDoc const boost::filesystem::path& getSavePath() const; + const std::vector& getContentFiles() const; + ///< \attention The last element in this collection is the file that is being edited, + /// but with its original path instead of the save path. + void save(); CSMWorld::UniversalId verify(); diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 797b32eae..fd6234594 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -50,7 +50,18 @@ void CSMDoc::WriteHeaderStage::perform (int stage, std::vector& mes mState.getWriter().setDescription (""); mState.getWriter().setRecordCount (0); - /// \todo fill in dependency list + /// \todo refine dependency list (at least remove redundant dependencies) + std::vector dependencies = mDocument.getContentFiles(); + std::vector::const_iterator end (--dependencies.end()); + + for (std::vector::const_iterator iter (dependencies.begin()); + iter!=end; ++iter) + { + std::string name = iter->filename().string(); + uint64_t size = boost::filesystem::file_size (*iter); + + mState.getWriter().addMaster (name, size); + } mState.getWriter().save (mState.getStream()); } From d7cff6361e091990e7b3a90fc94f824284543c13 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Mon, 23 Sep 2013 06:51:49 -0500 Subject: [PATCH 048/118] Fixed filter issue (all addons for a gamefile are enabled for checking). Note: Other dependencies are not yet automatically selected when an addon is checked. --- apps/opencs/view/doc/adjusterwidget.hpp | 1 - apps/opencs/view/doc/filedialog.cpp | 3 +- .../contentselector/model/contentmodel.cpp | 32 +++++++++++++------ .../contentselector/model/contentmodel.hpp | 3 +- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/apps/opencs/view/doc/adjusterwidget.hpp b/apps/opencs/view/doc/adjusterwidget.hpp index d970cffee..461cfb345 100644 --- a/apps/opencs/view/doc/adjusterwidget.hpp +++ b/apps/opencs/view/doc/adjusterwidget.hpp @@ -25,7 +25,6 @@ namespace CSVDoc void setLocalData (const boost::filesystem::path& localData); - QString getText() const; bool isValid() const; boost::filesystem::path getPath() const; diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 9dce090a1..68aab27d5 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -67,7 +67,6 @@ void CSVDoc::FileDialog::slotEnableCreateButton(bool enable, int widgetNumber) if (widgetNumber == 2) mEnable_2 = enable; - qDebug() << "update enabled" << mEnable_1 << mEnable_2 << enable; projectCreateButton->setEnabled(mEnable_1 && mEnable_2); } @@ -113,5 +112,5 @@ void CSVDoc::FileDialog::slotAdjusterChanged(bool value) void CSVDoc::FileDialog::slotGameFileSelected(int value) { - emit signalUpdateCreateButton(value > -1, 1); + emit signalUpdateCreateButton(value > -1, 1); } diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index b85da25c6..c1394ef47 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -65,7 +65,7 @@ ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(int row) return 0; } -const ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::findItem(const QString &name) const +const ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(const QString &name) const { foreach (const EsmFile *file, mFiles) { @@ -99,7 +99,7 @@ Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex &index if (canBeChecked(file)) return Qt::ItemIsEnabled | mDragDropFlags | mDefaultFlags; - return mDefaultFlags; + return Qt::NoItemFlags; } QVariant ContentSelectorModel::ContentModel::data(const QModelIndex &index, int role) const @@ -167,7 +167,7 @@ QVariant ContentSelectorModel::ContentModel::data(const QModelIndex &index, int if (file->isGameFile()) return ContentType_GameFile; else - if (flags(index) & Qt::ItemIsEnabled) + if (flags(index) & mDefaultFlags) return ContentType_Addon; break; @@ -373,12 +373,26 @@ bool ContentSelectorModel::ContentModel::dropMimeData(const QMimeData *data, Qt: bool ContentSelectorModel::ContentModel::canBeChecked(const EsmFile *file) const { - //element can be checked if all its dependencies are - foreach (const QString &gamefile, file->gameFiles()) - if (!isChecked(gamefile)) - return false; + //game files can always be checked + if (file->isGameFile()) + return true; - return true; + //addon can be checked if its gamefile is + foreach (const QString &fileName, file->gameFiles()) + { + const EsmFile *dependency = item(fileName); + + if (!dependency) + continue; + + if (dependency->isGameFile()) + { + if (isChecked(fileName)) + return true; + } + } + + return false; } void ContentSelectorModel::ContentModel::addFile(EsmFile *file) @@ -422,7 +436,7 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path) // Put the file in the table - if (findItem(path) == 0) + if (item(path) == 0) addFile(file); } catch(std::runtime_error &e) { diff --git a/components/contentselector/model/contentmodel.hpp b/components/contentselector/model/contentmodel.hpp index a8ff103da..a2a57f850 100644 --- a/components/contentselector/model/contentmodel.hpp +++ b/components/contentselector/model/contentmodel.hpp @@ -42,7 +42,7 @@ namespace ContentSelectorModel void addFiles(const QString &path); QModelIndex indexFromItem(const EsmFile *item) const; - const EsmFile *findItem(const QString &name) const; + const EsmFile *item(const QString &name) const; bool isChecked(const QString &name) const; void setCheckState(const QString &name, bool isChecked); @@ -54,6 +54,7 @@ namespace ContentSelectorModel void addFile(EsmFile *file); const EsmFile *item(int row) const; EsmFile *item(int row); + bool canBeChecked(const EsmFile *file) const; ContentFileList mFiles; From 9d358dd44c4df478ac90650338809321aa837aa8 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Mon, 23 Sep 2013 22:01:44 -0500 Subject: [PATCH 049/118] Further implemented auto-checking / unchecking of dependencies --- .../contentselector/model/contentmodel.cpp | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index c1394ef47..db6431810 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -458,17 +458,51 @@ bool ContentSelectorModel::ContentModel::isChecked(const QString& name) const return false; } -void ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool isChecked) +void ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool checkState) { if (name.isEmpty()) return; Qt::CheckState state = Qt::Unchecked; - if (isChecked) + if (checkState) state = Qt::Checked; mCheckStates[name] = state; + + const EsmFile *file = item(name); + + if (state == Qt::Checked) + { + foreach (const QString &upstreamName, file->gameFiles()) + { + const EsmFile *upstreamFile = item(upstreamName); + + if (!upstreamFile) + continue; + + if (!isChecked(upstreamName)) + { + mCheckStates[upstreamName] = Qt::Checked; + emit dataChanged(indexFromItem(upstreamFile), indexFromItem(upstreamFile)); + } + + } + } + else if (state == Qt::Unchecked) + { + foreach (const EsmFile *downstreamFile, mFiles) + { + if (downstreamFile->gameFiles().contains(name)) + { + if (mCheckStates.contains(downstreamFile->fileName())) + { + mCheckStates[downstreamFile->fileName()] = Qt::Unchecked; + emit dataChanged(indexFromItem(downstreamFile), indexFromItem(downstreamFile)); + } + } + } + } } ContentSelectorModel::ContentFileList ContentSelectorModel::ContentModel::checkedItems() const From c42e74dadf1160a908dff63a4a1c48763a766202 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 24 Sep 2013 13:17:28 +0200 Subject: [PATCH 050/118] make 4 byte record type accessable from record struct --- apps/opencs/model/doc/saving.cpp | 24 +++++++++++------------- apps/opencs/model/doc/savingstages.hpp | 12 ++++-------- components/esm/loadacti.cpp | 3 +++ components/esm/loadacti.hpp | 2 ++ components/esm/loadalch.cpp | 3 +++ components/esm/loadalch.hpp | 2 ++ components/esm/loadappa.cpp | 3 +++ components/esm/loadappa.hpp | 2 ++ components/esm/loadarmo.cpp | 3 +++ components/esm/loadarmo.hpp | 2 ++ components/esm/loadbody.cpp | 3 +++ components/esm/loadbody.hpp | 2 ++ components/esm/loadbook.cpp | 2 ++ components/esm/loadbook.hpp | 2 ++ components/esm/loadbsgn.cpp | 2 ++ components/esm/loadbsgn.hpp | 2 ++ components/esm/loadcell.cpp | 2 ++ components/esm/loadcell.hpp | 3 ++- components/esm/loadclas.cpp | 2 ++ components/esm/loadclas.hpp | 2 ++ components/esm/loadclot.cpp | 2 ++ components/esm/loadclot.hpp | 2 ++ components/esm/loadcont.cpp | 3 +++ components/esm/loadcont.hpp | 2 ++ components/esm/loadcrea.cpp | 3 +++ components/esm/loadcrea.hpp | 2 ++ components/esm/loadcrec.hpp | 2 ++ components/esm/loaddial.cpp | 2 ++ components/esm/loaddial.hpp | 2 ++ components/esm/loaddoor.cpp | 2 ++ components/esm/loaddoor.hpp | 2 ++ components/esm/loadench.cpp | 2 ++ components/esm/loadench.hpp | 2 ++ components/esm/loadfact.cpp | 3 +++ components/esm/loadfact.hpp | 2 ++ components/esm/loadglob.cpp | 4 ++++ components/esm/loadglob.hpp | 2 ++ components/esm/loadgmst.cpp | 4 ++++ components/esm/loadgmst.hpp | 2 ++ components/esm/loadinfo.cpp | 2 ++ components/esm/loadinfo.hpp | 2 ++ components/esm/loadingr.cpp | 2 ++ components/esm/loadingr.hpp | 2 ++ components/esm/loadland.cpp | 2 ++ components/esm/loadland.hpp | 2 ++ components/esm/loadlevlist.cpp | 5 +++++ components/esm/loadlevlist.hpp | 4 ++++ components/esm/loadligh.cpp | 2 ++ components/esm/loadligh.hpp | 2 ++ components/esm/loadlock.cpp | 2 ++ components/esm/loadlock.hpp | 2 ++ components/esm/loadltex.cpp | 2 ++ components/esm/loadltex.hpp | 2 ++ components/esm/loadmgef.cpp | 2 ++ components/esm/loadmgef.hpp | 2 ++ components/esm/loadmisc.cpp | 2 ++ components/esm/loadmisc.hpp | 2 ++ components/esm/loadnpc.cpp | 2 ++ components/esm/loadnpc.hpp | 2 ++ components/esm/loadnpcc.hpp | 2 ++ components/esm/loadpgrd.cpp | 2 ++ components/esm/loadpgrd.hpp | 2 ++ components/esm/loadprob.cpp | 2 ++ components/esm/loadprob.hpp | 2 ++ components/esm/loadrace.cpp | 3 +++ components/esm/loadrace.hpp | 2 ++ components/esm/loadregn.cpp | 2 ++ components/esm/loadregn.hpp | 2 ++ components/esm/loadrepa.cpp | 2 ++ components/esm/loadrepa.hpp | 2 ++ components/esm/loadscpt.cpp | 3 +++ components/esm/loadscpt.hpp | 2 ++ components/esm/loadskil.cpp | 3 +++ components/esm/loadskil.hpp | 2 ++ components/esm/loadsndg.cpp | 2 ++ components/esm/loadsndg.hpp | 2 ++ components/esm/loadsoun.cpp | 2 ++ components/esm/loadsoun.hpp | 2 ++ components/esm/loadspel.cpp | 2 ++ components/esm/loadspel.hpp | 2 ++ components/esm/loadsscr.cpp | 2 ++ components/esm/loadsscr.hpp | 2 ++ components/esm/loadstat.cpp | 2 ++ components/esm/loadstat.hpp | 2 ++ components/esm/loadtes3.cpp | 1 + components/esm/loadweap.cpp | 2 ++ components/esm/loadweap.hpp | 2 ++ 87 files changed, 204 insertions(+), 22 deletions(-) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index 7e0b10d66..c9035cfd4 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -1,8 +1,6 @@ #include "saving.hpp" -#include - #include "../world/data.hpp" #include "../world/idcollection.hpp" @@ -18,37 +16,37 @@ CSMDoc::Saving::Saving (Document& document) appendStage (new WriteHeaderStage (mDocument, mState)); appendStage (new WriteCollectionStage > - (mDocument.getData().getGlobals(), mState, ESM::REC_GLOB)); + (mDocument.getData().getGlobals(), mState)); appendStage (new WriteCollectionStage > - (mDocument.getData().getGmsts(), mState, ESM::REC_GMST)); + (mDocument.getData().getGmsts(), mState)); appendStage (new WriteCollectionStage > - (mDocument.getData().getSkills(), mState, ESM::REC_SKIL)); + (mDocument.getData().getSkills(), mState)); appendStage (new WriteCollectionStage > - (mDocument.getData().getClasses(), mState, ESM::REC_CLAS)); + (mDocument.getData().getClasses(), mState)); appendStage (new WriteCollectionStage > - (mDocument.getData().getFactions(), mState, ESM::REC_FACT)); + (mDocument.getData().getFactions(), mState)); appendStage (new WriteCollectionStage > - (mDocument.getData().getRaces(), mState, ESM::REC_RACE)); + (mDocument.getData().getRaces(), mState)); appendStage (new WriteCollectionStage > - (mDocument.getData().getSounds(), mState, ESM::REC_SOUN)); + (mDocument.getData().getSounds(), mState)); appendStage (new WriteCollectionStage > - (mDocument.getData().getScripts(), mState, ESM::REC_SCPT)); + (mDocument.getData().getScripts(), mState)); appendStage (new WriteCollectionStage > - (mDocument.getData().getRegions(), mState, ESM::REC_REGN)); + (mDocument.getData().getRegions(), mState)); appendStage (new WriteCollectionStage > - (mDocument.getData().getBirthsigns(), mState, ESM::REC_BSGN)); + (mDocument.getData().getBirthsigns(), mState)); appendStage (new WriteCollectionStage > - (mDocument.getData().getSpells(), mState, ESM::REC_SPEL)); + (mDocument.getData().getSpells(), mState)); appendStage (new CloseSaveStage (mState)); diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index 96b1fe17f..d5c4a69af 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -1,8 +1,6 @@ #ifndef CSM_DOC_SAVINGSTAGES_H #define CSM_DOC_SAVINGSTAGES_H -#include - #include "stage.hpp" #include "savingstate.hpp" @@ -52,12 +50,10 @@ namespace CSMDoc { const CollectionT& mCollection; SavingState& mState; - ESM::RecNameInts mRecordType; public: - WriteCollectionStage (const CollectionT& collection, SavingState& state, - ESM::RecNameInts recordType); + WriteCollectionStage (const CollectionT& collection, SavingState& state); virtual int setup(); ///< \return number of steps @@ -68,8 +64,8 @@ namespace CSMDoc template WriteCollectionStage::WriteCollectionStage (const CollectionT& collection, - SavingState& state, ESM::RecNameInts recordType) - : mCollection (collection), mState (state), mRecordType (recordType) + SavingState& state) + : mCollection (collection), mState (state) {} template @@ -89,7 +85,7 @@ namespace CSMDoc std::string type; for (int i=0; i<4; ++i) /// \todo make endianess agnostic (change ESMWriter interface?) - type += reinterpret_cast (&mRecordType)[i]; + type += reinterpret_cast (&mCollection.getRecord (stage).mModified.sRecordId)[i]; mState.getWriter().startRecord (type); mState.getWriter().writeHNCString ("NAME", mCollection.getId (stage)); diff --git a/components/esm/loadacti.cpp b/components/esm/loadacti.cpp index dcae845d0..6ba0df0b3 100644 --- a/components/esm/loadacti.cpp +++ b/components/esm/loadacti.cpp @@ -2,9 +2,12 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Activator::sRecordId = REC_ACTI; + void Activator::load(ESMReader &esm) { mModel = esm.getHNString("MODL"); diff --git a/components/esm/loadacti.hpp b/components/esm/loadacti.hpp index 6b072ee11..88f27de27 100644 --- a/components/esm/loadacti.hpp +++ b/components/esm/loadacti.hpp @@ -11,6 +11,8 @@ class ESMWriter; struct Activator { + static unsigned int sRecordId; + std::string mId, mName, mScript, mModel; void load(ESMReader &esm); diff --git a/components/esm/loadalch.cpp b/components/esm/loadalch.cpp index 187069c2e..f6bfc6a11 100644 --- a/components/esm/loadalch.cpp +++ b/components/esm/loadalch.cpp @@ -2,9 +2,12 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Potion::sRecordId = REC_ALCH; + void Potion::load(ESMReader &esm) { mModel = esm.getHNString("MODL"); diff --git a/components/esm/loadalch.hpp b/components/esm/loadalch.hpp index 8f0435292..141765aa8 100644 --- a/components/esm/loadalch.hpp +++ b/components/esm/loadalch.hpp @@ -17,6 +17,8 @@ class ESMWriter; struct Potion { + static unsigned int sRecordId; + struct ALDTstruct { float mWeight; diff --git a/components/esm/loadappa.cpp b/components/esm/loadappa.cpp index 01233a055..29ea78acc 100644 --- a/components/esm/loadappa.cpp +++ b/components/esm/loadappa.cpp @@ -2,9 +2,12 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Apparatus::sRecordId = REC_APPA; + void Apparatus::load(ESMReader &esm) { // we will not treat duplicated subrecords as errors here diff --git a/components/esm/loadappa.hpp b/components/esm/loadappa.hpp index d47643c6c..adc8e071f 100644 --- a/components/esm/loadappa.hpp +++ b/components/esm/loadappa.hpp @@ -15,6 +15,8 @@ class ESMWriter; struct Apparatus { + static unsigned int sRecordId; + enum AppaType { MortarPestle = 0, diff --git a/components/esm/loadarmo.cpp b/components/esm/loadarmo.cpp index 4dbdf1314..ec8ff4f20 100644 --- a/components/esm/loadarmo.cpp +++ b/components/esm/loadarmo.cpp @@ -2,6 +2,7 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { @@ -28,6 +29,8 @@ void PartReferenceList::save(ESMWriter &esm) const } } +unsigned int Armor::sRecordId = REC_ARMO; + void Armor::load(ESMReader &esm) { mModel = esm.getHNString("MODL"); diff --git a/components/esm/loadarmo.hpp b/components/esm/loadarmo.hpp index 5a38605e3..991f4e185 100644 --- a/components/esm/loadarmo.hpp +++ b/components/esm/loadarmo.hpp @@ -61,6 +61,8 @@ struct PartReferenceList struct Armor { + static unsigned int sRecordId; + enum Type { Helmet = 0, diff --git a/components/esm/loadbody.cpp b/components/esm/loadbody.cpp index a5d986f65..4015e6c91 100644 --- a/components/esm/loadbody.cpp +++ b/components/esm/loadbody.cpp @@ -2,9 +2,12 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int BodyPart::sRecordId = REC_BODY; + void BodyPart::load(ESMReader &esm) { diff --git a/components/esm/loadbody.hpp b/components/esm/loadbody.hpp index a8fd36aef..9623caa31 100644 --- a/components/esm/loadbody.hpp +++ b/components/esm/loadbody.hpp @@ -11,6 +11,8 @@ class ESMWriter; struct BodyPart { + static unsigned int sRecordId; + enum MeshPart { MP_Head = 0, diff --git a/components/esm/loadbook.cpp b/components/esm/loadbook.cpp index d9db11889..c8b7e9478 100644 --- a/components/esm/loadbook.cpp +++ b/components/esm/loadbook.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Book::sRecordId = REC_BOOK; void Book::load(ESMReader &esm) { diff --git a/components/esm/loadbook.hpp b/components/esm/loadbook.hpp index 688e9dd75..f96fbd709 100644 --- a/components/esm/loadbook.hpp +++ b/components/esm/loadbook.hpp @@ -14,6 +14,8 @@ class ESMWriter; struct Book { + static unsigned int sRecordId; + struct BKDTstruct { float mWeight; diff --git a/components/esm/loadbsgn.cpp b/components/esm/loadbsgn.cpp index 9d19f02c7..55e1e7f65 100644 --- a/components/esm/loadbsgn.cpp +++ b/components/esm/loadbsgn.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int BirthSign::sRecordId = REC_BSGN; void BirthSign::load(ESMReader &esm) { diff --git a/components/esm/loadbsgn.hpp b/components/esm/loadbsgn.hpp index 1ecb5e418..9f9435c8f 100644 --- a/components/esm/loadbsgn.hpp +++ b/components/esm/loadbsgn.hpp @@ -13,6 +13,8 @@ class ESMWriter; struct BirthSign { + static unsigned int sRecordId; + std::string mId, mName, mDescription, mTexture; // List of powers and abilities that come with this birth sign. diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index 9b3aa09e8..c22c1b22b 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -7,9 +7,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Cell::sRecordId = REC_CELL; /// Some overloaded compare operators. bool operator==(const MovedCellRef& ref, int pRefnum) diff --git a/components/esm/loadcell.hpp b/components/esm/loadcell.hpp index c417fceab..61d586b9d 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -16,7 +16,6 @@ namespace MWWorld namespace ESM { - class ESMReader; class ESMWriter; @@ -55,6 +54,8 @@ typedef std::list CellRefTracker; */ struct Cell { + static unsigned int sRecordId; + enum Flags { Interior = 0x01, // Interior cell diff --git a/components/esm/loadclas.cpp b/components/esm/loadclas.cpp index ef07430c7..33489eec4 100644 --- a/components/esm/loadclas.cpp +++ b/components/esm/loadclas.cpp @@ -4,9 +4,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Class::sRecordId = REC_CLAS; const Class::Specialization Class::sSpecializationIds[3] = { Class::Combat, diff --git a/components/esm/loadclas.hpp b/components/esm/loadclas.hpp index f241dca8d..3e489bb58 100644 --- a/components/esm/loadclas.hpp +++ b/components/esm/loadclas.hpp @@ -17,6 +17,8 @@ class ESMWriter; // class struct Class { + static unsigned int sRecordId; + enum AutoCalc { Weapon = 0x00001, diff --git a/components/esm/loadclot.cpp b/components/esm/loadclot.cpp index c623155df..d64564d77 100644 --- a/components/esm/loadclot.cpp +++ b/components/esm/loadclot.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Clothing::sRecordId = REC_CLOT; void Clothing::load(ESMReader &esm) { diff --git a/components/esm/loadclot.hpp b/components/esm/loadclot.hpp index 13fae865b..50896622a 100644 --- a/components/esm/loadclot.hpp +++ b/components/esm/loadclot.hpp @@ -17,6 +17,8 @@ class ESMWriter; struct Clothing { + static unsigned int sRecordId; + enum Type { Pants = 0, diff --git a/components/esm/loadcont.cpp b/components/esm/loadcont.cpp index 0cbb4acd1..7bdf9f05b 100644 --- a/components/esm/loadcont.cpp +++ b/components/esm/loadcont.cpp @@ -2,6 +2,7 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { @@ -24,6 +25,8 @@ void InventoryList::save(ESMWriter &esm) const } } + unsigned int Container::sRecordId = REC_CONT; + void Container::load(ESMReader &esm) { mModel = esm.getHNString("MODL"); diff --git a/components/esm/loadcont.hpp b/components/esm/loadcont.hpp index c854b5290..2808b67b5 100644 --- a/components/esm/loadcont.hpp +++ b/components/esm/loadcont.hpp @@ -32,6 +32,8 @@ struct InventoryList struct Container { + static unsigned int sRecordId; + enum Flags { Organic = 1, // Objects cannot be placed in this container diff --git a/components/esm/loadcrea.cpp b/components/esm/loadcrea.cpp index 30b70b35b..650de0801 100644 --- a/components/esm/loadcrea.cpp +++ b/components/esm/loadcrea.cpp @@ -2,9 +2,12 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Creature::sRecordId = REC_CREA; + void Creature::load(ESMReader &esm) { mPersistent = esm.getRecordFlags() & 0x0400; diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index 80e0fbd1c..99c4f5225 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -20,6 +20,8 @@ class ESMWriter; struct Creature { + static unsigned int sRecordId; + // Default is 0x48? enum Flags { diff --git a/components/esm/loadcrec.hpp b/components/esm/loadcrec.hpp index 2b840ccf4..280739aca 100644 --- a/components/esm/loadcrec.hpp +++ b/components/esm/loadcrec.hpp @@ -17,6 +17,8 @@ class ESMWriter; /// Changes a creature struct LoadCREC { + static unsigned int sRecordId; + std::string mId; void load(ESMReader &esm) diff --git a/components/esm/loaddial.cpp b/components/esm/loaddial.cpp index e014ca37e..f64ecb5a0 100644 --- a/components/esm/loaddial.cpp +++ b/components/esm/loaddial.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Dialogue::sRecordId = REC_DIAL; void Dialogue::load(ESMReader &esm) { diff --git a/components/esm/loaddial.hpp b/components/esm/loaddial.hpp index 0fe5027dc..3997d7753 100644 --- a/components/esm/loaddial.hpp +++ b/components/esm/loaddial.hpp @@ -19,6 +19,8 @@ class ESMWriter; struct Dialogue { + static unsigned int sRecordId; + enum Type { Topic = 0, diff --git a/components/esm/loaddoor.cpp b/components/esm/loaddoor.cpp index f666ac67a..c56b06337 100644 --- a/components/esm/loaddoor.cpp +++ b/components/esm/loaddoor.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Door::sRecordId = REC_DOOR; void Door::load(ESMReader &esm) { diff --git a/components/esm/loaddoor.hpp b/components/esm/loaddoor.hpp index 2b927c56e..ee2b7f7ac 100644 --- a/components/esm/loaddoor.hpp +++ b/components/esm/loaddoor.hpp @@ -11,6 +11,8 @@ class ESMWriter; struct Door { + static unsigned int sRecordId; + std::string mId, mName, mModel, mScript, mOpenSound, mCloseSound; void load(ESMReader &esm); diff --git a/components/esm/loadench.cpp b/components/esm/loadench.cpp index 4b4c3a1ec..a1e885f23 100644 --- a/components/esm/loadench.cpp +++ b/components/esm/loadench.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Enchantment::sRecordId = REC_ENCH; void Enchantment::load(ESMReader &esm) { diff --git a/components/esm/loadench.hpp b/components/esm/loadench.hpp index 3cdc3a0bd..f6ba8c6ab 100644 --- a/components/esm/loadench.hpp +++ b/components/esm/loadench.hpp @@ -17,6 +17,8 @@ class ESMWriter; struct Enchantment { + static unsigned int sRecordId; + enum Type { CastOnce = 0, diff --git a/components/esm/loadfact.cpp b/components/esm/loadfact.cpp index c8be51802..61fa90263 100644 --- a/components/esm/loadfact.cpp +++ b/components/esm/loadfact.cpp @@ -4,9 +4,12 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Faction::sRecordId = REC_FACT; + int& Faction::FADTstruct::getSkill (int index, bool ignored) { if (index<0 || index>=6) diff --git a/components/esm/loadfact.hpp b/components/esm/loadfact.hpp index 11f65a87f..9c257e068 100644 --- a/components/esm/loadfact.hpp +++ b/components/esm/loadfact.hpp @@ -29,6 +29,8 @@ struct RankData struct Faction { + static unsigned int sRecordId; + std::string mId, mName; struct FADTstruct diff --git a/components/esm/loadglob.cpp b/components/esm/loadglob.cpp index e1c2d4408..a78ed1a1b 100644 --- a/components/esm/loadglob.cpp +++ b/components/esm/loadglob.cpp @@ -1,7 +1,11 @@ #include "loadglob.hpp" +#include "defs.hpp" + namespace ESM { + unsigned int Global::sRecordId = REC_GLOB; + void Global::load (ESMReader &esm) { mValue.read (esm, ESM::Variant::Format_Global); diff --git a/components/esm/loadglob.hpp b/components/esm/loadglob.hpp index 06ff97ef2..51b2e2dc9 100644 --- a/components/esm/loadglob.hpp +++ b/components/esm/loadglob.hpp @@ -17,6 +17,8 @@ class ESMWriter; struct Global { + static unsigned int sRecordId; + std::string mId; Variant mValue; diff --git a/components/esm/loadgmst.cpp b/components/esm/loadgmst.cpp index 3a7df4506..21d66339a 100644 --- a/components/esm/loadgmst.cpp +++ b/components/esm/loadgmst.cpp @@ -1,7 +1,11 @@ #include "loadgmst.hpp" +#include "defs.hpp" + namespace ESM { + unsigned int GameSetting::sRecordId = REC_GMST; + void GameSetting::load (ESMReader &esm) { mValue.read (esm, ESM::Variant::Format_Gmst); diff --git a/components/esm/loadgmst.hpp b/components/esm/loadgmst.hpp index 9c37c7da0..6b66ac832 100644 --- a/components/esm/loadgmst.hpp +++ b/components/esm/loadgmst.hpp @@ -18,6 +18,8 @@ class ESMWriter; struct GameSetting { + static unsigned int sRecordId; + std::string mId; Variant mValue; diff --git a/components/esm/loadinfo.cpp b/components/esm/loadinfo.cpp index 1985da2cd..4f248cc65 100644 --- a/components/esm/loadinfo.cpp +++ b/components/esm/loadinfo.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int DialInfo::sRecordId = REC_INFO; void DialInfo::load(ESMReader &esm) { diff --git a/components/esm/loadinfo.hpp b/components/esm/loadinfo.hpp index 351768e96..2589ea7b8 100644 --- a/components/esm/loadinfo.hpp +++ b/components/esm/loadinfo.hpp @@ -20,6 +20,8 @@ class ESMWriter; struct DialInfo { + static unsigned int sRecordId; + enum Gender { Male = 0, diff --git a/components/esm/loadingr.cpp b/components/esm/loadingr.cpp index 1bc9ae41c..0e0243362 100644 --- a/components/esm/loadingr.cpp +++ b/components/esm/loadingr.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Ingredient::sRecordId = REC_INGR; void Ingredient::load(ESMReader &esm) { diff --git a/components/esm/loadingr.hpp b/components/esm/loadingr.hpp index 03e67924c..85f2d5e7d 100644 --- a/components/esm/loadingr.hpp +++ b/components/esm/loadingr.hpp @@ -15,6 +15,8 @@ class ESMWriter; struct Ingredient { + static unsigned int sRecordId; + struct IRDTstruct { float mWeight; diff --git a/components/esm/loadland.cpp b/components/esm/loadland.cpp index 8e54bcc5c..ede200d79 100644 --- a/components/esm/loadland.cpp +++ b/components/esm/loadland.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Land::sRecordId = REC_LAND; void Land::LandData::save(ESMWriter &esm) { diff --git a/components/esm/loadland.hpp b/components/esm/loadland.hpp index 3d3bcd67b..5649f9980 100644 --- a/components/esm/loadland.hpp +++ b/components/esm/loadland.hpp @@ -17,6 +17,8 @@ class ESMWriter; struct Land { + static unsigned int sRecordId; + Land(); ~Land(); diff --git a/components/esm/loadlevlist.cpp b/components/esm/loadlevlist.cpp index ab3f5e9e6..6385b9a71 100644 --- a/components/esm/loadlevlist.cpp +++ b/components/esm/loadlevlist.cpp @@ -2,6 +2,7 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { @@ -52,4 +53,8 @@ void LeveledListBase::save(ESMWriter &esm) const mChanceNone = 0; mList.clear(); } + + unsigned int CreatureLevList::sRecordId = REC_LEVC; + + unsigned int ItemLevList::sRecordId = REC_LEVI; } diff --git a/components/esm/loadlevlist.hpp b/components/esm/loadlevlist.hpp index f5fb7fd5b..9dcc6177a 100644 --- a/components/esm/loadlevlist.hpp +++ b/components/esm/loadlevlist.hpp @@ -59,6 +59,8 @@ struct LeveledListBase struct CreatureLevList: LeveledListBase { + static unsigned int sRecordId; + CreatureLevList() { mRecName = "CNAM"; @@ -67,6 +69,8 @@ struct CreatureLevList: LeveledListBase struct ItemLevList: LeveledListBase { + static unsigned int sRecordId; + ItemLevList() { mRecName = "INAM"; diff --git a/components/esm/loadligh.cpp b/components/esm/loadligh.cpp index 3f279c7c8..c02bb46b6 100644 --- a/components/esm/loadligh.cpp +++ b/components/esm/loadligh.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Light::sRecordId = REC_LIGH; void Light::load(ESMReader &esm) { diff --git a/components/esm/loadligh.hpp b/components/esm/loadligh.hpp index 9a341f0de..74eb37197 100644 --- a/components/esm/loadligh.hpp +++ b/components/esm/loadligh.hpp @@ -16,6 +16,8 @@ class ESMWriter; struct Light { + static unsigned int sRecordId; + enum Flags { Dynamic = 0x001, diff --git a/components/esm/loadlock.cpp b/components/esm/loadlock.cpp index 318769ec0..9ffce78a7 100644 --- a/components/esm/loadlock.cpp +++ b/components/esm/loadlock.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Lockpick::sRecordId = REC_LOCK; void Lockpick::load(ESMReader &esm) { diff --git a/components/esm/loadlock.hpp b/components/esm/loadlock.hpp index aea5a4f31..c44e2b006 100644 --- a/components/esm/loadlock.hpp +++ b/components/esm/loadlock.hpp @@ -11,6 +11,8 @@ class ESMWriter; struct Lockpick { + static unsigned int sRecordId; + struct Data { float mWeight; diff --git a/components/esm/loadltex.cpp b/components/esm/loadltex.cpp index dc1bc164b..bd28c8488 100644 --- a/components/esm/loadltex.cpp +++ b/components/esm/loadltex.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int LandTexture::sRecordId = REC_LTEX; void LandTexture::load(ESMReader &esm) { diff --git a/components/esm/loadltex.hpp b/components/esm/loadltex.hpp index 3d0816948..5e84428b2 100644 --- a/components/esm/loadltex.hpp +++ b/components/esm/loadltex.hpp @@ -27,6 +27,8 @@ class ESMWriter; struct LandTexture { + static unsigned int sRecordId; + std::string mId, mTexture; int mIndex; diff --git a/components/esm/loadmgef.cpp b/components/esm/loadmgef.cpp index 9eaeff704..332c27786 100644 --- a/components/esm/loadmgef.cpp +++ b/components/esm/loadmgef.cpp @@ -6,6 +6,7 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace { @@ -34,6 +35,7 @@ namespace namespace ESM { + unsigned int MagicEffect::sRecordId = REC_MGEF; void MagicEffect::load(ESMReader &esm) { diff --git a/components/esm/loadmgef.hpp b/components/esm/loadmgef.hpp index 220b3bdf3..613cbd2d8 100644 --- a/components/esm/loadmgef.hpp +++ b/components/esm/loadmgef.hpp @@ -12,6 +12,8 @@ class ESMWriter; struct MagicEffect { + static unsigned int sRecordId; + enum Flags { TargetSkill = 0x1, // Affects a specific skill, which is specified elsewhere in the effect structure. diff --git a/components/esm/loadmisc.cpp b/components/esm/loadmisc.cpp index a183821b7..2ca09e8ae 100644 --- a/components/esm/loadmisc.cpp +++ b/components/esm/loadmisc.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Miscellaneous::sRecordId = REC_MISC; void Miscellaneous::load(ESMReader &esm) { diff --git a/components/esm/loadmisc.hpp b/components/esm/loadmisc.hpp index 452eea53e..576bd18c0 100644 --- a/components/esm/loadmisc.hpp +++ b/components/esm/loadmisc.hpp @@ -16,6 +16,8 @@ class ESMWriter; struct Miscellaneous { + static unsigned int sRecordId; + struct MCDTstruct { float mWeight; diff --git a/components/esm/loadnpc.cpp b/components/esm/loadnpc.cpp index 7c26cb549..9fff2d885 100644 --- a/components/esm/loadnpc.cpp +++ b/components/esm/loadnpc.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int NPC::sRecordId = REC_NPC_; void NPC::load(ESMReader &esm) { diff --git a/components/esm/loadnpc.hpp b/components/esm/loadnpc.hpp index 009548c59..d9e691669 100644 --- a/components/esm/loadnpc.hpp +++ b/components/esm/loadnpc.hpp @@ -20,6 +20,8 @@ class ESMWriter; struct NPC { + static unsigned int sRecordId; + // Services enum Services { diff --git a/components/esm/loadnpcc.hpp b/components/esm/loadnpcc.hpp index f023fd217..c87c2545f 100644 --- a/components/esm/loadnpcc.hpp +++ b/components/esm/loadnpcc.hpp @@ -78,6 +78,8 @@ class ESMWriter; struct LoadNPCC { + static unsigned int sRecordId; + std::string mId; void load(ESMReader &esm) diff --git a/components/esm/loadpgrd.cpp b/components/esm/loadpgrd.cpp index 65d1f8055..3b5330e9f 100644 --- a/components/esm/loadpgrd.cpp +++ b/components/esm/loadpgrd.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Pathgrid::sRecordId = REC_PGRD; void Pathgrid::load(ESMReader &esm) { diff --git a/components/esm/loadpgrd.hpp b/components/esm/loadpgrd.hpp index d14433a78..9ee49552d 100644 --- a/components/esm/loadpgrd.hpp +++ b/components/esm/loadpgrd.hpp @@ -15,6 +15,8 @@ class ESMWriter; */ struct Pathgrid { + static unsigned int sRecordId; + struct DATAstruct { int mX, mY; // Grid location, matches cell for exterior cells diff --git a/components/esm/loadprob.cpp b/components/esm/loadprob.cpp index 0fb4c9750..caa3d7e0e 100644 --- a/components/esm/loadprob.cpp +++ b/components/esm/loadprob.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Probe::sRecordId = REC_PROB; void Probe::load(ESMReader &esm) { diff --git a/components/esm/loadprob.hpp b/components/esm/loadprob.hpp index d0a8256ab..b89b2ddeb 100644 --- a/components/esm/loadprob.hpp +++ b/components/esm/loadprob.hpp @@ -11,6 +11,8 @@ class ESMWriter; struct Probe { + static unsigned int sRecordId; + struct Data { float mWeight; diff --git a/components/esm/loadrace.cpp b/components/esm/loadrace.cpp index e9e1d0d79..e50e43a74 100644 --- a/components/esm/loadrace.cpp +++ b/components/esm/loadrace.cpp @@ -2,9 +2,12 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Race::sRecordId = REC_RACE; + int Race::MaleFemale::getValue (bool male) const { return male ? mMale : mFemale; diff --git a/components/esm/loadrace.hpp b/components/esm/loadrace.hpp index a53a98070..7d5736d9b 100644 --- a/components/esm/loadrace.hpp +++ b/components/esm/loadrace.hpp @@ -17,6 +17,8 @@ class ESMWriter; struct Race { + static unsigned int sRecordId; + struct SkillBonus { int mSkill; // SkillEnum diff --git a/components/esm/loadregn.cpp b/components/esm/loadregn.cpp index fd42b9ee8..fa4271e26 100644 --- a/components/esm/loadregn.cpp +++ b/components/esm/loadregn.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Region::sRecordId = REC_REGN; void Region::load(ESMReader &esm) { diff --git a/components/esm/loadregn.hpp b/components/esm/loadregn.hpp index a6075d65a..1992c951b 100644 --- a/components/esm/loadregn.hpp +++ b/components/esm/loadregn.hpp @@ -18,6 +18,8 @@ class ESMWriter; struct Region { + static unsigned int sRecordId; + #pragma pack(push) #pragma pack(1) struct WEATstruct diff --git a/components/esm/loadrepa.cpp b/components/esm/loadrepa.cpp index 59bfa0169..a7132828d 100644 --- a/components/esm/loadrepa.cpp +++ b/components/esm/loadrepa.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Repair::sRecordId = REC_REPA; void Repair::load(ESMReader &esm) { diff --git a/components/esm/loadrepa.hpp b/components/esm/loadrepa.hpp index 771e7ead0..5b404b0e4 100644 --- a/components/esm/loadrepa.hpp +++ b/components/esm/loadrepa.hpp @@ -11,6 +11,8 @@ class ESMWriter; struct Repair { + static unsigned int sRecordId; + struct Data { float mWeight; diff --git a/components/esm/loadscpt.cpp b/components/esm/loadscpt.cpp index 8afb85602..30460c17a 100644 --- a/components/esm/loadscpt.cpp +++ b/components/esm/loadscpt.cpp @@ -2,6 +2,7 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { @@ -12,6 +13,8 @@ struct SCHD Script::SCHDstruct mData; }; + unsigned int Script::sRecordId = REC_SCPT; + void Script::load(ESMReader &esm) { SCHD data; diff --git a/components/esm/loadscpt.hpp b/components/esm/loadscpt.hpp index 450224faa..d5200d4c1 100644 --- a/components/esm/loadscpt.hpp +++ b/components/esm/loadscpt.hpp @@ -19,6 +19,8 @@ class ESMWriter; class Script { public: + static unsigned int sRecordId; + struct SCHDstruct { /* Script name. diff --git a/components/esm/loadskil.cpp b/components/esm/loadskil.cpp index f6a2c4950..b6724e938 100644 --- a/components/esm/loadskil.cpp +++ b/components/esm/loadskil.cpp @@ -6,6 +6,7 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { @@ -126,6 +127,8 @@ namespace ESM HandToHand }}; + unsigned int Skill::sRecordId = REC_SKIL; + void Skill::load(ESMReader &esm) { esm.getHNT(mIndex, "INDX"); diff --git a/components/esm/loadskil.hpp b/components/esm/loadskil.hpp index 2436173cb..1b9db5bcf 100644 --- a/components/esm/loadskil.hpp +++ b/components/esm/loadskil.hpp @@ -19,6 +19,8 @@ class ESMWriter; struct Skill { + static unsigned int sRecordId; + std::string mId; struct SKDTstruct diff --git a/components/esm/loadsndg.cpp b/components/esm/loadsndg.cpp index 9b992c960..1a8ca6335 100644 --- a/components/esm/loadsndg.cpp +++ b/components/esm/loadsndg.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int SoundGenerator::sRecordId = REC_SNDG; void SoundGenerator::load(ESMReader &esm) { diff --git a/components/esm/loadsndg.hpp b/components/esm/loadsndg.hpp index 2756676ef..5509661c1 100644 --- a/components/esm/loadsndg.hpp +++ b/components/esm/loadsndg.hpp @@ -15,6 +15,8 @@ class ESMWriter; struct SoundGenerator { + static unsigned int sRecordId; + enum Type { LeftFoot = 0, diff --git a/components/esm/loadsoun.cpp b/components/esm/loadsoun.cpp index 0f6b0f84a..49c9eb54e 100644 --- a/components/esm/loadsoun.cpp +++ b/components/esm/loadsoun.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Sound::sRecordId = REC_SOUN; void Sound::load(ESMReader &esm) { diff --git a/components/esm/loadsoun.hpp b/components/esm/loadsoun.hpp index 6c9bb1fed..04a0984fd 100644 --- a/components/esm/loadsoun.hpp +++ b/components/esm/loadsoun.hpp @@ -16,6 +16,8 @@ struct SOUNstruct struct Sound { + static unsigned int sRecordId; + SOUNstruct mData; std::string mId, mSound; diff --git a/components/esm/loadspel.cpp b/components/esm/loadspel.cpp index 5c0bd956f..2c98d796d 100644 --- a/components/esm/loadspel.cpp +++ b/components/esm/loadspel.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Spell::sRecordId = REC_SPEL; void Spell::load(ESMReader &esm) { diff --git a/components/esm/loadspel.hpp b/components/esm/loadspel.hpp index b34bd29f1..cbf5366c4 100644 --- a/components/esm/loadspel.hpp +++ b/components/esm/loadspel.hpp @@ -13,6 +13,8 @@ class ESMWriter; struct Spell { + static unsigned int sRecordId; + enum SpellType { ST_Spell = 0, // Normal spell, must be cast and costs mana diff --git a/components/esm/loadsscr.cpp b/components/esm/loadsscr.cpp index f51b7be47..69b04bb23 100644 --- a/components/esm/loadsscr.cpp +++ b/components/esm/loadsscr.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int StartScript::sRecordId = REC_SSCR; void StartScript::load(ESMReader &esm) { diff --git a/components/esm/loadsscr.hpp b/components/esm/loadsscr.hpp index 2326f00f4..d09ad883e 100644 --- a/components/esm/loadsscr.hpp +++ b/components/esm/loadsscr.hpp @@ -19,6 +19,8 @@ class ESMWriter; struct StartScript { + static unsigned int sRecordId; + std::string mData; std::string mId, mScript; diff --git a/components/esm/loadstat.cpp b/components/esm/loadstat.cpp index 38206422b..a71f22dc2 100644 --- a/components/esm/loadstat.cpp +++ b/components/esm/loadstat.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Static::sRecordId = REC_STAT; void Static::load(ESMReader &esm) { diff --git a/components/esm/loadstat.hpp b/components/esm/loadstat.hpp index df42c0c49..d912d1058 100644 --- a/components/esm/loadstat.hpp +++ b/components/esm/loadstat.hpp @@ -22,6 +22,8 @@ class ESMWriter; struct Static { + static unsigned int sRecordId; + std::string mId, mModel; void load(ESMReader &esm); diff --git a/components/esm/loadtes3.cpp b/components/esm/loadtes3.cpp index 74d578ba7..a86c9b6f4 100644 --- a/components/esm/loadtes3.cpp +++ b/components/esm/loadtes3.cpp @@ -4,6 +4,7 @@ #include "esmcommon.hpp" #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" void ESM::Header::blank() { diff --git a/components/esm/loadweap.cpp b/components/esm/loadweap.cpp index e21d8924a..1d0b149df 100644 --- a/components/esm/loadweap.cpp +++ b/components/esm/loadweap.cpp @@ -2,9 +2,11 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" namespace ESM { + unsigned int Weapon::sRecordId = REC_WEAP; void Weapon::load(ESMReader &esm) { diff --git a/components/esm/loadweap.hpp b/components/esm/loadweap.hpp index 42810d3af..fde716b91 100644 --- a/components/esm/loadweap.hpp +++ b/components/esm/loadweap.hpp @@ -15,6 +15,8 @@ class ESMWriter; struct Weapon { + static unsigned int sRecordId; + enum Type { ShortBladeOneHand = 0, From e4fdebc85b917e5608c9da75eb9af8180c766105 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 24 Sep 2013 13:53:19 +0200 Subject: [PATCH 051/118] added saving for referenceable records --- apps/opencs/model/doc/saving.cpp | 2 ++ apps/opencs/model/doc/savingstages.cpp | 15 ++++++++++ apps/opencs/model/doc/savingstages.hpp | 17 +++++++++++ apps/opencs/model/world/refidcollection.cpp | 5 ++++ apps/opencs/model/world/refidcollection.hpp | 7 +++++ apps/opencs/model/world/refiddata.cpp | 13 +++++++++ apps/opencs/model/world/refiddata.hpp | 32 +++++++++++++++++++++ 7 files changed, 91 insertions(+) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index c9035cfd4..98af661fd 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -48,6 +48,8 @@ CSMDoc::Saving::Saving (Document& document) appendStage (new WriteCollectionStage > (mDocument.getData().getSpells(), mState)); + appendStage (new WriteRefIdCollectionStage (mDocument, mState)); + appendStage (new CloseSaveStage (mState)); diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index fd6234594..5da92f014 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -67,6 +67,21 @@ void CSMDoc::WriteHeaderStage::perform (int stage, std::vector& mes } +CSMDoc::WriteRefIdCollectionStage::WriteRefIdCollectionStage (Document& document, SavingState& state) +: mDocument (document), mState (state) +{} + +int CSMDoc::WriteRefIdCollectionStage::setup() +{ + return mDocument.getData().getReferenceables().getSize(); +} + +void CSMDoc::WriteRefIdCollectionStage::perform (int stage, std::vector& messages) +{ + mDocument.getData().getReferenceables().save (stage, mState.getWriter()); +} + + CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state) : mState (state) {} diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index d5c4a69af..2d32f38cb 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -99,6 +99,23 @@ namespace CSMDoc } + class WriteRefIdCollectionStage : public Stage + { + Document& mDocument; + SavingState& mState; + + public: + + WriteRefIdCollectionStage (Document& document, SavingState& state); + + virtual int setup(); + ///< \return number of steps + + virtual void perform (int stage, std::vector& messages); + ///< Messages resulting from this stage will be appended to \a messages. + }; + + class CloseSaveStage : public Stage { SavingState& mState; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index cda2711cc..3a6f70d31 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -539,3 +539,8 @@ std::vector CSMWorld::RefIdCollection::getIds (bool listDeleted) co { return mData.getIds (listDeleted); } + +void CSMWorld::RefIdCollection::save (int index, ESM::ESMWriter& writer) const +{ + mData.save (index, writer); +} \ No newline at end of file diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 22f83150d..a479735db 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -9,6 +9,11 @@ #include "collectionbase.hpp" #include "refiddata.hpp" +namespace ESM +{ + class ESMWriter; +} + namespace CSMWorld { class RefIdAdapter; @@ -94,6 +99,8 @@ namespace CSMWorld ///< Return a sorted collection of all IDs /// /// \param listDeleted include deleted record in the list + + void save (int index, ESM::ESMWriter& writer) const; }; } diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 9457937f1..8f59b0fe7 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -218,3 +218,16 @@ std::vector CSMWorld::RefIdData::getIds (bool listDeleted) const return ids; } + +void CSMWorld::RefIdData::save (int index, ESM::ESMWriter& writer) const +{ + LocalIndex localIndex = globalToLocalIndex (index); + + std::map::const_iterator iter = + mRecordContainers.find (localIndex.second); + + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + iter->second->save (localIndex.first, writer); +} \ No newline at end of file diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index e221fbc7c..9595ab23b 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "record.hpp" #include "universalid.hpp" @@ -51,6 +52,8 @@ namespace CSMWorld virtual void erase (int index, int count) = 0; virtual std::string getId (int index) const = 0; + + virtual void save (int index, ESM::ESMWriter& writer) const = 0; }; template @@ -71,6 +74,8 @@ namespace CSMWorld virtual void erase (int index, int count); virtual std::string getId (int index) const; + + virtual void save (int index, ESM::ESMWriter& writer) const; }; template @@ -123,6 +128,31 @@ namespace CSMWorld return mContainer.at (index).get().mId; } + template + void RefIdDataContainer::save (int index, ESM::ESMWriter& writer) const + { + CSMWorld::RecordBase::State state = mContainer.at (index).mState; + + if (state==CSMWorld::RecordBase::State_Modified || + state==CSMWorld::RecordBase::State_ModifiedOnly) + { + std::string type; + for (int i=0; i<4; ++i) + /// \todo make endianess agnostic (change ESMWriter interface?) + type += reinterpret_cast (&mContainer.at (index).mModified.sRecordId)[i]; + + writer.startRecord (type); + writer.writeHNCString ("NAME", getId (index)); + mContainer.at (index).mModified.save (writer); + writer.endRecord (type); + } + else if (state==CSMWorld::RecordBase::State_Deleted) + { + /// \todo write record with delete flag + } + } + + class RefIdData { public: @@ -187,6 +217,8 @@ namespace CSMWorld ///< Return a sorted collection of all IDs /// /// \param listDeleted include deleted record in the list + + void save (int index, ESM::ESMWriter& writer) const; }; } From 830530bd063e9a14819c6cf6cb263d6e4a1b32c4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 24 Sep 2013 17:08:24 +0200 Subject: [PATCH 052/118] set record count in TES3 header --- apps/opencs/model/doc/savingstages.cpp | 5 ++++- apps/opencs/model/world/data.cpp | 29 ++++++++++++++++++++++++++ apps/opencs/model/world/data.hpp | 5 +++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 5da92f014..ee2943ef4 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -48,7 +48,10 @@ void CSMDoc::WriteHeaderStage::perform (int stage, std::vector& mes /// \todo fill in missing header information mState.getWriter().setAuthor (""); mState.getWriter().setDescription (""); - mState.getWriter().setRecordCount (0); + mState.getWriter().setRecordCount ( + mDocument.getData().count (CSMWorld::RecordBase::State_Modified) + + mDocument.getData().count (CSMWorld::RecordBase::State_ModifiedOnly) + + mDocument.getData().count (CSMWorld::RecordBase::State_Deleted)); /// \todo refine dependency list (at least remove redundant dependencies) std::vector dependencies = mDocument.getContentFiles(); diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 7eb96a5c3..1bd818db4 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -43,6 +43,17 @@ void CSMWorld::Data::appendIds (std::vector& ids, const CollectionB ids.insert (ids.end(), ids2.begin(), ids2.end()); } +int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collection) +{ + int number = 0; + + for (int i=0; i); @@ -460,6 +471,24 @@ bool CSMWorld::Data::hasId (const std::string& id) const getReferenceables().searchId (id)!=-1; } +int CSMWorld::Data::count (RecordBase::State state) const +{ + return + count (state, mGlobals) + + count (state, mGmsts) + + count (state, mSkills) + + count (state, mClasses) + + count (state, mFactions) + + count (state, mRaces) + + count (state, mSounds) + + count (state, mScripts) + + count (state, mRegions) + + count (state, mBirthsigns) + + count (state, mSpells) + + count (state, mCells) + + count (state, mReferenceables); +} + std::vector CSMWorld::Data::getIds (bool listDeleted) const { std::vector ids; diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index e900bb10f..ebbafe711 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -66,6 +66,8 @@ namespace CSMWorld bool listDeleted); ///< Append all IDs from collection to \a ids. + static int count (RecordBase::State state, const CollectionBase& collection); + public: Data(); @@ -151,6 +153,9 @@ namespace CSMWorld /// /// \param listDeleted include deleted record in the list + int count (RecordBase::State state) const; + ///< Return number of top-level records with the given \a state. + signals: void idListChanged(); From 96fd1c35bf3e4296dc0ce012a47f049e6e87ec5d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 24 Sep 2013 17:17:01 +0200 Subject: [PATCH 053/118] preserve author/descriptin meta data --- apps/opencs/model/doc/document.cpp | 6 ++++++ apps/opencs/model/doc/savingstages.cpp | 5 ++--- apps/opencs/model/world/data.cpp | 23 +++++++++++++++++++++++ apps/opencs/model/world/data.hpp | 10 ++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 37294bcd1..f496d32ec 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2158,6 +2158,12 @@ CSMDoc::Document::Document (const std::vector& files, load (files.begin(), end, !new_); } + if (new_) + { + mData.setDescription (""); + mData.setAuthor (""); + } + addOptionalGmsts(); addOptionalGlobals(); diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index ee2943ef4..23a88bc17 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -45,9 +45,8 @@ void CSMDoc::WriteHeaderStage::perform (int stage, std::vector& mes mState.getWriter().setFormat (0); - /// \todo fill in missing header information - mState.getWriter().setAuthor (""); - mState.getWriter().setDescription (""); + mState.getWriter().setAuthor (mDocument.getData().getAuthor()); + mState.getWriter().setDescription (mDocument.getData().getDescription()); mState.getWriter().setRecordCount ( mDocument.getData().count (CSMWorld::RecordBase::State_Modified) + mDocument.getData().count (CSMWorld::RecordBase::State_ModifiedOnly) + diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 1bd818db4..c6423b76a 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -395,6 +395,9 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) reader.open (path.string()); + mAuthor = reader.getAuthor(); + mDescription = reader.getDesc(); + // Note: We do not need to send update signals here, because at this point the model is not connected // to any view. while (reader.hasMoreRecs()) @@ -489,6 +492,26 @@ int CSMWorld::Data::count (RecordBase::State state) const count (state, mReferenceables); } +void CSMWorld::Data::setDescription (const std::string& description) +{ + mDescription = description; +} + +std::string CSMWorld::Data::getDescription() const +{ + return mDescription; +} + +void CSMWorld::Data::setAuthor (const std::string& author) +{ + mAuthor = author; +} + +std::string CSMWorld::Data::getAuthor() const +{ + return mAuthor; +} + std::vector CSMWorld::Data::getIds (bool listDeleted) const { std::vector ids; diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index ebbafe711..eb6325a25 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -54,6 +54,8 @@ namespace CSMWorld IdCollection mFilters; std::vector mModels; std::map mModelIndex; + std::string mAuthor; + std::string mDescription; // not implemented Data (const Data&); @@ -156,6 +158,14 @@ namespace CSMWorld int count (RecordBase::State state) const; ///< Return number of top-level records with the given \a state. + void setDescription (const std::string& description); + + std::string getDescription() const; + + void setAuthor (const std::string& author); + + std::string getAuthor() const; + signals: void idListChanged(); From 5779f799ab064d72cf9641aaccdd8107d50c098b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Sep 2013 11:36:06 +0200 Subject: [PATCH 054/118] create project file when saving content file --- apps/opencs/editor.cpp | 3 +- apps/opencs/editor.hpp | 2 +- apps/opencs/model/doc/document.cpp | 5 +- apps/opencs/model/doc/document.hpp | 5 +- apps/opencs/model/doc/documentmanager.cpp | 15 +++++- apps/opencs/model/doc/documentmanager.hpp | 4 +- apps/opencs/model/doc/saving.cpp | 16 +++++-- apps/opencs/model/doc/saving.hpp | 4 +- apps/opencs/model/doc/savingstages.cpp | 58 ++++++++++++++--------- apps/opencs/model/doc/savingstages.hpp | 8 +++- apps/opencs/model/doc/savingstate.cpp | 19 ++++++-- apps/opencs/model/doc/savingstate.hpp | 10 +++- components/esm/esmwriter.cpp | 5 ++ components/esm/esmwriter.hpp | 2 + components/esm/loadtes3.cpp | 1 + 15 files changed, 113 insertions(+), 44 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 800f3984e..ead4d2a98 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -10,7 +10,8 @@ #include "model/world/data.hpp" -CS::Editor::Editor() : mViewManager (mDocumentManager) +CS::Editor::Editor() +: mDocumentManager (mCfgMgr.getUserPath() / "projects"), mViewManager (mDocumentManager) { mIpcServerName = "org.openmw.OpenCS"; diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index abf9496e4..16f6b9516 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -26,6 +26,7 @@ namespace CS { Q_OBJECT + Files::ConfigurationManager mCfgMgr; CSMSettings::UserSettings mUserSettings; CSMDoc::DocumentManager mDocumentManager; CSVDoc::ViewManager mViewManager; @@ -34,7 +35,6 @@ namespace CS CSVSettings::UserSettingsDialog mSettings; CSVDoc::FileDialog mFileDialog; - Files::ConfigurationManager mCfgMgr; boost::filesystem::path mLocal; void setupDataFiles(); diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index f496d32ec..f9aa7dfc0 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2140,8 +2140,9 @@ void CSMDoc::Document::createBase() } CSMDoc::Document::Document (const std::vector& files, - const boost::filesystem::path& savePath, bool new_) -: mSavePath (savePath), mContentFiles (files), mTools (mData), mSaving (*this) + const boost::filesystem::path& savePath, bool new_, + const boost::filesystem::path& projectPath) +: mSavePath (savePath), mContentFiles (files), mTools (mData), mSaving (*this, projectPath) { if (files.empty()) throw std::runtime_error ("Empty content file sequence"); diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index b1c6a0273..979b47734 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -65,7 +65,10 @@ namespace CSMDoc public: Document (const std::vector& files, - const boost::filesystem::path& savePath, bool new_); + const boost::filesystem::path& savePath, bool new_, + const boost::filesystem::path& projectPath); + ///< \param projectPath Location of file that can be used to store additional data for + /// this project. ~Document(); diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index b079109ea..1978c0e53 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -4,9 +4,16 @@ #include #include +#include + #include "document.hpp" -CSMDoc::DocumentManager::DocumentManager() {} +CSMDoc::DocumentManager::DocumentManager (const boost::filesystem::path& projectPath) +: mProjectPath (projectPath) +{ + if (!boost::filesystem::is_directory (mProjectPath)) + boost::filesystem::create_directories (mProjectPath); +} CSMDoc::DocumentManager::~DocumentManager() { @@ -17,7 +24,11 @@ CSMDoc::DocumentManager::~DocumentManager() CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::vector& files, const boost::filesystem::path& savePath, bool new_) { - Document *document = new Document (files, savePath, new_); + boost::filesystem::path projectFile (mProjectPath); + + projectFile /= savePath.filename().string() + ".project"; + + Document *document = new Document (files, savePath, new_, projectFile); mDocuments.push_back (document); diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index dfded8d5c..622a135a5 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -13,13 +13,15 @@ namespace CSMDoc class DocumentManager { std::vector mDocuments; + boost::filesystem::path mProjectPath; DocumentManager (const DocumentManager&); DocumentManager& operator= (const DocumentManager&); public: - DocumentManager(); + DocumentManager (const boost::filesystem::path& projectPath); + ///< \param projectPath Directory where additional per-project data will be stored. ~DocumentManager(); diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index 98af661fd..adcfca576 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -8,12 +8,20 @@ #include "savingstages.hpp" #include "document.hpp" -CSMDoc::Saving::Saving (Document& document) -: Operation (State_Saving, true, true), mDocument (document), mState (*this) +CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& projectPath) +: Operation (State_Saving, true, true), mDocument (document), mState (*this, projectPath) { - appendStage (new OpenSaveStage (mDocument, mState)); + // save project file + appendStage (new OpenSaveStage (mDocument, mState, true)); - appendStage (new WriteHeaderStage (mDocument, mState)); + appendStage (new WriteHeaderStage (mDocument, mState, true)); + + appendStage (new CloseSaveStage (mState)); + + // save content file + appendStage (new OpenSaveStage (mDocument, mState, false)); + + appendStage (new WriteHeaderStage (mDocument, mState, false)); appendStage (new WriteCollectionStage > (mDocument.getData().getGlobals(), mState)); diff --git a/apps/opencs/model/doc/saving.hpp b/apps/opencs/model/doc/saving.hpp index b89ba5f6d..cd1bbef98 100644 --- a/apps/opencs/model/doc/saving.hpp +++ b/apps/opencs/model/doc/saving.hpp @@ -1,6 +1,8 @@ #ifndef CSM_DOC_SAVING_H #define CSM_DOC_SAVING_H +#include + #include "operation.hpp" #include "savingstate.hpp" @@ -17,7 +19,7 @@ namespace CSMDoc public: - Saving (Document& document); + Saving (Document& document, const boost::filesystem::path& projectPath); }; } diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 23a88bc17..d48e22012 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -10,8 +10,8 @@ #include "document.hpp" #include "savingstate.hpp" -CSMDoc::OpenSaveStage::OpenSaveStage (Document& document, SavingState& state) -: mDocument (document), mState (state) +CSMDoc::OpenSaveStage::OpenSaveStage (Document& document, SavingState& state, bool projectFile) +: mDocument (document), mState (state), mProjectFile (projectFile) {} int CSMDoc::OpenSaveStage::setup() @@ -21,17 +21,17 @@ int CSMDoc::OpenSaveStage::setup() void CSMDoc::OpenSaveStage::perform (int stage, std::vector& messages) { - mState.start (mDocument); + mState.start (mDocument, mProjectFile); - mState.getStream().open (mState.getTmpPath().string().c_str()); + mState.getStream().open ((mProjectFile ? mState.getPath() : mState.getTmpPath()).string().c_str()); if (!mState.getStream().is_open()) throw std::runtime_error ("failed to open stream for saving"); } -CSMDoc::WriteHeaderStage::WriteHeaderStage (Document& document, SavingState& state) -: mDocument (document), mState (state) +CSMDoc::WriteHeaderStage::WriteHeaderStage (Document& document, SavingState& state, bool simple) +: mDocument (document), mState (state), mSimple (simple) {} int CSMDoc::WriteHeaderStage::setup() @@ -43,26 +43,38 @@ void CSMDoc::WriteHeaderStage::perform (int stage, std::vector& mes { mState.getWriter().setVersion(); - mState.getWriter().setFormat (0); + mState.getWriter().clearMaster(); - mState.getWriter().setAuthor (mDocument.getData().getAuthor()); - mState.getWriter().setDescription (mDocument.getData().getDescription()); - mState.getWriter().setRecordCount ( - mDocument.getData().count (CSMWorld::RecordBase::State_Modified) + - mDocument.getData().count (CSMWorld::RecordBase::State_ModifiedOnly) + - mDocument.getData().count (CSMWorld::RecordBase::State_Deleted)); - - /// \todo refine dependency list (at least remove redundant dependencies) - std::vector dependencies = mDocument.getContentFiles(); - std::vector::const_iterator end (--dependencies.end()); + mState.getWriter().setFormat (0); - for (std::vector::const_iterator iter (dependencies.begin()); - iter!=end; ++iter) + if (mSimple) { - std::string name = iter->filename().string(); - uint64_t size = boost::filesystem::file_size (*iter); + mState.getWriter().setAuthor (""); + mState.getWriter().setDescription (""); + mState.getWriter().setRecordCount (0); - mState.getWriter().addMaster (name, size); + } + else + { + mState.getWriter().setAuthor (mDocument.getData().getAuthor()); + mState.getWriter().setDescription (mDocument.getData().getDescription()); + mState.getWriter().setRecordCount ( + mDocument.getData().count (CSMWorld::RecordBase::State_Modified) + + mDocument.getData().count (CSMWorld::RecordBase::State_ModifiedOnly) + + mDocument.getData().count (CSMWorld::RecordBase::State_Deleted)); + + /// \todo refine dependency list (at least remove redundant dependencies) + std::vector dependencies = mDocument.getContentFiles(); + std::vector::const_iterator end (--dependencies.end()); + + for (std::vector::const_iterator iter (dependencies.begin()); + iter!=end; ++iter) + { + std::string name = iter->filename().string(); + uint64_t size = boost::filesystem::file_size (*iter); + + mState.getWriter().addMaster (name, size); + } } mState.getWriter().save (mState.getStream()); @@ -121,7 +133,7 @@ void CSMDoc::FinalSavingStage::perform (int stage, std::vector& mes if (boost::filesystem::exists (mState.getTmpPath())) boost::filesystem::remove (mState.getTmpPath()); } - else + else if (!mState.isProjectFile()) { if (boost::filesystem::exists (mState.getPath())) boost::filesystem::remove (mState.getPath()); diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index 2d32f38cb..367431fc1 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -16,10 +16,12 @@ namespace CSMDoc { Document& mDocument; SavingState& mState; + bool mProjectFile; public: - OpenSaveStage (Document& document, SavingState& state); + OpenSaveStage (Document& document, SavingState& state, bool projectFile); + ///< \param projectFile Saving the project file instead of the content file. virtual int setup(); ///< \return number of steps @@ -32,10 +34,12 @@ namespace CSMDoc { Document& mDocument; SavingState& mState; + bool mSimple; public: - WriteHeaderStage (Document& document, SavingState& state); + WriteHeaderStage (Document& document, SavingState& state, bool simple); + ///< \param simple Simplified header (used for project files). virtual int setup(); ///< \return number of steps diff --git a/apps/opencs/model/doc/savingstate.cpp b/apps/opencs/model/doc/savingstate.cpp index a49a0699b..4a1abb888 100644 --- a/apps/opencs/model/doc/savingstate.cpp +++ b/apps/opencs/model/doc/savingstate.cpp @@ -4,10 +4,11 @@ #include "operation.hpp" #include "document.hpp" -CSMDoc::SavingState::SavingState (Operation& operation) +CSMDoc::SavingState::SavingState (Operation& operation, const boost::filesystem::path& projectPath) : mOperation (operation), /// \todo set encoding properly, once config implementation has been fixed. - mEncoder (ToUTF8::calculateEncoding ("win1252")) + mEncoder (ToUTF8::calculateEncoding ("win1252")), + mProjectPath (projectPath), mProjectFile (false) { mWriter.setEncoder (&mEncoder); } @@ -17,14 +18,19 @@ bool CSMDoc::SavingState::hasError() const return mOperation.hasError(); } -void CSMDoc::SavingState::start (Document& document) +void CSMDoc::SavingState::start (Document& document, bool project) { + mProjectFile = project; + if (mStream.is_open()) mStream.close(); mStream.clear(); - mPath = document.getSavePath(); + if (project) + mPath = mProjectPath; + else + mPath = document.getSavePath(); boost::filesystem::path file (mPath.filename().string() + ".tmp"); @@ -51,4 +57,9 @@ std::ofstream& CSMDoc::SavingState::getStream() ESM::ESMWriter& CSMDoc::SavingState::getWriter() { return mWriter; +} + +bool CSMDoc::SavingState::isProjectFile() const +{ + return mProjectFile; } \ No newline at end of file diff --git a/apps/opencs/model/doc/savingstate.hpp b/apps/opencs/model/doc/savingstate.hpp index 3f42b4653..8cf7883e5 100644 --- a/apps/opencs/model/doc/savingstate.hpp +++ b/apps/opencs/model/doc/savingstate.hpp @@ -20,14 +20,17 @@ namespace CSMDoc ToUTF8::Utf8Encoder mEncoder; std::ofstream mStream; ESM::ESMWriter mWriter; + boost::filesystem::path mProjectPath; + bool mProjectFile; public: - SavingState (Operation& operation); + SavingState (Operation& operation, const boost::filesystem::path& projectPath); bool hasError() const; - void start (Document& document); + void start (Document& document, bool project); + ///< \param project Save project file instead of content file. const boost::filesystem::path& getPath() const; @@ -36,6 +39,9 @@ namespace CSMDoc std::ofstream& getStream(); ESM::ESMWriter& getWriter(); + + bool isProjectFile() const; + ///< Currently saving project file? (instead of content file) }; diff --git a/components/esm/esmwriter.cpp b/components/esm/esmwriter.cpp index 95ad44811..f39aa2b89 100644 --- a/components/esm/esmwriter.cpp +++ b/components/esm/esmwriter.cpp @@ -38,6 +38,11 @@ namespace ESM mHeader.mFormat = format; } + void ESMWriter::clearMaster() + { + mHeader.mMaster.clear(); + } + void ESMWriter::addMaster(const std::string& name, uint64_t size) { Header::MasterData d; diff --git a/components/esm/esmwriter.hpp b/components/esm/esmwriter.hpp index fc64c4a13..104f97f90 100644 --- a/components/esm/esmwriter.hpp +++ b/components/esm/esmwriter.hpp @@ -32,6 +32,8 @@ class ESMWriter void setRecordCount (int count); void setFormat (int format); + void clearMaster(); + void addMaster(const std::string& name, uint64_t size); void save(const std::string& file); diff --git a/components/esm/loadtes3.cpp b/components/esm/loadtes3.cpp index a86c9b6f4..87a8d1d57 100644 --- a/components/esm/loadtes3.cpp +++ b/components/esm/loadtes3.cpp @@ -14,6 +14,7 @@ void ESM::Header::blank() mData.desc.assign (""); mData.records = 0; mFormat = CurrentFormat; + mMaster.clear(); } void ESM::Header::load (ESMReader &esm) From 4ea5191d7d4c0ec38941f2e3731b4ee4a6e38925 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Sep 2013 13:17:04 +0200 Subject: [PATCH 055/118] fixed write function for ESM variant type --- components/esm/variantimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esm/variantimp.cpp b/components/esm/variantimp.cpp index 160402aa4..1bacdc077 100644 --- a/components/esm/variantimp.cpp +++ b/components/esm/variantimp.cpp @@ -193,7 +193,7 @@ void ESM::VariantIntegerData::write (ESMWriter& esm, Variant::Format format, Var } else if (format==Variant::Format_Gmst || format==Variant::Format_Info) { - if (type==VT_Int) + if (type!=VT_Int) { std::ostringstream stream; stream From 23095ec3ec5f934d74895b99dd5ad010cb42c4ce Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Sep 2013 13:54:21 +0200 Subject: [PATCH 056/118] added missing scope column to filter table --- apps/opencs/model/world/columnimp.hpp | 30 +++++++++++++++++++++++++++ apps/opencs/model/world/data.cpp | 1 + 2 files changed, 31 insertions(+) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 1a2bf9df1..f50212e56 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -1216,6 +1216,36 @@ namespace CSMWorld return true; } }; + + template + struct ScopeColumn : public Column + { + ScopeColumn() + : Column (Columns::ColumnId_Scope, ColumnBase::Display_Integer, 0) + {} + + virtual QVariant get (const Record& record) const + { + return static_cast (record.get().mScope); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + record2.mScope = static_cast (data.toInt()); + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + + virtual bool isUserEditable() const + { + return false; + } + }; } #endif diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index c6423b76a..a5e98fc60 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -182,6 +182,7 @@ CSMWorld::Data::Data() : mRefs (mCells) mFilters.addColumn (new RecordStateColumn); mFilters.addColumn (new FilterColumn); mFilters.addColumn (new DescriptionColumn); + mFilters.addColumn (new ScopeColumn); addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global); addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst); From 6f2c418a5cdd8d96b0d1c0afa859d8a06086349a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Sep 2013 13:54:51 +0200 Subject: [PATCH 057/118] (slightly) improved error reporting during save operations --- apps/opencs/model/doc/document.cpp | 7 +++++++ apps/opencs/model/doc/document.hpp | 2 ++ apps/opencs/model/doc/operation.cpp | 3 ++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index f9aa7dfc0..68e164c79 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2175,6 +2175,8 @@ CSMDoc::Document::Document (const std::vector& files, connect (&mSaving, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); connect (&mSaving, SIGNAL (done (int)), this, SLOT (operationDone (int))); + connect (&mSaving, SIGNAL (reportMessage (const QString&, int)), + this, SLOT (reportMessage (const QString&, int))); } CSMDoc::Document::~Document() @@ -2243,6 +2245,11 @@ void CSMDoc::Document::modificationStateChanged (bool clean) emit stateChanged (getState(), this); } +void CSMDoc::Document::reportMessage (const QString& message, int type) +{ + /// \todo find a better way to get these messages to the user. + std::cout << message.toUtf8().constData() << std::endl; +} void CSMDoc::Document::operationDone (int type) { diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 979b47734..7843cfbfe 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -105,6 +105,8 @@ namespace CSMDoc void modificationStateChanged (bool clean); + void reportMessage (const QString& message, int type); + void operationDone (int type); public slots: diff --git a/apps/opencs/model/doc/operation.cpp b/apps/opencs/model/doc/operation.cpp index 8af5a2c0d..d29cc2631 100644 --- a/apps/opencs/model/doc/operation.cpp +++ b/apps/opencs/model/doc/operation.cpp @@ -95,8 +95,9 @@ void CSMDoc::Operation::executeStage() { mCurrentStage->first->perform (mCurrentStep++, messages); } - catch (const std::exception&) + catch (const std::exception& e) { + emit reportMessage (e.what(), mType); abort(); } From 31346dde58090fed76333272d5593ef24eae96e4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Sep 2013 13:55:28 +0200 Subject: [PATCH 058/118] fixed uninitialise scope value for filters --- apps/opencs/view/filter/filtercreator.cpp | 16 +++++++++++++++- apps/opencs/view/filter/filtercreator.hpp | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/filter/filtercreator.cpp b/apps/opencs/view/filter/filtercreator.cpp index 47925ea57..640c9fe78 100644 --- a/apps/opencs/view/filter/filtercreator.cpp +++ b/apps/opencs/view/filter/filtercreator.cpp @@ -6,6 +6,11 @@ #include "../../model/filter/filter.hpp" +#include "../../model/world/data.hpp" +#include "../../model/world/commands.hpp" +#include "../../model/world/columns.hpp" +#include "../../model/world/idtable.hpp" + std::string CSVFilter::FilterCreator::getNamespace() const { switch (mScope->currentIndex()) @@ -28,6 +33,15 @@ std::string CSVFilter::FilterCreator::getId() const return getNamespace() + GenericCreator::getId(); } +void CSVFilter::FilterCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const +{ + int index = + dynamic_cast (*getData().getTableModel (getCollectionId())). + findColumnIndex (CSMWorld::Columns::ColumnId_Scope); + + command.addValue (index, mScope->currentIndex()); +} + CSVFilter::FilterCreator::FilterCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id) : GenericCreator (data, undoStack, id) @@ -39,7 +53,7 @@ CSVFilter::FilterCreator::FilterCreator (CSMWorld::Data& data, QUndoStack& undoS mScope->addItem ("Project"); mScope->addItem ("Session"); - /// \ŧodo re-enable for OpenMW 1.1 + /// \todo re-enable for OpenMW 1.1 // mScope->addItem ("Content"); connect (mScope, SIGNAL (currentIndexChanged (int)), this, SLOT (setScope (int))); diff --git a/apps/opencs/view/filter/filtercreator.hpp b/apps/opencs/view/filter/filtercreator.hpp index 82d38d22c..437d01c8d 100644 --- a/apps/opencs/view/filter/filtercreator.hpp +++ b/apps/opencs/view/filter/filtercreator.hpp @@ -25,6 +25,8 @@ namespace CSVFilter virtual std::string getId() const; + virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const; + public: FilterCreator (CSMWorld::Data& data, QUndoStack& undoStack, From 6ac4dedfbe7f88fb353cfdab0128cea612a85e38 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Sep 2013 13:56:23 +0200 Subject: [PATCH 059/118] added missing column enum --- apps/opencs/model/world/columns.cpp | 1 + apps/opencs/model/world/columns.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 5616a4a48..06649b01b 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -147,6 +147,7 @@ namespace CSMWorld { ColumnId_Magical, "Magical" }, { ColumnId_Silver, "Silver" }, { ColumnId_Filter, "Filter" }, + { ColumnId_Scope, "Scope", }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 69b20583a..bf1387067 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -140,6 +140,7 @@ namespace CSMWorld ColumnId_Magical = 107, ColumnId_Silver = 108, ColumnId_Filter = 109, + ColumnId_Scope = 110, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. From baae548106332e373cb16e3855ac588f16c1b7c4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Sep 2013 13:56:40 +0200 Subject: [PATCH 060/118] added project scope filter saving --- apps/opencs/model/doc/saving.cpp | 2 ++ apps/opencs/model/doc/savingstages.cpp | 18 +++++++++++++++++- apps/opencs/model/doc/savingstages.hpp | 17 +++++++++++++++++ components/esm/defs.hpp | 6 +++++- components/esm/filter.cpp | 3 +++ components/esm/filter.hpp | 2 ++ 6 files changed, 46 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index adcfca576..2b0056e72 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -16,6 +16,8 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje appendStage (new WriteHeaderStage (mDocument, mState, true)); + appendStage (new WriteFilterStage (mDocument, mState, CSMFilter::Filter::Scope_Project)); + appendStage (new CloseSaveStage (mState)); // save content file diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index d48e22012..d68c72317 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -52,7 +52,6 @@ void CSMDoc::WriteHeaderStage::perform (int stage, std::vector& mes mState.getWriter().setAuthor (""); mState.getWriter().setDescription (""); mState.getWriter().setRecordCount (0); - } else { @@ -96,6 +95,23 @@ void CSMDoc::WriteRefIdCollectionStage::perform (int stage, std::vector > (document.getData().getFilters(), + state), + mDocument (document), mScope (scope) +{} + +void CSMDoc::WriteFilterStage::perform (int stage, std::vector& messages) +{ + const CSMWorld::Record& record = + mDocument.getData().getFilters().getRecord (stage); + + if (record.get().mScope==mScope) + WriteCollectionStage >::perform (stage, messages); +} + + CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state) : mState (state) {} diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index 367431fc1..ff94116fd 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -6,6 +6,9 @@ #include "savingstate.hpp" #include "../world/record.hpp" +#include "../world/idcollection.hpp" + +#include "../filter/filter.hpp" namespace CSMDoc { @@ -120,6 +123,20 @@ namespace CSMDoc }; + class WriteFilterStage : public WriteCollectionStage > + { + Document& mDocument; + CSMFilter::Filter::Scope mScope; + + public: + + WriteFilterStage (Document& document, SavingState& state, CSMFilter::Filter::Scope scope); + + virtual void perform (int stage, std::vector& messages); + ///< Messages resulting from this stage will be appended to \a messages. + }; + + class CloseSaveStage : public Stage { SavingState& mState; diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index bd86f9ba0..dd7ebfe93 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -36,6 +36,7 @@ struct Position enum RecNameInts { + // format 0 / legacy REC_ACTI = 0x49544341, REC_ALCH = 0x48434c41, REC_APPA = 0x41505041, @@ -80,7 +81,10 @@ enum RecNameInts REC_SPEL = 0x4c455053, REC_SSCR = 0x52435353, REC_STAT = 0x54415453, - REC_WEAP = 0x50414557 + REC_WEAP = 0x50414557, + + // format 1 + REC_FILT = 0x544C4946 }; } diff --git a/components/esm/filter.cpp b/components/esm/filter.cpp index 96cc19d43..a80427bbe 100644 --- a/components/esm/filter.cpp +++ b/components/esm/filter.cpp @@ -3,6 +3,9 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include "defs.hpp" + +unsigned int ESM::Filter::sRecordId = REC_FILT; void ESM::Filter::load (ESMReader& esm) { diff --git a/components/esm/filter.hpp b/components/esm/filter.hpp index a44d1b198..bc3dd7bdc 100644 --- a/components/esm/filter.hpp +++ b/components/esm/filter.hpp @@ -10,6 +10,8 @@ namespace ESM struct Filter { + static unsigned int sRecordId; + std::string mId; std::string mDescription; From 62148b324702158d14366f214b56aa32984d92dc Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Sep 2013 15:04:09 +0200 Subject: [PATCH 061/118] moved implementation of searchColumnIndex and findColumnIndex functions from IdTable to CollectionBase --- apps/opencs/model/world/collectionbase.cpp | 25 ++++++++++++++++++++++ apps/opencs/model/world/collectionbase.hpp | 8 +++++++ apps/opencs/model/world/idtable.cpp | 15 ++----------- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/apps/opencs/model/world/collectionbase.cpp b/apps/opencs/model/world/collectionbase.cpp index 932ea27b5..241f198cb 100644 --- a/apps/opencs/model/world/collectionbase.cpp +++ b/apps/opencs/model/world/collectionbase.cpp @@ -1,6 +1,31 @@ #include "collectionbase.hpp" +#include + +#include "columnbase.hpp" + CSMWorld::CollectionBase::CollectionBase() {} CSMWorld::CollectionBase::~CollectionBase() {} + +int CSMWorld::CollectionBase::searchColumnIndex (Columns::ColumnId id) const +{ + int columns = getColumns(); + + for (int i=0; i #include "universalid.hpp" +#include "columns.hpp" class QVariant; @@ -83,6 +84,13 @@ namespace CSMWorld ///< Return a sorted collection of all IDs /// /// \param listDeleted include deleted record in the list + + int searchColumnIndex (Columns::ColumnId id) const; + ///< Return index of column with the given \a id. If no such column exists, -1 is returned. + + int findColumnIndex (Columns::ColumnId id) const; + ///< Return index of column with the given \a id. If no such column exists, an exception is + /// thrown. }; } diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index baaf75289..b7b1a9db0 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -161,21 +161,10 @@ const CSMWorld::RecordBase& CSMWorld::IdTable::getRecord (const std::string& id) int CSMWorld::IdTable::searchColumnIndex (Columns::ColumnId id) const { - int columns = mIdCollection->getColumns(); - - for (int i=0; igetColumn (i).mColumnId==id) - return i; - - return -1; + return mIdCollection->searchColumnIndex (id); } int CSMWorld::IdTable::findColumnIndex (Columns::ColumnId id) const { - int index = searchColumnIndex (id); - - if (index==-1) - throw std::logic_error ("invalid column index"); - - return index; + return mIdCollection->findColumnIndex (id); } \ No newline at end of file From e7c48cbe5805afa378dfd8e1db90357e8e7d8ab4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Sep 2013 15:04:30 +0200 Subject: [PATCH 062/118] load project files --- apps/opencs/model/doc/document.cpp | 19 +++++++++++++++++-- apps/opencs/model/world/data.cpp | 15 ++++++++++++++- apps/opencs/model/world/data.hpp | 4 +++- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 68e164c79..7f609f9f7 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -1,6 +1,9 @@ #include "document.hpp" + #include +#include + void CSMDoc::Document::load (const std::vector::const_iterator& begin, const std::vector::const_iterator& end, bool lastAsModified) { @@ -12,10 +15,10 @@ void CSMDoc::Document::load (const std::vector::const_i --end2; for (std::vector::const_iterator iter (begin); iter!=end2; ++iter) - getData().loadFile (*iter, true); + getData().loadFile (*iter, true, false); if (lastAsModified) - getData().loadFile (*end2, false); + getData().loadFile (*end2, false, false); } void CSMDoc::Document::addGmsts() @@ -2164,6 +2167,18 @@ CSMDoc::Document::Document (const std::vector& files, mData.setDescription (""); mData.setAuthor (""); } +/// \todo un-outcomment the else, once loading an existing content file works properly again. +// else + { + if (boost::filesystem::exists (projectPath)) + { + getData().loadFile (projectPath, false, true); + } + else + { + /// \todo create new project file with default filters + } + } addOptionalGmsts(); addOptionalGlobals(); diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index a5e98fc60..9227a5965 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -386,7 +386,7 @@ void CSMWorld::Data::merge() mGlobals.merge(); } -void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) +void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base, bool project) { ESM::ESMReader reader; @@ -449,6 +449,19 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) case ESM::REC_STAT: mReferenceables.load (reader, base, UniversalId::Type_Static); break; case ESM::REC_WEAP: mReferenceables.load (reader, base, UniversalId::Type_Weapon); break; + case ESM::REC_FILT: + + if (project) + { + mFilters.load (reader, base); + mFilters.setData (mFilters.getSize()-1, + mFilters.findColumnIndex (CSMWorld::Columns::ColumnId_Scope), + static_cast (CSMFilter::Filter::Scope_Project)); + break; + } + + // fall through (filter record in a content file is an error with format 0) + default: /// \todo throw an exception instead, once all records are implemented diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index eb6325a25..5d7fbd291 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -145,8 +145,10 @@ namespace CSMWorld void merge(); ///< Merge modified into base. - void loadFile (const boost::filesystem::path& path, bool base); + void loadFile (const boost::filesystem::path& path, bool base, bool project); ///< Merging content of a file into base or modified. + /// + /// \param project load project file instead of content file bool hasId (const std::string& id) const; From 6143ec33e0df352cdae04366c92ffa2ab977feb3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Sep 2013 15:24:58 +0200 Subject: [PATCH 063/118] giving Documents direct access to ConfigurationManager --- apps/opencs/editor.cpp | 2 +- apps/opencs/model/doc/document.cpp | 19 +++++++++++++------ apps/opencs/model/doc/document.hpp | 14 +++++++++----- apps/opencs/model/doc/documentmanager.cpp | 20 +++++++++++--------- apps/opencs/model/doc/documentmanager.hpp | 10 +++++++--- 5 files changed, 41 insertions(+), 24 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index ead4d2a98..a43059795 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -11,7 +11,7 @@ CS::Editor::Editor() -: mDocumentManager (mCfgMgr.getUserPath() / "projects"), mViewManager (mDocumentManager) +: mDocumentManager (mCfgMgr), mViewManager (mDocumentManager) { mIpcServerName = "org.openmw.OpenCS"; diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 7f609f9f7..5c29d9f61 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -4,6 +4,10 @@ #include +#ifndef Q_MOC_RUN +#include +#endif + void CSMDoc::Document::load (const std::vector::const_iterator& begin, const std::vector::const_iterator& end, bool lastAsModified) { @@ -2142,10 +2146,13 @@ void CSMDoc::Document::createBase() } } -CSMDoc::Document::Document (const std::vector& files, - const boost::filesystem::path& savePath, bool new_, - const boost::filesystem::path& projectPath) -: mSavePath (savePath), mContentFiles (files), mTools (mData), mSaving (*this, projectPath) +CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, + const std::vector& files, + const boost::filesystem::path& savePath, bool new_) +: mSavePath (savePath), mContentFiles (files), mTools (mData), + mProjectPath ((configuration.getUserPath() / "projects") / + (savePath.filename().string() + ".project")), + mSaving (*this, mProjectPath) { if (files.empty()) throw std::runtime_error ("Empty content file sequence"); @@ -2170,9 +2177,9 @@ CSMDoc::Document::Document (const std::vector& files, /// \todo un-outcomment the else, once loading an existing content file works properly again. // else { - if (boost::filesystem::exists (projectPath)) + if (boost::filesystem::exists (mProjectPath)) { - getData().loadFile (projectPath, false, true); + getData().loadFile (mProjectPath, false, true); } else { diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 7843cfbfe..d171dacae 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -24,6 +24,11 @@ namespace ESM struct Global; } +namespace Files +{ + class ConfigurationManager; +} + namespace CSMDoc { class Document : public QObject @@ -36,6 +41,7 @@ namespace CSMDoc std::vector mContentFiles; CSMWorld::Data mData; CSMTools::Tools mTools; + boost::filesystem::path mProjectPath; Saving mSaving; // It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is @@ -64,11 +70,9 @@ namespace CSMDoc public: - Document (const std::vector& files, - const boost::filesystem::path& savePath, bool new_, - const boost::filesystem::path& projectPath); - ///< \param projectPath Location of file that can be used to store additional data for - /// this project. + Document (const Files::ConfigurationManager& configuration, + const std::vector& files, + const boost::filesystem::path& savePath, bool new_); ~Document(); diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 1978c0e53..1d6c88dcc 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -6,13 +6,19 @@ #include +#ifndef Q_MOC_RUN +#include +#endif + #include "document.hpp" -CSMDoc::DocumentManager::DocumentManager (const boost::filesystem::path& projectPath) -: mProjectPath (projectPath) +CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& configuration) +: mConfiguration (configuration) { - if (!boost::filesystem::is_directory (mProjectPath)) - boost::filesystem::create_directories (mProjectPath); + boost::filesystem::path projectPath = configuration.getUserPath() / "projects"; + + if (!boost::filesystem::is_directory (projectPath)) + boost::filesystem::create_directories (projectPath); } CSMDoc::DocumentManager::~DocumentManager() @@ -24,11 +30,7 @@ CSMDoc::DocumentManager::~DocumentManager() CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::vector& files, const boost::filesystem::path& savePath, bool new_) { - boost::filesystem::path projectFile (mProjectPath); - - projectFile /= savePath.filename().string() + ".project"; - - Document *document = new Document (files, savePath, new_, projectFile); + Document *document = new Document (mConfiguration, files, savePath, new_); mDocuments.push_back (document); diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index 622a135a5..28a21216a 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -6,6 +6,11 @@ #include +namespace Files +{ + class ConfigurationManager; +} + namespace CSMDoc { class Document; @@ -13,15 +18,14 @@ namespace CSMDoc class DocumentManager { std::vector mDocuments; - boost::filesystem::path mProjectPath; + const Files::ConfigurationManager& mConfiguration; DocumentManager (const DocumentManager&); DocumentManager& operator= (const DocumentManager&); public: - DocumentManager (const boost::filesystem::path& projectPath); - ///< \param projectPath Directory where additional per-project data will be stored. + DocumentManager (const Files::ConfigurationManager& configuration); ~DocumentManager(); From 9c2145eda126cb05abe2f84213fce6fa242b92e5 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sun, 29 Sep 2013 09:11:57 +0200 Subject: [PATCH 064/118] Issue #913: Merge --master and --plugin switches Merged master/plugin switches into content in openmw and mwiniimporter. Extension in content files is now required. Signed-off-by: Lukasz Gromanowski --- apps/mwiniimporter/importer.cpp | 25 ++----- apps/openmw/CMakeLists.txt | 1 + apps/openmw/engine.cpp | 40 +++-------- apps/openmw/engine.hpp | 15 ++-- apps/openmw/main.cpp | 36 +++------- apps/openmw/mwworld/contentloader.hpp | 35 +++++++++ apps/openmw/mwworld/esmloader.cpp | 31 ++++++++ apps/openmw/mwworld/esmloader.hpp | 34 +++++++++ apps/openmw/mwworld/omwloader.cpp | 17 +++++ apps/openmw/mwworld/omwloader.hpp | 21 ++++++ apps/openmw/mwworld/worldimp.cpp | 100 +++++++++++++++++--------- apps/openmw/mwworld/worldimp.hpp | 15 +++- 12 files changed, 254 insertions(+), 116 deletions(-) create mode 100644 apps/openmw/mwworld/contentloader.hpp create mode 100644 apps/openmw/mwworld/esmloader.cpp create mode 100644 apps/openmw/mwworld/esmloader.hpp create mode 100644 apps/openmw/mwworld/omwloader.cpp create mode 100644 apps/openmw/mwworld/omwloader.hpp diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp index 8732b3eab..b8b7e4c9d 100644 --- a/apps/mwiniimporter/importer.cpp +++ b/apps/mwiniimporter/importer.cpp @@ -813,8 +813,7 @@ void MwIniImporter::importArchives(multistrmap &cfg, const multistrmap &ini) con } void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) const { - std::vector esmFiles; - std::vector espFiles; + std::vector contentFiles; std::string baseGameFile("Game Files:GameFile"); std::string gameFile(""); @@ -832,29 +831,19 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) co std::string filetype(entry->substr(entry->length()-3)); Misc::StringUtils::toLower(filetype); - if(filetype.compare("esm") == 0) { - esmFiles.push_back(*entry); - } - else if(filetype.compare("esp") == 0) { - espFiles.push_back(*entry); + if(filetype.compare("esm") == 0 || filetype.compare("esp") == 0) { + contentFiles.push_back(*entry); } } gameFile = ""; } - cfg.erase("master"); - cfg.insert( std::make_pair > ("master", std::vector() ) ); - - for(std::vector::const_iterator it=esmFiles.begin(); it!=esmFiles.end(); ++it) { - cfg["master"].push_back(*it); - } - - cfg.erase("plugin"); - cfg.insert( std::make_pair > ("plugin", std::vector() ) ); + cfg.erase("content"); + cfg.insert( std::make_pair("content", std::vector() ) ); - for(std::vector::const_iterator it=espFiles.begin(); it!=espFiles.end(); ++it) { - cfg["plugin"].push_back(*it); + for(std::vector::const_iterator it=contentFiles.begin(); it!=contentFiles.end(); ++it) { + cfg["content"].push_back(*it); } } diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index b367e2a1e..807b1b5ff 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -58,6 +58,7 @@ add_openmw_dir (mwworld cells localscripts customdata weather inventorystore ptr actionopen actionread actionequip timestamp actionalchemy cellstore actionapply actioneat esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor + contentloader esmloader omwloader ) add_openmw_dir (mwclass diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index a2eccbaf9..d29301ed3 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -261,34 +261,14 @@ void OMW::Engine::setCell (const std::string& cellName) mCellName = cellName; } -// Set master file (esm) -// - If the given name does not have an extension, ".esm" is added automatically - -void OMW::Engine::addMaster (const std::string& master) +void OMW::Engine::addContentFile(const std::string& file) { - mMaster.push_back(master); - std::string &str = mMaster.back(); - - // Append .esm if not already there - std::string::size_type sep = str.find_last_of ("."); - if (sep == std::string::npos) - { - str += ".esm"; - } -} + if (file.find_last_of(".") == std::string::npos) + { + throw std::runtime_error("Missing extension in content file!"); + } -// Add plugin file (esp) -void OMW::Engine::addPlugin (const std::string& plugin) -{ - mPlugins.push_back(plugin); - std::string &str = mPlugins.back(); - - // Append .esp if not already there - std::string::size_type sep = str.find_last_of ("."); - if (sep == std::string::npos) - { - str += ".esp"; - } + mContentFiles.push_back(file); } void OMW::Engine::setScriptsVerbosity(bool scriptsVerbosity) @@ -403,7 +383,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mEnvironment.getWindowManager()->setNewGame(true); // Create the world - mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mMaster, mPlugins, + mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mContentFiles, mResDir, mCfgMgr.getCachePath(), mEncoder, mFallbackMap, mActivationDistanceOverride)); MWBase::Environment::get().getWorld()->setupPlayer(); @@ -414,8 +394,8 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) //Load translation data mTranslationDataStorage.setEncoder(mEncoder); - for (size_t i = 0; i < mMaster.size(); i++) - mTranslationDataStorage.loadTranslationData(mFileCollections, mMaster[i]); + for (size_t i = 0; i < mContentFiles.size(); i++) + mTranslationDataStorage.loadTranslationData(mFileCollections, mContentFiles[i]); Compiler::registerExtensions (mExtensions); @@ -480,7 +460,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) void OMW::Engine::go() { assert (!mCellName.empty()); - assert (!mMaster.empty()); + assert (!mContentFiles.empty()); assert (!mOgre); Settings::Manager settings; diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 665b0094c..553d29068 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -68,8 +68,7 @@ namespace OMW boost::filesystem::path mResDir; OEngine::Render::OgreRenderer *mOgre; std::string mCellName; - std::vector mMaster; - std::vector mPlugins; + std::vector mContentFiles; int mFpsLevel; bool mVerboseScripts; bool mNewGame; @@ -135,13 +134,11 @@ namespace OMW /// Set start cell name (only interiors for now) void setCell(const std::string& cellName); - /// Set master file (esm) - /// - If the given name does not have an extension, ".esm" is added automatically - void addMaster(const std::string& master); - - /// Same as "addMaster", but for plugin files (esp) - /// - If the given name does not have an extension, ".esp" is added automatically - void addPlugin(const std::string& plugin); + /** + * @brief addContentFile - Adds content file (ie. esm/esp, or omwgame/omwaddon) to the content files container. + * @param file - filename (extension is required) + */ + void addContentFile(const std::string& file); /// Enable fps counter void showFPS(int level); diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 27afd734a..33f740b31 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -110,11 +110,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("start", bpo::value()->default_value("Beshara"), "set initial cell") - ("master", bpo::value()->default_value(StringsVector(), "") - ->multitoken(), "master file(s)") - - ("plugin", bpo::value()->default_value(StringsVector(), "") - ->multitoken(), "plugin file(s)") + ("content", bpo::value()->default_value(StringsVector(), "") + ->multitoken(), "content file(s): esm/esp, or omwgame/omwaddon") ("anim-verbose", bpo::value()->implicit_value(true) ->default_value(false), "output animation indices files") @@ -152,8 +149,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("activate-dist", bpo::value ()->default_value (-1), "activation distance override"); - ; - bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv) .options(desc).allow_unregistered().run(); @@ -211,29 +206,18 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat engine.setResourceDir(variables["resources"].as()); - // master and plugin - StringsVector master = variables["master"].as(); - if (master.empty()) + StringsVector content = variables["content"].as(); + if (content.empty()) { - std::cout << "No master file given. Aborting...\n"; - return false; + std::cout << "No content file given (esm/esp, nor omwgame/omwaddon). Aborting..." << std::endl; + return false; } - StringsVector plugin = variables["plugin"].as(); - // Removed check for 255 files, which would be the hard-coded limit in Morrowind. - // I'll keep the following variable in, maybe we can use it for something different. - // Say, a feedback like "loading file x/cnt". - // Commenting this out for now to silence compiler warning. - //int cnt = master.size() + plugin.size(); - - // Prepare loading master/plugin files (i.e. send filenames to engine) - for (std::vector::size_type i = 0; i < master.size(); i++) - { - engine.addMaster(master[i]); - } - for (std::vector::size_type i = 0; i < plugin.size(); i++) + StringsVector::const_iterator it(content.begin()); + StringsVector::const_iterator end(content.end()); + for (; it != end; ++it) { - engine.addPlugin(plugin[i]); + engine.addContentFile(*it); } // startup-settings diff --git a/apps/openmw/mwworld/contentloader.hpp b/apps/openmw/mwworld/contentloader.hpp new file mode 100644 index 000000000..c57935c90 --- /dev/null +++ b/apps/openmw/mwworld/contentloader.hpp @@ -0,0 +1,35 @@ +#ifndef CONTENTLOADER_HPP +#define CONTENTLOADER_HPP + +#include +#include + +#include "components/loadinglistener/loadinglistener.hpp" + +namespace MWWorld +{ + +struct ContentLoader +{ + ContentLoader(Loading::Listener& listener) + : mListener(listener) + { + } + + virtual ~ContentLoader() + { + } + + virtual void load(const boost::filesystem::path& filepath, int& index) + { + std::cout << "Loading content file " << filepath.string() << std::endl; + mListener.setLabel(filepath.string()); + } + + protected: + Loading::Listener& mListener; +}; + +} /* namespace MWWorld */ + +#endif /* CONTENTLOADER_HPP */ diff --git a/apps/openmw/mwworld/esmloader.cpp b/apps/openmw/mwworld/esmloader.cpp new file mode 100644 index 000000000..1b8880d37 --- /dev/null +++ b/apps/openmw/mwworld/esmloader.cpp @@ -0,0 +1,31 @@ +#include "esmloader.hpp" +#include "esmstore.hpp" + +#include "components/to_utf8/to_utf8.hpp" + +namespace MWWorld +{ + +EsmLoader::EsmLoader(MWWorld::ESMStore& store, std::vector& readers, + ToUTF8::Utf8Encoder* encoder, Loading::Listener& listener) + : ContentLoader(listener) + , mStore(store) + , mEsm(readers) + , mEncoder(encoder) +{ +} + +void EsmLoader::load(const boost::filesystem::path& filepath, int& index) +{ + ContentLoader::load(filepath.filename(), index); + + ESM::ESMReader lEsm; + lEsm.setEncoder(mEncoder); + lEsm.setIndex(index); + lEsm.setGlobalReaderList(&mEsm); + lEsm.open(filepath.string()); + mEsm[index] = lEsm; + mStore.load(mEsm[index], &mListener); +} + +} /* namespace MWWorld */ diff --git a/apps/openmw/mwworld/esmloader.hpp b/apps/openmw/mwworld/esmloader.hpp new file mode 100644 index 000000000..d799c3f15 --- /dev/null +++ b/apps/openmw/mwworld/esmloader.hpp @@ -0,0 +1,34 @@ +#ifndef ESMLOADER_HPP +#define ESMLOADER_HPP + +#include + +#include "contentloader.hpp" +#include "components/esm/esmreader.hpp" + +namespace ToUTF8 +{ + class Utf8Encoder; +} + +namespace MWWorld +{ + +class ESMStore; + +struct EsmLoader : public ContentLoader +{ + EsmLoader(MWWorld::ESMStore& store, std::vector& readers, + ToUTF8::Utf8Encoder* encoder, Loading::Listener& listener); + + void load(const boost::filesystem::path& filepath, int& index); + + private: + std::vector& mEsm; + MWWorld::ESMStore& mStore; + ToUTF8::Utf8Encoder* mEncoder; +}; + +} /* namespace MWWorld */ + +#endif // ESMLOADER_HPP diff --git a/apps/openmw/mwworld/omwloader.cpp b/apps/openmw/mwworld/omwloader.cpp new file mode 100644 index 000000000..8562a4fe0 --- /dev/null +++ b/apps/openmw/mwworld/omwloader.cpp @@ -0,0 +1,17 @@ +#include "omwloader.hpp" + +namespace MWWorld +{ + +OmwLoader::OmwLoader(Loading::Listener& listener) + : ContentLoader(listener) +{ +} + +void OmwLoader::load(const boost::filesystem::path& filepath, int& index) +{ + ContentLoader::load(filepath.filename(), index); +} + +} /* namespace MWWorld */ + diff --git a/apps/openmw/mwworld/omwloader.hpp b/apps/openmw/mwworld/omwloader.hpp new file mode 100644 index 000000000..cb9faa430 --- /dev/null +++ b/apps/openmw/mwworld/omwloader.hpp @@ -0,0 +1,21 @@ +#ifndef OMWLOADER_HPP +#define OMWLOADER_HPP + +#include "contentloader.hpp" + +namespace MWWorld +{ + +/** + * @brief Placeholder for real OpenMW content loader + */ +struct OmwLoader : public ContentLoader +{ + OmwLoader(Loading::Listener& listener); + + void load(const boost::filesystem::path& filepath, int& index); +}; + +} /* namespace MWWorld */ + +#endif /* OMWLOADER_HPP */ diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f3d4c81b7..b7b23e5c1 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1,4 +1,11 @@ #include "worldimp.hpp" +#ifdef _WIN32 +#include +#elif defined HAVE_UNORDERED_MAP +#include +#else +#include +#endif #include @@ -31,6 +38,10 @@ #include "containerstore.hpp" #include "inventorystore.hpp" +#include "contentloader.hpp" +#include "esmloader.hpp" +#include "omwloader.hpp" + using namespace Ogre; namespace @@ -80,6 +91,38 @@ namespace namespace MWWorld { + struct GameContentLoader : public ContentLoader + { + GameContentLoader(Loading::Listener& listener) + : ContentLoader(listener) + { + } + + bool addLoader(const std::string& extension, ContentLoader* loader) + { + return mLoaders.insert(std::make_pair(extension, loader)).second; + } + + void load(const boost::filesystem::path& filepath, int& index) + { + LoadersContainer::iterator it(mLoaders.find(filepath.extension().string())); + if (it != mLoaders.end()) + { + it->second->load(filepath, index); + } + else + { + std::string msg("Cannot load file: "); + msg += filepath.string(); + throw std::runtime_error(msg.c_str()); + } + } + + private: + typedef std::tr1::unordered_map LoadersContainer; + LoadersContainer mLoaders; + }; + Ptr World::getPtrViaHandle (const std::string& handle, Ptr::CellStore& cell) { if (MWWorld::LiveCellRef *ref = @@ -163,7 +206,7 @@ namespace MWWorld World::World (OEngine::Render::OgreRenderer& renderer, const Files::Collections& fileCollections, - const std::vector& master, const std::vector& plugins, + const std::vector& contentFiles, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, ToUTF8::Utf8Encoder* encoder, const std::map& fallbackMap, int mActivationDistanceOverride) : mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0), @@ -181,44 +224,22 @@ namespace MWWorld mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback); - int idx = 0; // NOTE: We might need to reserve one more for the running game / save. - mEsm.resize(master.size() + plugins.size()); + mEsm.resize(contentFiles.size()); Loading::Listener* listener = MWBase::Environment::get().getWindowManager()->getLoadingScreen(); listener->loadingOn(); - for (std::vector::size_type i = 0; i < master.size(); i++, idx++) - { - boost::filesystem::path masterPath (fileCollections.getCollection (".esm").getPath (master[i])); - std::cout << "Loading ESM " << masterPath.string() << "\n"; - listener->setLabel(masterPath.filename().string()); + GameContentLoader gameContentLoader(*listener); + EsmLoader esmLoader(mStore, mEsm, encoder, *listener); + OmwLoader omwLoader(*listener); - // This parses the ESM file - ESM::ESMReader lEsm; - lEsm.setEncoder(encoder); - lEsm.setIndex(idx); - lEsm.setGlobalReaderList(&mEsm); - lEsm.open (masterPath.string()); - mEsm[idx] = lEsm; - mStore.load (mEsm[idx], listener); - } - - for (std::vector::size_type i = 0; i < plugins.size(); i++, idx++) - { - boost::filesystem::path pluginPath (fileCollections.getCollection (".esp").getPath (plugins[i])); + gameContentLoader.addLoader(".esm", &esmLoader); + gameContentLoader.addLoader(".esp", &esmLoader); + gameContentLoader.addLoader(".omwgame", &omwLoader); + gameContentLoader.addLoader(".omwaddon", &omwLoader); - std::cout << "Loading ESP " << pluginPath.string() << "\n"; - listener->setLabel(pluginPath.filename().string()); + loadContentFiles(fileCollections, contentFiles, gameContentLoader); - // This parses the ESP file - ESM::ESMReader lEsm; - lEsm.setEncoder(encoder); - lEsm.setIndex(idx); - lEsm.setGlobalReaderList(&mEsm); - lEsm.open (pluginPath.string()); - mEsm[idx] = lEsm; - mStore.load (mEsm[idx], listener); - } listener->loadingOff(); // insert records that may not be present in all versions of MW @@ -1960,4 +1981,19 @@ namespace MWWorld return mGodMode; } + void World::loadContentFiles(const Files::Collections& fileCollections, + const std::vector& content, ContentLoader& contentLoader) + { + std::vector::const_iterator it(content.begin()); + std::vector::const_iterator end(content.end()); + for (int idx = 0; it != end; ++it, ++idx) + { + boost::filesystem::path filename(*it); + const Files::MultiDirCollection& col = fileCollections.getCollection(filename.extension().string()); + if (col.doesExist(*it)) + { + contentLoader.load(col.getPath(*it), idx); + } + } + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 53b01f1ab..d39189282 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -14,6 +14,8 @@ #include "../mwbase/world.hpp" +#include "contentloader.hpp" + namespace Ogre { class Vector3; @@ -41,6 +43,8 @@ namespace MWRender class Animation; } +struct ContentLoader; + namespace MWWorld { class WeatherManager; @@ -113,6 +117,15 @@ namespace MWWorld void ensureNeededRecords(); + /** + * @brief loadContentFiles - Loads content files (esm,esp,omwgame,omwaddon) + * @param fileCollections- Container which holds content file names and their paths + * @param content - Container which holds content file names + * @param contentLoader - + */ + void loadContentFiles(const Files::Collections& fileCollections, + const std::vector& content, ContentLoader& contentLoader); + int mPlayIntro; bool mTeleportEnabled; @@ -121,7 +134,7 @@ namespace MWWorld World (OEngine::Render::OgreRenderer& renderer, const Files::Collections& fileCollections, - const std::vector& master, const std::vector& plugins, + const std::vector& contentFiles, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, ToUTF8::Utf8Encoder* encoder, const std::map& fallbackMap, int mActivationDistanceOverride); From ef617d408b7baa09e704db40b8b157608ac9da98 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sun, 29 Sep 2013 09:14:40 +0200 Subject: [PATCH 065/118] Issue #913: Merge --master and --plugin switches Merged master/plugin switches in launcher. Signed-off-by: Lukasz Gromanowski --- apps/launcher/datafilespage.cpp | 9 +++++---- apps/launcher/settings/gamesettings.cpp | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 44392794b..43f09d168 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -206,19 +206,20 @@ void DataFilesPage::saveSettings() mLauncherSettings.remove(QString("Profiles/") + profile + QString("/plugin")); mGameSettings.remove(QString("master")); - mGameSettings.remove(QString("plugin")); + mGameSettings.remove(QString("plugins")); + mGameSettings.remove(QString("content")); - ContentSelectorModel::ContentFileList items = mContentModel->checkedItems(); + ContentSelectorModel::ContentFileList items = mContentModel->checkedItems(); foreach(const ContentSelectorModel::EsmFile *item, items) { if (item->gameFiles().size() == 0) { mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/master"), item->fileName()); - mGameSettings.setMultiValue(QString("master"), item->fileName()); + mGameSettings.setMultiValue(QString("content"), item->fileName()); } else { mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/plugin"), item->fileName()); - mGameSettings.setMultiValue(QString("plugin"), item->fileName()); + mGameSettings.setMultiValue(QString("content"), item->fileName()); } } diff --git a/apps/launcher/settings/gamesettings.cpp b/apps/launcher/settings/gamesettings.cpp index 205879bc3..7b2356cd0 100644 --- a/apps/launcher/settings/gamesettings.cpp +++ b/apps/launcher/settings/gamesettings.cpp @@ -163,12 +163,12 @@ bool GameSettings::writeFile(QTextStream &stream) QStringList masters = mSettings.values(QString("master")); for (int i = masters.count(); i--;) { - stream << "master=" << masters.at(i) << "\n"; + stream << "content=" << masters.at(i) << "\n"; } QStringList plugins = mSettings.values(QString("plugin")); for (int i = plugins.count(); i--;) { - stream << "plugin=" << plugins.at(i) << "\n"; + stream << "content=" << plugins.at(i) << "\n"; } return true; From 24b167b7552ce8bf6e62933a535752a899c77473 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 29 Sep 2013 12:19:07 -0500 Subject: [PATCH 066/118] Implemented ContentSelector as a singleton "charm" modifier for FileDialog... --- apps/launcher/datafilespage.cpp | 11 +- apps/opencs/editor.cpp | 13 +- apps/opencs/view/doc/filedialog.cpp | 99 +++----- apps/opencs/view/doc/filedialog.hpp | 38 ++-- .../contentselector/view/contentselector.cpp | 213 +++++++++++++++--- .../contentselector/view/contentselector.hpp | 51 ++++- 6 files changed, 283 insertions(+), 142 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 44392794b..828b2f2ba 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -29,8 +29,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam , mLauncherSettings(launcherSettings) { setupUi(this); - // mContentSelector.setParent(parent); - +/* // QMetaObject::connectSlotsByName(this); projectGroupBox->hide(); @@ -52,7 +51,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam setupDataFiles(); - updateViews(); + updateViews();*/ } void DataFilesPage::buildContentModel() @@ -112,10 +111,10 @@ void DataFilesPage::updateViews() void ContentSelectorView::ContentSelector::addFiles(const QString &path) { - mContentModel->addFiles(path); + // mContentModel->addFiles(path); //mContentModel->sort(3); // Sort by date accessed - gameFileView->setCurrentIndex(-1); - mContentModel->uncheckAll(); + // ui.gameFileView->setCurrentIndex(-1); + // mContentModel->uncheckAll(); } void DataFilesPage::createActions() diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index ba1dfb57e..fc9168e2e 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -123,37 +123,34 @@ void CS::Editor::loadDocument() void CS::Editor::openFiles() { std::vector files; - QStringList paths = mFileDialog.checkedItemsPaths(); - foreach (const QString &path, paths) { + foreach (const QString &path, mFileDialog.selectedFilepaths()) { files.push_back(path.toStdString()); } /// \todo Get the save path from the file dialogue - CSMDoc::Document *document = mDocumentManager.addDocument (files, *files.rbegin(), false); mViewManager.addView (document); - mFileDialog.hide(); + mFileDialog.close(); } void CS::Editor::createNewFile() { std::vector files; - QStringList paths = mFileDialog.checkedItemsPaths(); - foreach (const QString &path, paths) { + foreach (const QString &path, mFileDialog.selectedFilepaths()) { files.push_back(path.toStdString()); } - files.push_back(mFileDialog.fileName().toStdString()); + files.push_back(mFileDialog.filename().toStdString()); /// \todo Get the save path from the file dialogue. CSMDoc::Document *document = mDocumentManager.addDocument (files, *files.rbegin(), true); mViewManager.addView (document); - mFileDialog.hide(); + mFileDialog.close(); } void CS::Editor::createNewGame (const boost::filesystem::path& file) diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 68aab27d5..5a97a7a26 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -10,107 +10,76 @@ #include #include #include +#include #include #include - -#include "filewidget.hpp" -#include "adjusterwidget.hpp" +#include "components/contentselector/view/contentselector.hpp" #include CSVDoc::FileDialog::FileDialog(QWidget *parent) : - ContentSelector(parent), - mFileWidget (new FileWidget (this)), - mAdjusterWidget (new AdjusterWidget (this)), - mEnable_1(false), - mEnable_2(false) -{ - // Hide the profile elements - profileGroupBox->hide(); - addonView->showColumn(2); + QDialog(parent), + mOpenFileFlags (ContentSelectorView::Flag_Content | ContentSelectorView::Flag_LoadAddon), + mNewFileFlags (ContentSelectorView::Flag_Content | ContentSelectorView::Flag_NewAddon) +{ resize(400, 400); - - mFileWidget->setType(true); - mFileWidget->extensionLabelIsVisible(false); - - connect(projectCreateButton, SIGNAL(clicked()), this, SIGNAL(createNewFile())); - - connect(projectButtonBox, SIGNAL(accepted()), this, SIGNAL(openFiles())); - connect(projectButtonBox, SIGNAL(rejected()), this, SLOT(reject())); - - connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)), - mAdjusterWidget, SLOT (setName (const QString&, bool))); - - connect (mAdjusterWidget, SIGNAL (stateChanged (bool)), this, SLOT (slotAdjusterChanged(bool))); - connect (this, SIGNAL (signalGameFileChanged(int)), this, SLOT (slotGameFileSelected(int))); - connect (this, SIGNAL (signalUpdateCreateButton(bool, int)), this, SLOT (slotEnableCreateButton(bool, int))); } -void CSVDoc::FileDialog::updateOpenButton(const QStringList &items) +void CSVDoc::FileDialog::addFiles(const QString &path) { - QPushButton *openButton = projectButtonBox->button(QDialogButtonBox::Open); - - if (!openButton) - return; - - openButton->setEnabled(!items.isEmpty()); + ContentSelectorView::ContentSelector::addFiles(path); } -void CSVDoc::FileDialog::slotEnableCreateButton(bool enable, int widgetNumber) +QString CSVDoc::FileDialog::filename() { + return ContentSelectorView::ContentSelector::instance().filename(); +} - if (widgetNumber == 1) - mEnable_1 = enable; - - if (widgetNumber == 2) - mEnable_2 = enable; - - projectCreateButton->setEnabled(mEnable_1 && mEnable_2); +QStringList CSVDoc::FileDialog::selectedFilepaths() +{ + return ContentSelectorView::ContentSelector::instance().selectedFiles(); } -QString CSVDoc::FileDialog::fileName() +void CSVDoc::FileDialog::showDialog() { - return mFileWidget->getName(); + show(); + raise(); + activateWindow(); } void CSVDoc::FileDialog::openFile() { setWindowTitle(tr("Open")); - mFileWidget->hide(); - adjusterWidgetFrame->hide(); - projectCreateButton->hide(); - projectGroupBox->setTitle(tr("")); - projectButtonBox->button(QDialogButtonBox::Open)->setEnabled(false); + ContentSelectorView::ContentSelector::configure(this, mOpenFileFlags); - show(); - raise(); - activateWindow(); + connect (&ContentSelectorView::ContentSelector::instance(), + SIGNAL (accepted()), this, SIGNAL (openFiles())); + + connect (&ContentSelectorView::ContentSelector::instance(), + SIGNAL (rejected()), this, SLOT (slotRejected())); + + showDialog(); } void CSVDoc::FileDialog::newFile() { setWindowTitle(tr("New")); - fileWidgetFrame->layout()->addWidget(mFileWidget); - adjusterWidgetFrame->layout()->addWidget(mAdjusterWidget); + ContentSelectorView::ContentSelector::configure(this, mNewFileFlags); - projectButtonBox->setStandardButtons(QDialogButtonBox::Cancel); - projectButtonBox->addButton(projectCreateButton, QDialogButtonBox::ActionRole); + connect (&ContentSelectorView::ContentSelector::instance(), + SIGNAL (accepted()), this, SIGNAL (createNewFile())); - show(); - raise(); - activateWindow(); -} + connect (&ContentSelectorView::ContentSelector::instance(), + SIGNAL (rejected()), this, SLOT (slotRejected())); -void CSVDoc::FileDialog::slotAdjusterChanged(bool value) -{ - emit signalUpdateCreateButton(mAdjusterWidget->isValid(), 2); + showDialog(); } -void CSVDoc::FileDialog::slotGameFileSelected(int value) +void CSVDoc::FileDialog::slotRejected() { - emit signalUpdateCreateButton(value > -1, 1); + close(); } diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 7782dd94e..88d408b5c 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -3,9 +3,7 @@ #include #include - -#include "components/contentselector/view/contentselector.hpp" -#include "ui_datafilespage.h" +#include "../../../../components/contentselector/view/contentselector.hpp" class QDialogButtonBox; class QSortFilterProxyModel; @@ -19,6 +17,8 @@ class QLabel; class DataFilesModel; class PluginsProxyModel; + + namespace ContentSelectorView { class LineEdit; @@ -26,42 +26,38 @@ namespace ContentSelectorView namespace CSVDoc { - class FileWidget; - class AdjusterWidget; - - class FileDialog : public ContentSelectorView::ContentSelector + class FileDialog : public QDialog { Q_OBJECT - FileWidget *mFileWidget; - AdjusterWidget *mAdjusterWidget; - - bool mEnable_1; - bool mEnable_2; + unsigned char mOpenFileFlags; + unsigned char mNewFileFlags; public: explicit FileDialog(QWidget *parent = 0); void openFile(); void newFile(); + void addFiles (const QString &path); + + QString filename(); + QStringList selectedFilepaths(); - QString fileName(); + private: + + void showDialog(); signals: + void openFiles(); void createNewFile(); - void signalUpdateCreateButton (bool, int); - void signalUpdateCreateButtonFlags(int); - public slots: + void slotRejected(); + private slots: - //void updateViews(); - void updateOpenButton(const QStringList &items); - void slotEnableCreateButton(bool enable, int widgetNumber); - void slotAdjusterChanged(bool value); - void slotGameFileSelected(int value); + }; } #endif // FILEDIALOG_HPP diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index e6ed0ec56..d9caea3be 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -8,83 +8,205 @@ #include #include #include +#include +#include -ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) : - QDialog(parent) +#include "../../../apps/opencs/view/doc/filewidget.hpp" +#include "../../../apps/opencs/view/doc/adjusterwidget.hpp" + +ContentSelectorView::ContentSelector *ContentSelectorView::ContentSelector::mInstance = 0; +QStringList ContentSelectorView::ContentSelector::mFilePaths; + +void ContentSelectorView::ContentSelector::configure(QWidget *subject, unsigned char flags) +{ + assert(!mInstance); + mInstance = new ContentSelector (subject, flags); +} + +ContentSelectorView::ContentSelector& ContentSelectorView::ContentSelector::instance() +{ + assert(mInstance); + return *mInstance; +} + +ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent, unsigned char flags) : + QWidget(parent), mFlags (flags), + mAdjusterWidget (0), mFileWidget (0) { - setupUi(this); + ui.setupUi (this); + + parent->setLayout(new QGridLayout()); + parent->layout()->addWidget(this); buildContentModel(); buildGameFileView(); buildAddonView(); buildProfilesView(); + buildNewAddonView(); + buildLoadAddonView(); - updateViews(); + /* + //mContentModel->sort(3); // Sort by date accessed +*/ +} + +bool ContentSelectorView::ContentSelector::isFlagged(SelectorFlags flag) const +{ + return (mFlags & flag); } void ContentSelectorView::ContentSelector::buildContentModel() { + if (!isFlagged (Flag_Content)) + return; + mContentModel = new ContentSelectorModel::ContentModel(); - connect(mContentModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); + + if (mFilePaths.size()>0) + { + foreach (const QString &path, mFilePaths) + mContentModel->addFiles(path); + + mFilePaths.clear(); + } + + ui.gameFileView->setCurrentIndex(-1); + mContentModel->uncheckAll(); } void ContentSelectorView::ContentSelector::buildGameFileView() { + if (!isFlagged (Flag_Content)) + { + ui.gameFileView->setVisible(false); + return; + } + 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); + ui.gameFileView->setPlaceholderText(QString("Select a game file...")); + ui.gameFileView->setModel(mGameFileProxyModel); - connect(gameFileView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentGameFileIndexChanged(int))); - connect(gameFileView, SIGNAL(currentIndexChanged(int)), this, SIGNAL(signalGameFileChanged(int))); + connect(ui.gameFileView, SIGNAL(currentIndexChanged(int)), this, SLOT (slotCurrentGameFileIndexChanged(int))); - gameFileView->setCurrentIndex(-1); - gameFileView->setCurrentIndex(0); + ui.gameFileView->setCurrentIndex(-1); } void ContentSelectorView::ContentSelector::buildAddonView() { + if (!isFlagged (Flag_Content)) + { + ui.addonView->setVisible(false); + return; + } + 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); + ui.addonView->setModel(mAddonProxyModel); - connect(addonView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotAddonTableItemClicked(const QModelIndex &))); + connect(ui.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))); + if (!isFlagged (Flag_Profile)) + { + ui.profileGroupBox->setVisible(false); + return; + } + + ui.profilesComboBox->setPlaceholderText(QString("Select a profile...")); + connect(ui.profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); +} + +void ContentSelectorView::ContentSelector::buildLoadAddonView() +{ + if (!isFlagged (Flag_LoadAddon)) + { + ui.projectGroupBox->setVisible (false); + return; + } + + ui.projectCreateButton->setVisible (false); + // ui.projectButtonBox->setStandardButtons(QDialogButtonBox::Open | QDialogButtonBox::Cancel); + ui.projectGroupBox->setTitle (""); + + connect(ui.projectButtonBox, SIGNAL(accepted()), this, SIGNAL(accepted())); + connect(ui.projectButtonBox, SIGNAL(rejected()), this, SIGNAL(rejected())); +} + +void ContentSelectorView::ContentSelector::buildNewAddonView() +{ + if (!isFlagged (Flag_NewAddon)) + { + ui.profileGroupBox->setVisible (false); + return; + } + + mFileWidget = new CSVDoc::FileWidget (this); + mAdjusterWidget = new CSVDoc::AdjusterWidget (this); + + mFileWidget->setType(true); + mFileWidget->extensionLabelIsVisible(false); + + ui.fileWidgetFrame->layout()->addWidget(mFileWidget); + ui.adjusterWidgetFrame->layout()->addWidget(mAdjusterWidget); + + ui.projectButtonBox->setStandardButtons(QDialogButtonBox::Cancel); + ui.projectButtonBox->addButton(ui.projectCreateButton, QDialogButtonBox::ActionRole); + + connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)), + mAdjusterWidget, SLOT (setName (const QString&, bool))); + + connect (mAdjusterWidget, SIGNAL (stateChanged(bool)), this, SLOT (slotUpdateCreateButton(bool))); + + connect(ui.projectCreateButton, SIGNAL(clicked()), this, SIGNAL(accepted())); + connect(ui.projectButtonBox, SIGNAL(rejected()), this, SIGNAL(rejected())); +} + +QString ContentSelectorView::ContentSelector::filename() const +{ + QString filepath = ""; + + if (mAdjusterWidget) + filepath = QString::fromAscii(mAdjusterWidget->getPath().c_str()); + + return filepath; } -void ContentSelectorView::ContentSelector::updateViews() +QStringList ContentSelectorView::ContentSelector::selectedFiles() const { - // 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(); + QStringList filePaths; + + if (mContentModel) + { + foreach (ContentSelectorModel::EsmFile *file, mContentModel->checkedItems()) + filePaths.append(file->path()); + } + + return filePaths; } + void ContentSelectorView::ContentSelector::addFiles(const QString &path) { - mContentModel->addFiles(path); - //mContentModel->sort(3); // Sort by date accessed - gameFileView->setCurrentIndex(-1); - mContentModel->uncheckAll(); + // if the model hasn't been instantiated, queue the path + if (!mInstance) + mFilePaths.append(path); + else + { + mInstance->mContentModel->addFiles(path); + mInstance->ui.gameFileView->setCurrentIndex(-1); + mInstance->mContentModel->uncheckAll(); + } } QStringList ContentSelectorView::ContentSelector::checkedItemsPaths() @@ -99,14 +221,14 @@ QStringList ContentSelectorView::ContentSelector::checkedItemsPaths() void ContentSelectorView::ContentSelector::slotCurrentProfileIndexChanged(int index) { - emit profileChanged(index); + emit signalProfileChanged(index); } void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int index) { static int oldIndex = -1; - QAbstractItemModel *const model = gameFileView->model(); + QAbstractItemModel *const model = ui.gameFileView->model(); QSortFilterProxyModel *proxy = dynamic_cast(model); if (proxy) @@ -122,16 +244,37 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i if (proxy) proxy->setDynamicSortFilter(true); - emit signalGameFileChanged(true); + slotUpdateCreateButton(true); } void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QModelIndex &index) { - QAbstractItemModel *const model = addonView->model(); - //QSortFilterProxyModel *proxy = dynamic_cast(model); + QAbstractItemModel *const model = ui.addonView->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); } + +void ContentSelectorView::ContentSelector::slotUpdateOpenButton(const QStringList &items) +{ + QPushButton *openButton = ui.projectButtonBox->button(QDialogButtonBox::Open); + + if (!openButton) + return; + + openButton->setEnabled(!items.isEmpty()); +} + +void ContentSelectorView::ContentSelector::slotUpdateCreateButton(bool) +{ + //enable only if a game file is selected and the adjuster widget is non-empty + bool validGameFile = (ui.gameFileView->currentIndex() != -1); + bool validFilename = false; + + if (mAdjusterWidget) + validFilename = mAdjusterWidget->isValid(); + + ui.projectCreateButton->setEnabled(validGameFile && validFilename); +} diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index 5af53dc46..48c3ae103 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -9,12 +9,33 @@ namespace ContentSelectorModel { class ContentModel; } class QSortFilterProxyModel; +namespace CSVDoc +{ + class FileWidget; + class AdjusterWidget; +} namespace ContentSelectorView { - class ContentSelector : public QDialog, protected Ui::DataFilesPage + enum SelectorFlags + { + Flag_Content = 0x01, // gamefile combobox & addon list view + Flag_NewAddon = 0x02, // enable project button box (Create/Cancel) and file/adjuster widgets + Flag_LoadAddon = 0x04, // enable project button box (Open/Cancel) + Flag_Profile = 0x08 // enable profile combo box + }; + + class ContentSelector : public QWidget { Q_OBJECT + unsigned char mFlags; + + static ContentSelector *mInstance; + static QStringList mFilePaths; + + CSVDoc::FileWidget *mFileWidget; + CSVDoc::AdjusterWidget *mAdjusterWidget; + protected: ContentSelectorModel::ContentModel *mContentModel; @@ -23,30 +44,46 @@ namespace ContentSelectorView public: - explicit ContentSelector(QWidget *parent = 0); + static void configure(QWidget *subject, unsigned char flags = Flag_Content); + static ContentSelector &instance(); + static void addFiles(const QString &path); - static ContentSelector &cast(QWidget *subject); //static constructor function for singleton performance. - - void addFiles(const QString &path); void setCheckState(QModelIndex index, QSortFilterProxyModel *model); QStringList checkedItemsPaths(); + QString filename() const; + QStringList selectedFiles() const; private: + explicit ContentSelector(QWidget *parent = 0, unsigned char flags = Flag_Content); + Ui::DataFilesPage ui; + void buildContentModel(); void buildGameFileView(); void buildAddonView(); void buildProfilesView(); + void buildNewAddonView(); + void buildLoadAddonView(); + + bool isFlagged(SelectorFlags flag) const; signals: - void profileChanged(int index); + void accepted(); + void rejected(); + + void signalProfileChanged(int index); void signalGameFileChanged(int value); + void signalCreateButtonClicked(); + private slots: - void updateViews(); + void slotCurrentProfileIndexChanged(int index); void slotCurrentGameFileIndexChanged(int index); void slotAddonTableItemClicked(const QModelIndex &index); + + void slotUpdateCreateButton (bool); + void slotUpdateOpenButton(const QStringList &items); }; } From 00c78a4aa1be9d465d8e7e625871bf02af3619c5 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 1 Oct 2013 21:29:45 -0500 Subject: [PATCH 067/118] Implementing ContentSelector class in DataFilesPage Moved AdjusterWidget / FileWidget to ContentSelectorView --- apps/launcher/datafilespage.cpp | 336 ++++-------------- apps/launcher/datafilespage.hpp | 46 +-- apps/launcher/maindialog.cpp | 6 +- apps/opencs/CMakeLists.txt | 3 +- apps/opencs/editor.cpp | 4 +- apps/opencs/view/doc/filedialog.cpp | 11 +- apps/opencs/view/doc/filedialog.hpp | 2 +- apps/opencs/view/doc/newgame.cpp | 4 +- components/CMakeLists.txt | 1 + .../contentselector/view}/adjusterwidget.cpp | 0 .../contentselector/view}/adjusterwidget.hpp | 0 .../contentselector/view/contentselector.cpp | 169 ++++++++- .../contentselector/view/contentselector.hpp | 35 +- .../contentselector/view}/filewidget.cpp | 0 .../contentselector/view}/filewidget.hpp | 0 .../contentselector/view/profilescombobox.cpp | 3 + .../contentselector/view/profilescombobox.hpp | 2 + files/ui/datafilespage.ui | 49 ++- 18 files changed, 314 insertions(+), 357 deletions(-) rename {apps/opencs/view/doc => components/contentselector/view}/adjusterwidget.cpp (100%) rename {apps/opencs/view/doc => components/contentselector/view}/adjusterwidget.hpp (100%) rename {apps/opencs/view/doc => components/contentselector/view}/filewidget.cpp (100%) rename {apps/opencs/view/doc => components/contentselector/view}/filewidget.hpp (100%) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 828b2f2ba..b298f8a14 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -19,7 +19,6 @@ #include "utils/textinputdialog.hpp" #include "components/contentselector/view/contentselector.hpp" -#include "components/contentselector/model/contentmodel.hpp" #include @@ -28,176 +27,59 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam , mGameSettings(gameSettings) , mLauncherSettings(launcherSettings) { - setupUi(this); -/* - // QMetaObject::connectSlotsByName(this); + unsigned char flags; - projectGroupBox->hide(); + flags = ContentSelectorView::Flag_Content | ContentSelectorView::Flag_Profile; - // Create a dialog for the new profile name input - mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); + ContentSelectorView::ContentSelector::configure(this, flags); - connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString))); - - - - buildContentModel(); - buildGameFileView(); - buildAddonView(); - buildProfilesView(); - - - createActions(); setupDataFiles(); + ContentSelectorView::ContentSelector &cSelector = + ContentSelectorView::ContentSelector::instance(); - 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 (&cSelector, SIGNAL (signalProfileRenamed (QString, QString)), + this, SLOT (slotProfileRenamed (QString, QString))); - connect(addonView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotAddonTableItemClicked(const QModelIndex &))); -} + connect (&cSelector, SIGNAL (signalProfileChanged (QString, QString)), + this, SLOT (slotProfileChanged (QString, QString))); -void DataFilesPage::buildProfilesView() -{ - profilesComboBox->setPlaceholderText(QString("Select a profile...")); - connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); -} + connect (&cSelector, SIGNAL (signalProfileDeleted (QString)), + this, SLOT (slotProfileDeleted (QString))); -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 - // ui.gameFileView->setCurrentIndex(-1); - // mContentModel->uncheckAll(); -} - -void DataFilesPage::createActions() -{ - // Add the actions to the toolbuttons - newProfileButton->setDefaultAction(newProfileAction); - deleteProfileButton->setDefaultAction(deleteProfileAction); -} - -void DataFilesPage::setupDataFiles() -{ - // Set the encoding to the one found in openmw.cfg or the default - //mContentSelector.setEncoding(mGameSettings.value(QString("encoding"), QString("win1252"))); - - QStringList paths = mGameSettings.getDataDirs(); - - foreach (const QString &path, paths) { - //mContentSelector. - mContentModel->addFiles(path); - } - - QString dataLocal = mGameSettings.getDataLocal(); - if (!dataLocal.isEmpty()) - //mContentSelector. - mContentModel->addFiles(dataLocal); - - // Sort by date accessed for now - //mContentSelector->sort(3); - - QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/")); - QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); - - if (!profiles.isEmpty()) - profilesComboBox->addItems(profiles); - - // Add the current profile if empty - if (profilesComboBox->findText(profile) == -1 && !profile.isEmpty()) - profilesComboBox->addItem(profile); - - if (profilesComboBox->findText(QString("Default")) == -1) - profilesComboBox->addItem(QString("Default")); - - if (profile.isEmpty() || profile == QLatin1String("Default")) { - deleteProfileAction->setEnabled(false); - profilesComboBox->setEditEnabled(false); - profilesComboBox->setCurrentIndex(profilesComboBox->findText(QString("Default"))); - } else { - profilesComboBox->setEditEnabled(true); - profilesComboBox->setCurrentIndex(profilesComboBox->findText(profile)); - } - - // We do this here to prevent deletion of profiles when initializing the combobox - connect(profilesComboBox, SIGNAL(profileRenamed(QString,QString)), this, SLOT(profileRenamed(QString,QString))); - connect(profilesComboBox, SIGNAL(profileChanged(QString,QString)), this, SLOT(profileChanged(QString,QString))); - - loadSettings(); - - gameFileView->setCurrentIndex(-1); + connect (&cSelector, SIGNAL (signalProfileAdded ()), + this, SLOT (slotProfileAdded ())); } void DataFilesPage::loadSettings() { + QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); if (profile.isEmpty()) return; - // mContentSelector. - mContentModel->uncheckAll(); - - QStringList gameFiles = mLauncherSettings.values(QString("Profiles/") + profile + QString("/master"), Qt::MatchExactly); + QStringList files = mLauncherSettings.values(QString("Profiles/") + profile + QString("/master"), Qt::MatchExactly); QStringList addons = mLauncherSettings.values(QString("Profiles/") + profile + QString("/plugin"), Qt::MatchExactly); + + foreach (const QString &file, addons) + files.append(file); + + //ContentSelectorView::ContentSelector::instance().setCheckStates(files); } void DataFilesPage::saveSettings() { - if (mContentModel->rowCount() < 1) - return; + ContentSelectorModel::ContentFileList items = + ContentSelectorView::ContentSelector::instance().selectedFiles(); + + if (items.size() == 0) + return; QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); if (profile.isEmpty()) { - profile = profilesComboBox->currentText(); + profile = ContentSelectorView::ContentSelector::instance().getProfileText(); mLauncherSettings.setValue(QString("Profiles/currentprofile"), profile); } @@ -207,8 +89,6 @@ void DataFilesPage::saveSettings() mGameSettings.remove(QString("master")); mGameSettings.remove(QString("plugin")); - ContentSelectorModel::ContentFileList items = mContentModel->checkedItems(); - foreach(const ContentSelectorModel::EsmFile *item, items) { if (item->gameFiles().size() == 0) { @@ -223,109 +103,18 @@ void DataFilesPage::saveSettings() } -void DataFilesPage::updateOkButton(const QString &text) +void DataFilesPage::slotProfileDeleted (const QString &item) { - // We do this here because we need the profiles combobox text - if (text.isEmpty()) { - mNewProfileDialog->setOkButtonEnabled(false); - return; - } - - (profilesComboBox->findText(text) == -1) - ? mNewProfileDialog->setOkButtonEnabled(true) - : mNewProfileDialog->setOkButtonEnabled(false); -} - -void DataFilesPage::setProfilesComboBoxIndex(int index) -{ - profilesComboBox->setCurrentIndex(index); -} - -QAbstractItemModel* DataFilesPage::profilesComboBoxModel() -{ - return profilesComboBox->model(); -} - -int DataFilesPage::profilesComboBoxIndex() -{ - return profilesComboBox->currentIndex(); -} - -void DataFilesPage::on_newProfileAction_triggered() -{ - if (mNewProfileDialog->exec() == QDialog::Accepted) { - QString profile = mNewProfileDialog->lineEdit()->text(); - profilesComboBox->addItem(profile); - profilesComboBox->setCurrentIndex(profilesComboBox->findText(profile)); - } -} - -void DataFilesPage::on_deleteProfileAction_triggered() -{ - QString profile = profilesComboBox->currentText(); - - if (profile.isEmpty()) - return; - - QMessageBox msgBox(this); - msgBox.setWindowTitle(tr("Delete Profile")); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setStandardButtons(QMessageBox::Cancel); - msgBox.setText(tr("Are you sure you want to delete %0?").arg(profile)); - - QAbstractButton *deleteButton = - msgBox.addButton(tr("Delete"), QMessageBox::ActionRole); - - msgBox.exec(); - - if (msgBox.clickedButton() == deleteButton) { - mLauncherSettings.remove(QString("Profiles/") + profile + QString("/master")); - mLauncherSettings.remove(QString("Profiles/") + profile + QString("/plugin")); - - // Remove the profile from the combobox - profilesComboBox->removeItem(profilesComboBox->findText(profile)); - } -} - -void DataFilesPage::setPluginsCheckstates(Qt::CheckState state) -{ - if (!addonView->selectionModel()->hasSelection()) { - return; - } - - QModelIndexList indexes = addonView->selectionModel()->selectedIndexes(); - - foreach (const QModelIndex &index, indexes) - { - if (!index.isValid()) - return; - - QModelIndex sourceIndex = mAddonProxyModel->mapToSource(index); - - if (!sourceIndex.isValid()) - return; - - //bool isChecked = ( state == Qt::Checked ); - - mContentModel->setData(sourceIndex, state, Qt::CheckStateRole); - } + mLauncherSettings.remove(QString("Profiles/") + item + QString("/master")); + mLauncherSettings.remove(QString("Profiles/") + item + QString("/plugin")); } -void DataFilesPage::profileChanged(const QString &previous, const QString ¤t) +void DataFilesPage::slotProfileChanged(const QString &previous, const QString ¤t) { - // Prevent the deletion of the default profile - if (current == QLatin1String("Default")) { - deleteProfileAction->setEnabled(false); - profilesComboBox->setEditEnabled(false); - } else { - deleteProfileAction->setEnabled(true); - profilesComboBox->setEditEnabled(true); - } - if (previous.isEmpty()) return; - if (profilesComboBox->findText(previous) == -1) + if (ContentSelectorView::ContentSelector::instance().getProfileIndex (previous) == -1) return; // Profile was deleted // Store the previous profile @@ -336,7 +125,7 @@ void DataFilesPage::profileChanged(const QString &previous, const QString &curre loadSettings(); } -void DataFilesPage::profileRenamed(const QString &previous, const QString ¤t) +void DataFilesPage::slotProfileRenamed(const QString &previous, const QString ¤t) { if (previous.isEmpty()) return; @@ -350,56 +139,55 @@ void DataFilesPage::profileRenamed(const QString &previous, const QString &curre mLauncherSettings.remove(QString("Profiles/") + previous + QString("/plugin")); // Remove the profile from the combobox - profilesComboBox->removeItem(profilesComboBox->findText(previous)); + ContentSelectorView::ContentSelector::instance().removeProfile (previous); loadSettings(); - } -//////////////////////////// -QStringList DataFilesPage::checkedItemsPaths() +void DataFilesPage::slotProfileAdded() { - QStringList itemPaths; + TextInputDialog newDialog (tr("New Profile"), tr("Profile name:"), this); - foreach( const ContentSelectorModel::EsmFile *file, mContentModel->checkedItems()) - itemPaths << file->path(); + // connect(mNewDialog->lineEdit(), SIGNAL(textChanged(QString)), + // this, SLOT(updateOkButton(QString))); - return itemPaths; + if (newDialog.exec() == QDialog::Accepted) + { + QString profile = newDialog.lineEdit()->text(); + + ContentSelectorView::ContentSelector + ::instance().addProfile(profile, true); + } } -void DataFilesPage::slotCurrentProfileIndexChanged(int index) +void DataFilesPage::setProfilesComboBoxIndex(int index) { - emit profileChanged(index); + ContentSelectorView::ContentSelector::instance().setProfileIndex(index); } -void DataFilesPage::slotCurrentGameFileIndexChanged(int index) +void DataFilesPage::setupDataFiles() { - static int oldIndex = -1; + ContentSelectorView::ContentSelector &cSelector = + ContentSelectorView::ContentSelector::instance(); + + QStringList paths = mGameSettings.getDataDirs(); - QAbstractItemModel *const model = gameFileView->model(); - QSortFilterProxyModel *proxy = dynamic_cast(model); + foreach (const QString &path, paths) + cSelector.addFiles(path); - if (proxy) - proxy->setDynamicSortFilter(false); + QString dataLocal = mGameSettings.getDataLocal(); - if (oldIndex > -1) - model->setData(model->index(oldIndex, 0), false, Qt::UserRole + 1); + if (!dataLocal.isEmpty()) + cSelector.addFiles(dataLocal); - oldIndex = index; + QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/")); + QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); - model->setData(model->index(index, 0), true, Qt::UserRole + 1); - if (proxy) - proxy->setDynamicSortFilter(true); -} + foreach (const QString &item, profiles) + cSelector.addProfile (item); -void DataFilesPage::slotAddonTableItemClicked(const QModelIndex &index) -{ - QAbstractItemModel *const model = addonView->model(); - //QSortFilterProxyModel *proxy = dynamic_cast(model); + cSelector.addProfile (profile, true); - if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked) - model->setData(index, Qt::Checked, Qt::CheckStateRole); - else - model->setData(index, Qt::Unchecked, Qt::CheckStateRole); + loadSettings(); } diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index 9c7b0538e..6ed5d9ce9 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -4,9 +4,6 @@ #include #include -#include "ui_datafilespage.h" -#include "components/contentselector/view/contentselector.hpp" - class QSortFilterProxyModel; class QAbstractItemModel; class QAction; @@ -19,7 +16,7 @@ class LauncherSettings; namespace Files { struct ConfigurationManager; } -class DataFilesPage : public QWidget, private Ui::DataFilesPage +class DataFilesPage : public QWidget { Q_OBJECT @@ -36,58 +33,33 @@ signals: void profileChanged(int index); public slots: - void setProfilesComboBoxIndex(int index); + //void showContextMenu(const QPoint &point); - //void showContextMenu(const QPoint &point); - 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(); private slots: + void slotProfileAdded(); + void slotProfileChanged(const QString &previous, const QString ¤t); + void slotProfileRenamed(const QString &previous, const QString ¤t); + void slotProfileDeleted(const QString &item); + void setProfilesComboBoxIndex(int index); + private: QMenu *mContextMenu; - //ContentSelectorView::ContentSelector mContentSelector; - ContentSelectorModel::ContentModel *mContentModel; + Files::ConfigurationManager &mCfgMgr; GameSettings &mGameSettings; LauncherSettings &mLauncherSettings; - TextInputDialog *mNewProfileDialog; - QSortFilterProxyModel *mGameFileProxyModel; - QSortFilterProxyModel *mAddonProxyModel; - void setPluginsCheckstates(Qt::CheckState state); - void createActions(); void setupDataFiles(); void setupConfig(); void readConfig(); 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/maindialog.cpp b/apps/launcher/maindialog.cpp index 032f70916..311e3a25c 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -106,10 +106,10 @@ void MainDialog::createPages() mPlayPage = new PlayPage(this); mGraphicsPage = new GraphicsPage(mCfgMgr, mGraphicsSettings, this); mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this); - +/// reimplement datafilespage functions to provide access // Set the combobox of the play page to imitate the combobox on the datafilespage - mPlayPage->setProfilesComboBoxModel(mDataFilesPage->profilesComboBoxModel()); - mPlayPage->setProfilesComboBoxIndex(mDataFilesPage->profilesComboBoxIndex()); + // mPlayPage->setProfilesComboBoxModel(mDataFilesPage->profilesComboBoxModel()); + // mPlayPage->setProfilesComboBoxIndex(mDataFilesPage->profilesComboBoxIndex()); // Add the pages to the stacked widget pagesWidget->addWidget(mPlayPage); diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 00547a2ba..9ae12c7a7 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -43,8 +43,7 @@ opencs_units_noqt (model/tools opencs_units (view/doc - viewmanager view operations operation subview startup filedialog newgame filewidget - adjusterwidget + viewmanager view operations operation subview startup filedialog newgame ) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index fc9168e2e..401f3839f 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -124,7 +124,7 @@ void CS::Editor::openFiles() { std::vector files; - foreach (const QString &path, mFileDialog.selectedFilepaths()) { + foreach (const QString &path, mFileDialog.selectedFilePaths()) { files.push_back(path.toStdString()); } @@ -139,7 +139,7 @@ void CS::Editor::createNewFile() { std::vector files; - foreach (const QString &path, mFileDialog.selectedFilepaths()) { + foreach (const QString &path, mFileDialog.selectedFilePaths()) { files.push_back(path.toStdString()); } diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 5a97a7a26..b1b72dc1f 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -37,9 +37,16 @@ QString CSVDoc::FileDialog::filename() return ContentSelectorView::ContentSelector::instance().filename(); } -QStringList CSVDoc::FileDialog::selectedFilepaths() +QStringList CSVDoc::FileDialog::selectedFilePaths() { - return ContentSelectorView::ContentSelector::instance().selectedFiles(); + QStringList filePaths; + + foreach (ContentSelectorModel::EsmFile *file, ContentSelectorView::ContentSelector:: + instance().selectedFiles() ) + { + filePaths.append(file->fileName()); + } + return filePaths; } void CSVDoc::FileDialog::showDialog() diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 88d408b5c..acc35189d 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -41,7 +41,7 @@ namespace CSVDoc void addFiles (const QString &path); QString filename(); - QStringList selectedFilepaths(); + QStringList selectedFilePaths(); private: diff --git a/apps/opencs/view/doc/newgame.cpp b/apps/opencs/view/doc/newgame.cpp index 98681c499..265b98305 100644 --- a/apps/opencs/view/doc/newgame.cpp +++ b/apps/opencs/view/doc/newgame.cpp @@ -7,8 +7,8 @@ #include #include -#include "filewidget.hpp" -#include "adjusterwidget.hpp" +#include "components/contentselector/view/filewidget.hpp" +#include "components/contentselector/view/adjusterwidget.hpp" CSVDoc::NewGameDialogue::NewGameDialogue() { diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 7053bb973..ebce4578b 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -84,6 +84,7 @@ if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) model/naturalsort model/contentmodel view/profilescombobox view/comboboxlineedit view/lineedit view/contentselector + view/filewidget view/adjusterwidget ) include(${QT_USE_FILE}) diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/components/contentselector/view/adjusterwidget.cpp similarity index 100% rename from apps/opencs/view/doc/adjusterwidget.cpp rename to components/contentselector/view/adjusterwidget.cpp diff --git a/apps/opencs/view/doc/adjusterwidget.hpp b/components/contentselector/view/adjusterwidget.hpp similarity index 100% rename from apps/opencs/view/doc/adjusterwidget.hpp rename to components/contentselector/view/adjusterwidget.hpp diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index d9caea3be..cb0774f68 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -1,7 +1,7 @@ #include "contentselector.hpp" -#include "../model/contentmodel.hpp" #include "../model/esmfile.hpp" +#include "lineedit.hpp" #include @@ -9,10 +9,11 @@ #include #include #include +#include #include -#include "../../../apps/opencs/view/doc/filewidget.hpp" -#include "../../../apps/opencs/view/doc/adjusterwidget.hpp" +#include "filewidget.hpp" +#include "adjusterwidget.hpp" ContentSelectorView::ContentSelector *ContentSelectorView::ContentSelector::mInstance = 0; QStringList ContentSelectorView::ContentSelector::mFilePaths; @@ -25,6 +26,7 @@ void ContentSelectorView::ContentSelector::configure(QWidget *subject, unsigned ContentSelectorView::ContentSelector& ContentSelectorView::ContentSelector::instance() { + assert(mInstance); return *mInstance; } @@ -33,6 +35,7 @@ ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent, unsigned QWidget(parent), mFlags (flags), mAdjusterWidget (0), mFileWidget (0) { + ui.setupUi (this); parent->setLayout(new QGridLayout()); @@ -41,15 +44,23 @@ ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent, unsigned buildContentModel(); buildGameFileView(); buildAddonView(); - buildProfilesView(); buildNewAddonView(); buildLoadAddonView(); + buildProfilesView(); /* //mContentModel->sort(3); // Sort by date accessed */ } +QString ContentSelectorView::ContentSelector::getNewProfileName() +{ + // Create a dialog for the new profile name input + //mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); + + //connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString))); + return ""; +} bool ContentSelectorView::ContentSelector::isFlagged(SelectorFlags flag) const { @@ -123,8 +134,17 @@ void ContentSelectorView::ContentSelector::buildProfilesView() return; } - ui.profilesComboBox->setPlaceholderText(QString("Select a profile...")); - connect(ui.profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); + // Add the actions to the toolbuttons + ui.newProfileButton->setDefaultAction (ui.newProfileAction); + ui.deleteProfileButton->setDefaultAction (ui.deleteProfileAction); + + ui.profilesComboBox->addItem ("Default"); + ui.profilesComboBox->setPlaceholderText (QString("Select a profile...")); + + connect (ui.profilesComboBox, SIGNAL (currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); + connect (ui.profilesComboBox, SIGNAL (profileRenamed(QString,QString)), this, SIGNAL(signalProfileRenamed(QString,QString))); + connect (ui.profilesComboBox, SIGNAL (profileChanged(QString,QString)), this, SIGNAL(signalProfileChanged(QString,QString))); + connect (ui.profilesComboBox, SIGNAL (signalProfileTextChanged(QString)), this, SLOT (slotProfileTextChanged (QString))); } void ContentSelectorView::ContentSelector::buildLoadAddonView() @@ -136,7 +156,6 @@ void ContentSelectorView::ContentSelector::buildLoadAddonView() } ui.projectCreateButton->setVisible (false); - // ui.projectButtonBox->setStandardButtons(QDialogButtonBox::Open | QDialogButtonBox::Cancel); ui.projectGroupBox->setTitle (""); connect(ui.projectButtonBox, SIGNAL(accepted()), this, SIGNAL(accepted())); @@ -172,6 +191,17 @@ void ContentSelectorView::ContentSelector::buildNewAddonView() connect(ui.projectButtonBox, SIGNAL(rejected()), this, SIGNAL(rejected())); } +void ContentSelectorView::ContentSelector::setCheckStates(const QStringList &list) +{ + if (list.isEmpty()) + return; + + mContentModel->uncheckAll(); + + foreach (const QString &file, list) + mContentModel->setCheckState(file, Qt::Checked); +} + QString ContentSelectorView::ContentSelector::filename() const { QString filepath = ""; @@ -182,7 +212,7 @@ QString ContentSelectorView::ContentSelector::filename() const return filepath; } -QStringList ContentSelectorView::ContentSelector::selectedFiles() const +QStringList ContentSelectorView::ContentSelector::selectedFilePaths() const { QStringList filePaths; @@ -195,6 +225,15 @@ QStringList ContentSelectorView::ContentSelector::selectedFiles() const return filePaths; } +ContentSelectorModel::ContentFileList + ContentSelectorView::ContentSelector::selectedFiles() const +{ + if (mContentModel) + return mContentModel->checkedItems(); + + return ContentSelectorModel::ContentFileList(); +} + void ContentSelectorView::ContentSelector::addFiles(const QString &path) { @@ -209,6 +248,55 @@ void ContentSelectorView::ContentSelector::addFiles(const QString &path) } } +void ContentSelectorView::ContentSelector::removeProfile(const QString &item) +{ + int idx = ui.profilesComboBox->findText(item); + + if (idx != -1) + ui.profilesComboBox->removeItem(idx); +} + +int ContentSelectorView::ContentSelector::getProfileIndex ( const QString &item) const +{ + return ui.profilesComboBox->findText (item); +} + +void ContentSelectorView::ContentSelector::setProfileIndex(int index) +{ + if (index >=0 && index < ui.profilesComboBox->count()) + ui.profilesComboBox->setCurrentIndex(index); +} + +void ContentSelectorView::ContentSelector::addProfile (const QString &item, bool setAsCurrent) +{ + if (item.isEmpty()) + return; + + if (ui.profilesComboBox->findText(item) == -1) + ui.profilesComboBox->addItem(item); + + if (setAsCurrent) + ui.profilesComboBox->setCurrentIndex(ui.profilesComboBox->findText(item)); + + enableProfilesComboBox(); +} + +QString ContentSelectorView::ContentSelector::getProfileText() const +{ + return ui.profilesComboBox->currentText(); +} + +void ContentSelectorView::ContentSelector::enableProfilesComboBox() +{ + if (!ui.profilesComboBox->isEnabled()) + ui.profilesComboBox->setEnabled(true); + + if (!ui.deleteProfileAction->isEnabled()) + ui.deleteProfileAction->setEnabled(true); + + ui.projectButtonBox->button(QDialogButtonBox::Open)->setEnabled (true); +} + QStringList ContentSelectorView::ContentSelector::checkedItemsPaths() { QStringList itemPaths; @@ -221,6 +309,12 @@ QStringList ContentSelectorView::ContentSelector::checkedItemsPaths() void ContentSelectorView::ContentSelector::slotCurrentProfileIndexChanged(int index) { + //don't allow deleting "Default" profile + bool success = (ui.profilesComboBox->itemText(index) == "Default"); + + ui.deleteProfileAction->setEnabled(success); + ui.profilesComboBox->setEditEnabled(success); + emit signalProfileChanged(index); } @@ -247,6 +341,14 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i slotUpdateCreateButton(true); } +void ContentSelectorView::ContentSelector::slotProfileTextChanged(const QString &text) +{ + QPushButton *opnBtn = ui.projectButtonBox->button(QDialogButtonBox::Open); + + if (opnBtn->isEnabled()) + opnBtn->setEnabled (false); +} + void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QModelIndex &index) { QAbstractItemModel *const model = ui.addonView->model(); @@ -257,16 +359,6 @@ void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QMode model->setData(index, Qt::Unchecked, Qt::CheckStateRole); } -void ContentSelectorView::ContentSelector::slotUpdateOpenButton(const QStringList &items) -{ - QPushButton *openButton = ui.projectButtonBox->button(QDialogButtonBox::Open); - - if (!openButton) - return; - - openButton->setEnabled(!items.isEmpty()); -} - void ContentSelectorView::ContentSelector::slotUpdateCreateButton(bool) { //enable only if a game file is selected and the adjuster widget is non-empty @@ -278,3 +370,44 @@ void ContentSelectorView::ContentSelector::slotUpdateCreateButton(bool) ui.projectCreateButton->setEnabled(validGameFile && validFilename); } + + +void ContentSelectorView::ContentSelector::on_newProfileAction_triggered() +{ + emit signalProfileAdded(); +} + +void ContentSelectorView::ContentSelector::on_deleteProfileAction_triggered() +{ + QString profile = ui.profilesComboBox->currentText(); + + if (profile.isEmpty()) + return; + + QMessageBox msgBox(this); + msgBox.setWindowTitle(tr("Delete Profile")); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setStandardButtons(QMessageBox::Cancel); + msgBox.setText(tr("Are you sure you want to delete %0?").arg(profile)); + + QAbstractButton *deleteButton = + msgBox.addButton(tr("Delete"), QMessageBox::ActionRole); + + msgBox.exec(); + + if (msgBox.clickedButton() != deleteButton) + return; + + // Remove the profile from the combobox + ui.profilesComboBox->removeItem(ui.profilesComboBox->findText(profile)); + + //signal for removal from model + emit signalProfileDeleted (profile); +} +/* +void ContentSelectorView::ContentSelector::slotUpdateOkButton(const QString &text) +{ + bool success = (ui.profilesComboBox->findText(text) == -1); + + mNewDialog->setOkButtonEnabled(success); +}*/ diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index 48c3ae103..caf9cc670 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -4,10 +4,10 @@ #include #include "ui_datafilespage.h" - -namespace ContentSelectorModel { class ContentModel; } +#include "../model/contentmodel.hpp" class QSortFilterProxyModel; +class TextInputDialog; namespace CSVDoc { @@ -36,6 +36,8 @@ namespace ContentSelectorView CSVDoc::FileWidget *mFileWidget; CSVDoc::AdjusterWidget *mAdjusterWidget; + TextInputDialog *mNewDialog; + protected: ContentSelectorModel::ContentModel *mContentModel; @@ -43,19 +45,28 @@ namespace ContentSelectorView QSortFilterProxyModel *mAddonProxyModel; public: + explicit ContentSelector(QWidget *parent = 0, unsigned char flags = Flag_Content); static void configure(QWidget *subject, unsigned char flags = Flag_Content); static ContentSelector &instance(); static void addFiles(const QString &path); - void setCheckState(QModelIndex index, QSortFilterProxyModel *model); + void setCheckStates (const QStringList &list); QStringList checkedItemsPaths(); + ContentSelectorModel::ContentFileList *CheckedItems(); + QString filename() const; - QStringList selectedFiles() const; + ContentSelectorModel::ContentFileList selectedFiles() const; + QStringList selectedFilePaths() const; + + void addProfile (const QString &item, bool setAsCurrent = false); + void removeProfile (const QString &item); + int getProfileIndex (const QString &item) const; + void setProfileIndex (int index); + QString getProfileText() const; private: - explicit ContentSelector(QWidget *parent = 0, unsigned char flags = Flag_Content); Ui::DataFilesPage ui; void buildContentModel(); @@ -66,6 +77,8 @@ namespace ContentSelectorView void buildLoadAddonView(); bool isFlagged(SelectorFlags flag) const; + QString getNewProfileName(); + void enableProfilesComboBox(); signals: void accepted(); @@ -76,14 +89,24 @@ namespace ContentSelectorView void signalCreateButtonClicked(); + void signalProfileRenamed(QString,QString); + void signalProfileChanged(QString,QString); + void signalProfileDeleted(QString); + void signalProfileAdded(); + private slots: + void slotProfileTextChanged (const QString &text); void slotCurrentProfileIndexChanged(int index); void slotCurrentGameFileIndexChanged(int index); void slotAddonTableItemClicked(const QModelIndex &index); void slotUpdateCreateButton (bool); - void slotUpdateOpenButton(const QStringList &items); + // void slotUpdateOpenButton(const QStringList &items); + + // Action slots + void on_newProfileAction_triggered(); + void on_deleteProfileAction_triggered(); }; } diff --git a/apps/opencs/view/doc/filewidget.cpp b/components/contentselector/view/filewidget.cpp similarity index 100% rename from apps/opencs/view/doc/filewidget.cpp rename to components/contentselector/view/filewidget.cpp diff --git a/apps/opencs/view/doc/filewidget.hpp b/components/contentselector/view/filewidget.hpp similarity index 100% rename from apps/opencs/view/doc/filewidget.hpp rename to components/contentselector/view/filewidget.hpp diff --git a/components/contentselector/view/profilescombobox.cpp b/components/contentselector/view/profilescombobox.cpp index cb0ba7b77..29001189d 100644 --- a/components/contentselector/view/profilescombobox.cpp +++ b/components/contentselector/view/profilescombobox.cpp @@ -45,6 +45,9 @@ void ContentSelectorView::ProfilesComboBox::setEditEnabled(bool editable) connect(lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged(QString))); + + connect (lineEdit(), SIGNAL(textChanged(QString)), this, + SIGNAL (signalProfileTextChanged (QString))); } void ContentSelectorView::ProfilesComboBox::slotTextChanged(const QString &text) diff --git a/components/contentselector/view/profilescombobox.hpp b/components/contentselector/view/profilescombobox.hpp index d81c1e6a5..560c42c10 100644 --- a/components/contentselector/view/profilescombobox.hpp +++ b/components/contentselector/view/profilescombobox.hpp @@ -17,10 +17,12 @@ namespace ContentSelectorView void setPlaceholderText (const QString &text); signals: + void signalProfileTextChanged (const QString &item); void profileChanged(const QString &previous, const QString ¤t); void profileRenamed(const QString &oldName, const QString &newName); private slots: + void slotEditingFinished(); void slotIndexChanged(int index); void slotTextChanged(const QString &text); diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 949407759..73d7a4902 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -7,7 +7,7 @@ 0 0 518 - 313 + 424 @@ -26,6 +26,9 @@ Content + + 3 + @@ -116,6 +119,18 @@ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + 3 + + + 6 + + + 6 + + + 0 + @@ -143,18 +158,17 @@ - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Open - - - false + + + 0 + 0 + + Create @@ -209,7 +223,7 @@ 3 - 9 + 6 0 @@ -220,7 +234,7 @@ - true + false @@ -228,6 +242,11 @@ 0 + + + Default + + @@ -262,6 +281,13 @@ + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Open + + + @@ -280,6 +306,9 @@ + + false + From a5a0f615330e9593515153bee28430519c0ac57f Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 1 Oct 2013 22:36:49 -0500 Subject: [PATCH 068/118] Fixed missing profiles combobox --- apps/launcher/datafilespage.cpp | 2 +- components/contentselector/view/contentselector.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index b298f8a14..eee530672 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -65,7 +65,7 @@ void DataFilesPage::loadSettings() foreach (const QString &file, addons) files.append(file); - //ContentSelectorView::ContentSelector::instance().setCheckStates(files); + ContentSelectorView::ContentSelector::instance().setCheckStates(files); } void DataFilesPage::saveSettings() diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index cb0774f68..54199626e 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -129,10 +129,7 @@ void ContentSelectorView::ContentSelector::buildAddonView() void ContentSelectorView::ContentSelector::buildProfilesView() { if (!isFlagged (Flag_Profile)) - { - ui.profileGroupBox->setVisible(false); return; - } // Add the actions to the toolbuttons ui.newProfileButton->setDefaultAction (ui.newProfileAction); @@ -145,6 +142,8 @@ void ContentSelectorView::ContentSelector::buildProfilesView() connect (ui.profilesComboBox, SIGNAL (profileRenamed(QString,QString)), this, SIGNAL(signalProfileRenamed(QString,QString))); connect (ui.profilesComboBox, SIGNAL (profileChanged(QString,QString)), this, SIGNAL(signalProfileChanged(QString,QString))); connect (ui.profilesComboBox, SIGNAL (signalProfileTextChanged(QString)), this, SLOT (slotProfileTextChanged (QString))); + + ui.profileGroupBox->setVisible (true); } void ContentSelectorView::ContentSelector::buildLoadAddonView() From 217a4d75b4118d8a785f93f36852e6713a0d67c3 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 6 Oct 2013 21:13:47 -0500 Subject: [PATCH 069/118] Implemented profile function in launcher datafiles page Implemented dependency sorting to ensure dependent files appear latest in the list. --- apps/launcher/CMakeLists.txt | 4 - apps/launcher/datafilespage.cpp | 173 +++++++++--------- apps/launcher/datafilespage.hpp | 22 ++- apps/launcher/graphicspage.cpp | 1 + apps/launcher/maindialog.cpp | 30 ++- apps/launcher/playpage.cpp | 12 +- apps/launcher/playpage.hpp | 7 +- apps/opencs/view/doc/filedialog.cpp | 2 +- components/CMakeLists.txt | 2 + .../contentselector/model/contentmodel.cpp | 53 +++++- .../contentselector/model/contentmodel.hpp | 3 +- .../contentselector/view/contentselector.cpp | 162 ++++++++-------- .../contentselector/view/contentselector.hpp | 27 ++- .../contentselector/view/profilescombobox.cpp | 10 +- .../contentselector/view/profilescombobox.hpp | 10 +- .../contentselector/view}/textinputdialog.cpp | 23 ++- .../contentselector/view}/textinputdialog.hpp | 15 +- files/ui/datafilespage.ui | 7 +- 18 files changed, 311 insertions(+), 252 deletions(-) rename {apps/launcher/utils => components/contentselector/view}/textinputdialog.cpp (75%) rename {apps/launcher/utils => components/contentselector/view}/textinputdialog.hpp (78%) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 92cabffff..49dedd829 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -11,7 +11,6 @@ set(LAUNCHER settings/launchersettings.cpp utils/checkablemessagebox.cpp - utils/textinputdialog.cpp ${CMAKE_SOURCE_DIR}/files/launcher/launcher.rc ) @@ -32,8 +31,6 @@ set(LAUNCHER_HEADER settings/settingsbase.hpp utils/checkablemessagebox.hpp - utils/textinputdialog.hpp - ) if(NOT WIN32) LIST(APPEND LAUNCHER_HEADER unshieldthread.hpp) @@ -49,7 +46,6 @@ set(LAUNCHER_HEADER_MOC textslotmsgbox.hpp utils/checkablemessagebox.hpp - utils/textinputdialog.hpp ) if(NOT WIN32) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index eee530672..a705ae37d 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -17,177 +17,182 @@ #include "settings/gamesettings.hpp" #include "settings/launchersettings.hpp" -#include "utils/textinputdialog.hpp" #include "components/contentselector/view/contentselector.hpp" -#include - DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent) : mCfgMgr(cfg) , mGameSettings(gameSettings) , mLauncherSettings(launcherSettings) + , QWidget(parent) { - unsigned char flags; + setObjectName ("DataFilesPage"); + + unsigned char flags; - flags = ContentSelectorView::Flag_Content | ContentSelectorView::Flag_Profile; + flags = ContentSelectorView::Flag_Content | ContentSelectorView::Flag_Profile; - ContentSelectorView::ContentSelector::configure(this, flags); + ContentSelectorView::ContentSelector::configure(this, flags); + mSelector = &ContentSelectorView::ContentSelector::instance(); setupDataFiles(); - ContentSelectorView::ContentSelector &cSelector = - ContentSelectorView::ContentSelector::instance(); - connect (&cSelector, SIGNAL (signalProfileRenamed (QString, QString)), + connect (mSelector, SIGNAL (signalProfileRenamed (QString, QString)), this, SLOT (slotProfileRenamed (QString, QString))); - connect (&cSelector, SIGNAL (signalProfileChanged (QString, QString)), - this, SLOT (slotProfileChanged (QString, QString))); + connect (mSelector, SIGNAL (signalProfileChangedByUser (QString, QString)), + this, SLOT (slotProfileChangedByUser (QString, QString))); - connect (&cSelector, SIGNAL (signalProfileDeleted (QString)), + connect (mSelector, SIGNAL (signalProfileDeleted (QString)), this, SLOT (slotProfileDeleted (QString))); - connect (&cSelector, SIGNAL (signalProfileAdded ()), - this, SLOT (slotProfileAdded ())); + connect (mSelector, SIGNAL (signalAddNewProfile (QString)), + this, SLOT (slotAddNewProfile (QString))); } void DataFilesPage::loadSettings() { + QString profileName = mSelector->getProfileText(); - QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); - - if (profile.isEmpty()) - return; + QStringList files = mLauncherSettings.values(QString("Profiles/") + profileName + QString("/game"), Qt::MatchExactly); + QStringList addons = mLauncherSettings.values(QString("Profiles/") + profileName + QString("/addon"), Qt::MatchExactly); - QStringList files = mLauncherSettings.values(QString("Profiles/") + profile + QString("/master"), Qt::MatchExactly); - QStringList addons = mLauncherSettings.values(QString("Profiles/") + profile + QString("/plugin"), Qt::MatchExactly); + mSelector->clearCheckStates(); - foreach (const QString &file, addons) - files.append(file); + if (files.size() > 0) + mSelector->setGameFile(files.at(0)); + else + mSelector->setGameFile(); - ContentSelectorView::ContentSelector::instance().setCheckStates(files); + mSelector->setCheckStates(addons); } -void DataFilesPage::saveSettings() +void DataFilesPage::saveSettings(const QString &profile) { - ContentSelectorModel::ContentFileList items = - ContentSelectorView::ContentSelector::instance().selectedFiles(); + QString profileName = profile; - if (items.size() == 0) - return; + if (profileName.isEmpty()) + profileName = mSelector->getProfileText(); - QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); + //retrieve the files selected for the profile + ContentSelectorModel::ContentFileList items = mSelector->selectedFiles(); - if (profile.isEmpty()) { - profile = ContentSelectorView::ContentSelector::instance().getProfileText(); - mLauncherSettings.setValue(QString("Profiles/currentprofile"), profile); - } + removeProfile (profileName); - mLauncherSettings.remove(QString("Profiles/") + profile + QString("/master")); - mLauncherSettings.remove(QString("Profiles/") + profile + QString("/plugin")); + mGameSettings.remove(QString("game")); + mGameSettings.remove(QString("addon")); - mGameSettings.remove(QString("master")); - mGameSettings.remove(QString("plugin")); + //set the value of the current profile (not necessarily the profile being saved!) + mLauncherSettings.setValue(QString("Profiles/currentprofile"), mSelector->getProfileText()); foreach(const ContentSelectorModel::EsmFile *item, items) { if (item->gameFiles().size() == 0) { - mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/master"), item->fileName()); - mGameSettings.setMultiValue(QString("master"), item->fileName()); - + mLauncherSettings.setMultiValue(QString("Profiles/") + profileName + QString("/game"), item->fileName()); + mGameSettings.setMultiValue(QString("game"), item->fileName()); } else { - mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/plugin"), item->fileName()); - mGameSettings.setMultiValue(QString("plugin"), item->fileName()); + mLauncherSettings.setMultiValue(QString("Profiles/") + profileName + QString("/addon"), item->fileName()); + mGameSettings.setMultiValue(QString("addon"), item->fileName()); } } } -void DataFilesPage::slotProfileDeleted (const QString &item) +void DataFilesPage::removeProfile(const QString &profile) { - mLauncherSettings.remove(QString("Profiles/") + item + QString("/master")); - mLauncherSettings.remove(QString("Profiles/") + item + QString("/plugin")); + mLauncherSettings.remove(QString("Profiles/") + profile + QString("/game")); + mLauncherSettings.remove(QString("Profiles/") + profile + QString("/addon")); } -void DataFilesPage::slotProfileChanged(const QString &previous, const QString ¤t) +void DataFilesPage::changeProfiles(const QString &previous, const QString ¤t, bool savePrevious) { - if (previous.isEmpty()) + //abort if no change (typically a duplicate signal) + if (previous == current) return; - if (ContentSelectorView::ContentSelector::instance().getProfileIndex (previous) == -1) - return; // Profile was deleted + int index = -1; - // Store the previous profile - mLauncherSettings.setValue(QString("Profiles/currentprofile"), previous); - saveSettings(); - mLauncherSettings.setValue(QString("Profiles/currentprofile"), current); + if (!previous.isEmpty()) + index = mSelector->getProfileIndex(previous); + + // Store the previous profile if it exists + if ( (index != -1) && savePrevious) + saveSettings(previous); loadSettings(); } -void DataFilesPage::slotProfileRenamed(const QString &previous, const QString ¤t) +void DataFilesPage::slotAddNewProfile(const QString &profile) { - if (previous.isEmpty()) - return; - - // Save the new profile name - mLauncherSettings.setValue(QString("Profiles/currentprofile"), current); + saveSettings(); + mSelector->clearCheckStates(); + mSelector->addProfile(profile, true); + mSelector->setGameFile(); saveSettings(); - // Remove the old one - mLauncherSettings.remove(QString("Profiles/") + previous + QString("/master")); - mLauncherSettings.remove(QString("Profiles/") + previous + QString("/plugin")); + emit signalProfileChanged(mSelector->getProfileIndex(profile)); +} - // Remove the profile from the combobox - ContentSelectorView::ContentSelector::instance().removeProfile (previous); +void DataFilesPage::slotProfileDeleted (const QString &item) +{ + removeProfile (item); +} - loadSettings(); +void DataFilesPage::slotProfileChangedByUser(const QString &previous, const QString ¤t) +{ + changeProfiles(previous, current); + emit signalProfileChanged(mSelector->getProfileIndex(current)); } -void DataFilesPage::slotProfileAdded() +void DataFilesPage::slotProfileRenamed(const QString &previous, const QString ¤t) { - TextInputDialog newDialog (tr("New Profile"), tr("Profile name:"), this); + if (previous.isEmpty()) + return; - // connect(mNewDialog->lineEdit(), SIGNAL(textChanged(QString)), - // this, SLOT(updateOkButton(QString))); + // Save the new profile name + saveSettings(); - if (newDialog.exec() == QDialog::Accepted) - { - QString profile = newDialog.lineEdit()->text(); + // Remove the old one + removeProfile (previous); - ContentSelectorView::ContentSelector - ::instance().addProfile(profile, true); - } + loadSettings(); } -void DataFilesPage::setProfilesComboBoxIndex(int index) +void DataFilesPage::slotProfileChanged(int index) { - ContentSelectorView::ContentSelector::instance().setProfileIndex(index); + mSelector->setProfile(index); } void DataFilesPage::setupDataFiles() { - ContentSelectorView::ContentSelector &cSelector = - ContentSelectorView::ContentSelector::instance(); - QStringList paths = mGameSettings.getDataDirs(); foreach (const QString &path, paths) - cSelector.addFiles(path); + mSelector->addFiles(path); QString dataLocal = mGameSettings.getDataLocal(); if (!dataLocal.isEmpty()) - cSelector.addFiles(dataLocal); + mSelector->addFiles(dataLocal); QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/")); QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); foreach (const QString &item, profiles) - cSelector.addProfile (item); + mSelector->addProfile (item); - cSelector.addProfile (profile, true); + mSelector->addProfile (profile, true); loadSettings(); } + +QAbstractItemModel *DataFilesPage::profilesModel() const +{ + return mSelector->profilesModel(); +} + +int DataFilesPage::profilesIndex() const +{ + return mSelector->getProfileIndex(mSelector->getProfileText()); +} diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index 6ed5d9ce9..47e28493d 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -15,22 +15,26 @@ class LauncherSettings; namespace Files { struct ConfigurationManager; } +namespace ContentSelectorView { class ContentSelector; } class DataFilesPage : public QWidget { Q_OBJECT + ContentSelectorView::ContentSelector *mSelector; + public: DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent = 0); - QAbstractItemModel* profilesComboBoxModel(); - int profilesComboBoxIndex(); + QAbstractItemModel* profilesModel() const; + int profilesIndex() const; void writeConfig(QString profile = QString()); - void saveSettings(); + void saveSettings(const QString &profile = ""); + void loadSettings(); signals: - void profileChanged(int index); + void signalProfileChanged(int index); public slots: //void showContextMenu(const QPoint &point); @@ -38,11 +42,11 @@ public slots: private slots: - void slotProfileAdded(); - void slotProfileChanged(const QString &previous, const QString ¤t); + void slotAddNewProfile(const QString &profile); + void slotProfileChangedByUser(const QString &previous, const QString ¤t); + void slotProfileChanged(int); void slotProfileRenamed(const QString &previous, const QString ¤t); void slotProfileDeleted(const QString &item); - void setProfilesComboBoxIndex(int index); private: @@ -58,8 +62,8 @@ private: void setupDataFiles(); void setupConfig(); void readConfig(); - - void loadSettings(); + void removeProfile (const QString &profile); + void changeProfiles(const QString &previous, const QString ¤t, bool savePrevious = true); }; #endif diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 4d9ce14d6..2c6c711ea 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -38,6 +38,7 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &g , mGraphicsSettings(graphicsSetting) , QWidget(parent) { + setObjectName ("GraphicsPage"); setupUi(this); // Set the maximum res we can set in windowed mode diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 311e3a25c..fe9ca141e 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -106,10 +106,10 @@ void MainDialog::createPages() mPlayPage = new PlayPage(this); mGraphicsPage = new GraphicsPage(mCfgMgr, mGraphicsSettings, this); mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this); -/// reimplement datafilespage functions to provide access + // Set the combobox of the play page to imitate the combobox on the datafilespage - // mPlayPage->setProfilesComboBoxModel(mDataFilesPage->profilesComboBoxModel()); - // mPlayPage->setProfilesComboBoxIndex(mDataFilesPage->profilesComboBoxIndex()); + mPlayPage->setProfilesModel(mDataFilesPage->profilesModel()); + mPlayPage->setProfilesIndex(mDataFilesPage->profilesIndex()); // Add the pages to the stacked widget pagesWidget->addWidget(mPlayPage); @@ -121,8 +121,8 @@ void MainDialog::createPages() connect(mPlayPage, SIGNAL(playButtonClicked()), this, SLOT(play())); - connect(mPlayPage, SIGNAL(profileChanged(int)), mDataFilesPage, SLOT(setProfilesComboBoxIndex(int))); - connect(mDataFilesPage, SIGNAL(profileChanged(int)), mPlayPage, SLOT(setProfilesComboBoxIndex(int))); + connect(mPlayPage, SIGNAL(signalProfileChanged(int)), mDataFilesPage, SLOT(slotProfileChanged(int))); + connect(mDataFilesPage, SIGNAL(signalProfileChanged(int)), mPlayPage, SLOT(setProfilesIndex(int))); } @@ -316,7 +316,25 @@ void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) if (!current) current = previous; - pagesWidget->setCurrentIndex(iconWidget->row(current)); + int currentIndex = iconWidget->row(current); + int previousIndex = iconWidget->row(previous); + + pagesWidget->setCurrentIndex(currentIndex); + + DataFilesPage *previousPage = dynamic_cast(pagesWidget->widget(previousIndex)); + DataFilesPage *currentPage = dynamic_cast(pagesWidget->widget(currentIndex)); + + //special call to update/save data files page list view when it's displayed/hidden. + if (previousPage) + { + if (previousPage->objectName() == "DataFilesPage") + previousPage->saveSettings(); + } + else if (currentPage) + { + if (currentPage->objectName() == "DataFilesPage") + currentPage->loadSettings(); + } } bool MainDialog::setupLauncherSettings() diff --git a/apps/launcher/playpage.cpp b/apps/launcher/playpage.cpp index 46900c595..fc1ed1c69 100644 --- a/apps/launcher/playpage.cpp +++ b/apps/launcher/playpage.cpp @@ -8,6 +8,7 @@ PlayPage::PlayPage(QWidget *parent) : QWidget(parent) { + setObjectName ("PlayPage"); setupUi(this); // Hacks to get the stylesheet look properly @@ -17,26 +18,21 @@ PlayPage::PlayPage(QWidget *parent) : QWidget(parent) #endif profilesComboBox->setView(new QListView()); - connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentIndexChanged(int))); + connect(profilesComboBox, SIGNAL(activated(int)), this, SIGNAL (signalProfileChanged(int))); connect(playButton, SIGNAL(clicked()), this, SLOT(slotPlayClicked())); } -void PlayPage::setProfilesComboBoxModel(QAbstractItemModel *model) +void PlayPage::setProfilesModel(QAbstractItemModel *model) { profilesComboBox->setModel(model); } -void PlayPage::setProfilesComboBoxIndex(int index) +void PlayPage::setProfilesIndex(int index) { profilesComboBox->setCurrentIndex(index); } -void PlayPage::slotCurrentIndexChanged(int index) -{ - emit profileChanged(index); -} - void PlayPage::slotPlayClicked() { emit playButtonClicked(); diff --git a/apps/launcher/playpage.hpp b/apps/launcher/playpage.hpp index 4306396bd..42edfadb1 100644 --- a/apps/launcher/playpage.hpp +++ b/apps/launcher/playpage.hpp @@ -15,17 +15,16 @@ class PlayPage : public QWidget, private Ui::PlayPage public: PlayPage(QWidget *parent = 0); - void setProfilesComboBoxModel(QAbstractItemModel *model); + void setProfilesModel(QAbstractItemModel *model); signals: - void profileChanged(int index); + void signalProfileChanged(int index); void playButtonClicked(); public slots: - void setProfilesComboBoxIndex(int index); + void setProfilesIndex(int index); private slots: - void slotCurrentIndexChanged(int index); void slotPlayClicked(); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index b1b72dc1f..efa31100a 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -34,7 +34,7 @@ void CSVDoc::FileDialog::addFiles(const QString &path) QString CSVDoc::FileDialog::filename() { - return ContentSelectorView::ContentSelector::instance().filename(); + return ContentSelectorView::ContentSelector::instance().projectFilename(); } QStringList CSVDoc::FileDialog::selectedFilePaths() diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index ebce4578b..103c6f412 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -85,6 +85,8 @@ if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) view/profilescombobox view/comboboxlineedit view/lineedit view/contentselector view/filewidget view/adjusterwidget + view/textinputdialog + ) include(${QT_USE_FILE}) diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index db6431810..a9796a1fb 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -391,7 +391,6 @@ bool ContentSelectorModel::ContentModel::canBeChecked(const EsmFile *file) const return true; } } - return false; } @@ -448,6 +447,39 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path) } delete decoder; + + sortFiles(); +} + +void ContentSelectorModel::ContentModel::sortFiles() +{ + //first, sort the model such that all dependencies are ordered upstream (gamefile) first. + bool movedFiles = true; + int fileCount = mFiles.size(); + + //Dependency sort + //iterate until no sorting of files occurs + while (movedFiles) + { + movedFiles = false; + //iterate each file, obtaining a reference to it's gamefiles list + for (int i = 0; i < fileCount; i++) + { + const QStringList &gamefiles = mFiles.at(i)->gameFiles(); + //iterate each file after the current file, verifying that none of it's + //dependencies appear. + for (int j = i + 1; j < fileCount; j++) + { + if (gamefiles.contains(mFiles.at(j)->fileName())) + { + mFiles.move(j, i); + movedFiles = true; + } + } + if (movedFiles) + break; + } + } } bool ContentSelectorModel::ContentModel::isChecked(const QString& name) const @@ -460,6 +492,7 @@ bool ContentSelectorModel::ContentModel::isChecked(const QString& name) const void ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool checkState) { + if (name.isEmpty()) return; @@ -469,9 +502,14 @@ void ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool state = Qt::Checked; mCheckStates[name] = state; + emit dataChanged(indexFromItem(item(name)), indexFromItem(item(name))); const EsmFile *file = item(name); + if (file->isGameFile()) + emit dataChanged (index(0,0), index(rowCount()-1,0)); + + //if we're checking an item, ensure all "upstream" files (dependencies) are checked as well. if (state == Qt::Checked) { foreach (const QString &upstreamName, file->gameFiles()) @@ -482,24 +520,23 @@ void ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool continue; if (!isChecked(upstreamName)) - { mCheckStates[upstreamName] = Qt::Checked; - emit dataChanged(indexFromItem(upstreamFile), indexFromItem(upstreamFile)); - } + + emit dataChanged(indexFromItem(upstreamFile), indexFromItem(upstreamFile)); } } - else if (state == Qt::Unchecked) + //otherwise, if we're unchecking an item (or the file is a game file) ensure all downstream files are unchecked. + if (state == Qt::Unchecked) { foreach (const EsmFile *downstreamFile, mFiles) { if (downstreamFile->gameFiles().contains(name)) { if (mCheckStates.contains(downstreamFile->fileName())) - { mCheckStates[downstreamFile->fileName()] = Qt::Unchecked; - emit dataChanged(indexFromItem(downstreamFile), indexFromItem(downstreamFile)); - } + + emit dataChanged(indexFromItem(downstreamFile), indexFromItem(downstreamFile)); } } } diff --git a/components/contentselector/model/contentmodel.hpp b/components/contentselector/model/contentmodel.hpp index a2a57f850..feea3643b 100644 --- a/components/contentselector/model/contentmodel.hpp +++ b/components/contentselector/model/contentmodel.hpp @@ -56,19 +56,20 @@ namespace ContentSelectorModel EsmFile *item(int row); bool canBeChecked(const EsmFile *file) const; + void sortFiles(); ContentFileList mFiles; QHash mCheckStates; QTextCodec *mCodec; public: + QString mMimeType; QStringList mMimeTypes; int mColumnCount; Qt::ItemFlags mDragDropFlags; Qt::ItemFlags mDefaultFlags; Qt::DropActions mDropActions; - }; } #endif // CONTENTMODEL_HPP diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index 54199626e..6965c948e 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -5,7 +5,6 @@ #include -#include #include #include #include @@ -14,6 +13,9 @@ #include "filewidget.hpp" #include "adjusterwidget.hpp" +#include "textinputdialog.hpp" + +#include ContentSelectorView::ContentSelector *ContentSelectorView::ContentSelector::mInstance = 0; QStringList ContentSelectorView::ContentSelector::mFilePaths; @@ -33,7 +35,8 @@ ContentSelectorView::ContentSelector& ContentSelectorView::ContentSelector::inst ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent, unsigned char flags) : QWidget(parent), mFlags (flags), - mAdjusterWidget (0), mFileWidget (0) + mAdjusterWidget (0), mFileWidget (0), + mIgnoreProfileSignal (false) { ui.setupUi (this); @@ -53,14 +56,6 @@ ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent, unsigned */ } -QString ContentSelectorView::ContentSelector::getNewProfileName() -{ - // Create a dialog for the new profile name input - //mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); - - //connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString))); - return ""; -} bool ContentSelectorView::ContentSelector::isFlagged(SelectorFlags flag) const { @@ -94,6 +89,8 @@ void ContentSelectorView::ContentSelector::buildGameFileView() return; } + ui.gameFileView->setVisible (true); + mGameFileProxyModel = new QSortFilterProxyModel(this); mGameFileProxyModel->setFilterRegExp(QString::number((int)ContentSelectorModel::ContentType_GameFile)); mGameFileProxyModel->setFilterRole (Qt::UserRole); @@ -102,7 +99,7 @@ void ContentSelectorView::ContentSelector::buildGameFileView() ui.gameFileView->setPlaceholderText(QString("Select a game file...")); ui.gameFileView->setModel(mGameFileProxyModel); - connect(ui.gameFileView, SIGNAL(currentIndexChanged(int)), this, SLOT (slotCurrentGameFileIndexChanged(int))); + connect (ui.gameFileView, SIGNAL(currentIndexChanged(int)), this, SLOT (slotCurrentGameFileIndexChanged(int))); ui.gameFileView->setCurrentIndex(-1); } @@ -115,6 +112,8 @@ void ContentSelectorView::ContentSelector::buildAddonView() return; } + ui.addonView->setVisible (true); + mAddonProxyModel = new QSortFilterProxyModel(this); mAddonProxyModel->setFilterRegExp (QString::number((int)ContentSelectorModel::ContentType_Addon)); mAddonProxyModel->setFilterRole (Qt::UserRole); @@ -129,31 +128,48 @@ void ContentSelectorView::ContentSelector::buildAddonView() void ContentSelectorView::ContentSelector::buildProfilesView() { if (!isFlagged (Flag_Profile)) + { + ui.profileGroupBox->setVisible(false); return; + } + + ui.profileGroupBox->setVisible (true); // Add the actions to the toolbuttons ui.newProfileButton->setDefaultAction (ui.newProfileAction); ui.deleteProfileButton->setDefaultAction (ui.deleteProfileAction); + //enable ui elements ui.profilesComboBox->addItem ("Default"); ui.profilesComboBox->setPlaceholderText (QString("Select a profile...")); + if (!ui.profilesComboBox->isEnabled()) + ui.profilesComboBox->setEnabled(true); + + if (!ui.deleteProfileAction->isEnabled()) + ui.deleteProfileAction->setEnabled(true); + + //establish connections connect (ui.profilesComboBox, SIGNAL (currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); connect (ui.profilesComboBox, SIGNAL (profileRenamed(QString,QString)), this, SIGNAL(signalProfileRenamed(QString,QString))); - connect (ui.profilesComboBox, SIGNAL (profileChanged(QString,QString)), this, SIGNAL(signalProfileChanged(QString,QString))); + connect (ui.profilesComboBox, SIGNAL (signalProfileChanged(QString,QString)), this, SIGNAL(signalProfileChangedByUser(QString,QString))); connect (ui.profilesComboBox, SIGNAL (signalProfileTextChanged(QString)), this, SLOT (slotProfileTextChanged (QString))); ui.profileGroupBox->setVisible (true); + ui.projectButtonBox->setVisible (false); } void ContentSelectorView::ContentSelector::buildLoadAddonView() { if (!isFlagged (Flag_LoadAddon)) { - ui.projectGroupBox->setVisible (false); + if (!isFlagged (Flag_NewAddon)) + ui.projectGroupBox->setVisible (false); + return; } + ui.projectGroupBox->setVisible (true); ui.projectCreateButton->setVisible (false); ui.projectGroupBox->setTitle (""); @@ -165,10 +181,14 @@ void ContentSelectorView::ContentSelector::buildNewAddonView() { if (!isFlagged (Flag_NewAddon)) { - ui.profileGroupBox->setVisible (false); + if (!isFlagged (Flag_LoadAddon)) + ui.projectGroupBox->setVisible (false); + return; } + ui.projectGroupBox->setVisible (true); + mFileWidget = new CSVDoc::FileWidget (this); mAdjusterWidget = new CSVDoc::AdjusterWidget (this); @@ -190,18 +210,36 @@ void ContentSelectorView::ContentSelector::buildNewAddonView() connect(ui.projectButtonBox, SIGNAL(rejected()), this, SIGNAL(rejected())); } +void ContentSelectorView::ContentSelector::setGameFile(const QString &filename) +{ + int index = -1; + + if (!filename.isEmpty()) + { + index = ui.gameFileView->findText(filename); + + //verify that the current index is also checked in the model + mContentModel->setCheckState(filename, true); + } + + ui.gameFileView->setCurrentIndex(index); +} + +void ContentSelectorView::ContentSelector::clearCheckStates() +{ + mContentModel->uncheckAll(); +} + void ContentSelectorView::ContentSelector::setCheckStates(const QStringList &list) { if (list.isEmpty()) return; - mContentModel->uncheckAll(); - foreach (const QString &file, list) mContentModel->setCheckState(file, Qt::Checked); } -QString ContentSelectorView::ContentSelector::filename() const +QString ContentSelectorView::ContentSelector::projectFilename() const { QString filepath = ""; @@ -211,26 +249,13 @@ QString ContentSelectorView::ContentSelector::filename() const return filepath; } -QStringList ContentSelectorView::ContentSelector::selectedFilePaths() const -{ - QStringList filePaths; - - if (mContentModel) - { - foreach (ContentSelectorModel::EsmFile *file, mContentModel->checkedItems()) - filePaths.append(file->path()); - } - - return filePaths; -} - ContentSelectorModel::ContentFileList ContentSelectorView::ContentSelector::selectedFiles() const { - if (mContentModel) - return mContentModel->checkedItems(); + if (!mContentModel) + return ContentSelectorModel::ContentFileList(); - return ContentSelectorModel::ContentFileList(); + return mContentModel->checkedItems(); } @@ -243,78 +268,58 @@ void ContentSelectorView::ContentSelector::addFiles(const QString &path) { mInstance->mContentModel->addFiles(path); mInstance->ui.gameFileView->setCurrentIndex(-1); - mInstance->mContentModel->uncheckAll(); } } -void ContentSelectorView::ContentSelector::removeProfile(const QString &item) -{ - int idx = ui.profilesComboBox->findText(item); - - if (idx != -1) - ui.profilesComboBox->removeItem(idx); -} - int ContentSelectorView::ContentSelector::getProfileIndex ( const QString &item) const { return ui.profilesComboBox->findText (item); } -void ContentSelectorView::ContentSelector::setProfileIndex(int index) -{ - if (index >=0 && index < ui.profilesComboBox->count()) - ui.profilesComboBox->setCurrentIndex(index); -} - void ContentSelectorView::ContentSelector::addProfile (const QString &item, bool setAsCurrent) { if (item.isEmpty()) return; + QString previous = ui.profilesComboBox->currentText(); + if (ui.profilesComboBox->findText(item) == -1) ui.profilesComboBox->addItem(item); if (setAsCurrent) - ui.profilesComboBox->setCurrentIndex(ui.profilesComboBox->findText(item)); - - enableProfilesComboBox(); + setProfile (ui.profilesComboBox->findText(item)); } -QString ContentSelectorView::ContentSelector::getProfileText() const +void ContentSelectorView::ContentSelector::setProfile(int index) { - return ui.profilesComboBox->currentText(); + //programmatic change requires second call to non-signalized "slot" since no signal responses + //occur for programmatic changes to the profilesComboBox. + if (index >= -1 && index < ui.profilesComboBox->count()) + { + QString previous = ui.profilesComboBox->itemText(ui.profilesComboBox->currentIndex()); + QString current = ui.profilesComboBox->itemText(index); + + ui.profilesComboBox->setCurrentIndex(index); + } } -void ContentSelectorView::ContentSelector::enableProfilesComboBox() +QString ContentSelectorView::ContentSelector::getProfileText() const { - if (!ui.profilesComboBox->isEnabled()) - ui.profilesComboBox->setEnabled(true); - - if (!ui.deleteProfileAction->isEnabled()) - ui.deleteProfileAction->setEnabled(true); - - ui.projectButtonBox->button(QDialogButtonBox::Open)->setEnabled (true); + return ui.profilesComboBox->currentText(); } -QStringList ContentSelectorView::ContentSelector::checkedItemsPaths() +QAbstractItemModel *ContentSelectorView::ContentSelector::profilesModel() const { - QStringList itemPaths; - - foreach( const ContentSelectorModel::EsmFile *file, mContentModel->checkedItems()) - itemPaths << file->path(); - - return itemPaths; + return ui.profilesComboBox->model(); } void ContentSelectorView::ContentSelector::slotCurrentProfileIndexChanged(int index) { //don't allow deleting "Default" profile - bool success = (ui.profilesComboBox->itemText(index) == "Default"); + bool success = (ui.profilesComboBox->itemText(index) != "Default"); ui.deleteProfileAction->setEnabled(success); ui.profilesComboBox->setEditEnabled(success); - - emit signalProfileChanged(index); } void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int index) @@ -370,10 +375,12 @@ void ContentSelectorView::ContentSelector::slotUpdateCreateButton(bool) ui.projectCreateButton->setEnabled(validGameFile && validFilename); } - void ContentSelectorView::ContentSelector::on_newProfileAction_triggered() { - emit signalProfileAdded(); + TextInputDialog newDialog (tr("New Profile"), tr("Profile name:"), this); + + if (newDialog.exec() == QDialog::Accepted) + emit signalAddNewProfile(newDialog.getText()); } void ContentSelectorView::ContentSelector::on_deleteProfileAction_triggered() @@ -402,11 +409,6 @@ void ContentSelectorView::ContentSelector::on_deleteProfileAction_triggered() //signal for removal from model emit signalProfileDeleted (profile); -} -/* -void ContentSelectorView::ContentSelector::slotUpdateOkButton(const QString &text) -{ - bool success = (ui.profilesComboBox->findText(text) == -1); - mNewDialog->setOkButtonEnabled(success); -}*/ + slotCurrentProfileIndexChanged(ui.profilesComboBox->currentIndex()); +} diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index caf9cc670..64b9b3732 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -7,7 +7,6 @@ #include "../model/contentmodel.hpp" class QSortFilterProxyModel; -class TextInputDialog; namespace CSVDoc { @@ -29,6 +28,7 @@ namespace ContentSelectorView Q_OBJECT unsigned char mFlags; + bool mIgnoreProfileSignal; static ContentSelector *mInstance; static QStringList mFilePaths; @@ -36,8 +36,6 @@ namespace ContentSelectorView CSVDoc::FileWidget *mFileWidget; CSVDoc::AdjusterWidget *mAdjusterWidget; - TextInputDialog *mNewDialog; - protected: ContentSelectorModel::ContentModel *mContentModel; @@ -45,26 +43,28 @@ namespace ContentSelectorView QSortFilterProxyModel *mAddonProxyModel; public: + explicit ContentSelector(QWidget *parent = 0, unsigned char flags = Flag_Content); static void configure(QWidget *subject, unsigned char flags = Flag_Content); static ContentSelector &instance(); static void addFiles(const QString &path); + void clearCheckStates(); void setCheckStates (const QStringList &list); - QStringList checkedItemsPaths(); ContentSelectorModel::ContentFileList *CheckedItems(); - QString filename() const; + QString projectFilename() const; ContentSelectorModel::ContentFileList selectedFiles() const; - QStringList selectedFilePaths() const; + QAbstractItemModel *profilesModel() const; + void setGameFile (const QString &filename = ""); void addProfile (const QString &item, bool setAsCurrent = false); - void removeProfile (const QString &item); + void setProfile (int index); int getProfileIndex (const QString &item) const; - void setProfileIndex (int index); QString getProfileText() const; + private: Ui::DataFilesPage ui; @@ -77,22 +77,18 @@ namespace ContentSelectorView void buildLoadAddonView(); bool isFlagged(SelectorFlags flag) const; - QString getNewProfileName(); - void enableProfilesComboBox(); signals: + void accepted(); void rejected(); - void signalProfileChanged(int index); - void signalGameFileChanged(int value); - void signalCreateButtonClicked(); void signalProfileRenamed(QString,QString); - void signalProfileChanged(QString,QString); + void signalProfileChangedByUser(QString,QString); void signalProfileDeleted(QString); - void signalProfileAdded(); + void signalAddNewProfile(QString); private slots: @@ -102,7 +98,6 @@ namespace ContentSelectorView void slotAddonTableItemClicked(const QModelIndex &index); void slotUpdateCreateButton (bool); - // void slotUpdateOpenButton(const QStringList &items); // Action slots void on_newProfileAction_triggered(); diff --git a/components/contentselector/view/profilescombobox.cpp b/components/contentselector/view/profilescombobox.cpp index 29001189d..0e9905df4 100644 --- a/components/contentselector/view/profilescombobox.cpp +++ b/components/contentselector/view/profilescombobox.cpp @@ -15,8 +15,8 @@ ContentSelectorView::ProfilesComboBox::ProfilesComboBox(QWidget *parent) : setValidator(mValidator); setCompleter(0); - connect(this, SIGNAL(currentIndexChanged(int)), this, - SLOT(slotIndexChanged(int))); + connect(this, SIGNAL(activated(int)), this, + SLOT(slotIndexChangedByUser(int))); setInsertPolicy(QComboBox::NoInsert); } @@ -85,13 +85,13 @@ void ContentSelectorView::ProfilesComboBox::slotEditingFinished() emit(profileRenamed(previous, current)); } -void ContentSelectorView::ProfilesComboBox::slotIndexChanged(int index) +void ContentSelectorView::ProfilesComboBox::slotIndexChangedByUser(int index) { if (index == -1) return; - emit(profileChanged(mOldProfile, currentText())); - mOldProfile = itemText(index); + emit (signalProfileChanged(mOldProfile, currentText())); + mOldProfile = currentText(); } void ContentSelectorView::ProfilesComboBox::paintEvent(QPaintEvent *) diff --git a/components/contentselector/view/profilescombobox.hpp b/components/contentselector/view/profilescombobox.hpp index 560c42c10..fc87a94b4 100644 --- a/components/contentselector/view/profilescombobox.hpp +++ b/components/contentselector/view/profilescombobox.hpp @@ -14,17 +14,19 @@ namespace ContentSelectorView public: explicit ProfilesComboBox(QWidget *parent = 0); void setEditEnabled(bool editable); - void setPlaceholderText (const QString &text); + void setPlaceholderText(const QString &text); + // void indexChanged(int index); signals: - void signalProfileTextChanged (const QString &item); - void profileChanged(const QString &previous, const QString ¤t); + void signalProfileTextChanged(const QString &item); + void signalProfileChanged(const QString &previous, const QString ¤t); + void signalProfileChanged(int index); void profileRenamed(const QString &oldName, const QString &newName); private slots: void slotEditingFinished(); - void slotIndexChanged(int index); + void slotIndexChangedByUser(int index); void slotTextChanged(const QString &text); private: diff --git a/apps/launcher/utils/textinputdialog.cpp b/components/contentselector/view/textinputdialog.cpp similarity index 75% rename from apps/launcher/utils/textinputdialog.cpp rename to components/contentselector/view/textinputdialog.cpp index 51928c09a..6bb92f113 100644 --- a/apps/launcher/utils/textinputdialog.cpp +++ b/components/contentselector/view/textinputdialog.cpp @@ -16,6 +16,7 @@ TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWid mButtonBox = new QDialogButtonBox(this); mButtonBox->addButton(QDialogButtonBox::Ok); mButtonBox->addButton(QDialogButtonBox::Cancel); + mButtonBox->button(QDialogButtonBox::Ok)->setEnabled (false); // Line edit QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore @@ -38,11 +39,11 @@ TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWid Q_UNUSED(title); #endif - setOkButtonEnabled(false); setModal(true); connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(mLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateOkButton(QString))); } @@ -53,19 +54,23 @@ int TextInputDialog::exec() return QDialog::exec(); } -void TextInputDialog::setOkButtonEnabled(bool enabled) +QString TextInputDialog::getText() const { - QPushButton *okButton = mButtonBox->button(QDialogButtonBox::Ok); - okButton->setEnabled(enabled); + return mLineEdit->text(); +} - QPalette *palette = new QPalette(); - palette->setColor(QPalette::Text,Qt::red); +void TextInputDialog::slotUpdateOkButton(QString text) +{ + bool enabled = !(text.isEmpty()); + mButtonBox->button(QDialogButtonBox::Ok)->setEnabled(enabled); - if (enabled) { + if (enabled) mLineEdit->setPalette(QApplication::palette()); - } else { + else + { // Existing profile name, make the text red + QPalette *palette = new QPalette(); + palette->setColor(QPalette::Text,Qt::red); mLineEdit->setPalette(*palette); } - } diff --git a/apps/launcher/utils/textinputdialog.hpp b/components/contentselector/view/textinputdialog.hpp similarity index 78% rename from apps/launcher/utils/textinputdialog.hpp rename to components/contentselector/view/textinputdialog.hpp index de3a9fb72..a0b7e350a 100644 --- a/apps/launcher/utils/textinputdialog.hpp +++ b/components/contentselector/view/textinputdialog.hpp @@ -13,18 +13,19 @@ namespace ContentSelectorView { class TextInputDialog : public QDialog { Q_OBJECT -public: - explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0); - inline ContentSelectorView::LineEdit *lineEdit() { return mLineEdit; } - void setOkButtonEnabled(bool enabled); ContentSelectorView::LineEdit *mLineEdit; + QDialogButtonBox *mButtonBox; - int exec(); +public: -private: - QDialogButtonBox *mButtonBox; + explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0); + QString getText() const; + + int exec(); +private slots: + void slotUpdateOkButton(QString text); }; diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 73d7a4902..0cafd606a 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -7,7 +7,7 @@ 0 0 518 - 424 + 436 @@ -242,11 +242,6 @@ 0 - - - Default - -
From 4c72a9ffdfe592f154beeb4be2d05d3c1514fc01 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 6 Oct 2013 22:10:38 -0500 Subject: [PATCH 070/118] Fixed non-loading files --- apps/opencs/editor.cpp | 3 +++ apps/opencs/view/doc/filedialog.cpp | 2 +- components/contentselector/model/contentmodel.cpp | 11 ++++++----- components/contentselector/model/contentmodel.hpp | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 401f3839f..ae10ec642 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -128,6 +128,9 @@ void CS::Editor::openFiles() files.push_back(path.toStdString()); } + foreach (const boost::filesystem::path fp, files) + qDebug() << "loading files: " << fp.c_str(); + /// \todo Get the save path from the file dialogue CSMDoc::Document *document = mDocumentManager.addDocument (files, *files.rbegin(), false); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index efa31100a..2017ab103 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -44,7 +44,7 @@ QStringList CSVDoc::FileDialog::selectedFilePaths() foreach (ContentSelectorModel::EsmFile *file, ContentSelectorView::ContentSelector:: instance().selectedFiles() ) { - filePaths.append(file->fileName()); + filePaths.append(file->path()); } return filePaths; } diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index a9796a1fb..8bb052d3d 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -15,10 +15,10 @@ ContentSelectorModel::ContentModel::ContentModel(QObject *parent) : mDefaultFlags (Qt::ItemIsDropEnabled | Qt::ItemIsSelectable), mDropActions (Qt::CopyAction | Qt::MoveAction) { - // setEncoding ("win1252"); + setEncoding ("win1252"); uncheckAll(); } -/* + void ContentSelectorModel::ContentModel::setEncoding(const QString &encoding) { if (encoding == QLatin1String("win1252")) @@ -33,7 +33,7 @@ void ContentSelectorModel::ContentModel::setEncoding(const QString &encoding) else return; // This should never happen; } -*/ + int ContentSelectorModel::ContentModel::columnCount(const QModelIndex &parent) const { if (parent.isValid()) @@ -420,8 +420,9 @@ void ContentSelectorModel::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.getGameFiles()) diff --git a/components/contentselector/model/contentmodel.hpp b/components/contentselector/model/contentmodel.hpp index feea3643b..0d6c52cc6 100644 --- a/components/contentselector/model/contentmodel.hpp +++ b/components/contentselector/model/contentmodel.hpp @@ -22,7 +22,7 @@ namespace ContentSelectorModel 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; From 3000386443acf0a8214994aaa14e59c68eb6d05f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 16 Oct 2013 13:07:26 +0200 Subject: [PATCH 071/118] failed attempt on switch adding. --- apps/opencs/editor.cpp | 54 +++++++++++++++++++++++++++++++++++++++++- apps/opencs/editor.hpp | 5 +++- apps/opencs/main.cpp | 2 +- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index a43059795..4c75ed1cc 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -6,6 +6,8 @@ #include #include +#include + #include "model/doc/document.hpp" #include "model/world/data.hpp" @@ -208,8 +210,13 @@ void CS::Editor::connectToIPCServer() mClientSocket->close(); } -int CS::Editor::run() +int CS::Editor::run(int argc, char** argv) { + if (!parseOptions(argc, argv) ) + { + return 0; + } + if (mLocal.empty()) return 1; @@ -219,3 +226,48 @@ int CS::Editor::run() return QApplication::exec(); } + +bool CS::Editor::parseOptions (int argc, char** argv) +{ + // Create a local alias for brevity + namespace bpo = boost::program_options; + typedef std::vector StringsVector; + + bpo::options_description desc("Syntax: openmw \nAllowed options"); + + desc.add_options() + ("help", "print help message") + + ("resources", bpo::value()->default_value("resources"), "set resources directory"); + + bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); + + bpo::variables_map variables; + + // Runtime options override settings from all configs + bpo::store(valid_opts, variables); + bpo::notify(variables); + +// cfgMgr.readConfiguration(variables, desc); + + bool run = true; + + if (variables.count ("help")) + { + std::cout << desc << std::endl; + run = false; + } + + if (!run) + return false; + + setResourceDir(variables["resources"].as()); + + return true; +} + +// Set resource dir +void CS::Editor::setResourceDir (const boost::filesystem::path& parResDir) +{ + mResDir = boost::filesystem::system_complete(parResDir); +} \ No newline at end of file diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 16f6b9516..77ba0993e 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -50,7 +50,7 @@ namespace CS bool makeIPCServer(); void connectToIPCServer(); - int run(); + int run(int argc, char** argv); ///< \return error status private slots: @@ -66,12 +66,15 @@ namespace CS void showStartup(); void showSettings(); + bool parseOptions (int argc, char** argv); + void setResourceDir (const boost::filesystem::path& parResDir); private: QString mIpcServerName; QLocalServer *mServer; QLocalSocket *mClientSocket; + boost::filesystem::path mResDir; }; } diff --git a/apps/opencs/main.cpp b/apps/opencs/main.cpp index e5e7514ce..bec09bd4a 100644 --- a/apps/opencs/main.cpp +++ b/apps/opencs/main.cpp @@ -45,5 +45,5 @@ int main(int argc, char *argv[]) // return 0; } - return editor.run(); + return editor.run(argc, argv); } From a7002e8a09602f4dfcbe3e1031ab6a4ef365cbad Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 17 Oct 2013 18:21:41 +0200 Subject: [PATCH 072/118] Implements switch (--help and --resources), and copying defaultfilters.omwaddon.project. Seems to work. --- apps/opencs/editor.cpp | 17 ++++------------- apps/opencs/editor.hpp | 2 -- apps/opencs/model/doc/document.cpp | 10 +++++----- apps/opencs/model/doc/document.hpp | 7 +++---- apps/opencs/model/doc/documentmanager.cpp | 7 ++++++- apps/opencs/model/doc/documentmanager.hpp | 7 +++++-- 6 files changed, 23 insertions(+), 27 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 4c75ed1cc..d5888a312 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -6,8 +6,6 @@ #include #include -#include - #include "model/doc/document.hpp" #include "model/world/data.hpp" @@ -59,7 +57,7 @@ void CS::Editor::setupDataFiles() if (!variables["data"].empty()) { dataDirs = Files::PathContainer(variables["data"].as()); } - + std::string local = variables["data-local"].as(); if (!local.empty()) { dataLocal.push_back(Files::PathContainer::value_type(local)); @@ -231,9 +229,8 @@ bool CS::Editor::parseOptions (int argc, char** argv) { // Create a local alias for brevity namespace bpo = boost::program_options; - typedef std::vector StringsVector; - bpo::options_description desc("Syntax: openmw \nAllowed options"); + bpo::options_description desc("Syntax: opencs \nAllowed options"); desc.add_options() ("help", "print help message") @@ -248,7 +245,7 @@ bool CS::Editor::parseOptions (int argc, char** argv) bpo::store(valid_opts, variables); bpo::notify(variables); -// cfgMgr.readConfiguration(variables, desc); + mCfgMgr.readConfiguration(variables, desc); bool run = true; @@ -261,13 +258,7 @@ bool CS::Editor::parseOptions (int argc, char** argv) if (!run) return false; - setResourceDir(variables["resources"].as()); + mDocumentManager.setResourceDir(variables["resources"].as()); return true; -} - -// Set resource dir -void CS::Editor::setResourceDir (const boost::filesystem::path& parResDir) -{ - mResDir = boost::filesystem::system_complete(parResDir); } \ No newline at end of file diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 77ba0993e..763cde100 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -67,14 +67,12 @@ namespace CS void showSettings(); bool parseOptions (int argc, char** argv); - void setResourceDir (const boost::filesystem::path& parResDir); private: QString mIpcServerName; QLocalServer *mServer; QLocalSocket *mClientSocket; - boost::filesystem::path mResDir; }; } diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 5c29d9f61..afb68b440 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2146,10 +2146,8 @@ void CSMDoc::Document::createBase() } } -CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, - const std::vector& files, - const boost::filesystem::path& savePath, bool new_) -: mSavePath (savePath), mContentFiles (files), mTools (mData), +CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, bool new_) +: mSavePath (savePath), mContentFiles (files), mTools (mData), mResDir(resDir), mProjectPath ((configuration.getUserPath() / "projects") / (savePath.filename().string() + ".project")), mSaving (*this, mProjectPath) @@ -2183,7 +2181,9 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, } else { - /// \todo create new project file with default filters + boost::filesystem::path filters = mResDir; + filters /= "defaultfilters.omwaddon.project"; + boost::filesystem::copy_file(mResDir, mProjectPath); } } diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index d171dacae..e6d1b0c87 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -43,13 +43,14 @@ namespace CSMDoc CSMTools::Tools mTools; boost::filesystem::path mProjectPath; Saving mSaving; + boost::filesystem::path mResDir; // It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is // using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late. QUndoStack mUndoStack; // not implemented - Document (const Document&); + Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, bool new_); Document& operator= (const Document&); void load (const std::vector::const_iterator& begin, @@ -70,9 +71,7 @@ namespace CSMDoc public: - Document (const Files::ConfigurationManager& configuration, - const std::vector& files, - const boost::filesystem::path& savePath, bool new_); + Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, bool new_); ~Document(); diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 1d6c88dcc..024c46bea 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -30,7 +30,7 @@ CSMDoc::DocumentManager::~DocumentManager() CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::vector& files, const boost::filesystem::path& savePath, bool new_) { - Document *document = new Document (mConfiguration, files, savePath, new_); + Document *document = new Document (mConfiguration, files, savePath, mResDir, new_); mDocuments.push_back (document); @@ -48,4 +48,9 @@ bool CSMDoc::DocumentManager::removeDocument (Document *document) delete document; return mDocuments.empty(); +} + +void CSMDoc::DocumentManager::setResourceDir (const boost::filesystem::path& parResDir) +{ + mResDir = boost::filesystem::system_complete(parResDir); } \ No newline at end of file diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index 28a21216a..b80a18642 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -29,8 +29,7 @@ namespace CSMDoc ~DocumentManager(); - Document *addDocument (const std::vector& files, - const boost::filesystem::path& savePath, bool new_); + Document *addDocument (const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, bool new_); ///< The ownership of the returned document is not transferred to the caller. /// /// \param new_ Do not load the last content file in \a files and instead create in an @@ -38,6 +37,10 @@ namespace CSMDoc bool removeDocument (Document *document); ///< \return last document removed? + void setResourceDir (const boost::filesystem::path& parResDir); + + private: + boost::filesystem::path mResDir; }; } From 4e26a61db3f217a8bf4bb6ce2f36e8a0a65b57c5 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 18 Oct 2013 22:11:14 +0200 Subject: [PATCH 073/118] Removed command line handling. Maybe zini will let me to implement it later. Implemented switch to handle resources directory. TODO: check for defaultfilters on data path. --- apps/opencs/editor.cpp | 55 ++++++------------------------------------ apps/opencs/editor.hpp | 3 +-- apps/opencs/main.cpp | 2 +- 3 files changed, 10 insertions(+), 50 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index d5888a312..97c958f3d 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -41,13 +41,14 @@ CS::Editor::Editor() void CS::Editor::setupDataFiles() { boost::program_options::variables_map variables; - boost::program_options::options_description desc; - + boost::program_options::options_description desc("Syntax: opencs \nAllowed options"); + desc.add_options() ("data", boost::program_options::value()->default_value(Files::PathContainer(), "data")->multitoken()) ("data-local", boost::program_options::value()->default_value("")) ("fs-strict", boost::program_options::value()->implicit_value(true)->default_value(false)) - ("encoding", boost::program_options::value()->default_value("win1252")); + ("encoding", boost::program_options::value()->default_value("win1252")) + ("resources", boost::program_options::value()->default_value("resources"), "set resources directory"); boost::program_options::notify(variables); @@ -86,6 +87,9 @@ void CS::Editor::setupDataFiles() //mFileDialog.setEncoding(encoding); dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end()); + +// Setting Resources directory. + mDocumentManager.setResourceDir(variables["resources"].as()); for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) { @@ -208,13 +212,8 @@ void CS::Editor::connectToIPCServer() mClientSocket->close(); } -int CS::Editor::run(int argc, char** argv) +int CS::Editor::run() { - if (!parseOptions(argc, argv) ) - { - return 0; - } - if (mLocal.empty()) return 1; @@ -223,42 +222,4 @@ int CS::Editor::run(int argc, char** argv) QApplication::setQuitOnLastWindowClosed (true); return QApplication::exec(); -} - -bool CS::Editor::parseOptions (int argc, char** argv) -{ - // Create a local alias for brevity - namespace bpo = boost::program_options; - - bpo::options_description desc("Syntax: opencs \nAllowed options"); - - desc.add_options() - ("help", "print help message") - - ("resources", bpo::value()->default_value("resources"), "set resources directory"); - - bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); - - bpo::variables_map variables; - - // Runtime options override settings from all configs - bpo::store(valid_opts, variables); - bpo::notify(variables); - - mCfgMgr.readConfiguration(variables, desc); - - bool run = true; - - if (variables.count ("help")) - { - std::cout << desc << std::endl; - run = false; - } - - if (!run) - return false; - - mDocumentManager.setResourceDir(variables["resources"].as()); - - return true; } \ No newline at end of file diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 763cde100..16f6b9516 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -50,7 +50,7 @@ namespace CS bool makeIPCServer(); void connectToIPCServer(); - int run(int argc, char** argv); + int run(); ///< \return error status private slots: @@ -66,7 +66,6 @@ namespace CS void showStartup(); void showSettings(); - bool parseOptions (int argc, char** argv); private: diff --git a/apps/opencs/main.cpp b/apps/opencs/main.cpp index bec09bd4a..e5e7514ce 100644 --- a/apps/opencs/main.cpp +++ b/apps/opencs/main.cpp @@ -45,5 +45,5 @@ int main(int argc, char *argv[]) // return 0; } - return editor.run(argc, argv); + return editor.run(); } From 184456892b4abc42b4db73f66ecb82c21073011e Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 19 Oct 2013 18:43:47 +0200 Subject: [PATCH 074/118] Added check to load custom filters set when present. --- apps/opencs/editor.cpp | 21 +++++++++++---------- apps/opencs/model/doc/document.cpp | 26 +++++++++++++++++--------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 97c958f3d..9abc9ee78 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -8,10 +8,11 @@ #include "model/doc/document.hpp" #include "model/world/data.hpp" +#include CS::Editor::Editor() -: mDocumentManager (mCfgMgr), mViewManager (mDocumentManager) + : mDocumentManager (mCfgMgr), mViewManager (mDocumentManager) { mIpcServerName = "org.openmw.OpenCS"; @@ -32,23 +33,23 @@ CS::Editor::Editor() connect (&mFileDialog, SIGNAL(openFiles()), this, SLOT(openFiles())); connect (&mFileDialog, SIGNAL(createNewFile (const boost::filesystem::path&)), - this, SLOT(createNewFile (const boost::filesystem::path&))); + this, SLOT(createNewFile (const boost::filesystem::path&))); connect (&mNewGame, SIGNAL (createRequest (const boost::filesystem::path&)), - this, SLOT (createNewGame (const boost::filesystem::path&))); + this, SLOT (createNewGame (const boost::filesystem::path&))); } void CS::Editor::setupDataFiles() { boost::program_options::variables_map variables; boost::program_options::options_description desc("Syntax: opencs \nAllowed options"); - + desc.add_options() ("data", boost::program_options::value()->default_value(Files::PathContainer(), "data")->multitoken()) ("data-local", boost::program_options::value()->default_value("")) ("fs-strict", boost::program_options::value()->implicit_value(true)->default_value(false)) ("encoding", boost::program_options::value()->default_value("win1252")) - ("resources", boost::program_options::value()->default_value("resources"), "set resources directory"); + ("resources", boost::program_options::value()->default_value("resources")); boost::program_options::notify(variables); @@ -58,7 +59,7 @@ void CS::Editor::setupDataFiles() if (!variables["data"].empty()) { dataDirs = Files::PathContainer(variables["data"].as()); } - + std::string local = variables["data-local"].as(); if (!local.empty()) { dataLocal.push_back(Files::PathContainer::value_type(local)); @@ -83,12 +84,12 @@ void CS::Editor::setupDataFiles() } // Set the charset for reading the esm/esp files - // QString encoding = QString::fromStdString(variables["encoding"].as()); + // QString encoding = QString::fromStdString(variables["encoding"].as()); //mFileDialog.setEncoding(encoding); dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end()); - -// Setting Resources directory. + +// Adding Resources directory. First check if there is a file defaultfilters in the user path. mDocumentManager.setResourceDir(variables["resources"].as()); for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) @@ -222,4 +223,4 @@ int CS::Editor::run() QApplication::setQuitOnLastWindowClosed (true); return QApplication::exec(); -} \ No newline at end of file +} diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index afb68b440..32c728f88 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -9,7 +9,7 @@ #endif void CSMDoc::Document::load (const std::vector::const_iterator& begin, - const std::vector::const_iterator& end, bool lastAsModified) + const std::vector::const_iterator& end, bool lastAsModified) { assert (begin!=end); @@ -2147,10 +2147,10 @@ void CSMDoc::Document::createBase() } CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, bool new_) -: mSavePath (savePath), mContentFiles (files), mTools (mData), mResDir(resDir), - mProjectPath ((configuration.getUserPath() / "projects") / - (savePath.filename().string() + ".project")), - mSaving (*this, mProjectPath) + : mSavePath (savePath), mContentFiles (files), mTools (mData), mResDir(resDir), + mProjectPath ((configuration.getUserPath() / "projects") / + (savePath.filename().string() + ".project")), + mSaving (*this, mProjectPath) { if (files.empty()) throw std::runtime_error ("Empty content file sequence"); @@ -2181,9 +2181,17 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, co } else { - boost::filesystem::path filters = mResDir; - filters /= "defaultfilters.omwaddon.project"; - boost::filesystem::copy_file(mResDir, mProjectPath); + boost::filesystem::path locCustomFiltersPath (configuration.getUserPath()); + locCustomFiltersPath /= "defaultfilters.omwaddon.project"; + if (boost::filesystem::exists(locCustomFiltersPath)) + { + boost::filesystem::copy(locCustomFiltersPath, mProjectPath); + } else { + boost::filesystem::path filters(mResDir); + filters /= "defaultfilters.omwaddon.project"; + boost::filesystem::copy_file(filters, mProjectPath); + } + getData().loadFile (mProjectPath, false, true); } } @@ -2198,7 +2206,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, co connect (&mSaving, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int))); connect (&mSaving, SIGNAL (done (int)), this, SLOT (operationDone (int))); connect (&mSaving, SIGNAL (reportMessage (const QString&, int)), - this, SLOT (reportMessage (const QString&, int))); + this, SLOT (reportMessage (const QString&, int))); } CSMDoc::Document::~Document() From 762cbf62785d8f26ea2d58bcf24a65f32bedf64d Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 19 Oct 2013 18:51:36 +0200 Subject: [PATCH 075/118] Changed gauntlets filter. It showes now both gauntlets and bracers. --- files/opencs/defaultfilters.omwaddon.project | Bin 0 -> 10544 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 files/opencs/defaultfilters.omwaddon.project diff --git a/files/opencs/defaultfilters.omwaddon.project b/files/opencs/defaultfilters.omwaddon.project new file mode 100644 index 0000000000000000000000000000000000000000..e58ed92786f2e0333519341d24f008e772828e34 GIT binary patch literal 10544 zcmeHNOK&4f6`s50{k*)Pu6a3-JK_#(7=f;wOlA_4nH%E3@DM`fb~$d+?zXzx$pnEI z-a;%83nU~EumKjZVaE?(#joN#>Qq;i+jd6IlHPROed>H)omW+z&e_56^Iv%Bj=v5M z9-QvN@5$tEultAp|6{EM9v&T^eKU}FGI)IOPWU~qtM8etxqtu4=y_GzJ1F>3cww75 zFVFkEQbAR)Xtp;2gCh$fz)tXT`64@?uETePGFMKK0sRZ-P5OL*5_(ehwYhN10qw0#d z?Qh9#ueuUqz7~M)4px6iSiRiAO4ndC;&rekuK{WjW_?hG?uE4sA2T^Un=Q(`fmK5F zCsnP0wRNfVyM*coI;duKWvy6o+j!h}%7if19g0Um>9FS?6O!-kAUUdvhRpc@UT%{x zd!R_j`TR!h-L@3kV$k0wTswXL%(#lWZN3big{A)!fK9g4@Hi~_9X0fZJY5yK4W4Zc zTElax0R1VkXSABT0yHWXW#cTmZG7&bu3$O+l-QI&Hd*!W3EQr8B1QM6oc!A^sZ96Y zp?aE+jfCyaI?l7oHpMmUDfDC_L7Oh9YiMVbWZQ0CJnj9WvYz*=H{gAx>nYSTQw#S| zV)AGS&{>mT>PEKduYhd#W@{jVyotgJ!sGHI%`iKVAm$kHl03(B*j?K>B9|Y zpuYx3MO=JwJ@l(vUS66KW_DeT@Z7_QColpEyx&pQeCEMg0Grv~Nrj6*Z)ewUDczP+ z1P1fDu647p9WrN5$pDW%9q*lvQB_^61^|CIQ#g*T9uF^TGtOadftGk4v)tk)T$iR= z*g$H<{ux$-6$UBt^Jxe(hYhtJ6=W+sc0fY0k3KH(kT*uptZJsZQJF5)$f$XqU6`?2 z%-Lyc<1wqsM&~6&FQw7yc=UoD@#x>Vg_v@7qJy+AJPxasw5sn4&m8>LNb>$$c*7m3<1x@jxQDTM8Im8q5c%Mw z+}k*T&w*;n`?4xu?V3b3HMX(4YEhR~nI^ltLyr74jFSuJ5%&o)Uw{T66y|3fu}@C+ zS4MMI8_3JrxPa_|qOd?gg;RYP57b1`GPM)o1$U%|XL@g9C~YvZoO4uQ;B=QqWJVr- z6NnHlV$sw!Jdq3aM{5V`_l#(O0_koPkz**dAwkJw7w(my!5snL26sQ9kr^|s@Kis{ z>U`cn0o*g=??UM<$GRRf$Y%tkE%Mw>07c5uIHj9LgWt!T-#<>^qYWN+b*8468QzU< z*xYk>2vW@F7*$t)#6KiWvaaJy$s!Ek?D6tTEu&=zP> zMp{k-3nwO6x14=892CVqD_pjRdcp|)Nx70 z1%|2=cGE>e_w=Ix5z&!xC;1IWIgt-5kTCHDbPtq?0or7Qhb}~ZmP|hi5kZ*aj)iP+ z1mbH_Q3kA~bb{KJI1vV0>8A;&PAfsl;x6)SPy%)r|)InL=Z`)=*-Kxoy~h<$e}h5}_m z>CHk35tz`=6FYSVI8@D=&2&4_1loj>w-RAE=iQ9d#jTP;ZOf$asU!8T#8RCRbzW3b zoEwl|QwwDM+OUm!L<%=9$|B~LWN%gG!>(Ri%6TtqcbzMP8IOds%oN0 zF%wBEcGP2%k^Z1gX2M=dLPjjK@0uB%gnVm5)V72?K)2hXZ`i)IVXOtK=ei(PuLG+! zRXc9M9LP}g88^BVTg{gauiYwWqd2$yC~;eS#FL)O#LRTT8-Xvq2&;!QZi$lbBeULs z&SgR;>X=-ZYYv_b$DdVA*CVSyMazcm<98ycp1n0mSVXZLX(va062z16aj_i9GMt|~ zzPlR+?(+mSTGie6Bg$|WANN5X;=?zL<0Xp+wAIv&bpNE1gob+=|KG(A6F!j@93Pt( zm+qfazW73PcwofFf63r?F`4HHnaDUkfouT>(zTV(IVMh?c2hwL+|M1CKz;{9FI|ZI zAmI}k$Mf-7^JO+p`?(`_R!pbOnu&&gsOkw3-)2O$LDFE0TrO;@MT?Fe!+)cYNwDTf zm_Dw?`6M@EOojnUq)QGB<7_w<-Ed#-Vrt6<4?D7<_B{}A%6+Dd;2G=wTB1AJo7H9p zTUaI^u9%_v2L_H!p1yCcjQKHxd?Nvg8V56H2{KXGiVacx-<&sSU|I`h@ZCHA1I?m& AoB#j- literal 0 HcmV?d00001 From cafea438bdc1108c0a6cdf1f183b453ee2ef2bf9 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 20 Oct 2013 09:44:10 +0200 Subject: [PATCH 076/118] Added missing light filter. --- files/opencs/defaultfilters.omwaddon.project | Bin 10544 -> 10962 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/files/opencs/defaultfilters.omwaddon.project b/files/opencs/defaultfilters.omwaddon.project index e58ed92786f2e0333519341d24f008e772828e34..c66990fdc2c26863fa33edefe0d336ef9ae8fa3b 100644 GIT binary patch delta 295 zcmdlGbSZR$f#&43jEX!tnduoN#SCtqJ|VJ`8+j#FeLw=53@)z0&VmdK48a-s(uCL|53?mdFQ-x=FF#KKW+aN8{gW9bWh5YW7MCQJWF~`cbVAtZ53?~Z Mzl3yKbunxO07-RSssI20 delta 7 OcmcZ Date: Sun, 20 Oct 2013 09:50:16 +0200 Subject: [PATCH 077/118] Added configrue file in cmake. Hopefully it will copy defaultfilters file. --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 625239aa0..a436d1fc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -319,6 +319,9 @@ configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg configure_file(${OpenMW_SOURCE_DIR}/files/opencs.cfg "${OpenMW_BINARY_DIR}/opencs.cfg") + +configure_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters.omwaddon.project + "${OpenMW_BINARY_DIR}/resources/defaultfilters.omwaddon.project") if (NOT WIN32 AND NOT APPLE) configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop From 6b293961b4c7ee5152a282a6c245ec57c227b128 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 20 Oct 2013 10:02:33 +0200 Subject: [PATCH 078/118] This appears to work. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a436d1fc3..2a902eb83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -321,7 +321,7 @@ configure_file(${OpenMW_SOURCE_DIR}/files/opencs.cfg "${OpenMW_BINARY_DIR}/opencs.cfg") configure_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters.omwaddon.project - "${OpenMW_BINARY_DIR}/resources/defaultfilters.omwaddon.project") + "${OpenMW_BINARY_DIR}/resources/defaultfilters.omwaddon.project" COPYONLY) if (NOT WIN32 AND NOT APPLE) configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop From 96b6787255fb4596a0b02d3cecc438c086e29c73 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 20 Oct 2013 10:56:27 +0200 Subject: [PATCH 079/118] Getting rid of extension. Correcting tiny mistake in filters file. --- CMakeLists.txt | 2 +- apps/opencs/model/doc/document.cpp | 4 ++-- files/opencs/defaultfilters.omwaddon.project | Bin 10962 -> 10958 bytes 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a902eb83..df2986715 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -321,7 +321,7 @@ configure_file(${OpenMW_SOURCE_DIR}/files/opencs.cfg "${OpenMW_BINARY_DIR}/opencs.cfg") configure_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters.omwaddon.project - "${OpenMW_BINARY_DIR}/resources/defaultfilters.omwaddon.project" COPYONLY) + "${OpenMW_BINARY_DIR}/resources/defaultfilters" COPYONLY) if (NOT WIN32 AND NOT APPLE) configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 32c728f88..fd2b32861 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2182,13 +2182,13 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, co else { boost::filesystem::path locCustomFiltersPath (configuration.getUserPath()); - locCustomFiltersPath /= "defaultfilters.omwaddon.project"; + locCustomFiltersPath /= "customfilters.omwaddon.project"; if (boost::filesystem::exists(locCustomFiltersPath)) { boost::filesystem::copy(locCustomFiltersPath, mProjectPath); } else { boost::filesystem::path filters(mResDir); - filters /= "defaultfilters.omwaddon.project"; + filters /= "defaultfilters"; boost::filesystem::copy_file(filters, mProjectPath); } getData().loadFile (mProjectPath, false, true); diff --git a/files/opencs/defaultfilters.omwaddon.project b/files/opencs/defaultfilters.omwaddon.project index c66990fdc2c26863fa33edefe0d336ef9ae8fa3b..0ac3c8db4bd939b8b9d559ab4af4056fc0b8d80e 100644 GIT binary patch delta 37 tcmcZXdMR|nEKSDV$rIINCU4h_oV;2~aI&n{MgWvH3W5Lt From ebf77329128ac86833586ce4e00ceec2916d3e1e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 20 Oct 2013 15:48:39 +0200 Subject: [PATCH 080/118] some cleanup --- apps/opencs/model/world/idcollection.hpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 04e65eea7..72aafb91f 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -14,14 +14,11 @@ namespace CSMWorld { public: - void load (ESM::ESMReader& reader, bool base, - UniversalId::Type type = UniversalId::Type_None); - ///< \param type Will be ignored, unless the collection supports multiple record types + void load (ESM::ESMReader& reader, bool base); }; template - void IdCollection::load (ESM::ESMReader& reader, bool base, - UniversalId::Type type) + void IdCollection::load (ESM::ESMReader& reader, bool base) { std::string id = reader.getHNOString ("NAME"); From adf3a41a835af0315adf53ab7a31f3a1c2356cfc Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 20 Oct 2013 17:13:31 +0200 Subject: [PATCH 081/118] added topic and journal tables --- apps/opencs/model/world/data.cpp | 58 ++++++++++++++++++++++++ apps/opencs/model/world/data.hpp | 11 +++++ apps/opencs/model/world/idcollection.hpp | 46 +++++++++++-------- apps/opencs/model/world/universalid.cpp | 4 ++ apps/opencs/model/world/universalid.hpp | 4 ++ apps/opencs/view/doc/view.cpp | 18 ++++++++ apps/opencs/view/doc/view.hpp | 4 ++ apps/opencs/view/world/subviews.cpp | 2 + components/esm/loaddial.cpp | 5 ++ components/esm/loaddial.hpp | 3 ++ 10 files changed, 136 insertions(+), 19 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 1e290d45f..2af76cfa7 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -141,6 +141,12 @@ CSMWorld::Data::Data() : mRefs (mCells) mSpells.addColumn (new FlagColumn (Columns::ColumnId_StarterSpell, 0x2)); mSpells.addColumn (new FlagColumn (Columns::ColumnId_AlwaysSucceeds, 0x4)); + mTopics.addColumn (new StringIdColumn); + mTopics.addColumn (new RecordStateColumn); + + mJournals.addColumn (new StringIdColumn); + mJournals.addColumn (new RecordStateColumn); + mCells.addColumn (new StringIdColumn); mCells.addColumn (new RecordStateColumn); mCells.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Cell)); @@ -196,6 +202,8 @@ CSMWorld::Data::Data() : mRefs (mCells) addModel (new IdTable (&mRegions), UniversalId::Type_Regions, UniversalId::Type_Region); addModel (new IdTable (&mBirthsigns), UniversalId::Type_Birthsigns, UniversalId::Type_Birthsign); addModel (new IdTable (&mSpells), UniversalId::Type_Spells, UniversalId::Type_Spell); + addModel (new IdTable (&mTopics), UniversalId::Type_Topics, UniversalId::Type_Topic); + addModel (new IdTable (&mJournals), UniversalId::Type_Journals, UniversalId::Type_Journal); addModel (new IdTable (&mCells), UniversalId::Type_Cells, UniversalId::Type_Cell); addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables, UniversalId::Type_Referenceable); @@ -319,6 +327,28 @@ CSMWorld::IdCollection& CSMWorld::Data::getSpells() return mSpells; } + +const CSMWorld::IdCollection& CSMWorld::Data::getTopcis() const +{ + return mTopics; +} + +CSMWorld::IdCollection& CSMWorld::Data::getTopcis() +{ + return mTopics; +} + +const CSMWorld::IdCollection& CSMWorld::Data::getJournals() const +{ + return mJournals; +} + +CSMWorld::IdCollection& CSMWorld::Data::getJournals() +{ + return mJournals; +} + + const CSMWorld::IdCollection& CSMWorld::Data::getCells() const { return mCells; @@ -447,6 +477,30 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) case ESM::REC_STAT: mReferenceables.load (reader, base, UniversalId::Type_Static); break; case ESM::REC_WEAP: mReferenceables.load (reader, base, UniversalId::Type_Weapon); break; + case ESM::REC_DIAL: + { + std::string id = reader.getHNOString ("NAME"); + + ESM::Dialogue record; + record.mId = id; + record.load (reader); + + if (record.mType==ESM::Dialogue::Journal) + { + mJournals.load (record, base); + } + else if (record.mType==ESM::Dialogue::Deleted) + { + /// \todo handle deleted records + } + else + { + mTopics.load (record, base); + } + + break; + } + default: /// \todo throw an exception instead, once all records are implemented @@ -469,6 +523,8 @@ bool CSMWorld::Data::hasId (const std::string& id) const getRegions().searchId (id)!=-1 || getBirthsigns().searchId (id)!=-1 || getSpells().searchId (id)!=-1 || + getTopcis().searchId (id)!=-1 || + getJournals().searchId (id)!=-1 || getCells().searchId (id)!=-1 || getReferenceables().searchId (id)!=-1; } @@ -487,6 +543,8 @@ std::vector CSMWorld::Data::getIds (bool listDeleted) const appendIds (ids, mRegions, listDeleted); appendIds (ids, mBirthsigns, listDeleted); appendIds (ids, mSpells, listDeleted); + appendIds (ids, mTopics, listDeleted); + appendIds (ids, mJournals, listDeleted); appendIds (ids, mCells, listDeleted); appendIds (ids, mReferenceables, listDeleted); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index e900bb10f..74304e029 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "../filter/filter.hpp" @@ -48,6 +49,8 @@ namespace CSMWorld IdCollection mRegions; IdCollection mBirthsigns; IdCollection mSpells; + IdCollection mTopics; + IdCollection mJournals; IdCollection mCells; RefIdCollection mReferenceables; RefCollection mRefs; @@ -116,6 +119,14 @@ namespace CSMWorld IdCollection& getSpells(); + const IdCollection& getTopcis() const; + + IdCollection& getTopcis(); + + const IdCollection& getJournals() const; + + IdCollection& getJournals(); + const IdCollection& getCells() const; IdCollection& getCells(); diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 72aafb91f..b6ae04572 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -15,6 +15,8 @@ namespace CSMWorld public: void load (ESM::ESMReader& reader, bool base); + + void load (const ESXRecordT& record, bool base); }; template @@ -53,29 +55,35 @@ namespace CSMWorld IdAccessorT().getId (record) = id; record.load (reader); - int index = this->searchId (IdAccessorT().getId (record)); + load (record, base); + } + } - if (index==-1) - { - // new record - Record record2; - record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; - (base ? record2.mBase : record2.mModified) = record; + template + void IdCollection::load (const ESXRecordT& record, bool base) + { + int index = this->searchId (IdAccessorT().getId (record)); - this->appendRecord (record2); - } - else - { - // old record - Record record2 = Collection::getRecord (index); + if (index==-1) + { + // new record + Record record2; + record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; + (base ? record2.mBase : record2.mModified) = record; + + this->appendRecord (record2); + } + else + { + // old record + Record record2 = Collection::getRecord (index); - if (base) - record2.mBase = record; - else - record2.setModified (record); + if (base) + record2.mBase = record; + else + record2.setModified (record); - this->setRecord (index, record2); - } + this->setRecord (index, record2); } } } diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index c9edd0c16..6201a3cda 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -29,6 +29,8 @@ namespace { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Regions, "Regions", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Birthsigns, "Birthsigns", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Spells, "Spells", 0 }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Topics, "Topics", 0 }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Journals, "Journals", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Cells, "Cells", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables, "Referenceables", 0 }, @@ -54,6 +56,8 @@ namespace { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region", ":./land.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign", ":./birthsign.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", ":./spell.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Topic, "Topic", 0 }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Journal, "Journal", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables", 0 }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Activator, "Activator", ":./activator.png" }, diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 246640733..ffd99e572 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -87,6 +87,10 @@ namespace CSMWorld Type_RegionMap, Type_Filter, Type_Filters, + Type_Topics, + Type_Topic, + Type_Journals, + Type_Journal, Type_Scene }; diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index b29250d20..5713449f2 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -163,6 +163,14 @@ void CSVDoc::View::setupMechanicsMenu() QAction *spells = new QAction (tr ("Spells"), this); connect (spells, SIGNAL (triggered()), this, SLOT (addSpellsSubView())); mechanics->addAction (spells); + + QAction *topics = new QAction (tr ("Topics"), this); + connect (topics, SIGNAL (triggered()), this, SLOT (addTopicsSubView())); + mechanics->addAction (topics); + + QAction *journals = new QAction (tr ("Journals"), this); + connect (journals, SIGNAL (triggered()), this, SLOT (addJournalsSubView())); + mechanics->addAction (journals); } void CSVDoc::View::setupAssetsMenu() @@ -412,6 +420,16 @@ void CSVDoc::View::addSceneSubView() addSubView (CSMWorld::UniversalId::Type_Scene); } +void CSVDoc::View::addTopicsSubView() +{ + addSubView (CSMWorld::UniversalId::Type_Topics); +} + +void CSVDoc::View::addJournalsSubView() +{ + addSubView (CSMWorld::UniversalId::Type_Journals); +} + void CSVDoc::View::abortOperation (int type) { mDocument->abortOperation (type); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 6f3c38daa..2a31d9d80 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -166,6 +166,10 @@ namespace CSVDoc void addSceneSubView(); + void addTopicsSubView(); + + void addJournalsSubView(); + void toggleShowStatusBar (bool show); }; } diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 0e3465b38..417a7258f 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -36,6 +36,8 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Regions, CSMWorld::UniversalId::Type_Birthsigns, CSMWorld::UniversalId::Type_Spells, + CSMWorld::UniversalId::Type_Topics, + CSMWorld::UniversalId::Type_Journals, CSMWorld::UniversalId::Type_None // end marker }; diff --git a/components/esm/loaddial.cpp b/components/esm/loaddial.cpp index fb50d5e9f..f6c63efd2 100644 --- a/components/esm/loaddial.cpp +++ b/components/esm/loaddial.cpp @@ -36,4 +36,9 @@ void Dialogue::save(ESMWriter &esm) } } + void Dialogue::blank() + { + mInfo.clear(); + } + } diff --git a/components/esm/loaddial.hpp b/components/esm/loaddial.hpp index 61f3f763d..0f4ceb6ac 100644 --- a/components/esm/loaddial.hpp +++ b/components/esm/loaddial.hpp @@ -35,6 +35,9 @@ struct Dialogue void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID and does not change the type). }; } #endif From b138533bf307332852d907b181114f53b2bf4d91 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 20 Oct 2013 17:21:09 +0200 Subject: [PATCH 082/118] renamed defaultfilter.omwaddon.project to defaultfilters. --- CMakeLists.txt | 2 +- files/opencs/defaultfilters.omwaddon.project | Bin 10958 -> 0 bytes 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 files/opencs/defaultfilters.omwaddon.project diff --git a/CMakeLists.txt b/CMakeLists.txt index df2986715..cfb682cdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -320,7 +320,7 @@ configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg configure_file(${OpenMW_SOURCE_DIR}/files/opencs.cfg "${OpenMW_BINARY_DIR}/opencs.cfg") -configure_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters.omwaddon.project +configure_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters "${OpenMW_BINARY_DIR}/resources/defaultfilters" COPYONLY) if (NOT WIN32 AND NOT APPLE) diff --git a/files/opencs/defaultfilters.omwaddon.project b/files/opencs/defaultfilters.omwaddon.project deleted file mode 100644 index 0ac3c8db4bd939b8b9d559ab4af4056fc0b8d80e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10958 zcmeHN%Woq|8K1rKelD=EP-|WeWJm14g%PlFGMPzGW;VoO2Ux9E<#yR_((bmp+sOoh z7~Vo0RveI!K)?k!z=a!s04M$`zDIr4Rn=`fBj<=Oj=R75e!u!&RrOWQ4u)U;%5%5e z=kVa(=`Q@9O#b$&d-(r9)>`2H(ec@LJ&8wyhX?P6-;1*NzDer4cQ1`z6nS+E1wRQd zs=7?`X}@=BlA;`|v#W*a?JAbqxpnVgxc>o=8qSJKrL)YwsBY8v*CU|!`9Qjy7bWAo zxDtni7zSB77#_?h--}Q_;-e%c%PRAvHf36rL<(Q$MXl__PR%qe@?F*IG0ca27#X-? zK5e8l_mDmas;+|~gDgr8!{meR`8fP=?g{2I(dUNdi`^0Mc^JLDPh#Vz-#%m z=4?Zi&wVI$#mh$o>b zf>SjFeHhvQ6teJ*d_Mu-&PSGSR^(F}|H_Ok^$=vXA$$z_T716R%A6bwtZo|VOAP7!i{OSWgEN<#Ss;mQaBSB`{VM)a`u#Zf#e zE{WUzmfZG=OCjcJ0qE{v^@oVn^Bt^o2}UDc2V3$QpeA9~2W9A9Sj+G+lhgD0GEZw* zB~*V>lnPi^HkE!CQTF(7!A@Hnk4cf&I?W+^DUDXgqZ90iNB7PixBda-~{rTVt;EWmHIB=5h4H+&;?JO;W5cQ93&`{aku zMBY0o_cl)8OQ4$aJ}>f@yC#v$OjTFAYFXx$GIer$haCAE7$+Z`N7yGwTmc$@ke{Dn z#6CLNUm49wX&^64V*|1Wiu?iv6;AbGJWvzKim9ClFZf1kc&2wIhSCNj^94r*22OW* zL}ujScYp}tA{I?u!xQ#z^fnsNlo|>z1|8hJ&KmXNAl5P>*=*T|$qvGn4;DOu~dAe=YPf8<*0=d;$Zu z_t%NlxzWarU~FSYYlV%UMlnTMoE?Cdgw_1nz&X~ZXJUXcDO zS*E3~xMW;6SGxmwpEb1@Sp@d|H5kF}M_-tmVDx}BwHR3hX7pxcBixO;YMR*H+J?F< zn>sG3xWG`A!fv`~=$?KMAR;<4_9VaIC@1oM1rjE%fbM}ZF+h`y@X&_H&!g!FAtDG1 z+_8`ijzD}(D$0Phlul4vixXk6m3|g+>a-G+Ebb!T1SN2nX;VUo6`9mY39nhmN;l!S zQ#vGYL^;PHf@Sop$Vfq7K>VQROIY=Y(>HIxa|2Q*u6s9VNoNJI@QwwDM+OUm!Kngc5$|7c$WM@_8!>(Ri%6Ttqc@0!}YM##EL@>Xqiy~uO><~n_u3^$NRcNN}_JEb7iOv)$V%*Jbqd+>s7H+3zp;I_QkX78ap`@q2MZOgQz88MGJxUE%-0Xsm%YH$EO*zbv zaNJ@-1KH%ijsSug&Gi%-deG;Gdw5z(R-F$*uwCV6*g>Aa6=pq$wiY(x#M)S6$l8YA z^Pv-wnAlZBEQp27TtF8LdS$hlGqYU~k8FKryLLw)q>k+fb(~gE49OnuQeD)k3|>~M zm?%=rMB<7a^q6F%JE)VHu$K~%5ex0xW=1C=*V+)Z4Iu~6?Y7_!+qE`KRe{x0oe`^7 zfz_I-9kyT&WGMQK8(oU6=1PatUMXm!ShxK+a$9)Blb*}O%yq^afv-IatNS#rMalJ% zS+7UuBBB#?OwP>}2hWD%&#I>DQKdjd!-nnSb|R>ry)}tg1hE`wCr5o2#G~-Bu^h-U zoSQqoyX^<=(+D+K)$RQeWw?!xyC4to;Tp!_lEnj>YHCN?e^QA;!@dmv@8U-hpTG*1 zPnBjD_McO}`b>0qV8F)RWbnI?%+rWWU>uh~RR#yrwUy60CQP1YQ$Y&s&mEgUZU;jz zZHW9Z;u9Fh@o`!6bv90O-4Qw~q|;>0M8iK+^@NCPGoo5AX|P2uA8e}yi;f<{f1{8| zu;xgZJ}k!RBsF79h5<^%OAZa=Y&aI(@ZIiW>WU5ScVvC-dmvzyyG$FwGuHj>NO!O| zE6p6XuuR@xF@5#-3>=#reb-zW^J512P6QG(4(8SpWFo&6>!Y~8Id9Owv=+)>#(6!$ zL4Uc$pDu8?e7y+I#Svi~98(*R7CW?r+wt*WMu~R-K_;-ETn^Ekz5$9>mkCB}_FO0J zdnKadHd{pwSF!>C>m77XZA!ciK=Q#j3AQFI$ajWBYY#*>)ABbatEi#V$WlZNuR~h& F{s+fR@9+Qs From 75c5316ad779a2ac5e6b989aea03e752c8198e26 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 20 Oct 2013 17:26:09 +0200 Subject: [PATCH 083/118] added dialogue type column to topics table --- apps/opencs/model/world/columnbase.hpp | 3 ++- apps/opencs/model/world/columnimp.hpp | 27 ++++++++++++++++++++++++++ apps/opencs/model/world/columns.cpp | 7 +++++++ apps/opencs/model/world/columns.hpp | 1 + apps/opencs/model/world/data.cpp | 1 + apps/opencs/view/doc/viewmanager.cpp | 3 ++- 6 files changed, 40 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index c1b423c94..9b8d7dafb 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -43,7 +43,8 @@ namespace CSMWorld Display_CreatureType, Display_WeaponType, Display_RecordState, - Display_RefRecordType + Display_RefRecordType, + Display_DialogueType }; int mColumnId; diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index a13ac9a8a..eec0a41e2 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -1284,6 +1284,33 @@ namespace CSMWorld return true; } }; + + template + struct DialogueTypeColumn : public Column + { + DialogueTypeColumn() + : Column (Columns::ColumnId_DialogueType, ColumnBase::Display_DialogueType) + {} + + virtual QVariant get (const Record& record) const + { + return static_cast (record.get().mType); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mType = data.toInt(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return false; + } + }; } #endif diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index ca37840ad..ae4136bd9 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -159,6 +159,7 @@ namespace CSMWorld { ColumnId_DoorPositionXRot, "Teleport Rot X" }, { ColumnId_DoorPositionYRot, "Teleport Rot Y" }, { ColumnId_DoorPositionZRot, "Teleport Rot Z" }, + { ColumnId_DialogueType, "Dialogue Type" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, @@ -269,6 +270,11 @@ namespace "unknown", "none", "short", "integer", "long", "float", "string", 0 }; + static const char *sDialogueTypeEnums[] = + { + "Topic", "Voice", "Greeting", "Persuasion", 0 + }; + const char **getEnumNames (CSMWorld::Columns::ColumnId column) { switch (column) @@ -283,6 +289,7 @@ namespace case CSMWorld::Columns::ColumnId_WeaponType: return sWeaponTypes; case CSMWorld::Columns::ColumnId_Modification: return sModificationEnums; case CSMWorld::Columns::ColumnId_ValueType: return sVarTypeEnums; + case CSMWorld::Columns::ColumnId_DialogueType: return sDialogueTypeEnums; default: return 0; } diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 9b26cac4c..111931fa8 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -152,6 +152,7 @@ namespace CSMWorld ColumnId_DoorPositionXRot = 139, ColumnId_DoorPositionYRot = 140, ColumnId_DoorPositionZRot = 141, + ColumnId_DialogueType = 142, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 2af76cfa7..284e756f0 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -143,6 +143,7 @@ CSMWorld::Data::Data() : mRefs (mCells) mTopics.addColumn (new StringIdColumn); mTopics.addColumn (new RecordStateColumn); + mTopics.addColumn (new DialogueTypeColumn); mJournals.addColumn (new StringIdColumn); mJournals.addColumn (new RecordStateColumn); diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 83cd93e5d..a4849795b 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -74,7 +74,8 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) { CSMWorld::ColumnBase::Display_ArmorType, CSMWorld::Columns::ColumnId_ArmorType, false }, { CSMWorld::ColumnBase::Display_ClothingType, CSMWorld::Columns::ColumnId_ClothingType, false }, { CSMWorld::ColumnBase::Display_CreatureType, CSMWorld::Columns::ColumnId_CreatureType, false }, - { CSMWorld::ColumnBase::Display_WeaponType, CSMWorld::Columns::ColumnId_WeaponType, false } + { CSMWorld::ColumnBase::Display_WeaponType, CSMWorld::Columns::ColumnId_WeaponType, false }, + { CSMWorld::ColumnBase::Display_DialogueType, CSMWorld::Columns::ColumnId_DialogueType, false } }; for (std::size_t i=0; i Date: Mon, 21 Oct 2013 13:39:13 +0200 Subject: [PATCH 084/118] set dialogue type for newly created dialogue records --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/columnimp.hpp | 10 ++++-- apps/opencs/model/world/data.cpp | 1 + apps/opencs/view/world/dialoguecreator.cpp | 35 ++++++++++++++++++ apps/opencs/view/world/dialoguecreator.hpp | 41 ++++++++++++++++++++++ apps/opencs/view/world/subviews.cpp | 9 +++-- 6 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 apps/opencs/view/world/dialoguecreator.cpp create mode 100644 apps/opencs/view/world/dialoguecreator.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index f918cfebf..541b3b5a2 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -66,7 +66,7 @@ opencs_units (view/world opencs_units_noqt (view/world dialoguesubview subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate - scripthighlighter idvalidator + scripthighlighter idvalidator dialoguecreator ) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index eec0a41e2..23c529b3e 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -1288,8 +1288,9 @@ namespace CSMWorld template struct DialogueTypeColumn : public Column { - DialogueTypeColumn() - : Column (Columns::ColumnId_DialogueType, ColumnBase::Display_DialogueType) + DialogueTypeColumn (bool hidden = false) + : Column (Columns::ColumnId_DialogueType, ColumnBase::Display_DialogueType, + hidden ? 0 : ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue) {} virtual QVariant get (const Record& record) const @@ -1307,6 +1308,11 @@ namespace CSMWorld } virtual bool isEditable() const + { + return true; + } + + virtual bool isUserEditable() const { return false; } diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 284e756f0..70e0e891d 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -147,6 +147,7 @@ CSMWorld::Data::Data() : mRefs (mCells) mJournals.addColumn (new StringIdColumn); mJournals.addColumn (new RecordStateColumn); + mJournals.addColumn (new DialogueTypeColumn (true)); mCells.addColumn (new StringIdColumn); mCells.addColumn (new RecordStateColumn); diff --git a/apps/opencs/view/world/dialoguecreator.cpp b/apps/opencs/view/world/dialoguecreator.cpp new file mode 100644 index 000000000..c16214283 --- /dev/null +++ b/apps/opencs/view/world/dialoguecreator.cpp @@ -0,0 +1,35 @@ + +#include "dialoguecreator.hpp" + +#include + +#include "../../model/world/data.hpp" +#include "../../model/world/commands.hpp" +#include "../../model/world/columns.hpp" +#include "../../model/world/idtable.hpp" + +void CSVWorld::DialogueCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const +{ + int index = + dynamic_cast (*getData().getTableModel (getCollectionId())). + findColumnIndex (CSMWorld::Columns::ColumnId_DialogueType); + + command.addValue (index, mType); +} + +CSVWorld::DialogueCreator::DialogueCreator (CSMWorld::Data& data, QUndoStack& undoStack, + const CSMWorld::UniversalId& id, int type) +: GenericCreator (data, undoStack, id), mType (type) +{} + +CSVWorld::Creator *CSVWorld::TopicCreatorFactory::makeCreator (CSMWorld::Data& data, + QUndoStack& undoStack, const CSMWorld::UniversalId& id) const +{ + return new DialogueCreator (data, undoStack, id, ESM::Dialogue::Topic); +} + +CSVWorld::Creator *CSVWorld::JournalCreatorFactory::makeCreator (CSMWorld::Data& data, + QUndoStack& undoStack, const CSMWorld::UniversalId& id) const +{ + return new DialogueCreator (data, undoStack, id, ESM::Dialogue::Journal); +} \ No newline at end of file diff --git a/apps/opencs/view/world/dialoguecreator.hpp b/apps/opencs/view/world/dialoguecreator.hpp new file mode 100644 index 000000000..26f866909 --- /dev/null +++ b/apps/opencs/view/world/dialoguecreator.hpp @@ -0,0 +1,41 @@ +#ifndef CSV_WORLD_DIALOGUECREATOR_H +#define CSV_WORLD_DIALOGUECREATOR_H + +#include "genericcreator.hpp" + +namespace CSVWorld +{ + class DialogueCreator : public GenericCreator + { + int mType; + + protected: + + virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const; + + public: + + DialogueCreator (CSMWorld::Data& data, QUndoStack& undoStack, + const CSMWorld::UniversalId& id, int type); + }; + + class TopicCreatorFactory : public CreatorFactoryBase + { + public: + + virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack, + const CSMWorld::UniversalId& id) const; + ///< The ownership of the returned Creator is transferred to the caller. + }; + + class JournalCreatorFactory : public CreatorFactoryBase + { + public: + + virtual Creator *makeCreator (CSMWorld::Data& data, QUndoStack& undoStack, + const CSMWorld::UniversalId& id) const; + ///< The ownership of the returned Creator is transferred to the caller. + }; +} + +#endif diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 417a7258f..3d98cf73c 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -14,6 +14,7 @@ #include "referenceablecreator.hpp" #include "referencecreator.hpp" #include "scenesubview.hpp" +#include "dialoguecreator.hpp" void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) { @@ -36,8 +37,6 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Regions, CSMWorld::UniversalId::Type_Birthsigns, CSMWorld::UniversalId::Type_Spells, - CSMWorld::UniversalId::Type_Topics, - CSMWorld::UniversalId::Type_Journals, CSMWorld::UniversalId::Type_None // end marker }; @@ -55,6 +54,12 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add (CSMWorld::UniversalId::Type_References, new CSVDoc::SubViewFactoryWithCreator >); + manager.add (CSMWorld::UniversalId::Type_Topics, + new CSVDoc::SubViewFactoryWithCreator); + + manager.add (CSMWorld::UniversalId::Type_Journal, + new CSVDoc::SubViewFactoryWithCreator); + // Subviews for editing/viewing individual records manager.add (CSMWorld::UniversalId::Type_Script, new CSVDoc::SubViewFactory); From c0e550143108e81ffcb6ee896e1ea0dfaeffaff8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 21 Oct 2013 13:58:47 +0200 Subject: [PATCH 085/118] disallow the deletion of non-topic, non-journal dialogue records --- apps/opencs/view/world/table.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 6167c084a..a58eb873f 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -87,19 +87,33 @@ std::vector CSVWorld::Table::listDeletableSelectedIds() const { QModelIndex index = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0)); + // check record state CSMWorld::RecordBase::State state = static_cast ( mModel->data (mModel->index (index.row(), 1)).toInt()); - if (state!=CSMWorld::RecordBase::State_Deleted) - { - int columnIndex = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id); + if (state==CSMWorld::RecordBase::State_Deleted) + continue; - std::string id = mModel->data (mModel->index (index.row(), columnIndex)). - toString().toUtf8().constData(); + // check other columns (only relevant for a subset of the tables) + int dialogueTypeIndex = + mModel->searchColumnIndex (CSMWorld::Columns::ColumnId_DialogueType); - deletableIds.push_back (id); + if (dialogueTypeIndex!=-1) + { + int type = mModel->data (mModel->index (index.row(), dialogueTypeIndex)).toInt(); + + if (type!=ESM::Dialogue::Topic && type!=ESM::Dialogue::Journal) + continue; } + + // add the id to the collection + int columnIndex = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id); + + std::string id = mModel->data (mModel->index (index.row(), columnIndex)). + toString().toUtf8().constData(); + + deletableIds.push_back (id); } } From dc12648a3efd8da82e148d2610536753434eff73 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 21 Oct 2013 14:26:54 +0200 Subject: [PATCH 086/118] add fixed dialogue records when creating a new omwgame file --- apps/opencs/model/doc/document.cpp | 73 ++++++++++++++++++++++++++++++ apps/opencs/model/world/data.cpp | 6 +-- apps/opencs/model/world/data.hpp | 4 +- 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index d7138f671..64f627b5a 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2137,6 +2137,79 @@ void CSMDoc::Document::createBase() getData().getSkills().add (record); } + + static const char *sVoice[] = + { + "Intruder", + "Attack", + "Hello", + "Thief", + "Alarm", + "Idle", + "Flee", + "Hit", + 0 + }; + + for (int i=0; sVoice[i]; ++i) + { + ESM::Dialogue record; + record.mId = sVoice[i]; + record.mType = ESM::Dialogue::Voice; + record.blank(); + + getData().getTopics().add (record); + } + + static const char *sGreetings[] = + { + "Greeting 0", + "Greeting 1", + "Greeting 2", + "Greeting 3", + "Greeting 4", + "Greeting 5", + "Greeting 6", + "Greeting 7", + "Greeting 8", + "Greeting 9", + 0 + }; + + for (int i=0; sGreetings[i]; ++i) + { + ESM::Dialogue record; + record.mId = sGreetings[i]; + record.mType = ESM::Dialogue::Greeting; + record.blank(); + + getData().getTopics().add (record); + } + + static const char *sPersuasion[] = + { + "Intimidate Success", + "Intimidate Fail", + "Service Refusal", + "Admire Success", + "Taunt Success", + "Bribe Success", + "Info Refusal", + "Admire Fail", + "Taunt Fail", + "Bribe Fail", + 0 + }; + + for (int i=0; sPersuasion[i]; ++i) + { + ESM::Dialogue record; + record.mId = sPersuasion[i]; + record.mType = ESM::Dialogue::Persuasion; + record.blank(); + + getData().getTopics().add (record); + } } CSMDoc::Document::Document (const std::vector& files, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 70e0e891d..c854711b1 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -330,12 +330,12 @@ CSMWorld::IdCollection& CSMWorld::Data::getSpells() } -const CSMWorld::IdCollection& CSMWorld::Data::getTopcis() const +const CSMWorld::IdCollection& CSMWorld::Data::getTopics() const { return mTopics; } -CSMWorld::IdCollection& CSMWorld::Data::getTopcis() +CSMWorld::IdCollection& CSMWorld::Data::getTopics() { return mTopics; } @@ -525,7 +525,7 @@ bool CSMWorld::Data::hasId (const std::string& id) const getRegions().searchId (id)!=-1 || getBirthsigns().searchId (id)!=-1 || getSpells().searchId (id)!=-1 || - getTopcis().searchId (id)!=-1 || + getTopics().searchId (id)!=-1 || getJournals().searchId (id)!=-1 || getCells().searchId (id)!=-1 || getReferenceables().searchId (id)!=-1; diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 74304e029..cf31c9494 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -119,9 +119,9 @@ namespace CSMWorld IdCollection& getSpells(); - const IdCollection& getTopcis() const; + const IdCollection& getTopics() const; - IdCollection& getTopcis(); + IdCollection& getTopics(); const IdCollection& getJournals() const; From 3b85d970872afc58954c1f5b9e3ec2951b5a2fb5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 21 Oct 2013 15:38:13 +0200 Subject: [PATCH 087/118] handle deleted dialogue records --- apps/opencs/model/world/data.cpp | 13 +++++++++- apps/opencs/model/world/idcollection.hpp | 32 +++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index c854711b1..130ce334f 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -493,7 +493,18 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) } else if (record.mType==ESM::Dialogue::Deleted) { - /// \todo handle deleted records + if (mJournals.tryDelete (id)) + { + /// \todo handle info records + } + else if (mTopics.tryDelete (id)) + { + /// \todo handle info records + } + else + { + /// \todo report deletion of non-existing record + } } else { diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index b6ae04572..0d723bef1 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -7,7 +7,6 @@ namespace CSMWorld { - /// \brief Single type collection of top level records template > class IdCollection : public Collection @@ -17,6 +16,11 @@ namespace CSMWorld void load (ESM::ESMReader& reader, bool base); void load (const ESXRecordT& record, bool base); + + bool tryDelete (const std::string& id); + ///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored. + /// + /// \return Has the ID been deleted? }; template @@ -86,6 +90,32 @@ namespace CSMWorld this->setRecord (index, record2); } } + + template + bool IdCollection::tryDelete (const std::string& id) + { + int index = this->searchId (id); + + if (index==-1) + return false; + + Record record = Collection::getRecord (index); + + if (record.isDeleted()) + return false; + + if (record.mState==RecordBase::State_ModifiedOnly) + { + Collection::removeRows (index, 1); + } + else + { + record.mState = RecordBase::State_Deleted; + setRecord (index, record); + } + + return true; + } } #endif From b23df42817a0ed45a460e2680b98d02b2e19ab1d Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 21 Oct 2013 16:06:16 +0200 Subject: [PATCH 088/118] Removed old comment. Changed to set resources path correctly. --- apps/opencs/editor.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 9abc9ee78..94faa713b 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -89,8 +89,7 @@ void CS::Editor::setupDataFiles() dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end()); -// Adding Resources directory. First check if there is a file defaultfilters in the user path. - mDocumentManager.setResourceDir(variables["resources"].as()); + mDocumentManager.setResourceDir(mCfgMgr.getGlobalDataPath()); for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) { From 743c6ea5b1bf1f10b6c429da6523f54d99c3eb0b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 21 Oct 2013 16:47:32 +0200 Subject: [PATCH 089/118] save dialogue records --- apps/opencs/model/doc/saving.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index 2b0056e72..b756a9dc1 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -58,6 +58,13 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje appendStage (new WriteCollectionStage > (mDocument.getData().getSpells(), mState)); + /// \todo deal with info records for topcis and journals + appendStage (new WriteCollectionStage > + (mDocument.getData().getTopics(), mState)); + + appendStage (new WriteCollectionStage > + (mDocument.getData().getJournals(), mState)); + appendStage (new WriteRefIdCollectionStage (mDocument, mState)); From 5e1bdd605b37e808e4785074cc675c9f8ca680d6 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 21 Oct 2013 18:15:26 +0200 Subject: [PATCH 090/118] Corrected formatting in document.hpp --- apps/opencs/model/doc/document.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index e6d1b0c87..fb929cca6 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -43,7 +43,7 @@ namespace CSMDoc CSMTools::Tools mTools; boost::filesystem::path mProjectPath; Saving mSaving; - boost::filesystem::path mResDir; + boost::filesystem::path mResDir; // It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is // using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late. @@ -119,3 +119,4 @@ namespace CSMDoc } #endif + From 70602c2c36b74164112f2b5118ac620b08488db5 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 21 Oct 2013 18:24:16 +0200 Subject: [PATCH 091/118] Removed changes in the unimplemented copy ctor. --- apps/opencs/model/doc/document.cpp | 2 +- apps/opencs/model/doc/document.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index fd2b32861..b56460a03 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2182,7 +2182,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, co else { boost::filesystem::path locCustomFiltersPath (configuration.getUserPath()); - locCustomFiltersPath /= "customfilters.omwaddon.project"; + locCustomFiltersPath /= "defaultfilters"; if (boost::filesystem::exists(locCustomFiltersPath)) { boost::filesystem::copy(locCustomFiltersPath, mProjectPath); diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index fb929cca6..437b0c513 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -50,7 +50,7 @@ namespace CSMDoc QUndoStack mUndoStack; // not implemented - Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, const boost::filesystem::path& savePath, bool new_); + Document (const Document&); Document& operator= (const Document&); void load (const std::vector::const_iterator& begin, From ce2c5582573118e19677690e2738d1913306db5d Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 21 Oct 2013 18:40:20 +0200 Subject: [PATCH 092/118] Missed a file. --- files/opencs/defaultfilters | Bin 0 -> 10958 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 files/opencs/defaultfilters diff --git a/files/opencs/defaultfilters b/files/opencs/defaultfilters new file mode 100644 index 0000000000000000000000000000000000000000..0ac3c8db4bd939b8b9d559ab4af4056fc0b8d80e GIT binary patch literal 10958 zcmeHN%Woq|8K1rKelD=EP-|WeWJm14g%PlFGMPzGW;VoO2Ux9E<#yR_((bmp+sOoh z7~Vo0RveI!K)?k!z=a!s04M$`zDIr4Rn=`fBj<=Oj=R75e!u!&RrOWQ4u)U;%5%5e z=kVa(=`Q@9O#b$&d-(r9)>`2H(ec@LJ&8wyhX?P6-;1*NzDer4cQ1`z6nS+E1wRQd zs=7?`X}@=BlA;`|v#W*a?JAbqxpnVgxc>o=8qSJKrL)YwsBY8v*CU|!`9Qjy7bWAo zxDtni7zSB77#_?h--}Q_;-e%c%PRAvHf36rL<(Q$MXl__PR%qe@?F*IG0ca27#X-? zK5e8l_mDmas;+|~gDgr8!{meR`8fP=?g{2I(dUNdi`^0Mc^JLDPh#Vz-#%m z=4?Zi&wVI$#mh$o>b zf>SjFeHhvQ6teJ*d_Mu-&PSGSR^(F}|H_Ok^$=vXA$$z_T716R%A6bwtZo|VOAP7!i{OSWgEN<#Ss;mQaBSB`{VM)a`u#Zf#e zE{WUzmfZG=OCjcJ0qE{v^@oVn^Bt^o2}UDc2V3$QpeA9~2W9A9Sj+G+lhgD0GEZw* zB~*V>lnPi^HkE!CQTF(7!A@Hnk4cf&I?W+^DUDXgqZ90iNB7PixBda-~{rTVt;EWmHIB=5h4H+&;?JO;W5cQ93&`{aku zMBY0o_cl)8OQ4$aJ}>f@yC#v$OjTFAYFXx$GIer$haCAE7$+Z`N7yGwTmc$@ke{Dn z#6CLNUm49wX&^64V*|1Wiu?iv6;AbGJWvzKim9ClFZf1kc&2wIhSCNj^94r*22OW* zL}ujScYp}tA{I?u!xQ#z^fnsNlo|>z1|8hJ&KmXNAl5P>*=*T|$qvGn4;DOu~dAe=YPf8<*0=d;$Zu z_t%NlxzWarU~FSYYlV%UMlnTMoE?Cdgw_1nz&X~ZXJUXcDO zS*E3~xMW;6SGxmwpEb1@Sp@d|H5kF}M_-tmVDx}BwHR3hX7pxcBixO;YMR*H+J?F< zn>sG3xWG`A!fv`~=$?KMAR;<4_9VaIC@1oM1rjE%fbM}ZF+h`y@X&_H&!g!FAtDG1 z+_8`ijzD}(D$0Phlul4vixXk6m3|g+>a-G+Ebb!T1SN2nX;VUo6`9mY39nhmN;l!S zQ#vGYL^;PHf@Sop$Vfq7K>VQROIY=Y(>HIxa|2Q*u6s9VNoNJI@QwwDM+OUm!Kngc5$|7c$WM@_8!>(Ri%6Ttqc@0!}YM##EL@>Xqiy~uO><~n_u3^$NRcNN}_JEb7iOv)$V%*Jbqd+>s7H+3zp;I_QkX78ap`@q2MZOgQz88MGJxUE%-0Xsm%YH$EO*zbv zaNJ@-1KH%ijsSug&Gi%-deG;Gdw5z(R-F$*uwCV6*g>Aa6=pq$wiY(x#M)S6$l8YA z^Pv-wnAlZBEQp27TtF8LdS$hlGqYU~k8FKryLLw)q>k+fb(~gE49OnuQeD)k3|>~M zm?%=rMB<7a^q6F%JE)VHu$K~%5ex0xW=1C=*V+)Z4Iu~6?Y7_!+qE`KRe{x0oe`^7 zfz_I-9kyT&WGMQK8(oU6=1PatUMXm!ShxK+a$9)Blb*}O%yq^afv-IatNS#rMalJ% zS+7UuBBB#?OwP>}2hWD%&#I>DQKdjd!-nnSb|R>ry)}tg1hE`wCr5o2#G~-Bu^h-U zoSQqoyX^<=(+D+K)$RQeWw?!xyC4to;Tp!_lEnj>YHCN?e^QA;!@dmv@8U-hpTG*1 zPnBjD_McO}`b>0qV8F)RWbnI?%+rWWU>uh~RR#yrwUy60CQP1YQ$Y&s&mEgUZU;jz zZHW9Z;u9Fh@o`!6bv90O-4Qw~q|;>0M8iK+^@NCPGoo5AX|P2uA8e}yi;f<{f1{8| zu;xgZJ}k!RBsF79h5<^%OAZa=Y&aI(@ZIiW>WU5ScVvC-dmvzyyG$FwGuHj>NO!O| zE6p6XuuR@xF@5#-3>=#reb-zW^J512P6QG(4(8SpWFo&6>!Y~8Id9Owv=+)>#(6!$ zL4Uc$pDu8?e7y+I#Svi~98(*R7CW?r+wt*WMu~R-K_;-ETn^Ekz5$9>mkCB}_FO0J zdnKadHd{pwSF!>C>m77XZA!ciK=Q#j3AQFI$ajWBYY#*>)ABbatEi#V$WlZNuR~h& F{s+fR@9+Qs literal 0 HcmV?d00001 From 3146af34d642a28b15b55f7eb9999d8ac50168a0 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 21 Oct 2013 19:28:57 +0200 Subject: [PATCH 093/118] some fixes for the merged filter branch --- apps/opencs/editor.cpp | 2 +- apps/opencs/model/doc/document.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 94faa713b..a05b515d3 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -89,7 +89,7 @@ void CS::Editor::setupDataFiles() dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end()); - mDocumentManager.setResourceDir(mCfgMgr.getGlobalDataPath()); + mDocumentManager.setResourceDir (variables["resources"].as()); for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) { diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 34bdc056f..cc886f9cc 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2258,7 +2258,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, co locCustomFiltersPath /= "defaultfilters"; if (boost::filesystem::exists(locCustomFiltersPath)) { - boost::filesystem::copy(locCustomFiltersPath, mProjectPath); + boost::filesystem::copy_file (locCustomFiltersPath, mProjectPath); } else { boost::filesystem::path filters(mResDir); filters /= "defaultfilters"; From f9591ddda61fec57783514e4b2bd860b86e39f09 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 22 Oct 2013 21:52:35 -0500 Subject: [PATCH 094/118] Reimplemented constentselector view class --- apps/launcher/CMakeLists.txt | 11 + apps/launcher/datafilespage.cpp | 201 +++++++++---- apps/launcher/datafilespage.hpp | 33 ++- apps/launcher/maindialog.cpp | 2 +- .../launcher/utils/lineedit.cpp | 20 +- .../view => apps/launcher/utils}/lineedit.hpp | 33 ++- .../launcher/utils}/profilescombobox.cpp | 41 +-- apps/launcher/utils/profilescombobox.hpp | 40 +++ .../launcher/utils}/textinputdialog.cpp | 17 +- .../launcher/utils}/textinputdialog.hpp | 17 +- apps/opencs/CMakeLists.txt | 9 +- apps/opencs/editor.cpp | 6 +- .../opencs/view/doc}/adjusterwidget.cpp | 0 .../opencs/view/doc}/adjusterwidget.hpp | 0 apps/opencs/view/doc/filedialog.cpp | 109 ++++--- apps/opencs/view/doc/filedialog.hpp | 44 +-- .../opencs/view/doc}/filewidget.cpp | 0 .../opencs/view/doc}/filewidget.hpp | 0 apps/opencs/view/doc/newgame.cpp | 4 +- components/CMakeLists.txt | 8 +- .../contentselector/model/contentmodel.cpp | 10 + components/contentselector/view/combobox.cpp | 39 +++ components/contentselector/view/combobox.hpp | 30 ++ .../contentselector/view/comboboxlineedit.hpp | 37 --- .../contentselector/view/contentselector.cpp | 279 +----------------- .../contentselector/view/contentselector.hpp | 72 +---- components/contentselector/view/lineedit.cpp | 39 --- .../contentselector/view/profilescombobox.hpp | 42 --- files/ui/contentselector.ui | 111 +++++++ files/ui/datafilespage.ui | 203 +------------ files/ui/filedialog.ui | 73 +++++ 31 files changed, 692 insertions(+), 838 deletions(-) rename components/contentselector/view/comboboxlineedit.cpp => apps/launcher/utils/lineedit.cpp (58%) rename {components/contentselector/view => apps/launcher/utils}/lineedit.hpp (54%) rename {components/contentselector/view => apps/launcher/utils}/profilescombobox.cpp (60%) create mode 100644 apps/launcher/utils/profilescombobox.hpp rename {components/contentselector/view => apps/launcher/utils}/textinputdialog.cpp (77%) rename {components/contentselector/view => apps/launcher/utils}/textinputdialog.hpp (66%) rename {components/contentselector/view => apps/opencs/view/doc}/adjusterwidget.cpp (100%) rename {components/contentselector/view => apps/opencs/view/doc}/adjusterwidget.hpp (100%) rename {components/contentselector/view => apps/opencs/view/doc}/filewidget.cpp (100%) rename {components/contentselector/view => apps/opencs/view/doc}/filewidget.hpp (100%) create mode 100644 components/contentselector/view/combobox.cpp create mode 100644 components/contentselector/view/combobox.hpp delete mode 100644 components/contentselector/view/comboboxlineedit.hpp delete mode 100644 components/contentselector/view/lineedit.cpp delete mode 100644 components/contentselector/view/profilescombobox.hpp create mode 100644 files/ui/contentselector.ui create mode 100644 files/ui/filedialog.ui diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 49dedd829..18c555a24 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -11,6 +11,9 @@ set(LAUNCHER settings/launchersettings.cpp utils/checkablemessagebox.cpp + utils/profilescombobox.cpp + utils/textinputdialog.cpp + utils/lineedit.cpp ${CMAKE_SOURCE_DIR}/files/launcher/launcher.rc ) @@ -31,6 +34,9 @@ set(LAUNCHER_HEADER settings/settingsbase.hpp utils/checkablemessagebox.hpp + utils/profilescombobox.hpp + utils/textinputdialog.hpp + utils/lineedit.hpp ) if(NOT WIN32) LIST(APPEND LAUNCHER_HEADER unshieldthread.hpp) @@ -45,7 +51,11 @@ set(LAUNCHER_HEADER_MOC playpage.hpp textslotmsgbox.hpp + utils/textinputdialog.hpp utils/checkablemessagebox.hpp + utils/profilescombobox.hpp + utils/lineedit.hpp + ) if(NOT WIN32) @@ -58,6 +68,7 @@ set(LAUNCHER_UI ${CMAKE_SOURCE_DIR}/files/ui/graphicspage.ui ${CMAKE_SOURCE_DIR}/files/ui/mainwindow.ui ${CMAKE_SOURCE_DIR}/files/ui/playpage.ui + ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui ) source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER}) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index a705ae37d..2140caaf9 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -5,14 +5,16 @@ #include #include #include +#include #include #include -#include #include -#include + +#include "utils/textinputdialog.hpp" +#include "utils/profilescombobox.hpp" #include "settings/gamesettings.hpp" #include "settings/launchersettings.hpp" @@ -25,45 +27,30 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam , mLauncherSettings(launcherSettings) , QWidget(parent) { - setObjectName ("DataFilesPage"); - - unsigned char flags; + ui.setupUi (this); - flags = ContentSelectorView::Flag_Content | ContentSelectorView::Flag_Profile; - - ContentSelectorView::ContentSelector::configure(this, flags); - mSelector = &ContentSelectorView::ContentSelector::instance(); + setObjectName ("DataFilesPage"); + mSelector = new ContentSelectorView::ContentSelector (ui.contentSelectorWidget); + buildView(); setupDataFiles(); - - - connect (mSelector, SIGNAL (signalProfileRenamed (QString, QString)), - this, SLOT (slotProfileRenamed (QString, QString))); - - connect (mSelector, SIGNAL (signalProfileChangedByUser (QString, QString)), - this, SLOT (slotProfileChangedByUser (QString, QString))); - - connect (mSelector, SIGNAL (signalProfileDeleted (QString)), - this, SLOT (slotProfileDeleted (QString))); - - connect (mSelector, SIGNAL (signalAddNewProfile (QString)), - this, SLOT (slotAddNewProfile (QString))); } void DataFilesPage::loadSettings() { - QString profileName = mSelector->getProfileText(); + QString profileName = ui.profilesComboBox->currentText(); QStringList files = mLauncherSettings.values(QString("Profiles/") + profileName + QString("/game"), Qt::MatchExactly); QStringList addons = mLauncherSettings.values(QString("Profiles/") + profileName + QString("/addon"), Qt::MatchExactly); mSelector->clearCheckStates(); - if (files.size() > 0) - mSelector->setGameFile(files.at(0)); - else - mSelector->setGameFile(); + QString gameFile (""); + if (files.size()>0) + gameFile = files.at (0); + + mSelector->setGameFile(gameFile); mSelector->setCheckStates(addons); } @@ -72,7 +59,7 @@ void DataFilesPage::saveSettings(const QString &profile) QString profileName = profile; if (profileName.isEmpty()) - profileName = mSelector->getProfileText(); + profileName = ui.profilesComboBox->currentText(); //retrieve the files selected for the profile ContentSelectorModel::ContentFileList items = mSelector->selectedFiles(); @@ -83,7 +70,7 @@ void DataFilesPage::saveSettings(const QString &profile) mGameSettings.remove(QString("addon")); //set the value of the current profile (not necessarily the profile being saved!) - mLauncherSettings.setValue(QString("Profiles/currentprofile"), mSelector->getProfileText()); + mLauncherSettings.setValue(QString("Profiles/currentprofile"), ui.profilesComboBox->currentText()); foreach(const ContentSelectorModel::EsmFile *item, items) { @@ -98,39 +85,64 @@ void DataFilesPage::saveSettings(const QString &profile) } +void DataFilesPage::buildView() +{ + ui.verticalLayout->insertWidget (0, mSelector->uiWidget()); + + //tool buttons + ui.newProfileButton->setToolTip ("Create a new profile"); + ui.deleteProfileButton->setToolTip ("Delete an existing profile"); + + //combo box + ui.profilesComboBox->addItem ("Default"); + ui.profilesComboBox->setPlaceholderText (QString("Select a profile...")); + + // Add the actions to the toolbuttons + ui.newProfileButton->setDefaultAction (ui.newProfileAction); + ui.deleteProfileButton->setDefaultAction (ui.deleteProfileAction); + + //establish connections + connect (ui.profilesComboBox, SIGNAL (currentIndexChanged(int)), + this, SLOT (slotProfileChanged(int))); + + connect (ui.profilesComboBox, SIGNAL (profileRenamed(QString, QString)), + this, SLOT (slotProfileRenamed(QString, QString))); + + connect (ui.profilesComboBox, SIGNAL (signalProfileChanged(QString, QString)), + this, SLOT (slotProfileChangedByUser(QString, QString))); +} + void DataFilesPage::removeProfile(const QString &profile) { mLauncherSettings.remove(QString("Profiles/") + profile + QString("/game")); mLauncherSettings.remove(QString("Profiles/") + profile + QString("/addon")); } -void DataFilesPage::changeProfiles(const QString &previous, const QString ¤t, bool savePrevious) +void DataFilesPage::setProfile(int index, bool savePrevious) { - //abort if no change (typically a duplicate signal) - if (previous == current) - return; + if (index >= -1 && index < ui.profilesComboBox->count()) + { + QString previous = ui.profilesComboBox->itemText(ui.profilesComboBox->currentIndex()); + QString current = ui.profilesComboBox->itemText(index); - int index = -1; + setProfile (previous, current, savePrevious); + } +} - if (!previous.isEmpty()) - index = mSelector->getProfileIndex(previous); +void DataFilesPage::setProfile (const QString &previous, const QString ¤t, bool savePrevious) +{ + //abort if no change (poss. duplicate signal) + if (previous == current) + return; - // Store the previous profile if it exists - if ( (index != -1) && savePrevious) - saveSettings(previous); + if (!previous.isEmpty() && savePrevious) + saveSettings (previous); - loadSettings(); -} + ui.profilesComboBox->setCurrentIndex (ui.profilesComboBox->findText (current)); -void DataFilesPage::slotAddNewProfile(const QString &profile) -{ - saveSettings(); - mSelector->clearCheckStates(); - mSelector->addProfile(profile, true); - mSelector->setGameFile(); - saveSettings(); + loadSettings(); - emit signalProfileChanged(mSelector->getProfileIndex(profile)); + checkForDefaultProfile(); } void DataFilesPage::slotProfileDeleted (const QString &item) @@ -140,8 +152,8 @@ void DataFilesPage::slotProfileDeleted (const QString &item) void DataFilesPage::slotProfileChangedByUser(const QString &previous, const QString ¤t) { - changeProfiles(previous, current); - emit signalProfileChanged(mSelector->getProfileIndex(current)); + setProfile(previous, current, true); + emit signalProfileChanged (ui.profilesComboBox->findText(current)); } void DataFilesPage::slotProfileRenamed(const QString &previous, const QString ¤t) @@ -160,7 +172,7 @@ void DataFilesPage::slotProfileRenamed(const QString &previous, const QString &c void DataFilesPage::slotProfileChanged(int index) { - mSelector->setProfile(index); + setProfile (index, true); } void DataFilesPage::setupDataFiles() @@ -178,21 +190,92 @@ void DataFilesPage::setupDataFiles() QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/")); QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); - foreach (const QString &item, profiles) - mSelector->addProfile (item); + addProfile (item, false); - mSelector->addProfile (profile, true); + addProfile (profile, true); loadSettings(); } -QAbstractItemModel *DataFilesPage::profilesModel() const +void DataFilesPage::on_newProfileAction_triggered() { - return mSelector->profilesModel(); + TextInputDialog newDialog (tr("New Profile"), tr("Profile name:"), this); + + if (newDialog.exec() != QDialog::Accepted) + return; + + QString profile = newDialog.getText(); + + if (profile.isEmpty()) + return; + + saveSettings(); + + mSelector->clearCheckStates(); + + addProfile(profile, true); + + mSelector->setGameFile(); + + saveSettings(); + + emit signalProfileChanged (ui.profilesComboBox->findText(profile)); +} + +void DataFilesPage::addProfile (const QString &profile, bool setAsCurrent) +{ + if (profile.isEmpty()) + return; + + if (ui.profilesComboBox->findText (profile) != -1) + return; + + ui.profilesComboBox->addItem (profile); + + if (setAsCurrent) + setProfile (ui.profilesComboBox->findText (profile), false); } -int DataFilesPage::profilesIndex() const +void DataFilesPage::on_deleteProfileAction_triggered() { - return mSelector->getProfileIndex(mSelector->getProfileText()); + QString profile = ui.profilesComboBox->currentText(); + + if (profile.isEmpty()) + return; + + if (!showDeleteMessageBox (profile)) + return; + + // Remove the profile from the combobox + ui.profilesComboBox->removeItem (ui.profilesComboBox->findText (profile)); + + loadSettings(); + + checkForDefaultProfile(); +} + +void DataFilesPage::checkForDefaultProfile() +{ + //don't allow deleting "Default" profile + bool success = (ui.profilesComboBox->currentText() != "Default"); + + ui.deleteProfileAction->setEnabled (success); + ui.profilesComboBox->setEditEnabled (success); +} + +bool DataFilesPage::showDeleteMessageBox (const QString &text) +{ + QMessageBox msgBox(this); + msgBox.setWindowTitle(tr("Delete Profile")); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setStandardButtons(QMessageBox::Cancel); + msgBox.setText(tr("Are you sure you want to delete %0?").arg(text)); + + QAbstractButton *deleteButton = + msgBox.addButton(tr("Delete"), QMessageBox::ActionRole); + + msgBox.exec(); + + return (msgBox.clickedButton() == deleteButton); } diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index 47e28493d..cc054a4e4 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -1,6 +1,7 @@ #ifndef DATAFILESPAGE_H #define DATAFILESPAGE_H +#include "ui_datafilespage.h" #include #include @@ -12,7 +13,7 @@ class QMenu; class TextInputDialog; class GameSettings; class LauncherSettings; - +class ProfilesComboBox; namespace Files { struct ConfigurationManager; } namespace ContentSelectorView { class ContentSelector; } @@ -22,32 +23,37 @@ class DataFilesPage : public QWidget Q_OBJECT ContentSelectorView::ContentSelector *mSelector; + Ui::DataFilesPage ui; public: - DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent = 0); + explicit DataFilesPage (Files::ConfigurationManager &cfg, GameSettings &gameSettings, + LauncherSettings &launcherSettings, QWidget *parent = 0); + + QAbstractItemModel* profilesModel() const + { return ui.profilesComboBox->model(); } - QAbstractItemModel* profilesModel() const; - int profilesIndex() const; + int profilesIndex() const + { return ui.profilesComboBox->currentIndex(); } - void writeConfig(QString profile = QString()); + //void writeConfig(QString profile = QString()); void saveSettings(const QString &profile = ""); void loadSettings(); signals: - void signalProfileChanged(int index); + void signalProfileChanged (int index); public slots: - //void showContextMenu(const QPoint &point); - + void slotProfileChanged (int index); private slots: - void slotAddNewProfile(const QString &profile); void slotProfileChangedByUser(const QString &previous, const QString ¤t); - void slotProfileChanged(int); void slotProfileRenamed(const QString &previous, const QString ¤t); void slotProfileDeleted(const QString &item); + void on_newProfileAction_triggered(); + void on_deleteProfileAction_triggered(); + private: QMenu *mContextMenu; @@ -59,11 +65,16 @@ private: void setPluginsCheckstates(Qt::CheckState state); + void buildView(); void setupDataFiles(); void setupConfig(); void readConfig(); + void setProfile (int index, bool savePrevious); + void setProfile (const QString &previous, const QString ¤t, bool savePrevious); void removeProfile (const QString &profile); - void changeProfiles(const QString &previous, const QString ¤t, bool savePrevious = true); + bool showDeleteMessageBox (const QString &text); + void addProfile (const QString &profile, bool setAsCurrent); + void checkForDefaultProfile(); }; #endif diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index fe9ca141e..e514755fe 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -485,7 +485,7 @@ bool MainDialog::setupGameSettings() foreach (const QString path, mGameSettings.getDataDirs()) { QDir dir(path); QStringList filters; - filters << "*.esp" << "*.esm"; + filters << "*.esp" << "*.esm" << "*.omwgame" << "*.omwaddon"; if (!dir.entryList(filters).isEmpty()) dataDirs.append(path); diff --git a/components/contentselector/view/comboboxlineedit.cpp b/apps/launcher/utils/lineedit.cpp similarity index 58% rename from components/contentselector/view/comboboxlineedit.cpp rename to apps/launcher/utils/lineedit.cpp index df647a4a0..348707580 100644 --- a/components/contentselector/view/comboboxlineedit.cpp +++ b/apps/launcher/utils/lineedit.cpp @@ -1,10 +1,12 @@ -#include -#include +#include "lineedit.hpp" -#include "comboboxlineedit.hpp" - -ContentSelectorView::ComboBoxLineEdit::ComboBoxLineEdit(QWidget *parent) +LineEdit::LineEdit(QWidget *parent) : QLineEdit(parent) +{ + setupClearButton(); +} + +void LineEdit::setupClearButton() { mClearButton = new QToolButton(this); QPixmap pixmap(":images/clear.png"); @@ -15,13 +17,9 @@ ContentSelectorView::ComboBoxLineEdit::ComboBoxLineEdit(QWidget *parent) mClearButton->hide(); connect(mClearButton, SIGNAL(clicked()), this, SLOT(clear())); connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateClearButton(const QString&))); - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - - setObjectName(QString("ComboBoxLineEdit")); - setStyleSheet(QString("ComboBoxLineEdit { background-color: transparent; padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1)); } -void ContentSelectorView::ComboBoxLineEdit::resizeEvent(QResizeEvent *) +void LineEdit::resizeEvent(QResizeEvent *) { QSize sz = mClearButton->sizeHint(); int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); @@ -29,7 +27,7 @@ void ContentSelectorView::ComboBoxLineEdit::resizeEvent(QResizeEvent *) (rect().bottom() + 1 - sz.height())/2); } -void ContentSelectorView::ComboBoxLineEdit::updateClearButton(const QString& text) +void LineEdit::updateClearButton(const QString& text) { mClearButton->setVisible(!text.isEmpty()); } diff --git a/components/contentselector/view/lineedit.hpp b/apps/launcher/utils/lineedit.hpp similarity index 54% rename from components/contentselector/view/lineedit.hpp rename to apps/launcher/utils/lineedit.hpp index ab1c37203..2dd7da32b 100644 --- a/components/contentselector/view/lineedit.hpp +++ b/apps/launcher/utils/lineedit.hpp @@ -11,29 +11,32 @@ #define LINEEDIT_H #include +#include +#include +#include class QToolButton; -namespace ContentSelectorView +class LineEdit : public QLineEdit { - class LineEdit : public QLineEdit - { - Q_OBJECT + Q_OBJECT - QString mPlaceholderText; + QString mPlaceholderText; - public: - LineEdit(QWidget *parent = 0); +public: + LineEdit(QWidget *parent = 0); - protected: - void resizeEvent(QResizeEvent *); +protected: + void resizeEvent(QResizeEvent *); - private slots: - void updateClearButton(const QString &text); +private slots: + void updateClearButton(const QString &text); + +protected: + QToolButton *mClearButton; + + void setupClearButton(); +}; - private: - QToolButton *mClearButton; - }; -} #endif // LIENEDIT_H diff --git a/components/contentselector/view/profilescombobox.cpp b/apps/launcher/utils/profilescombobox.cpp similarity index 60% rename from components/contentselector/view/profilescombobox.cpp rename to apps/launcher/utils/profilescombobox.cpp index 0e9905df4..c14330724 100644 --- a/components/contentselector/view/profilescombobox.cpp +++ b/apps/launcher/utils/profilescombobox.cpp @@ -5,23 +5,17 @@ #include #include "profilescombobox.hpp" -#include "comboboxlineedit.hpp" -ContentSelectorView::ProfilesComboBox::ProfilesComboBox(QWidget *parent) : - QComboBox(parent) +ProfilesComboBox::ProfilesComboBox(QWidget *parent) : + ContentSelectorView::ComboBox(parent) { - mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore - setEditEnabled(true); - setValidator(mValidator); - setCompleter(0); - connect(this, SIGNAL(activated(int)), this, SLOT(slotIndexChangedByUser(int))); setInsertPolicy(QComboBox::NoInsert); } -void ContentSelectorView::ProfilesComboBox::setEditEnabled(bool editable) +void ProfilesComboBox::setEditEnabled(bool editable) { if (isEditable() == editable) return; @@ -37,6 +31,7 @@ void ContentSelectorView::ProfilesComboBox::setEditEnabled(bool editable) setValidator(mValidator); ComboBoxLineEdit *edit = new ComboBoxLineEdit(this); + setLineEdit(edit); setCompleter(0); @@ -50,7 +45,7 @@ void ContentSelectorView::ProfilesComboBox::setEditEnabled(bool editable) SIGNAL (signalProfileTextChanged (QString))); } -void ContentSelectorView::ProfilesComboBox::slotTextChanged(const QString &text) +void ProfilesComboBox::slotTextChanged(const QString &text) { QPalette *palette = new QPalette(); palette->setColor(QPalette::Text,Qt::red); @@ -64,7 +59,7 @@ void ContentSelectorView::ProfilesComboBox::slotTextChanged(const QString &text) } } -void ContentSelectorView::ProfilesComboBox::slotEditingFinished() +void ProfilesComboBox::slotEditingFinished() { QString current = currentText(); QString previous = itemText(currentIndex()); @@ -85,7 +80,7 @@ void ContentSelectorView::ProfilesComboBox::slotEditingFinished() emit(profileRenamed(previous, current)); } -void ContentSelectorView::ProfilesComboBox::slotIndexChangedByUser(int index) +void ProfilesComboBox::slotIndexChangedByUser(int index) { if (index == -1) return; @@ -94,23 +89,11 @@ void ContentSelectorView::ProfilesComboBox::slotIndexChangedByUser(int index) mOldProfile = currentText(); } -void ContentSelectorView::ProfilesComboBox::paintEvent(QPaintEvent *) +ProfilesComboBox::ComboBoxLineEdit::ComboBoxLineEdit (QWidget *parent) + : LineEdit (parent) { - QStylePainter painter(this); - painter.setPen(palette().color(QPalette::Text)); - - // draw the combobox frame, focusrect and selected etc. - QStyleOptionComboBox opt; - initStyleOption(&opt); - painter.drawComplexControl(QStyle::CC_ComboBox, opt); - - // draw the icon and text - if (!opt.editable && currentIndex() == -1) // <<< we adjust the text displayed when nothing is selected - opt.currentText = mPlaceholderText; - painter.drawControl(QStyle::CE_ComboBoxLabel, opt); -} + int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); -void ContentSelectorView::ProfilesComboBox::setPlaceholderText(const QString &text) -{ - mPlaceholderText = text; + setObjectName(QString("ComboBoxLineEdit")); + setStyleSheet(QString("ComboBoxLineEdit { background-color: transparent; padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1)); } diff --git a/apps/launcher/utils/profilescombobox.hpp b/apps/launcher/utils/profilescombobox.hpp new file mode 100644 index 000000000..1e27f66a9 --- /dev/null +++ b/apps/launcher/utils/profilescombobox.hpp @@ -0,0 +1,40 @@ +#ifndef PROFILESCOMBOBOX_HPP +#define PROFILESCOMBOBOX_HPP + +#include "components/contentselector/view/combobox.hpp" +#include "lineedit.hpp" + +class QString; + +class ProfilesComboBox : public ContentSelectorView::ComboBox +{ + Q_OBJECT + +public: + class ComboBoxLineEdit : public LineEdit + { + public: + explicit ComboBoxLineEdit (QWidget *parent = 0); + }; + +public: + + explicit ProfilesComboBox(QWidget *parent = 0); + void setEditEnabled(bool editable); + +signals: + void signalProfileTextChanged(const QString &item); + void signalProfileChanged(const QString &previous, const QString ¤t); + void signalProfileChanged(int index); + void profileRenamed(const QString &oldName, const QString &newName); + +private slots: + + void slotEditingFinished(); + void slotIndexChangedByUser(int index); + void slotTextChanged(const QString &text); + +private: + QString mOldProfile; +}; +#endif // PROFILESCOMBOBOX_HPP diff --git a/components/contentselector/view/textinputdialog.cpp b/apps/launcher/utils/textinputdialog.cpp similarity index 77% rename from components/contentselector/view/textinputdialog.cpp rename to apps/launcher/utils/textinputdialog.cpp index 6bb92f113..9957e7dda 100644 --- a/components/contentselector/view/textinputdialog.cpp +++ b/apps/launcher/utils/textinputdialog.cpp @@ -7,8 +7,6 @@ #include #include -#include - TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWidget *parent) : QDialog(parent) { @@ -20,7 +18,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 ContentSelectorView::LineEdit(this); + mLineEdit = new DialogLineEdit(this); mLineEdit->setValidator(validator); mLineEdit->setCompleter(0); @@ -74,3 +72,16 @@ void TextInputDialog::slotUpdateOkButton(QString text) mLineEdit->setPalette(*palette); } } + +TextInputDialog::DialogLineEdit::DialogLineEdit (QWidget *parent) : + LineEdit (parent) +{ + int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + + setObjectName(QString("LineEdit")); + setStyleSheet(QString("LineEdit { padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1)); + QSize msz = minimumSizeHint(); + setMinimumSize(qMax(msz.width(), mClearButton->sizeHint().height() + frameWidth * 2 + 2), + qMax(msz.height(), mClearButton->sizeHint().height() + frameWidth * 2 + 2)); + +} diff --git a/components/contentselector/view/textinputdialog.hpp b/apps/launcher/utils/textinputdialog.hpp similarity index 66% rename from components/contentselector/view/textinputdialog.hpp rename to apps/launcher/utils/textinputdialog.hpp index a0b7e350a..148bbd152 100644 --- a/components/contentselector/view/textinputdialog.hpp +++ b/apps/launcher/utils/textinputdialog.hpp @@ -3,23 +3,30 @@ #include -class QDialogButtonBox; +#include "lineedit.hpp" -namespace ContentSelectorView { - class LineEdit; -} +class QDialogButtonBox; +class LineEdit; class TextInputDialog : public QDialog { Q_OBJECT - ContentSelectorView::LineEdit *mLineEdit; + class DialogLineEdit : public LineEdit + { + public: + explicit DialogLineEdit (QWidget *parent = 0); + }; + + DialogLineEdit *mLineEdit; QDialogButtonBox *mButtonBox; public: explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0); + ~TextInputDialog () {} + QString getText() const; int exec(); diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 9ae12c7a7..bc78352d4 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -44,6 +44,7 @@ opencs_units_noqt (model/tools opencs_units (view/doc viewmanager view operations operation subview startup filedialog newgame + filewidget adjusterwidget ) @@ -122,11 +123,13 @@ opencs_units (view/filter set (OPENCS_US ) -set (OPENCS_RES ../../files/opencs/resources.qrc - ../../files/launcher/launcher.qrc +set (OPENCS_RES ${CMAKE_SOURCE_DIR}/files/opencs/resources.qrc + ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc ) -set (OPENCS_UI ../../files/ui/datafilespage.ui +set (OPENCS_UI + ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui + ${CMAKE_SOURCE_DIR}/files/ui/filedialog.ui ) source_group (opencs FILES ${OPENCS_SRC} ${OPENCS_HDR}) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index ae10ec642..e78357bc5 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -109,15 +109,13 @@ void CS::Editor::createGame() void CS::Editor::createAddon() { mStartup.hide(); - - mFileDialog.newFile(); + mFileDialog.showDialog (CSVDoc::FileDialog::DialogType_New); } void CS::Editor::loadDocument() { mStartup.hide(); - - mFileDialog.openFile(); + mFileDialog.showDialog (CSVDoc::FileDialog::DialogType_Open); } void CS::Editor::openFiles() diff --git a/components/contentselector/view/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp similarity index 100% rename from components/contentselector/view/adjusterwidget.cpp rename to apps/opencs/view/doc/adjusterwidget.cpp diff --git a/components/contentselector/view/adjusterwidget.hpp b/apps/opencs/view/doc/adjusterwidget.hpp similarity index 100% rename from components/contentselector/view/adjusterwidget.hpp rename to apps/opencs/view/doc/adjusterwidget.hpp diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 2017ab103..49e90ec81 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -12,81 +12,120 @@ #include #include -#include -#include +#include "components/contentselector/model/esmfile.hpp" #include "components/contentselector/view/contentselector.hpp" +#include "filewidget.hpp" +#include "adjusterwidget.hpp" #include CSVDoc::FileDialog::FileDialog(QWidget *parent) : - QDialog(parent), - mOpenFileFlags (ContentSelectorView::Flag_Content | ContentSelectorView::Flag_LoadAddon), - mNewFileFlags (ContentSelectorView::Flag_Content | ContentSelectorView::Flag_NewAddon) - + QDialog(parent), mSelector (0) { + ui.setupUi (this); resize(400, 400); -} -void CSVDoc::FileDialog::addFiles(const QString &path) -{ - ContentSelectorView::ContentSelector::addFiles(path); + setObjectName ("FileDialog"); + mSelector = new ContentSelectorView::ContentSelector (ui.contentSelectorWidget); } -QString CSVDoc::FileDialog::filename() +void CSVDoc::FileDialog::addFiles(const QString &path) { - return ContentSelectorView::ContentSelector::instance().projectFilename(); + mSelector->addFiles(path); } QStringList CSVDoc::FileDialog::selectedFilePaths() { QStringList filePaths; - foreach (ContentSelectorModel::EsmFile *file, ContentSelectorView::ContentSelector:: - instance().selectedFiles() ) - { + foreach (ContentSelectorModel::EsmFile *file, mSelector->selectedFiles() ) filePaths.append(file->path()); - } + return filePaths; } -void CSVDoc::FileDialog::showDialog() +void CSVDoc::FileDialog::showDialog(DialogType dialogType) { + mDialogType = dialogType; + + switch (mDialogType) + { + case DialogType_New: + buildNewFileView(); + break; + + case DialogType_Open: + buildOpenFileView(); + break; + default: + break; + } + show(); raise(); activateWindow(); } -void CSVDoc::FileDialog::openFile() +void CSVDoc::FileDialog::buildNewFileView() { - setWindowTitle(tr("Open")); + setWindowTitle(tr("Create a new addon")); - ContentSelectorView::ContentSelector::configure(this, mOpenFileFlags); + QPushButton* createButton = ui.projectButtonBox->button (QDialogButtonBox::Ok); + createButton->setText ("Create"); + createButton->setEnabled (false); - connect (&ContentSelectorView::ContentSelector::instance(), - SIGNAL (accepted()), this, SIGNAL (openFiles())); + mFileWidget = new FileWidget (this); - connect (&ContentSelectorView::ContentSelector::instance(), - SIGNAL (rejected()), this, SLOT (slotRejected())); + mFileWidget->setType (true); + mFileWidget->extensionLabelIsVisible(true); - showDialog(); -} + ui.projectGroupBoxLayout->insertWidget (0, mFileWidget); -void CSVDoc::FileDialog::newFile() -{ - setWindowTitle(tr("New")); + connect (mFileWidget, SIGNAL (nameChanged(const QString &, bool)), + this, SLOT (slotUpdateCreateButton(const QString &, bool))); + + connect (mSelector, SIGNAL (signalCurrentGamefileIndexChanged (int)), + this, SLOT (slotUpdateCreateButton (int))); - ContentSelectorView::ContentSelector::configure(this, mNewFileFlags); + connect (ui.projectButtonBox, SIGNAL (accepted()), this, SIGNAL (createNewFile())); - connect (&ContentSelectorView::ContentSelector::instance(), - SIGNAL (accepted()), this, SIGNAL (createNewFile())); + connect (ui.projectButtonBox, SIGNAL (rejected()), this, SLOT (slotRejected())); +} - connect (&ContentSelectorView::ContentSelector::instance(), - SIGNAL (rejected()), this, SLOT (slotRejected())); +void CSVDoc::FileDialog::buildOpenFileView() +{ + setWindowTitle(tr("Open")); + ui.projectGroupBox->setTitle (QString("")); - showDialog(); + connect (ui.projectButtonBox, SIGNAL (accepted()), this, SIGNAL (openFiles())); + connect (ui.projectButtonBox, SIGNAL (rejected()), this , SIGNAL (rejected())); } void CSVDoc::FileDialog::slotRejected() { close(); } + +void CSVDoc::FileDialog::slotUpdateCreateButton (int) +{ + slotUpdateCreateButton (mFileWidget->getName(), true); +} + +void CSVDoc::FileDialog::slotUpdateCreateButton(const QString &name, bool) +{ + if (!(mDialogType == DialogType_New)) + return; + + bool success = (!name.isEmpty() && mSelector->selectedFiles().size() > 0); + + ui.projectButtonBox->button (QDialogButtonBox::Ok)->setEnabled (success); +} + +QString CSVDoc::FileDialog::filename() const +{ + if (mDialogType == DialogType_New) + return mFileWidget->getName(); + + return QString (""); +} + diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index acc35189d..78883791e 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -3,49 +3,54 @@ #include #include -#include "../../../../components/contentselector/view/contentselector.hpp" -class QDialogButtonBox; -class QSortFilterProxyModel; -class QAbstractItemModel; -class QPushButton; -class QStringList; -class QString; -class QMenu; -class QLabel; +#include "ui_filedialog.h" class DataFilesModel; class PluginsProxyModel; - - namespace ContentSelectorView { - class LineEdit; + class ContentSelector; } namespace CSVDoc { + class FileWidget; + class FileDialog : public QDialog { Q_OBJECT - unsigned char mOpenFileFlags; - unsigned char mNewFileFlags; + public: + + enum DialogType + { + DialogType_New, + DialogType_Open + }; + + private: + + ContentSelectorView::ContentSelector *mSelector; + Ui::FileDialog ui; + DialogType mDialogType; + FileWidget *mFileWidget; public: + explicit FileDialog(QWidget *parent = 0); + void showDialog (DialogType dialogType); - void openFile(); - void newFile(); void addFiles (const QString &path); - QString filename(); + QString filename() const; QStringList selectedFilePaths(); private: - void showDialog(); + void buildNewFileView(); + void buildOpenFileView(); signals: @@ -58,6 +63,9 @@ namespace CSVDoc private slots: + void slotUpdateCreateButton (int); + void slotUpdateCreateButton (const QString &, bool); + }; } #endif // FILEDIALOG_HPP diff --git a/components/contentselector/view/filewidget.cpp b/apps/opencs/view/doc/filewidget.cpp similarity index 100% rename from components/contentselector/view/filewidget.cpp rename to apps/opencs/view/doc/filewidget.cpp diff --git a/components/contentselector/view/filewidget.hpp b/apps/opencs/view/doc/filewidget.hpp similarity index 100% rename from components/contentselector/view/filewidget.hpp rename to apps/opencs/view/doc/filewidget.hpp diff --git a/apps/opencs/view/doc/newgame.cpp b/apps/opencs/view/doc/newgame.cpp index 265b98305..98681c499 100644 --- a/apps/opencs/view/doc/newgame.cpp +++ b/apps/opencs/view/doc/newgame.cpp @@ -7,8 +7,8 @@ #include #include -#include "components/contentselector/view/filewidget.hpp" -#include "components/contentselector/view/adjusterwidget.hpp" +#include "filewidget.hpp" +#include "adjusterwidget.hpp" CSVDoc::NewGameDialogue::NewGameDialogue() { diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 103c6f412..acb70b04d 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -74,7 +74,7 @@ add_component_dir (loadinglistener loadinglistener ) -set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/datafilespage.ui +set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui ) find_package(Qt4 COMPONENTS QtCore QtGui) @@ -82,11 +82,7 @@ if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) add_component_qt_dir (contentselector model/modelitem model/esmfile model/naturalsort model/contentmodel - view/profilescombobox view/comboboxlineedit - view/lineedit view/contentselector - view/filewidget view/adjusterwidget - view/textinputdialog - + view/combobox view/contentselector ) include(${QT_USE_FILE}) diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 8bb052d3d..accc149cb 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -399,6 +399,10 @@ void ContentSelectorModel::ContentModel::addFile(EsmFile *file) beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); mFiles.append(file); endInsertRows(); + + QModelIndex idx = index (mFiles.size() - 2, 0, QModelIndex()); + + emit dataChanged (idx, idx); } void ContentSelectorModel::ContentModel::addFiles(const QString &path) @@ -466,6 +470,7 @@ void ContentSelectorModel::ContentModel::sortFiles() //iterate each file, obtaining a reference to it's gamefiles list for (int i = 0; i < fileCount; i++) { + QModelIndex idx1 = index (i, 0, QModelIndex()); const QStringList &gamefiles = mFiles.at(i)->gameFiles(); //iterate each file after the current file, verifying that none of it's //dependencies appear. @@ -474,6 +479,11 @@ void ContentSelectorModel::ContentModel::sortFiles() if (gamefiles.contains(mFiles.at(j)->fileName())) { mFiles.move(j, i); + + QModelIndex idx2 = index (j, 0, QModelIndex()); + + emit dataChanged (idx1, idx2); + movedFiles = true; } } diff --git a/components/contentselector/view/combobox.cpp b/components/contentselector/view/combobox.cpp new file mode 100644 index 000000000..1d773b62d --- /dev/null +++ b/components/contentselector/view/combobox.cpp @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +#include "combobox.hpp" + +ContentSelectorView::ComboBox::ComboBox(QWidget *parent) : + QComboBox(parent) +{ + mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore + setValidator(mValidator); + setCompleter(0); + setEnabled (true); + + setInsertPolicy(QComboBox::NoInsert); +} + +void ContentSelectorView::ComboBox::paintEvent(QPaintEvent *) +{ + QStylePainter painter(this); + painter.setPen(palette().color(QPalette::Text)); + + // draw the combobox frame, focusrect and selected etc. + QStyleOptionComboBox opt; + initStyleOption(&opt); + painter.drawComplexControl(QStyle::CC_ComboBox, opt); + + // draw the icon and text + if (!opt.editable && currentIndex() == -1) // <<< we adjust the text displayed when nothing is selected + opt.currentText = mPlaceholderText; + painter.drawControl(QStyle::CE_ComboBoxLabel, opt); +} + +void ContentSelectorView::ComboBox::setPlaceholderText(const QString &text) +{ + mPlaceholderText = text; +} diff --git a/components/contentselector/view/combobox.hpp b/components/contentselector/view/combobox.hpp new file mode 100644 index 000000000..e3888af2c --- /dev/null +++ b/components/contentselector/view/combobox.hpp @@ -0,0 +1,30 @@ +#ifndef COMBOBOX_HPP +#define COMBOBOX_HPP + +#include +#include + +class QString; +class QRegExpValidator; + +namespace ContentSelectorView +{ + class ComboBox : public QComboBox + { + Q_OBJECT + + public: + explicit ComboBox (QWidget *parent = 0); + + void setPlaceholderText(const QString &text); + + private: + QString mPlaceholderText; + + protected: + void paintEvent(QPaintEvent *); + QRegExpValidator *mValidator; + }; +} + +#endif // COMBOBOX_HPP diff --git a/components/contentselector/view/comboboxlineedit.hpp b/components/contentselector/view/comboboxlineedit.hpp deleted file mode 100644 index 1aef2f57b..000000000 --- a/components/contentselector/view/comboboxlineedit.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/**************************************************************************** -** -** Copyright (c) 2007 Trolltech ASA -** -** Use, modification and distribution is allowed without limitation, -** warranty, liability or support of any kind. -** -****************************************************************************/ - -#ifndef LINEEDIT_H -#define LINEEDIT_H - -#include - -class QToolButton; - -namespace ContentSelectorView -{ - class ComboBoxLineEdit : public QLineEdit - { - Q_OBJECT - - public: - ComboBoxLineEdit(QWidget *parent = 0); - - protected: - void resizeEvent(QResizeEvent *); - - private slots: - void updateClearButton(const QString &text); - - private: - QToolButton *mClearButton; - }; -} -#endif // LIENEDIT_H - diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index 6965c948e..7a7e1fd9d 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -1,7 +1,6 @@ #include "contentselector.hpp" #include "../model/esmfile.hpp" -#include "lineedit.hpp" #include @@ -11,45 +10,16 @@ #include #include -#include "filewidget.hpp" -#include "adjusterwidget.hpp" -#include "textinputdialog.hpp" - #include -ContentSelectorView::ContentSelector *ContentSelectorView::ContentSelector::mInstance = 0; -QStringList ContentSelectorView::ContentSelector::mFilePaths; - -void ContentSelectorView::ContentSelector::configure(QWidget *subject, unsigned char flags) -{ - assert(!mInstance); - mInstance = new ContentSelector (subject, flags); -} - -ContentSelectorView::ContentSelector& ContentSelectorView::ContentSelector::instance() +ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) : + QObject(parent) { - - assert(mInstance); - return *mInstance; -} - -ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent, unsigned char flags) : - QWidget(parent), mFlags (flags), - mAdjusterWidget (0), mFileWidget (0), - mIgnoreProfileSignal (false) -{ - - ui.setupUi (this); - - parent->setLayout(new QGridLayout()); - parent->layout()->addWidget(this); + ui.setupUi (parent); buildContentModel(); buildGameFileView(); buildAddonView(); - buildNewAddonView(); - buildLoadAddonView(); - buildProfilesView(); /* //mContentModel->sort(3); // Sort by date accessed @@ -57,16 +27,8 @@ ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent, unsigned */ } -bool ContentSelectorView::ContentSelector::isFlagged(SelectorFlags flag) const -{ - return (mFlags & flag); -} - void ContentSelectorView::ContentSelector::buildContentModel() { - if (!isFlagged (Flag_Content)) - return; - mContentModel = new ContentSelectorModel::ContentModel(); if (mFilePaths.size()>0) @@ -83,12 +45,6 @@ void ContentSelectorView::ContentSelector::buildContentModel() void ContentSelectorView::ContentSelector::buildGameFileView() { - if (!isFlagged (Flag_Content)) - { - ui.gameFileView->setVisible(false); - return; - } - ui.gameFileView->setVisible (true); mGameFileProxyModel = new QSortFilterProxyModel(this); @@ -99,19 +55,17 @@ void ContentSelectorView::ContentSelector::buildGameFileView() ui.gameFileView->setPlaceholderText(QString("Select a game file...")); ui.gameFileView->setModel(mGameFileProxyModel); - connect (ui.gameFileView, SIGNAL(currentIndexChanged(int)), this, SLOT (slotCurrentGameFileIndexChanged(int))); + connect (ui.gameFileView, SIGNAL(currentIndexChanged(int)), + this, SLOT (slotCurrentGameFileIndexChanged(int))); + + connect (ui.gameFileView, SIGNAL (currentIndexChanged (int)), + this, SIGNAL (signalCurrentGamefileIndexChanged (int))); ui.gameFileView->setCurrentIndex(-1); } void ContentSelectorView::ContentSelector::buildAddonView() { - if (!isFlagged (Flag_Content)) - { - ui.addonView->setVisible(false); - return; - } - ui.addonView->setVisible (true); mAddonProxyModel = new QSortFilterProxyModel(this); @@ -123,91 +77,9 @@ void ContentSelectorView::ContentSelector::buildAddonView() ui.addonView->setModel(mAddonProxyModel); connect(ui.addonView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotAddonTableItemClicked(const QModelIndex &))); -} - -void ContentSelectorView::ContentSelector::buildProfilesView() -{ - if (!isFlagged (Flag_Profile)) - { - ui.profileGroupBox->setVisible(false); - return; - } - - ui.profileGroupBox->setVisible (true); - - // Add the actions to the toolbuttons - ui.newProfileButton->setDefaultAction (ui.newProfileAction); - ui.deleteProfileButton->setDefaultAction (ui.deleteProfileAction); - - //enable ui elements - ui.profilesComboBox->addItem ("Default"); - ui.profilesComboBox->setPlaceholderText (QString("Select a profile...")); - - if (!ui.profilesComboBox->isEnabled()) - ui.profilesComboBox->setEnabled(true); - - if (!ui.deleteProfileAction->isEnabled()) - ui.deleteProfileAction->setEnabled(true); - - //establish connections - connect (ui.profilesComboBox, SIGNAL (currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int))); - connect (ui.profilesComboBox, SIGNAL (profileRenamed(QString,QString)), this, SIGNAL(signalProfileRenamed(QString,QString))); - connect (ui.profilesComboBox, SIGNAL (signalProfileChanged(QString,QString)), this, SIGNAL(signalProfileChangedByUser(QString,QString))); - connect (ui.profilesComboBox, SIGNAL (signalProfileTextChanged(QString)), this, SLOT (slotProfileTextChanged (QString))); - - ui.profileGroupBox->setVisible (true); - ui.projectButtonBox->setVisible (false); -} - -void ContentSelectorView::ContentSelector::buildLoadAddonView() -{ - if (!isFlagged (Flag_LoadAddon)) - { - if (!isFlagged (Flag_NewAddon)) - ui.projectGroupBox->setVisible (false); - - return; - } - - ui.projectGroupBox->setVisible (true); - ui.projectCreateButton->setVisible (false); - ui.projectGroupBox->setTitle (""); - - connect(ui.projectButtonBox, SIGNAL(accepted()), this, SIGNAL(accepted())); - connect(ui.projectButtonBox, SIGNAL(rejected()), this, SIGNAL(rejected())); -} - -void ContentSelectorView::ContentSelector::buildNewAddonView() -{ - if (!isFlagged (Flag_NewAddon)) - { - if (!isFlagged (Flag_LoadAddon)) - ui.projectGroupBox->setVisible (false); - - return; - } - - ui.projectGroupBox->setVisible (true); - - mFileWidget = new CSVDoc::FileWidget (this); - mAdjusterWidget = new CSVDoc::AdjusterWidget (this); - - mFileWidget->setType(true); - mFileWidget->extensionLabelIsVisible(false); - - ui.fileWidgetFrame->layout()->addWidget(mFileWidget); - ui.adjusterWidgetFrame->layout()->addWidget(mAdjusterWidget); - - ui.projectButtonBox->setStandardButtons(QDialogButtonBox::Cancel); - ui.projectButtonBox->addButton(ui.projectCreateButton, QDialogButtonBox::ActionRole); - - connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)), - mAdjusterWidget, SLOT (setName (const QString&, bool))); - - connect (mAdjusterWidget, SIGNAL (stateChanged(bool)), this, SLOT (slotUpdateCreateButton(bool))); - connect(ui.projectCreateButton, SIGNAL(clicked()), this, SIGNAL(accepted())); - connect(ui.projectButtonBox, SIGNAL(rejected()), this, SIGNAL(rejected())); + for (int i = 0; i < mAddonProxyModel->rowCount(); ++i) + qDebug() << mAddonProxyModel->data(mAddonProxyModel->index(i,0,QModelIndex())); } void ContentSelectorView::ContentSelector::setGameFile(const QString &filename) @@ -239,16 +111,6 @@ void ContentSelectorView::ContentSelector::setCheckStates(const QStringList &lis mContentModel->setCheckState(file, Qt::Checked); } -QString ContentSelectorView::ContentSelector::projectFilename() const -{ - QString filepath = ""; - - if (mAdjusterWidget) - filepath = QString::fromAscii(mAdjusterWidget->getPath().c_str()); - - return filepath; -} - ContentSelectorModel::ContentFileList ContentSelectorView::ContentSelector::selectedFiles() const { @@ -261,65 +123,10 @@ ContentSelectorModel::ContentFileList void ContentSelectorView::ContentSelector::addFiles(const QString &path) { - // if the model hasn't been instantiated, queue the path - if (!mInstance) - mFilePaths.append(path); - else - { - mInstance->mContentModel->addFiles(path); - mInstance->ui.gameFileView->setCurrentIndex(-1); - } -} - -int ContentSelectorView::ContentSelector::getProfileIndex ( const QString &item) const -{ - return ui.profilesComboBox->findText (item); -} - -void ContentSelectorView::ContentSelector::addProfile (const QString &item, bool setAsCurrent) -{ - if (item.isEmpty()) - return; - - QString previous = ui.profilesComboBox->currentText(); - - if (ui.profilesComboBox->findText(item) == -1) - ui.profilesComboBox->addItem(item); - - if (setAsCurrent) - setProfile (ui.profilesComboBox->findText(item)); -} - -void ContentSelectorView::ContentSelector::setProfile(int index) -{ - //programmatic change requires second call to non-signalized "slot" since no signal responses - //occur for programmatic changes to the profilesComboBox. - if (index >= -1 && index < ui.profilesComboBox->count()) - { - QString previous = ui.profilesComboBox->itemText(ui.profilesComboBox->currentIndex()); - QString current = ui.profilesComboBox->itemText(index); - - ui.profilesComboBox->setCurrentIndex(index); - } -} - -QString ContentSelectorView::ContentSelector::getProfileText() const -{ - return ui.profilesComboBox->currentText(); -} - -QAbstractItemModel *ContentSelectorView::ContentSelector::profilesModel() const -{ - return ui.profilesComboBox->model(); -} - -void ContentSelectorView::ContentSelector::slotCurrentProfileIndexChanged(int index) -{ - //don't allow deleting "Default" profile - bool success = (ui.profilesComboBox->itemText(index) != "Default"); + mContentModel->addFiles(path); - ui.deleteProfileAction->setEnabled(success); - ui.profilesComboBox->setEditEnabled(success); + if (ui.gameFileView->currentIndex() != -1) + ui.gameFileView->setCurrentIndex(-1); } void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int index) @@ -341,16 +148,6 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i if (proxy) proxy->setDynamicSortFilter(true); - - slotUpdateCreateButton(true); -} - -void ContentSelectorView::ContentSelector::slotProfileTextChanged(const QString &text) -{ - QPushButton *opnBtn = ui.projectButtonBox->button(QDialogButtonBox::Open); - - if (opnBtn->isEnabled()) - opnBtn->setEnabled (false); } void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QModelIndex &index) @@ -362,53 +159,3 @@ void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QMode else model->setData(index, Qt::Unchecked, Qt::CheckStateRole); } - -void ContentSelectorView::ContentSelector::slotUpdateCreateButton(bool) -{ - //enable only if a game file is selected and the adjuster widget is non-empty - bool validGameFile = (ui.gameFileView->currentIndex() != -1); - bool validFilename = false; - - if (mAdjusterWidget) - validFilename = mAdjusterWidget->isValid(); - - ui.projectCreateButton->setEnabled(validGameFile && validFilename); -} - -void ContentSelectorView::ContentSelector::on_newProfileAction_triggered() -{ - TextInputDialog newDialog (tr("New Profile"), tr("Profile name:"), this); - - if (newDialog.exec() == QDialog::Accepted) - emit signalAddNewProfile(newDialog.getText()); -} - -void ContentSelectorView::ContentSelector::on_deleteProfileAction_triggered() -{ - QString profile = ui.profilesComboBox->currentText(); - - if (profile.isEmpty()) - return; - - QMessageBox msgBox(this); - msgBox.setWindowTitle(tr("Delete Profile")); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setStandardButtons(QMessageBox::Cancel); - msgBox.setText(tr("Are you sure you want to delete %0?").arg(profile)); - - QAbstractButton *deleteButton = - msgBox.addButton(tr("Delete"), QMessageBox::ActionRole); - - msgBox.exec(); - - if (msgBox.clickedButton() != deleteButton) - return; - - // Remove the profile from the combobox - ui.profilesComboBox->removeItem(ui.profilesComboBox->findText(profile)); - - //signal for removal from model - emit signalProfileDeleted (profile); - - slotCurrentProfileIndexChanged(ui.profilesComboBox->currentIndex()); -} diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index 64b9b3732..0882abfb7 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -3,38 +3,19 @@ #include -#include "ui_datafilespage.h" +#include "ui_contentselector.h" #include "../model/contentmodel.hpp" class QSortFilterProxyModel; -namespace CSVDoc -{ - class FileWidget; - class AdjusterWidget; -} namespace ContentSelectorView { - enum SelectorFlags - { - Flag_Content = 0x01, // gamefile combobox & addon list view - Flag_NewAddon = 0x02, // enable project button box (Create/Cancel) and file/adjuster widgets - Flag_LoadAddon = 0x04, // enable project button box (Open/Cancel) - Flag_Profile = 0x08 // enable profile combo box - }; - class ContentSelector : public QWidget + class ContentSelector : public QObject { Q_OBJECT - unsigned char mFlags; - bool mIgnoreProfileSignal; - - static ContentSelector *mInstance; - static QStringList mFilePaths; - - CSVDoc::FileWidget *mFileWidget; - CSVDoc::AdjusterWidget *mAdjusterWidget; + QStringList mFilePaths; protected: @@ -44,64 +25,39 @@ namespace ContentSelectorView public: - explicit ContentSelector(QWidget *parent = 0, unsigned char flags = Flag_Content); + explicit ContentSelector(QWidget *parent = 0); - static void configure(QWidget *subject, unsigned char flags = Flag_Content); - static ContentSelector &instance(); - static void addFiles(const QString &path); + void addFiles(const QString &path); void clearCheckStates(); void setCheckStates (const QStringList &list); - ContentSelectorModel::ContentFileList *CheckedItems(); - QString projectFilename() const; ContentSelectorModel::ContentFileList selectedFiles() const; - QAbstractItemModel *profilesModel() const; - void setGameFile (const QString &filename = ""); - void addProfile (const QString &item, bool setAsCurrent = false); - void setProfile (int index); - int getProfileIndex (const QString &item) const; - QString getProfileText() const; + void setGameFile (const QString &filename = QString("")); + + bool isGamefileSelected() const + { return ui.gameFileView->currentIndex() != -1; } + + QWidget *uiWidget() const + { return ui.contentGroupBox; } private: - Ui::DataFilesPage ui; + Ui::ContentSelector ui; void buildContentModel(); void buildGameFileView(); void buildAddonView(); - void buildProfilesView(); - void buildNewAddonView(); - void buildLoadAddonView(); - - bool isFlagged(SelectorFlags flag) const; signals: - - void accepted(); - void rejected(); - - void signalCreateButtonClicked(); - - void signalProfileRenamed(QString,QString); - void signalProfileChangedByUser(QString,QString); - void signalProfileDeleted(QString); - void signalAddNewProfile(QString); + void signalCurrentGamefileIndexChanged (int); private slots: - void slotProfileTextChanged (const QString &text); - void slotCurrentProfileIndexChanged(int index); void slotCurrentGameFileIndexChanged(int index); void slotAddonTableItemClicked(const QModelIndex &index); - - void slotUpdateCreateButton (bool); - - // Action slots - void on_newProfileAction_triggered(); - void on_deleteProfileAction_triggered(); }; } diff --git a/components/contentselector/view/lineedit.cpp b/components/contentselector/view/lineedit.cpp deleted file mode 100644 index b6fdfa805..000000000 --- a/components/contentselector/view/lineedit.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include - -#include "lineedit.hpp" - -ContentSelectorView::LineEdit::LineEdit(QWidget *parent) - : QLineEdit(parent) -{ - mClearButton = new QToolButton(this); - QPixmap pixmap(":images/clear.png"); - mClearButton->setIcon(QIcon(pixmap)); - mClearButton->setIconSize(pixmap.size()); - mClearButton->setCursor(Qt::ArrowCursor); - mClearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); - mClearButton->hide(); - connect(mClearButton, SIGNAL(clicked()), this, SLOT(clear())); - connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateClearButton(const QString&))); - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - - setObjectName(QString("LineEdit")); - setStyleSheet(QString("LineEdit { padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1)); - QSize msz = minimumSizeHint(); - setMinimumSize(qMax(msz.width(), mClearButton->sizeHint().height() + frameWidth * 2 + 2), - qMax(msz.height(), mClearButton->sizeHint().height() + frameWidth * 2 + 2)); -} - -void ContentSelectorView::LineEdit::resizeEvent(QResizeEvent *) -{ - QSize sz = mClearButton->sizeHint(); - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - mClearButton->move(rect().right() - frameWidth - sz.width(), - (rect().bottom() + 1 - sz.height())/2); -} - -void ContentSelectorView::LineEdit::updateClearButton(const QString& text) -{ - mClearButton->setVisible(!text.isEmpty()); -} diff --git a/components/contentselector/view/profilescombobox.hpp b/components/contentselector/view/profilescombobox.hpp deleted file mode 100644 index fc87a94b4..000000000 --- a/components/contentselector/view/profilescombobox.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef PROFILESCOMBOBOX_HPP -#define PROFILESCOMBOBOX_HPP - -#include -#include -class QString; -class QRegExpValidator; - -namespace ContentSelectorView -{ - class ProfilesComboBox : public QComboBox - { - Q_OBJECT - public: - explicit ProfilesComboBox(QWidget *parent = 0); - void setEditEnabled(bool editable); - void setPlaceholderText(const QString &text); - // void indexChanged(int index); - - signals: - void signalProfileTextChanged(const QString &item); - void signalProfileChanged(const QString &previous, const QString ¤t); - void signalProfileChanged(int index); - void profileRenamed(const QString &oldName, const QString &newName); - - private slots: - - void slotEditingFinished(); - void slotIndexChangedByUser(int index); - void slotTextChanged(const QString &text); - - private: - QString mOldProfile; - QString mPlaceholderText; - QRegExpValidator *mValidator; - - protected: - void paintEvent(QPaintEvent *); - }; -} - -#endif // PROFILESCOMBOBOX_HPP diff --git a/files/ui/contentselector.ui b/files/ui/contentselector.ui new file mode 100644 index 000000000..b9b5ba5a0 --- /dev/null +++ b/files/ui/contentselector.ui @@ -0,0 +1,111 @@ + + + ContentSelector + + + + 0 + 0 + 518 + 436 + + + + + 0 + 0 + + + + Qt::DefaultContextMenu + + + + 0 + + + + + Content + + + + 3 + + + + + false + + + + + + + + 0 + 0 + + + + Qt::DefaultContextMenu + + + true + + + QAbstractItemView::NoEditTriggers + + + true + + + false + + + QAbstractItemView::DragDrop + + + Qt::MoveAction + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + Qt::ElideLeft + + + false + + + false + + + true + + + false + + + + + + + + + + + ContentSelectorView::ComboBox + QComboBox +
components/contentselector/view/combobox.hpp
+
+
+ + +
diff --git a/files/ui/datafilespage.ui b/files/ui/datafilespage.ui index 0cafd606a..eb5ebc61d 100644 --- a/files/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -7,7 +7,7 @@ 0 0 518 - 436 + 108 @@ -21,188 +21,7 @@ - - - Content - - - - 3 - - - - - - - false - - - - - - - - - - - - 0 - 0 - - - - Qt::DefaultContextMenu - - - true - - - QAbstractItemView::NoEditTriggers - - - true - - - false - - - QAbstractItemView::DragDrop - - - Qt::MoveAction - - - true - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - Qt::ElideLeft - - - false - - - false - - - true - - - false - - - - - - - - - - - - - - - 0 - 0 - - - - Project - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - 3 - - - 6 - - - 6 - - - 0 - - - - - - 0 - 0 - - - - QFrame::NoFrame - - - QFrame::Plain - - - 0 - - - - 0 - - - 0 - - - - - - - - false - - - - 0 - 0 - - - - Create - - - - - - - - - - - 1 - 0 - - - - QFrame::NoFrame - - - QFrame::Plain - - - 0 - - - - 0 - - - 0 - - - + @@ -232,9 +51,9 @@ 6 - + - false + true @@ -242,6 +61,9 @@ 0 + + Select a profiile + @@ -276,13 +98,6 @@
- - - - QDialogButtonBox::Cancel|QDialogButtonBox::Open - - -
@@ -332,9 +147,9 @@ - ContentSelectorView::ProfilesComboBox + ProfilesComboBox QComboBox -
components/contentselector/view/profilescombobox.hpp
+
apps/launcher/utils/profilescombobox.hpp
diff --git a/files/ui/filedialog.ui b/files/ui/filedialog.ui new file mode 100644 index 000000000..114345e53 --- /dev/null +++ b/files/ui/filedialog.ui @@ -0,0 +1,73 @@ + + + FileDialog + + + + 0 + 0 + 518 + 108 + + + + + 0 + 0 + + + + Qt::DefaultContextMenu + + + + + + + + + Qt::NoFocus + + + Project Name + + + false + + + + 6 + + + 3 + + + 6 + + + 0 + + + 6 + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + + + + From ba3589bc763383ac03a2ebfb9710b20b86d178c8 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Tue, 22 Oct 2013 22:20:21 -0500 Subject: [PATCH 095/118] Revert "Implemented ContentSelector as a singleton "charm" modifier for" This reverts commit 24b167b7552ce8bf6e62933a535752a899c77473. Conflicts: apps/launcher/datafilespage.cpp apps/opencs/editor.cpp apps/opencs/view/doc/filedialog.cpp apps/opencs/view/doc/filedialog.hpp components/contentselector/view/contentselector.cpp components/contentselector/view/contentselector.hpp --- apps/launcher/datafilespage.cpp | 1 - apps/opencs/editor.cpp | 9 +++-- apps/opencs/view/doc/filedialog.cpp | 6 ++-- apps/opencs/view/doc/filedialog.hpp | 7 ++-- .../contentselector/view/contentselector.cpp | 33 +++++++------------ .../contentselector/view/contentselector.hpp | 1 - 6 files changed, 23 insertions(+), 34 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 2140caaf9..ca404c5d8 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -28,7 +28,6 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam , QWidget(parent) { ui.setupUi (this); - setObjectName ("DataFilesPage"); mSelector = new ContentSelectorView::ContentSelector (ui.contentSelectorWidget); diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index e78357bc5..284762812 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -121,6 +121,7 @@ void CS::Editor::loadDocument() void CS::Editor::openFiles() { std::vector files; + QStringList paths = mFileDialog.checkedItemsPaths(); foreach (const QString &path, mFileDialog.selectedFilePaths()) { files.push_back(path.toStdString()); @@ -130,28 +131,30 @@ void CS::Editor::openFiles() qDebug() << "loading files: " << fp.c_str(); /// \todo Get the save path from the file dialogue + CSMDoc::Document *document = mDocumentManager.addDocument (files, *files.rbegin(), false); mViewManager.addView (document); - mFileDialog.close(); + mFileDialog.hide(); } void CS::Editor::createNewFile() { std::vector files; + QStringList paths = mFileDialog.checkedItemsPaths(); foreach (const QString &path, mFileDialog.selectedFilePaths()) { files.push_back(path.toStdString()); } - files.push_back(mFileDialog.filename().toStdString()); + files.push_back(mFileDialog.fileName().toStdString()); /// \todo Get the save path from the file dialogue. CSMDoc::Document *document = mDocumentManager.addDocument (files, *files.rbegin(), true); mViewManager.addView (document); - mFileDialog.close(); + mFileDialog.hide(); } void CS::Editor::createNewGame (const boost::filesystem::path& file) diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 49e90ec81..5438effff 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -10,10 +10,10 @@ #include #include #include -#include #include "components/contentselector/model/esmfile.hpp" #include "components/contentselector/view/contentselector.hpp" + #include "filewidget.hpp" #include "adjusterwidget.hpp" @@ -101,9 +101,9 @@ void CSVDoc::FileDialog::buildOpenFileView() connect (ui.projectButtonBox, SIGNAL (rejected()), this , SIGNAL (rejected())); } -void CSVDoc::FileDialog::slotRejected() +void CSVDoc::FileDialog::slotGameFileSelected(int value) { - close(); + emit signalUpdateCreateButton(value > -1, 1); } void CSVDoc::FileDialog::slotUpdateCreateButton (int) diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 78883791e..85582e95f 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -53,19 +53,18 @@ namespace CSVDoc void buildOpenFileView(); signals: - void openFiles(); void createNewFile(); - public slots: + void signalUpdateCreateButton (bool, int); + void signalUpdateCreateButtonFlags(int); - void slotRejected(); + public slots: private slots: void slotUpdateCreateButton (int); void slotUpdateCreateButton (const QString &, bool); - }; } #endif // FILEDIALOG_HPP diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index 7a7e1fd9d..cb405f092 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -6,6 +6,7 @@ #include #include + #include #include #include @@ -21,26 +22,13 @@ ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) : buildGameFileView(); buildAddonView(); - /* - //mContentModel->sort(3); // Sort by date accessed - -*/ + updateViews(); } void ContentSelectorView::ContentSelector::buildContentModel() { mContentModel = new ContentSelectorModel::ContentModel(); - - if (mFilePaths.size()>0) - { - foreach (const QString &path, mFilePaths) - mContentModel->addFiles(path); - - mFilePaths.clear(); - } - - ui.gameFileView->setCurrentIndex(-1); - mContentModel->uncheckAll(); + connect(mContentModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); } void ContentSelectorView::ContentSelector::buildGameFileView() @@ -52,8 +40,8 @@ void ContentSelectorView::ContentSelector::buildGameFileView() mGameFileProxyModel->setFilterRole (Qt::UserRole); mGameFileProxyModel->setSourceModel (mContentModel); - ui.gameFileView->setPlaceholderText(QString("Select a game file...")); - ui.gameFileView->setModel(mGameFileProxyModel); + gameFileView->setPlaceholderText(QString("Select a game file...")); + gameFileView->setModel(mGameFileProxyModel); connect (ui.gameFileView, SIGNAL(currentIndexChanged(int)), this, SLOT (slotCurrentGameFileIndexChanged(int))); @@ -61,7 +49,8 @@ void ContentSelectorView::ContentSelector::buildGameFileView() connect (ui.gameFileView, SIGNAL (currentIndexChanged (int)), this, SIGNAL (signalCurrentGamefileIndexChanged (int))); - ui.gameFileView->setCurrentIndex(-1); + gameFileView->setCurrentIndex(-1); + gameFileView->setCurrentIndex(0); } void ContentSelectorView::ContentSelector::buildAddonView() @@ -74,7 +63,7 @@ void ContentSelectorView::ContentSelector::buildAddonView() mAddonProxyModel->setDynamicSortFilter (true); mAddonProxyModel->setSourceModel (mContentModel); - ui.addonView->setModel(mAddonProxyModel); + addonView->setModel(mAddonProxyModel); connect(ui.addonView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotAddonTableItemClicked(const QModelIndex &))); @@ -120,7 +109,6 @@ ContentSelectorModel::ContentFileList return mContentModel->checkedItems(); } - void ContentSelectorView::ContentSelector::addFiles(const QString &path) { mContentModel->addFiles(path); @@ -133,7 +121,7 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i { static int oldIndex = -1; - QAbstractItemModel *const model = ui.gameFileView->model(); + QAbstractItemModel *const model = gameFileView->model(); QSortFilterProxyModel *proxy = dynamic_cast(model); if (proxy) @@ -152,7 +140,8 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QModelIndex &index) { - QAbstractItemModel *const model = ui.addonView->model(); + 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); diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index 0882abfb7..163b19855 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -10,7 +10,6 @@ class QSortFilterProxyModel; namespace ContentSelectorView { - class ContentSelector : public QObject { Q_OBJECT From b48f066f33e0d54b5369e13194175ea2736203c7 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Wed, 23 Oct 2013 17:39:17 -0500 Subject: [PATCH 096/118] Reimplemented content selector for filedialog and datafilespage classes --- apps/opencs/editor.cpp | 4 +--- apps/opencs/view/doc/filedialog.cpp | 13 ++++++------- apps/opencs/view/doc/filedialog.hpp | 4 ++-- .../contentselector/view/contentselector.cpp | 18 ++++++++---------- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 284762812..1099226d2 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -121,7 +121,6 @@ void CS::Editor::loadDocument() void CS::Editor::openFiles() { std::vector files; - QStringList paths = mFileDialog.checkedItemsPaths(); foreach (const QString &path, mFileDialog.selectedFilePaths()) { files.push_back(path.toStdString()); @@ -141,13 +140,12 @@ void CS::Editor::openFiles() void CS::Editor::createNewFile() { std::vector files; - QStringList paths = mFileDialog.checkedItemsPaths(); foreach (const QString &path, mFileDialog.selectedFilePaths()) { files.push_back(path.toStdString()); } - files.push_back(mFileDialog.fileName().toStdString()); + files.push_back(mFileDialog.filename().toStdString()); /// \todo Get the save path from the file dialogue. diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 5438effff..1ac476cb2 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -88,7 +88,6 @@ void CSVDoc::FileDialog::buildNewFileView() this, SLOT (slotUpdateCreateButton (int))); connect (ui.projectButtonBox, SIGNAL (accepted()), this, SIGNAL (createNewFile())); - connect (ui.projectButtonBox, SIGNAL (rejected()), this, SLOT (slotRejected())); } @@ -98,12 +97,7 @@ void CSVDoc::FileDialog::buildOpenFileView() ui.projectGroupBox->setTitle (QString("")); connect (ui.projectButtonBox, SIGNAL (accepted()), this, SIGNAL (openFiles())); - connect (ui.projectButtonBox, SIGNAL (rejected()), this , SIGNAL (rejected())); -} - -void CSVDoc::FileDialog::slotGameFileSelected(int value) -{ - emit signalUpdateCreateButton(value > -1, 1); + connect (ui.projectButtonBox, SIGNAL (rejected()), this, SLOT (slotRejected())); } void CSVDoc::FileDialog::slotUpdateCreateButton (int) @@ -129,3 +123,8 @@ QString CSVDoc::FileDialog::filename() const return QString (""); } +void CSVDoc::FileDialog::slotRejected() +{ + emit rejected(); + close(); +} diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 85582e95f..3b93f42a8 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -53,18 +53,18 @@ namespace CSVDoc void buildOpenFileView(); signals: + void openFiles(); void createNewFile(); void signalUpdateCreateButton (bool, int); void signalUpdateCreateButtonFlags(int); - public slots: - private slots: void slotUpdateCreateButton (int); void slotUpdateCreateButton (const QString &, bool); + void slotRejected(); }; } #endif // FILEDIALOG_HPP diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index cb405f092..3d615906d 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -21,14 +21,12 @@ ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) : buildContentModel(); buildGameFileView(); buildAddonView(); - - updateViews(); } void ContentSelectorView::ContentSelector::buildContentModel() { mContentModel = new ContentSelectorModel::ContentModel(); - connect(mContentModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); + //connect(mContentModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); } void ContentSelectorView::ContentSelector::buildGameFileView() @@ -40,8 +38,8 @@ void ContentSelectorView::ContentSelector::buildGameFileView() mGameFileProxyModel->setFilterRole (Qt::UserRole); mGameFileProxyModel->setSourceModel (mContentModel); - gameFileView->setPlaceholderText(QString("Select a game file...")); - gameFileView->setModel(mGameFileProxyModel); + ui.gameFileView->setPlaceholderText(QString("Select a game file...")); + ui.gameFileView->setModel(mGameFileProxyModel); connect (ui.gameFileView, SIGNAL(currentIndexChanged(int)), this, SLOT (slotCurrentGameFileIndexChanged(int))); @@ -49,8 +47,8 @@ void ContentSelectorView::ContentSelector::buildGameFileView() connect (ui.gameFileView, SIGNAL (currentIndexChanged (int)), this, SIGNAL (signalCurrentGamefileIndexChanged (int))); - gameFileView->setCurrentIndex(-1); - gameFileView->setCurrentIndex(0); + ui.gameFileView->setCurrentIndex(-1); + ui.gameFileView->setCurrentIndex(0); } void ContentSelectorView::ContentSelector::buildAddonView() @@ -63,7 +61,7 @@ void ContentSelectorView::ContentSelector::buildAddonView() mAddonProxyModel->setDynamicSortFilter (true); mAddonProxyModel->setSourceModel (mContentModel); - addonView->setModel(mAddonProxyModel); + ui.addonView->setModel(mAddonProxyModel); connect(ui.addonView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotAddonTableItemClicked(const QModelIndex &))); @@ -121,7 +119,7 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i { static int oldIndex = -1; - QAbstractItemModel *const model = gameFileView->model(); + QAbstractItemModel *const model = ui.gameFileView->model(); QSortFilterProxyModel *proxy = dynamic_cast(model); if (proxy) @@ -140,7 +138,7 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QModelIndex &index) { - QAbstractItemModel *const model = addonView->model(); + QAbstractItemModel *const model = ui.addonView->model(); //QSortFilterProxyModel *proxy = dynamic_cast(model); if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked) From 2ca7f247317ea2270df6f816c1a209ac1360efef Mon Sep 17 00:00:00 2001 From: graffy76 Date: Thu, 24 Oct 2013 17:33:28 -0500 Subject: [PATCH 097/118] Fixed filedialog new / edit content path issue --- apps/opencs/editor.cpp | 11 +++--- apps/opencs/view/doc/filedialog.cpp | 2 +- .../contentselector/model/contentmodel.cpp | 1 - .../contentselector/view/contentselector.cpp | 34 ++++++++++++------- .../contentselector/view/contentselector.hpp | 2 ++ 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 1099226d2..6396563f2 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -126,12 +126,9 @@ void CS::Editor::openFiles() files.push_back(path.toStdString()); } - foreach (const boost::filesystem::path fp, files) - qDebug() << "loading files: " << fp.c_str(); + boost::filesystem::path savePath = mFileDialog.filename().toStdString(); - /// \todo Get the save path from the file dialogue - - CSMDoc::Document *document = mDocumentManager.addDocument (files, *files.rbegin(), false); + CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, false); mViewManager.addView (document); mFileDialog.hide(); @@ -147,9 +144,9 @@ void CS::Editor::createNewFile() files.push_back(mFileDialog.filename().toStdString()); - /// \todo Get the save path from the file dialogue. + boost::filesystem::path savePath = mFileDialog.filename().toStdString(); - CSMDoc::Document *document = mDocumentManager.addDocument (files, *files.rbegin(), true); + CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, true); mViewManager.addView (document); mFileDialog.hide(); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 1ac476cb2..e82cc30cb 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -120,7 +120,7 @@ QString CSVDoc::FileDialog::filename() const if (mDialogType == DialogType_New) return mFileWidget->getName(); - return QString (""); + return mSelector->currentFile(); } void CSVDoc::FileDialog::slotRejected() diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index accc149cb..0674642ee 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -503,7 +503,6 @@ bool ContentSelectorModel::ContentModel::isChecked(const QString& name) const void ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool checkState) { - if (name.isEmpty()) return; diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index 3d615906d..33b31b00c 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -9,10 +9,9 @@ #include #include +#include #include -#include - ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) : QObject(parent) { @@ -26,7 +25,6 @@ ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) : void ContentSelectorView::ContentSelector::buildContentModel() { mContentModel = new ContentSelectorModel::ContentModel(); - //connect(mContentModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); } void ContentSelectorView::ContentSelector::buildGameFileView() @@ -41,7 +39,7 @@ void ContentSelectorView::ContentSelector::buildGameFileView() ui.gameFileView->setPlaceholderText(QString("Select a game file...")); ui.gameFileView->setModel(mGameFileProxyModel); - connect (ui.gameFileView, SIGNAL(currentIndexChanged(int)), + connect (ui.gameFileView, SIGNAL (currentIndexChanged(int)), this, SLOT (slotCurrentGameFileIndexChanged(int))); connect (ui.gameFileView, SIGNAL (currentIndexChanged (int)), @@ -64,9 +62,6 @@ void ContentSelectorView::ContentSelector::buildAddonView() ui.addonView->setModel(mAddonProxyModel); connect(ui.addonView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotAddonTableItemClicked(const QModelIndex &))); - - for (int i = 0; i < mAddonProxyModel->rowCount(); ++i) - qDebug() << mAddonProxyModel->data(mAddonProxyModel->index(i,0,QModelIndex())); } void ContentSelectorView::ContentSelector::setGameFile(const QString &filename) @@ -113,6 +108,19 @@ void ContentSelectorView::ContentSelector::addFiles(const QString &path) if (ui.gameFileView->currentIndex() != -1) ui.gameFileView->setCurrentIndex(-1); + + mContentModel->uncheckAll(); +} + +QString ContentSelectorView::ContentSelector::currentFile() const +{ + QModelIndex currentIdx = ui.addonView->currentIndex(); + + if (!currentIdx.isValid()) + return ui.gameFileView->currentText(); + + QModelIndex idx = mContentModel->index(mAddonProxyModel->mapToSource(currentIdx).row(), 0, QModelIndex()); + return mContentModel->data(idx, Qt::DisplayRole).toString(); } void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int index) @@ -125,12 +133,15 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i if (proxy) proxy->setDynamicSortFilter(false); - if (oldIndex > -1) - model->setData(model->index(oldIndex, 0), false, Qt::UserRole + 1); + if (index != oldIndex) + { + if (oldIndex > -1) + model->setData(model->index(oldIndex, 0), false, Qt::UserRole + 1); - oldIndex = index; + oldIndex = index; - model->setData(model->index(index, 0), true, Qt::UserRole + 1); + model->setData(model->index(index, 0), true, Qt::UserRole + 1); + } if (proxy) proxy->setDynamicSortFilter(true); @@ -139,7 +150,6 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QModelIndex &index) { QAbstractItemModel *const model = ui.addonView->model(); - //QSortFilterProxyModel *proxy = dynamic_cast(model); if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked) model->setData(index, Qt::Checked, Qt::CheckStateRole); diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index 163b19855..1e24a5523 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -26,6 +26,8 @@ namespace ContentSelectorView explicit ContentSelector(QWidget *parent = 0); + QString currentFile() const; + void addFiles(const QString &path); void clearCheckStates(); From 1a23cccce3a067943f27b2a2a00b18f175f867c7 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 25 Oct 2013 11:17:26 -0500 Subject: [PATCH 098/118] Implemented Launcher namespace --- apps/launcher/datafilespage.cpp | 44 +++--- apps/launcher/datafilespage.hpp | 94 ++++++------ apps/launcher/graphicspage.cpp | 24 +-- apps/launcher/graphicspage.hpp | 85 ++++++----- apps/launcher/main.cpp | 3 +- apps/launcher/maindialog.cpp | 41 ++--- apps/launcher/maindialog.hpp | 78 +++++----- apps/launcher/playpage.cpp | 8 +- apps/launcher/playpage.hpp | 30 ++-- apps/launcher/settings/gamesettings.cpp | 12 +- apps/launcher/settings/gamesettings.hpp | 74 ++++----- apps/launcher/settings/graphicssettings.cpp | 6 +- apps/launcher/settings/graphicssettings.hpp | 16 +- apps/launcher/settings/launchersettings.cpp | 10 +- apps/launcher/settings/launchersettings.hpp | 20 +-- apps/launcher/settings/settingsbase.hpp | 144 +++++++++--------- apps/launcher/textslotmsgbox.cpp | 2 +- apps/launcher/textslotmsgbox.hpp | 14 +- apps/launcher/unshieldthread.cpp | 26 ++-- apps/launcher/unshieldthread.hpp | 64 ++++---- apps/launcher/utils/checkablemessagebox.cpp | 159 +++++++++----------- apps/launcher/utils/checkablemessagebox.hpp | 138 +++++++++-------- apps/launcher/utils/textinputdialog.cpp | 10 +- apps/launcher/utils/textinputdialog.hpp | 41 ++--- 24 files changed, 588 insertions(+), 555 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index ca404c5d8..e246b4515 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -21,7 +21,7 @@ #include "components/contentselector/view/contentselector.hpp" -DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent) +Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent) : mCfgMgr(cfg) , mGameSettings(gameSettings) , mLauncherSettings(launcherSettings) @@ -35,7 +35,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam setupDataFiles(); } -void DataFilesPage::loadSettings() +void Launcher::DataFilesPage::loadSettings() { QString profileName = ui.profilesComboBox->currentText(); @@ -53,7 +53,7 @@ void DataFilesPage::loadSettings() mSelector->setCheckStates(addons); } -void DataFilesPage::saveSettings(const QString &profile) +void Launcher::DataFilesPage::saveSettings(const QString &profile) { QString profileName = profile; @@ -84,7 +84,7 @@ void DataFilesPage::saveSettings(const QString &profile) } -void DataFilesPage::buildView() +void Launcher::DataFilesPage::buildView() { ui.verticalLayout->insertWidget (0, mSelector->uiWidget()); @@ -111,13 +111,23 @@ void DataFilesPage::buildView() this, SLOT (slotProfileChangedByUser(QString, QString))); } -void DataFilesPage::removeProfile(const QString &profile) +void Launcher::DataFilesPage::removeProfile(const QString &profile) { mLauncherSettings.remove(QString("Profiles/") + profile + QString("/game")); mLauncherSettings.remove(QString("Profiles/") + profile + QString("/addon")); } -void DataFilesPage::setProfile(int index, bool savePrevious) +QAbstractItemModel *Launcher::DataFilesPage::profilesModel() const +{ + return ui.profilesComboBox->model(); +} + +int Launcher::DataFilesPage::profilesIndex() const +{ + return ui.profilesComboBox->currentIndex(); +} + +void Launcher::DataFilesPage::setProfile(int index, bool savePrevious) { if (index >= -1 && index < ui.profilesComboBox->count()) { @@ -128,7 +138,7 @@ void DataFilesPage::setProfile(int index, bool savePrevious) } } -void DataFilesPage::setProfile (const QString &previous, const QString ¤t, bool savePrevious) +void Launcher::DataFilesPage::setProfile (const QString &previous, const QString ¤t, bool savePrevious) { //abort if no change (poss. duplicate signal) if (previous == current) @@ -144,18 +154,18 @@ void DataFilesPage::setProfile (const QString &previous, const QString ¤t, checkForDefaultProfile(); } -void DataFilesPage::slotProfileDeleted (const QString &item) +void Launcher::DataFilesPage::slotProfileDeleted (const QString &item) { removeProfile (item); } -void DataFilesPage::slotProfileChangedByUser(const QString &previous, const QString ¤t) +void Launcher::DataFilesPage::slotProfileChangedByUser(const QString &previous, const QString ¤t) { setProfile(previous, current, true); emit signalProfileChanged (ui.profilesComboBox->findText(current)); } -void DataFilesPage::slotProfileRenamed(const QString &previous, const QString ¤t) +void Launcher::DataFilesPage::slotProfileRenamed(const QString &previous, const QString ¤t) { if (previous.isEmpty()) return; @@ -169,12 +179,12 @@ void DataFilesPage::slotProfileRenamed(const QString &previous, const QString &c loadSettings(); } -void DataFilesPage::slotProfileChanged(int index) +void Launcher::DataFilesPage::slotProfileChanged(int index) { setProfile (index, true); } -void DataFilesPage::setupDataFiles() +void Launcher::DataFilesPage::setupDataFiles() { QStringList paths = mGameSettings.getDataDirs(); @@ -197,7 +207,7 @@ void DataFilesPage::setupDataFiles() loadSettings(); } -void DataFilesPage::on_newProfileAction_triggered() +void Launcher::DataFilesPage::on_newProfileAction_triggered() { TextInputDialog newDialog (tr("New Profile"), tr("Profile name:"), this); @@ -222,7 +232,7 @@ void DataFilesPage::on_newProfileAction_triggered() emit signalProfileChanged (ui.profilesComboBox->findText(profile)); } -void DataFilesPage::addProfile (const QString &profile, bool setAsCurrent) +void Launcher::DataFilesPage::addProfile (const QString &profile, bool setAsCurrent) { if (profile.isEmpty()) return; @@ -236,7 +246,7 @@ void DataFilesPage::addProfile (const QString &profile, bool setAsCurrent) setProfile (ui.profilesComboBox->findText (profile), false); } -void DataFilesPage::on_deleteProfileAction_triggered() +void Launcher::DataFilesPage::on_deleteProfileAction_triggered() { QString profile = ui.profilesComboBox->currentText(); @@ -254,7 +264,7 @@ void DataFilesPage::on_deleteProfileAction_triggered() checkForDefaultProfile(); } -void DataFilesPage::checkForDefaultProfile() +void Launcher::DataFilesPage::checkForDefaultProfile() { //don't allow deleting "Default" profile bool success = (ui.profilesComboBox->currentText() != "Default"); @@ -263,7 +273,7 @@ void DataFilesPage::checkForDefaultProfile() ui.profilesComboBox->setEditEnabled (success); } -bool DataFilesPage::showDeleteMessageBox (const QString &text) +bool Launcher::DataFilesPage::showDeleteMessageBox (const QString &text) { QMessageBox msgBox(this); msgBox.setWindowTitle(tr("Delete Profile")); diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index cc054a4e4..e394e6f41 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -3,78 +3,76 @@ #include "ui_datafilespage.h" #include -#include class QSortFilterProxyModel; class QAbstractItemModel; -class QAction; class QMenu; -class TextInputDialog; -class GameSettings; -class LauncherSettings; -class ProfilesComboBox; - namespace Files { struct ConfigurationManager; } namespace ContentSelectorView { class ContentSelector; } -class DataFilesPage : public QWidget +namespace Launcher { - Q_OBJECT + class TextInputDialog; + class GameSettings; + class LauncherSettings; + class ProfilesComboBox; - ContentSelectorView::ContentSelector *mSelector; - Ui::DataFilesPage ui; + class DataFilesPage : public QWidget + { + Q_OBJECT -public: - explicit DataFilesPage (Files::ConfigurationManager &cfg, GameSettings &gameSettings, - LauncherSettings &launcherSettings, QWidget *parent = 0); + ContentSelectorView::ContentSelector *mSelector; + Ui::DataFilesPage ui; - QAbstractItemModel* profilesModel() const - { return ui.profilesComboBox->model(); } + public: + explicit DataFilesPage (Files::ConfigurationManager &cfg, GameSettings &gameSettings, + LauncherSettings &launcherSettings, QWidget *parent = 0); - int profilesIndex() const - { return ui.profilesComboBox->currentIndex(); } + QAbstractItemModel* profilesModel() const; - //void writeConfig(QString profile = QString()); - void saveSettings(const QString &profile = ""); - void loadSettings(); + int profilesIndex() const; -signals: - void signalProfileChanged (int index); + //void writeConfig(QString profile = QString()); + void saveSettings(const QString &profile = ""); + void loadSettings(); -public slots: - void slotProfileChanged (int index); + signals: + void signalProfileChanged (int index); -private slots: + public slots: + void slotProfileChanged (int index); - void slotProfileChangedByUser(const QString &previous, const QString ¤t); - void slotProfileRenamed(const QString &previous, const QString ¤t); - void slotProfileDeleted(const QString &item); + private slots: - void on_newProfileAction_triggered(); - void on_deleteProfileAction_triggered(); + void slotProfileChangedByUser(const QString &previous, const QString ¤t); + void slotProfileRenamed(const QString &previous, const QString ¤t); + void slotProfileDeleted(const QString &item); -private: + void on_newProfileAction_triggered(); + void on_deleteProfileAction_triggered(); - QMenu *mContextMenu; + private: - Files::ConfigurationManager &mCfgMgr; + QMenu *mContextMenu; - GameSettings &mGameSettings; - LauncherSettings &mLauncherSettings; + Files::ConfigurationManager &mCfgMgr; - void setPluginsCheckstates(Qt::CheckState state); + GameSettings &mGameSettings; + LauncherSettings &mLauncherSettings; - void buildView(); - void setupDataFiles(); - void setupConfig(); - void readConfig(); - void setProfile (int index, bool savePrevious); - void setProfile (const QString &previous, const QString ¤t, bool savePrevious); - void removeProfile (const QString &profile); - bool showDeleteMessageBox (const QString &text); - void addProfile (const QString &profile, bool setAsCurrent); - void checkForDefaultProfile(); -}; + void setPluginsCheckstates(Qt::CheckState state); + void buildView(); + void setupDataFiles(); + void setupConfig(); + void readConfig(); + void setProfile (int index, bool savePrevious); + void setProfile (const QString &previous, const QString ¤t, bool savePrevious); + void removeProfile (const QString &profile); + bool showDeleteMessageBox (const QString &text); + void addProfile (const QString &profile, bool setAsCurrent); + void checkForDefaultProfile(); + }; +} #endif diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 2c6c711ea..1ed1abaeb 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -33,7 +33,7 @@ QString getAspect(int x, int y) return QString(QString::number(xaspect) + ":" + QString::number(yaspect)); } -GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSetting, QWidget *parent) +Launcher::GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSetting, QWidget *parent) : mCfgMgr(cfg) , mGraphicsSettings(graphicsSetting) , QWidget(parent) @@ -53,7 +53,7 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &g } -bool GraphicsPage::setupOgre() +bool Launcher::GraphicsPage::setupOgre() { // Create a log manager so we can surpress debug text to stdout/stderr Ogre::LogManager* logMgr = OGRE_NEW Ogre::LogManager; @@ -157,7 +157,7 @@ bool GraphicsPage::setupOgre() return true; } -bool GraphicsPage::setupSDL() +bool Launcher::GraphicsPage::setupSDL() { int displays = SDL_GetNumVideoDisplays(); @@ -180,7 +180,7 @@ bool GraphicsPage::setupSDL() return true; } -bool GraphicsPage::loadSettings() +bool Launcher::GraphicsPage::loadSettings() { if (!setupSDL()) return false; @@ -219,7 +219,7 @@ bool GraphicsPage::loadSettings() return true; } -void GraphicsPage::saveSettings() +void Launcher::GraphicsPage::saveSettings() { vSyncCheckBox->checkState() ? mGraphicsSettings.setValue(QString("Video/vsync"), QString("true")) : mGraphicsSettings.setValue(QString("Video/vsync"), QString("false")); @@ -246,7 +246,7 @@ void GraphicsPage::saveSettings() mGraphicsSettings.setValue(QString("Video/screen"), QString::number(screenComboBox->currentIndex())); } -QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer) +QStringList Launcher::GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer) { QStringList result; @@ -279,7 +279,7 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy return result; } -QStringList GraphicsPage::getAvailableResolutions(int screen) +QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen) { QStringList result; SDL_DisplayMode mode; @@ -326,7 +326,7 @@ QStringList GraphicsPage::getAvailableResolutions(int screen) return result; } -QRect GraphicsPage::getMaximumResolution() +QRect Launcher::GraphicsPage::getMaximumResolution() { QRect max; int screens = QApplication::desktop()->screenCount(); @@ -341,7 +341,7 @@ QRect GraphicsPage::getMaximumResolution() return max; } -void GraphicsPage::rendererChanged(const QString &renderer) +void Launcher::GraphicsPage::rendererChanged(const QString &renderer) { mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString()); @@ -350,7 +350,7 @@ void GraphicsPage::rendererChanged(const QString &renderer) antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem)); } -void GraphicsPage::screenChanged(int screen) +void Launcher::GraphicsPage::screenChanged(int screen) { if (screen >= 0) { resolutionComboBox->clear(); @@ -358,7 +358,7 @@ void GraphicsPage::screenChanged(int screen) } } -void GraphicsPage::slotFullScreenChanged(int state) +void Launcher::GraphicsPage::slotFullScreenChanged(int state) { if (state == Qt::Checked) { standardRadioButton->toggle(); @@ -372,7 +372,7 @@ void GraphicsPage::slotFullScreenChanged(int state) } } -void GraphicsPage::slotStandardToggled(bool checked) +void Launcher::GraphicsPage::slotStandardToggled(bool checked) { if (checked) { resolutionComboBox->setEnabled(true); diff --git a/apps/launcher/graphicspage.hpp b/apps/launcher/graphicspage.hpp index d233ea12e..7f5dcae1e 100644 --- a/apps/launcher/graphicspage.hpp +++ b/apps/launcher/graphicspage.hpp @@ -18,49 +18,52 @@ #include "ui_graphicspage.h" -class GraphicsSettings; namespace Files { struct ConfigurationManager; } -class GraphicsPage : public QWidget, private Ui::GraphicsPage +namespace Launcher { - Q_OBJECT - -public: - GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSettings, QWidget *parent = 0); - - void saveSettings(); - bool loadSettings(); - -public slots: - void rendererChanged(const QString &renderer); - void screenChanged(int screen); - -private slots: - void slotFullScreenChanged(int state); - void slotStandardToggled(bool checked); - -private: - Ogre::Root *mOgre; - Ogre::RenderSystem *mSelectedRenderSystem; - Ogre::RenderSystem *mOpenGLRenderSystem; - Ogre::RenderSystem *mDirect3DRenderSystem; - #ifdef ENABLE_PLUGIN_GL - Ogre::GLPlugin* mGLPlugin; - #endif - #ifdef ENABLE_PLUGIN_Direct3D9 - Ogre::D3D9Plugin* mD3D9Plugin; - #endif - - Files::ConfigurationManager &mCfgMgr; - GraphicsSettings &mGraphicsSettings; - - QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer); - QStringList getAvailableResolutions(int screen); - QRect getMaximumResolution(); - - bool setupOgre(); - bool setupSDL(); -}; - + class GraphicsSettings; + + class GraphicsPage : public QWidget, private Ui::GraphicsPage + { + Q_OBJECT + + public: + GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSettings, QWidget *parent = 0); + + void saveSettings(); + bool loadSettings(); + + public slots: + void rendererChanged(const QString &renderer); + void screenChanged(int screen); + + private slots: + void slotFullScreenChanged(int state); + void slotStandardToggled(bool checked); + + private: + Ogre::Root *mOgre; + Ogre::RenderSystem *mSelectedRenderSystem; + Ogre::RenderSystem *mOpenGLRenderSystem; + Ogre::RenderSystem *mDirect3DRenderSystem; + #ifdef ENABLE_PLUGIN_GL + Ogre::GLPlugin* mGLPlugin; + #endif + #ifdef ENABLE_PLUGIN_Direct3D9 + Ogre::D3D9Plugin* mD3D9Plugin; + #endif + + Files::ConfigurationManager &mCfgMgr; + GraphicsSettings &mGraphicsSettings; + + QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer); + QStringList getAvailableResolutions(int screen); + QRect getMaximumResolution(); + + bool setupOgre(); + bool setupSDL(); + }; +} #endif diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index f67f5edcf..0b5e62a66 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -49,7 +49,7 @@ int main(int argc, char *argv[]) // Support non-latin characters QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); - MainDialog mainWin; + Launcher::MainDialog mainWin; if (mainWin.setup()) { mainWin.show(); @@ -61,4 +61,3 @@ int main(int argc, char *argv[]) SDL_Quit(); return returnValue; } - diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index e514755fe..dca9720ac 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -1,5 +1,6 @@ #include "maindialog.hpp" +#include #include #include #include @@ -23,8 +24,8 @@ #include "graphicspage.hpp" #include "datafilespage.hpp" -MainDialog::MainDialog() - : mGameSettings(mCfgMgr) +Launcher::MainDialog::MainDialog(QWidget *parent) + : mGameSettings(mCfgMgr), QMainWindow (parent) { // Install the stylesheet font QFile file; @@ -69,7 +70,7 @@ MainDialog::MainDialog() createIcons(); } -void MainDialog::createIcons() +void Launcher::MainDialog::createIcons() { if (!QIcon::hasThemeIcon("document-new")) QIcon::setThemeName("tango"); @@ -101,7 +102,7 @@ void MainDialog::createIcons() } -void MainDialog::createPages() +void Launcher::MainDialog::createPages() { mPlayPage = new PlayPage(this); mGraphicsPage = new GraphicsPage(mCfgMgr, mGraphicsSettings, this); @@ -126,7 +127,7 @@ void MainDialog::createPages() } -bool MainDialog::showFirstRunDialog() +bool Launcher::MainDialog::showFirstRunDialog() { QStringList iniPaths; @@ -282,7 +283,7 @@ bool MainDialog::showFirstRunDialog() return true; } -bool MainDialog::setup() +bool Launcher::MainDialog::setup() { if (!setupLauncherSettings()) return false; @@ -311,7 +312,7 @@ bool MainDialog::setup() return true; } -void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) +void Launcher::MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) { if (!current) current = previous; @@ -337,7 +338,7 @@ void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) } } -bool MainDialog::setupLauncherSettings() +bool Launcher::MainDialog::setupLauncherSettings() { mLauncherSettings.setMultiValueEnabled(true); @@ -374,7 +375,7 @@ bool MainDialog::setupLauncherSettings() } #ifndef WIN32 -bool expansions(UnshieldThread& cd) +bool Launcher::expansions(Launcher::UnshieldThread& cd) { if(cd.BloodmoonDone()) { @@ -385,7 +386,7 @@ bool expansions(UnshieldThread& cd) QMessageBox expansionsBox; expansionsBox.setText(QObject::tr("
Would you like to install expansions now ? (make sure you have the disc)
\ If you want to install both Bloodmoon and Tribunal, you have to install Tribunal first.
")); - + QAbstractButton* tribunalButton = NULL; if(!cd.TribunalDone()) tribunalButton = expansionsBox.addButton(QObject::tr("&Tribunal"), QMessageBox::ActionRole); @@ -404,7 +405,7 @@ bool expansions(UnshieldThread& cd) { TextSlotMsgBox cdbox; - cdbox.setStandardButtons(QMessageBox::Cancel); + cdbox.setStandardButtons(QMessageBox::Cancel); QObject::connect(&cd,SIGNAL(signalGUI(const QString&)), &cdbox, SLOT(setTextSlot(const QString&))); QObject::connect(&cd,SIGNAL(close()), &cdbox, SLOT(reject())); @@ -423,7 +424,7 @@ bool expansions(UnshieldThread& cd) { TextSlotMsgBox cdbox; - cdbox.setStandardButtons(QMessageBox::Cancel); + cdbox.setStandardButtons(QMessageBox::Cancel); QObject::connect(&cd,SIGNAL(signalGUI(const QString&)), &cdbox, SLOT(setTextSlot(const QString&))); QObject::connect(&cd,SIGNAL(close()), &cdbox, SLOT(reject())); @@ -445,7 +446,7 @@ bool expansions(UnshieldThread& cd) } #endif // WIN32 -bool MainDialog::setupGameSettings() +bool Launcher::MainDialog::setupGameSettings() { QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string()); QString globalPath = QString::fromStdString(mCfgMgr.getGlobalPath().string()); @@ -568,7 +569,7 @@ bool MainDialog::setupGameSettings() return true; } -bool MainDialog::setupGraphicsSettings() +bool Launcher::MainDialog::setupGraphicsSettings() { mGraphicsSettings.setMultiValueEnabled(false); @@ -622,7 +623,7 @@ bool MainDialog::setupGraphicsSettings() return true; } -void MainDialog::loadSettings() +void Launcher::MainDialog::loadSettings() { int width = mLauncherSettings.value(QString("General/MainWindow/width")).toInt(); int height = mLauncherSettings.value(QString("General/MainWindow/height")).toInt(); @@ -634,7 +635,7 @@ void MainDialog::loadSettings() move(posX, posY); } -void MainDialog::saveSettings() +void Launcher::MainDialog::saveSettings() { QString width = QString::number(this->width()); QString height = QString::number(this->height()); @@ -652,7 +653,7 @@ void MainDialog::saveSettings() } -bool MainDialog::writeSettings() +bool Launcher::MainDialog::writeSettings() { // Now write all config files saveSettings(); @@ -745,13 +746,13 @@ bool MainDialog::writeSettings() return true; } -void MainDialog::closeEvent(QCloseEvent *event) +void Launcher::MainDialog::closeEvent(QCloseEvent *event) { writeSettings(); event->accept(); } -void MainDialog::play() +void Launcher::MainDialog::play() { if (!writeSettings()) { qApp->quit(); @@ -774,7 +775,7 @@ void MainDialog::play() qApp->quit(); } -bool MainDialog::startProgram(const QString &name, const QStringList &arguments, bool detached) +bool Launcher::MainDialog::startProgram(const QString &name, const QStringList &arguments, bool detached) { QString path = name; #ifdef Q_OS_WIN diff --git a/apps/launcher/maindialog.hpp b/apps/launcher/maindialog.hpp index 824dff6e8..5b8e4908e 100644 --- a/apps/launcher/maindialog.hpp +++ b/apps/launcher/maindialog.hpp @@ -11,57 +11,59 @@ #include "ui_mainwindow.h" -class QListWidget; class QListWidgetItem; -class QStackedWidget; -class QStringList; -class QStringListModel; -class QString; -class PlayPage; -class GraphicsPage; -class DataFilesPage; - -class MainDialog : public QMainWindow, private Ui::MainWindow +namespace Launcher { - Q_OBJECT + class PlayPage; + class GraphicsPage; + class DataFilesPage; + class UnshieldThread; + +#ifndef WIN32 + bool expansions(Launcher::UnshieldThread& cd); +#endif -public: - MainDialog(); - bool setup(); - bool showFirstRunDialog(); + class MainDialog : public QMainWindow, private Ui::MainWindow + { + Q_OBJECT -public slots: - void changePage(QListWidgetItem *current, QListWidgetItem *previous); - void play(); + public: + explicit MainDialog(QWidget *parent = 0); + bool setup(); + bool showFirstRunDialog(); -private: - void createIcons(); - void createPages(); + public slots: + void changePage(QListWidgetItem *current, QListWidgetItem *previous); + void play(); - bool setupLauncherSettings(); - bool setupGameSettings(); - bool setupGraphicsSettings(); + private: + void createIcons(); + void createPages(); - void loadSettings(); - void saveSettings(); - bool writeSettings(); + bool setupLauncherSettings(); + bool setupGameSettings(); + bool setupGraphicsSettings(); - inline bool startProgram(const QString &name, bool detached = false) { return startProgram(name, QStringList(), detached); } - bool startProgram(const QString &name, const QStringList &arguments, bool detached = false); + void loadSettings(); + void saveSettings(); + bool writeSettings(); - void closeEvent(QCloseEvent *event); + inline bool startProgram(const QString &name, bool detached = false) { return startProgram(name, QStringList(), detached); } + bool startProgram(const QString &name, const QStringList &arguments, bool detached = false); - PlayPage *mPlayPage; - GraphicsPage *mGraphicsPage; - DataFilesPage *mDataFilesPage; + void closeEvent(QCloseEvent *event); - Files::ConfigurationManager mCfgMgr; + PlayPage *mPlayPage; + GraphicsPage *mGraphicsPage; + DataFilesPage *mDataFilesPage; - GameSettings mGameSettings; - GraphicsSettings mGraphicsSettings; - LauncherSettings mLauncherSettings; + Files::ConfigurationManager mCfgMgr; -}; + GameSettings mGameSettings; + GraphicsSettings mGraphicsSettings; + LauncherSettings mLauncherSettings; + }; +} #endif diff --git a/apps/launcher/playpage.cpp b/apps/launcher/playpage.cpp index fc1ed1c69..6cfb9686f 100644 --- a/apps/launcher/playpage.cpp +++ b/apps/launcher/playpage.cpp @@ -6,7 +6,7 @@ #include #endif -PlayPage::PlayPage(QWidget *parent) : QWidget(parent) +Launcher::PlayPage::PlayPage(QWidget *parent) : QWidget(parent) { setObjectName ("PlayPage"); setupUi(this); @@ -23,17 +23,17 @@ PlayPage::PlayPage(QWidget *parent) : QWidget(parent) } -void PlayPage::setProfilesModel(QAbstractItemModel *model) +void Launcher::PlayPage::setProfilesModel(QAbstractItemModel *model) { profilesComboBox->setModel(model); } -void PlayPage::setProfilesIndex(int index) +void Launcher::PlayPage::setProfilesIndex(int index) { profilesComboBox->setCurrentIndex(index); } -void PlayPage::slotPlayClicked() +void Launcher::PlayPage::slotPlayClicked() { emit playButtonClicked(); } diff --git a/apps/launcher/playpage.hpp b/apps/launcher/playpage.hpp index 42edfadb1..1dc5bb0fe 100644 --- a/apps/launcher/playpage.hpp +++ b/apps/launcher/playpage.hpp @@ -9,26 +9,28 @@ class QComboBox; class QPushButton; class QAbstractItemModel; -class PlayPage : public QWidget, private Ui::PlayPage +namespace Launcher { - Q_OBJECT + class PlayPage : public QWidget, private Ui::PlayPage + { + Q_OBJECT -public: - PlayPage(QWidget *parent = 0); - void setProfilesModel(QAbstractItemModel *model); + public: + PlayPage(QWidget *parent = 0); + void setProfilesModel(QAbstractItemModel *model); -signals: - void signalProfileChanged(int index); - void playButtonClicked(); + signals: + void signalProfileChanged(int index); + void playButtonClicked(); -public slots: - void setProfilesIndex(int index); + public slots: + void setProfilesIndex(int index); -private slots: - void slotPlayClicked(); + private slots: + void slotPlayClicked(); -}; - + }; +} #endif diff --git a/apps/launcher/settings/gamesettings.cpp b/apps/launcher/settings/gamesettings.cpp index 205879bc3..5231753f2 100644 --- a/apps/launcher/settings/gamesettings.cpp +++ b/apps/launcher/settings/gamesettings.cpp @@ -26,16 +26,16 @@ namespace boost #endif /* (BOOST_VERSION <= 104600) */ -GameSettings::GameSettings(Files::ConfigurationManager &cfg) +Launcher::GameSettings::GameSettings(Files::ConfigurationManager &cfg) : mCfgMgr(cfg) { } -GameSettings::~GameSettings() +Launcher::GameSettings::~GameSettings() { } -void GameSettings::validatePaths() +void Launcher::GameSettings::validatePaths() { if (mSettings.isEmpty() || !mDataDirs.isEmpty()) return; // Don't re-validate paths if they are already parsed @@ -81,14 +81,14 @@ void GameSettings::validatePaths() } } -QStringList GameSettings::values(const QString &key, const QStringList &defaultValues) +QStringList Launcher::GameSettings::values(const QString &key, const QStringList &defaultValues) { if (!mSettings.values(key).isEmpty()) return mSettings.values(key); return defaultValues; } -bool GameSettings::readFile(QTextStream &stream) +bool Launcher::GameSettings::readFile(QTextStream &stream) { QMap cache; QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$"); @@ -130,7 +130,7 @@ bool GameSettings::readFile(QTextStream &stream) return true; } -bool GameSettings::writeFile(QTextStream &stream) +bool Launcher::GameSettings::writeFile(QTextStream &stream) { // Iterate in reverse order to preserve insertion order QMapIterator i(mSettings); diff --git a/apps/launcher/settings/gamesettings.hpp b/apps/launcher/settings/gamesettings.hpp index 55b2107e2..11f06b027 100644 --- a/apps/launcher/settings/gamesettings.hpp +++ b/apps/launcher/settings/gamesettings.hpp @@ -11,52 +11,54 @@ namespace Files { typedef std::vector PathContainer; struct ConfigurationManager;} -class GameSettings +namespace Launcher { -public: - GameSettings(Files::ConfigurationManager &cfg); - ~GameSettings(); - - inline QString value(const QString &key, const QString &defaultValue = QString()) + class GameSettings { - return mSettings.value(key).isEmpty() ? defaultValue : mSettings.value(key); - } + public: + GameSettings(Files::ConfigurationManager &cfg); + ~GameSettings(); + inline QString value(const QString &key, const QString &defaultValue = QString()) + { + return mSettings.value(key).isEmpty() ? defaultValue : mSettings.value(key); + } - inline void setValue(const QString &key, const QString &value) - { - mSettings.insert(key, value); - } - inline void setMultiValue(const QString &key, const QString &value) - { - QStringList values = mSettings.values(key); - if (!values.contains(value)) - mSettings.insertMulti(key, value); - } + inline void setValue(const QString &key, const QString &value) + { + mSettings.insert(key, value); + } - inline void remove(const QString &key) - { - mSettings.remove(key); - } + inline void setMultiValue(const QString &key, const QString &value) + { + QStringList values = mSettings.values(key); + if (!values.contains(value)) + mSettings.insertMulti(key, value); + } - inline QStringList getDataDirs() { return mDataDirs; } - inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); } - inline QString getDataLocal() {return mDataLocal; } - inline bool hasMaster() { return mSettings.count(QString("master")) > 0; } + inline void remove(const QString &key) + { + mSettings.remove(key); + } - QStringList values(const QString &key, const QStringList &defaultValues = QStringList()); - bool readFile(QTextStream &stream); - bool writeFile(QTextStream &stream); + inline QStringList getDataDirs() { return mDataDirs; } + inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); } + inline QString getDataLocal() {return mDataLocal; } + inline bool hasMaster() { return mSettings.count(QString("master")) > 0; } -private: - Files::ConfigurationManager &mCfgMgr; + QStringList values(const QString &key, const QStringList &defaultValues = QStringList()); + bool readFile(QTextStream &stream); + bool writeFile(QTextStream &stream); - void validatePaths(); - QMap mSettings; + private: + Files::ConfigurationManager &mCfgMgr; - QStringList mDataDirs; - QString mDataLocal; -}; + void validatePaths(); + QMap mSettings; + QStringList mDataDirs; + QString mDataLocal; + }; +} #endif // GAMESETTINGS_HPP diff --git a/apps/launcher/settings/graphicssettings.cpp b/apps/launcher/settings/graphicssettings.cpp index 0c5580091..9dad3dee6 100644 --- a/apps/launcher/settings/graphicssettings.cpp +++ b/apps/launcher/settings/graphicssettings.cpp @@ -5,15 +5,15 @@ #include #include -GraphicsSettings::GraphicsSettings() +Launcher::GraphicsSettings::GraphicsSettings() { } -GraphicsSettings::~GraphicsSettings() +Launcher::GraphicsSettings::~GraphicsSettings() { } -bool GraphicsSettings::writeFile(QTextStream &stream) +bool Launcher::GraphicsSettings::writeFile(QTextStream &stream) { QString sectionPrefix; QRegExp sectionRe("([^/]+)/(.+)$"); diff --git a/apps/launcher/settings/graphicssettings.hpp b/apps/launcher/settings/graphicssettings.hpp index 3e8617849..6f7c13547 100644 --- a/apps/launcher/settings/graphicssettings.hpp +++ b/apps/launcher/settings/graphicssettings.hpp @@ -3,14 +3,16 @@ #include "settingsbase.hpp" -class GraphicsSettings : public SettingsBase > +namespace Launcher { -public: - GraphicsSettings(); - ~GraphicsSettings(); + class GraphicsSettings : public SettingsBase > + { + public: + GraphicsSettings(); + ~GraphicsSettings(); - bool writeFile(QTextStream &stream); - -}; + bool writeFile(QTextStream &stream); + }; +} #endif // GRAPHICSSETTINGS_HPP diff --git a/apps/launcher/settings/launchersettings.cpp b/apps/launcher/settings/launchersettings.cpp index 5d298e814..7c97144ea 100644 --- a/apps/launcher/settings/launchersettings.cpp +++ b/apps/launcher/settings/launchersettings.cpp @@ -5,15 +5,15 @@ #include #include -LauncherSettings::LauncherSettings() +Launcher::LauncherSettings::LauncherSettings() { } -LauncherSettings::~LauncherSettings() +Launcher::LauncherSettings::~LauncherSettings() { } -QStringList LauncherSettings::values(const QString &key, Qt::MatchFlags flags) +QStringList Launcher::LauncherSettings::values(const QString &key, Qt::MatchFlags flags) { QMap settings = SettingsBase::getSettings(); @@ -34,7 +34,7 @@ QStringList LauncherSettings::values(const QString &key, Qt::MatchFlags flags) return result; } -QStringList LauncherSettings::subKeys(const QString &key) +QStringList Launcher::LauncherSettings::subKeys(const QString &key) { QMap settings = SettingsBase::getSettings(); QStringList keys = settings.uniqueKeys(); @@ -61,7 +61,7 @@ QStringList LauncherSettings::subKeys(const QString &key) return result; } -bool LauncherSettings::writeFile(QTextStream &stream) +bool Launcher::LauncherSettings::writeFile(QTextStream &stream) { QString sectionPrefix; QRegExp sectionRe("([^/]+)/(.+)$"); diff --git a/apps/launcher/settings/launchersettings.hpp b/apps/launcher/settings/launchersettings.hpp index 60c6f86bc..8acc389a9 100644 --- a/apps/launcher/settings/launchersettings.hpp +++ b/apps/launcher/settings/launchersettings.hpp @@ -3,17 +3,19 @@ #include "settingsbase.hpp" -class LauncherSettings : public SettingsBase > +namespace Launcher { -public: - LauncherSettings(); - ~LauncherSettings(); + class LauncherSettings : public SettingsBase > + { + public: + LauncherSettings(); + ~LauncherSettings(); - QStringList subKeys(const QString &key); - QStringList values(const QString &key, Qt::MatchFlags flags = Qt::MatchExactly); + QStringList subKeys(const QString &key); + QStringList values(const QString &key, Qt::MatchFlags flags = Qt::MatchExactly); - bool writeFile(QTextStream &stream); - -}; + bool writeFile(QTextStream &stream); + }; +} #endif // LAUNCHERSETTINGS_HPP diff --git a/apps/launcher/settings/settingsbase.hpp b/apps/launcher/settings/settingsbase.hpp index ed8ada56c..3a1cf8e30 100644 --- a/apps/launcher/settings/settingsbase.hpp +++ b/apps/launcher/settings/settingsbase.hpp @@ -7,103 +7,105 @@ #include #include -template -class SettingsBase +namespace Launcher { + template + class SettingsBase + { -public: - SettingsBase() { mMultiValue = false; } - ~SettingsBase() {} + public: + SettingsBase() { mMultiValue = false; } + ~SettingsBase() {} - inline QString value(const QString &key, const QString &defaultValue = QString()) - { - return mSettings.value(key).isEmpty() ? defaultValue : mSettings.value(key); - } + inline QString value(const QString &key, const QString &defaultValue = QString()) + { + return mSettings.value(key).isEmpty() ? defaultValue : mSettings.value(key); + } - inline void setValue(const QString &key, const QString &value) - { - QStringList values = mSettings.values(key); - if (!values.contains(value)) - mSettings.insert(key, value); - } + inline void setValue(const QString &key, const QString &value) + { + QStringList values = mSettings.values(key); + if (!values.contains(value)) + mSettings.insert(key, value); + } - inline void setMultiValue(const QString &key, const QString &value) - { - QStringList values = mSettings.values(key); - if (!values.contains(value)) - mSettings.insertMulti(key, value); - } + inline void setMultiValue(const QString &key, const QString &value) + { + QStringList values = mSettings.values(key); + if (!values.contains(value)) + mSettings.insertMulti(key, value); + } - inline void setMultiValueEnabled(bool enable) - { - mMultiValue = enable; - } + inline void setMultiValueEnabled(bool enable) + { + mMultiValue = enable; + } - inline void remove(const QString &key) - { - mSettings.remove(key); - } + inline void remove(const QString &key) + { + mSettings.remove(key); + } - Map getSettings() {return mSettings;} + Map getSettings() {return mSettings;} - bool readFile(QTextStream &stream) - { - mCache.clear(); + bool readFile(QTextStream &stream) + { + mCache.clear(); - QString sectionPrefix; + QString sectionPrefix; - QRegExp sectionRe("^\\[([^]]+)\\]"); - QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$"); + QRegExp sectionRe("^\\[([^]]+)\\]"); + QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$"); - while (!stream.atEnd()) { - QString line = stream.readLine(); + while (!stream.atEnd()) { + QString line = stream.readLine(); - if (line.isEmpty() || line.startsWith("#")) - continue; + if (line.isEmpty() || line.startsWith("#")) + continue; - if (sectionRe.exactMatch(line)) { - sectionPrefix = sectionRe.cap(1); - sectionPrefix.append("/"); - continue; - } + if (sectionRe.exactMatch(line)) { + sectionPrefix = sectionRe.cap(1); + sectionPrefix.append("/"); + continue; + } - if (keyRe.indexIn(line) != -1) { + if (keyRe.indexIn(line) != -1) { - QString key = keyRe.cap(1).trimmed(); - QString value = keyRe.cap(2).trimmed(); + QString key = keyRe.cap(1).trimmed(); + QString value = keyRe.cap(2).trimmed(); - if (!sectionPrefix.isEmpty()) - key.prepend(sectionPrefix); + if (!sectionPrefix.isEmpty()) + key.prepend(sectionPrefix); - mSettings.remove(key); + mSettings.remove(key); - QStringList values = mCache.values(key); + QStringList values = mCache.values(key); - if (!values.contains(value)) { - if (mMultiValue) { - mCache.insertMulti(key, value); - } else { - mCache.insert(key, value); + if (!values.contains(value)) { + if (mMultiValue) { + mCache.insertMulti(key, value); + } else { + mCache.insert(key, value); + } } } } - } - if (mSettings.isEmpty()) { - mSettings = mCache; // This is the first time we read a file + if (mSettings.isEmpty()) { + mSettings = mCache; // This is the first time we read a file + return true; + } + + // Merge the changed keys with those which didn't + mSettings.unite(mCache); return true; } - // Merge the changed keys with those which didn't - mSettings.unite(mCache); - return true; - } - -private: - Map mSettings; - Map mCache; - - bool mMultiValue; -}; + private: + Map mSettings; + Map mCache; + bool mMultiValue; + }; +} #endif // SETTINGSBASE_HPP diff --git a/apps/launcher/textslotmsgbox.cpp b/apps/launcher/textslotmsgbox.cpp index 0607d1cc6..62d9cf576 100644 --- a/apps/launcher/textslotmsgbox.cpp +++ b/apps/launcher/textslotmsgbox.cpp @@ -1,6 +1,6 @@ #include "textslotmsgbox.hpp" -void TextSlotMsgBox::setTextSlot(const QString& string) +void Launcher::TextSlotMsgBox::setTextSlot(const QString& string) { setText(string); } diff --git a/apps/launcher/textslotmsgbox.hpp b/apps/launcher/textslotmsgbox.hpp index a29e2c354..a0fefaa25 100644 --- a/apps/launcher/textslotmsgbox.hpp +++ b/apps/launcher/textslotmsgbox.hpp @@ -3,11 +3,13 @@ #include -class TextSlotMsgBox : public QMessageBox +namespace Launcher { -Q_OBJECT - public slots: - void setTextSlot(const QString& string); -}; - + class TextSlotMsgBox : public QMessageBox + { + Q_OBJECT + public slots: + void setTextSlot(const QString& string); + }; +} #endif diff --git a/apps/launcher/unshieldthread.cpp b/apps/launcher/unshieldthread.cpp index 69b241365..d0dbeb1bd 100644 --- a/apps/launcher/unshieldthread.cpp +++ b/apps/launcher/unshieldthread.cpp @@ -292,30 +292,30 @@ namespace } -bool UnshieldThread::SetMorrowindPath(const std::string& path) +bool Launcher::UnshieldThread::SetMorrowindPath(const std::string& path) { mMorrowindPath = path; return true; } -bool UnshieldThread::SetTribunalPath(const std::string& path) +bool Launcher::UnshieldThread::SetTribunalPath(const std::string& path) { mTribunalPath = path; return true; } -bool UnshieldThread::SetBloodmoonPath(const std::string& path) +bool Launcher::UnshieldThread::SetBloodmoonPath(const std::string& path) { mBloodmoonPath = path; return true; } -void UnshieldThread::SetOutputPath(const std::string& path) +void Launcher::UnshieldThread::SetOutputPath(const std::string& path) { mOutputPath = path; } -bool UnshieldThread::extract_file(Unshield* unshield, bfs::path output_dir, const char* prefix, int index) +bool Launcher::UnshieldThread::extract_file(Unshield* unshield, bfs::path output_dir, const char* prefix, int index) { bool success; bfs::path dirname; @@ -349,7 +349,7 @@ bool UnshieldThread::extract_file(Unshield* unshield, bfs::path output_dir, cons return success; } -void UnshieldThread::extract_cab(const bfs::path& cab, const bfs::path& output_dir, bool extract_ini) +void Launcher::UnshieldThread::extract_cab(const bfs::path& cab, const bfs::path& output_dir, bool extract_ini) { Unshield * unshield; unshield = unshield_open(cab.c_str()); @@ -369,7 +369,7 @@ void UnshieldThread::extract_cab(const bfs::path& cab, const bfs::path& output_d } -bool UnshieldThread::extract() +bool Launcher::UnshieldThread::extract() { bfs::path outputDataFilesDir = mOutputPath; outputDataFilesDir /= "Data Files"; @@ -475,7 +475,7 @@ bool UnshieldThread::extract() return true; } -void UnshieldThread::Done() +void Launcher::UnshieldThread::Done() { // Get rid of unnecessary files bfs::remove_all(mOutputPath / "extract-temp"); @@ -491,28 +491,28 @@ void UnshieldThread::Done() bfs::last_write_time(findFile(mOutputPath, "bloodmoon.esm"), getTime("3 June 2003")); } -std::string UnshieldThread::GetMWEsmPath() +std::string Launcher::UnshieldThread::GetMWEsmPath() { return findFile(mOutputPath / "Data Files", "morrowind.esm").string(); } -bool UnshieldThread::TribunalDone() +bool Launcher::UnshieldThread::TribunalDone() { return mTribunalDone; } -bool UnshieldThread::BloodmoonDone() +bool Launcher::UnshieldThread::BloodmoonDone() { return mBloodmoonDone; } -void UnshieldThread::run() +void Launcher::UnshieldThread::run() { extract(); emit close(); } -UnshieldThread::UnshieldThread() +Launcher::UnshieldThread::UnshieldThread() { unshield_set_log_level(0); mMorrowindDone = false; diff --git a/apps/launcher/unshieldthread.hpp b/apps/launcher/unshieldthread.hpp index 655cb5b53..de6a32b44 100644 --- a/apps/launcher/unshieldthread.hpp +++ b/apps/launcher/unshieldthread.hpp @@ -7,50 +7,52 @@ #include -class UnshieldThread : public QThread +namespace Launcher { - Q_OBJECT + class UnshieldThread : public QThread + { + Q_OBJECT - public: - bool SetMorrowindPath(const std::string& path); - bool SetTribunalPath(const std::string& path); - bool SetBloodmoonPath(const std::string& path); + public: + bool SetMorrowindPath(const std::string& path); + bool SetTribunalPath(const std::string& path); + bool SetBloodmoonPath(const std::string& path); - void SetOutputPath(const std::string& path); - - bool extract(); + void SetOutputPath(const std::string& path); - bool TribunalDone(); - bool BloodmoonDone(); + bool extract(); - void Done(); + bool TribunalDone(); + bool BloodmoonDone(); - std::string GetMWEsmPath(); + void Done(); - UnshieldThread(); + std::string GetMWEsmPath(); - private: + UnshieldThread(); - void extract_cab(const boost::filesystem::path& cab, const boost::filesystem::path& output_dir, bool extract_ini = false); - bool extract_file(Unshield* unshield, boost::filesystem::path output_dir, const char* prefix, int index); - - boost::filesystem::path mMorrowindPath; - boost::filesystem::path mTribunalPath; - boost::filesystem::path mBloodmoonPath; + private: - bool mMorrowindDone; - bool mTribunalDone; - bool mBloodmoonDone; + void extract_cab(const boost::filesystem::path& cab, const boost::filesystem::path& output_dir, bool extract_ini = false); + bool extract_file(Unshield* unshield, boost::filesystem::path output_dir, const char* prefix, int index); - boost::filesystem::path mOutputPath; + boost::filesystem::path mMorrowindPath; + boost::filesystem::path mTribunalPath; + boost::filesystem::path mBloodmoonPath; + bool mMorrowindDone; + bool mTribunalDone; + bool mBloodmoonDone; - protected: - virtual void run(); + boost::filesystem::path mOutputPath; - signals: - void signalGUI(QString); - void close(); -}; + protected: + virtual void run(); + + signals: + void signalGUI(QString); + void close(); + }; +} #endif diff --git a/apps/launcher/utils/checkablemessagebox.cpp b/apps/launcher/utils/checkablemessagebox.cpp index 41207a8de..2f775af57 100644 --- a/apps/launcher/utils/checkablemessagebox.cpp +++ b/apps/launcher/utils/checkablemessagebox.cpp @@ -54,72 +54,61 @@ Emulates the QMessageBox API with static conveniences. The message label can open external URLs. */ - -class CheckableMessageBoxPrivate -{ -public: - CheckableMessageBoxPrivate(QDialog *q) +Launcher::CheckableMessageBoxPrivate::CheckableMessageBoxPrivate(QDialog *q) : clickedButton(0) - { - QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); - - pixmapLabel = new QLabel(q); - sizePolicy.setHorizontalStretch(0); - sizePolicy.setVerticalStretch(0); - sizePolicy.setHeightForWidth(pixmapLabel->sizePolicy().hasHeightForWidth()); - pixmapLabel->setSizePolicy(sizePolicy); - pixmapLabel->setVisible(false); - - QSpacerItem *pixmapSpacer = - new QSpacerItem(0, 5, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding); - - messageLabel = new QLabel(q); - messageLabel->setMinimumSize(QSize(300, 0)); - messageLabel->setWordWrap(true); - messageLabel->setOpenExternalLinks(true); - messageLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse); - - QSpacerItem *checkBoxRightSpacer = - new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum); - QSpacerItem *buttonSpacer = - new QSpacerItem(0, 1, QSizePolicy::Minimum, QSizePolicy::Minimum); - - checkBox = new QCheckBox(q); - checkBox->setText(CheckableMessageBox::tr("Do not ask again")); - - buttonBox = new QDialogButtonBox(q); - buttonBox->setOrientation(Qt::Horizontal); - buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); - - QVBoxLayout *verticalLayout = new QVBoxLayout(); - verticalLayout->addWidget(pixmapLabel); - verticalLayout->addItem(pixmapSpacer); - - QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); - horizontalLayout_2->addLayout(verticalLayout); - horizontalLayout_2->addWidget(messageLabel); - - QHBoxLayout *horizontalLayout = new QHBoxLayout(); - horizontalLayout->addWidget(checkBox); - horizontalLayout->addItem(checkBoxRightSpacer); - - QVBoxLayout *verticalLayout_2 = new QVBoxLayout(q); - verticalLayout_2->addLayout(horizontalLayout_2); - verticalLayout_2->addLayout(horizontalLayout); - verticalLayout_2->addItem(buttonSpacer); - verticalLayout_2->addWidget(buttonBox); - } - - QLabel *pixmapLabel; - QLabel *messageLabel; - QCheckBox *checkBox; - QDialogButtonBox *buttonBox; - QAbstractButton *clickedButton; -}; +{ + QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); + + pixmapLabel = new QLabel(q); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(pixmapLabel->sizePolicy().hasHeightForWidth()); + pixmapLabel->setSizePolicy(sizePolicy); + pixmapLabel->setVisible(false); + + QSpacerItem *pixmapSpacer = + new QSpacerItem(0, 5, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding); + + messageLabel = new QLabel(q); + messageLabel->setMinimumSize(QSize(300, 0)); + messageLabel->setWordWrap(true); + messageLabel->setOpenExternalLinks(true); + messageLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse); + + QSpacerItem *checkBoxRightSpacer = + new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum); + QSpacerItem *buttonSpacer = + new QSpacerItem(0, 1, QSizePolicy::Minimum, QSizePolicy::Minimum); + + checkBox = new QCheckBox(q); + checkBox->setText(Launcher::CheckableMessageBox::tr("Do not ask again")); + + buttonBox = new QDialogButtonBox(q); + buttonBox->setOrientation(Qt::Horizontal); + buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + + QVBoxLayout *verticalLayout = new QVBoxLayout(); + verticalLayout->addWidget(pixmapLabel); + verticalLayout->addItem(pixmapSpacer); + + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->addLayout(verticalLayout); + horizontalLayout_2->addWidget(messageLabel); + + QHBoxLayout *horizontalLayout = new QHBoxLayout(); + horizontalLayout->addWidget(checkBox); + horizontalLayout->addItem(checkBoxRightSpacer); + + QVBoxLayout *verticalLayout_2 = new QVBoxLayout(q); + verticalLayout_2->addLayout(horizontalLayout_2); + verticalLayout_2->addLayout(horizontalLayout); + verticalLayout_2->addItem(buttonSpacer); + verticalLayout_2->addWidget(buttonBox); +} -CheckableMessageBox::CheckableMessageBox(QWidget *parent) : +Launcher::CheckableMessageBox::CheckableMessageBox(QWidget *parent) : QDialog(parent), - d(new CheckableMessageBoxPrivate(this)) + d(new Launcher::CheckableMessageBoxPrivate(this)) { setModal(true); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); @@ -129,102 +118,102 @@ CheckableMessageBox::CheckableMessageBox(QWidget *parent) : SLOT(slotClicked(QAbstractButton*))); } -CheckableMessageBox::~CheckableMessageBox() +Launcher::CheckableMessageBox::~CheckableMessageBox() { delete d; } -void CheckableMessageBox::slotClicked(QAbstractButton *b) +void Launcher::CheckableMessageBox::slotClicked(QAbstractButton *b) { d->clickedButton = b; } -QAbstractButton *CheckableMessageBox::clickedButton() const +QAbstractButton *Launcher::CheckableMessageBox::clickedButton() const { return d->clickedButton; } -QDialogButtonBox::StandardButton CheckableMessageBox::clickedStandardButton() const +QDialogButtonBox::StandardButton Launcher::CheckableMessageBox::clickedStandardButton() const { if (d->clickedButton) return d->buttonBox->standardButton(d->clickedButton); return QDialogButtonBox::NoButton; } -QString CheckableMessageBox::text() const +QString Launcher::CheckableMessageBox::text() const { return d->messageLabel->text(); } -void CheckableMessageBox::setText(const QString &t) +void Launcher::CheckableMessageBox::setText(const QString &t) { d->messageLabel->setText(t); } -QPixmap CheckableMessageBox::iconPixmap() const +QPixmap Launcher::CheckableMessageBox::iconPixmap() const { if (const QPixmap *p = d->pixmapLabel->pixmap()) return QPixmap(*p); return QPixmap(); } -void CheckableMessageBox::setIconPixmap(const QPixmap &p) +void Launcher::CheckableMessageBox::setIconPixmap(const QPixmap &p) { d->pixmapLabel->setPixmap(p); d->pixmapLabel->setVisible(!p.isNull()); } -bool CheckableMessageBox::isChecked() const +bool Launcher::CheckableMessageBox::isChecked() const { return d->checkBox->isChecked(); } -void CheckableMessageBox::setChecked(bool s) +void Launcher::CheckableMessageBox::setChecked(bool s) { d->checkBox->setChecked(s); } -QString CheckableMessageBox::checkBoxText() const +QString Launcher::CheckableMessageBox::checkBoxText() const { return d->checkBox->text(); } -void CheckableMessageBox::setCheckBoxText(const QString &t) +void Launcher::CheckableMessageBox::setCheckBoxText(const QString &t) { d->checkBox->setText(t); } -bool CheckableMessageBox::isCheckBoxVisible() const +bool Launcher::CheckableMessageBox::isCheckBoxVisible() const { return d->checkBox->isVisible(); } -void CheckableMessageBox::setCheckBoxVisible(bool v) +void Launcher::CheckableMessageBox::setCheckBoxVisible(bool v) { d->checkBox->setVisible(v); } -QDialogButtonBox::StandardButtons CheckableMessageBox::standardButtons() const +QDialogButtonBox::StandardButtons Launcher::CheckableMessageBox::standardButtons() const { return d->buttonBox->standardButtons(); } -void CheckableMessageBox::setStandardButtons(QDialogButtonBox::StandardButtons s) +void Launcher::CheckableMessageBox::setStandardButtons(QDialogButtonBox::StandardButtons s) { d->buttonBox->setStandardButtons(s); } -QPushButton *CheckableMessageBox::button(QDialogButtonBox::StandardButton b) const +QPushButton *Launcher::CheckableMessageBox::button(QDialogButtonBox::StandardButton b) const { return d->buttonBox->button(b); } -QPushButton *CheckableMessageBox::addButton(const QString &text, QDialogButtonBox::ButtonRole role) +QPushButton *Launcher::CheckableMessageBox::addButton(const QString &text, QDialogButtonBox::ButtonRole role) { return d->buttonBox->addButton(text, role); } -QDialogButtonBox::StandardButton CheckableMessageBox::defaultButton() const +QDialogButtonBox::StandardButton Launcher::CheckableMessageBox::defaultButton() const { foreach (QAbstractButton *b, d->buttonBox->buttons()) if (QPushButton *pb = qobject_cast(b)) @@ -233,7 +222,7 @@ QDialogButtonBox::StandardButton CheckableMessageBox::defaultButton() const return QDialogButtonBox::NoButton; } -void CheckableMessageBox::setDefaultButton(QDialogButtonBox::StandardButton s) +void Launcher::CheckableMessageBox::setDefaultButton(QDialogButtonBox::StandardButton s) { if (QPushButton *b = d->buttonBox->button(s)) { b->setDefault(true); @@ -242,7 +231,7 @@ void CheckableMessageBox::setDefaultButton(QDialogButtonBox::StandardButton s) } QDialogButtonBox::StandardButton -CheckableMessageBox::question(QWidget *parent, +Launcher::CheckableMessageBox::question(QWidget *parent, const QString &title, const QString &question, const QString &checkBoxText, @@ -263,7 +252,7 @@ CheckableMessageBox::question(QWidget *parent, return mb.clickedStandardButton(); } -QMessageBox::StandardButton CheckableMessageBox::dialogButtonBoxToMessageBoxButton(QDialogButtonBox::StandardButton db) +QMessageBox::StandardButton Launcher::CheckableMessageBox::dialogButtonBoxToMessageBoxButton(QDialogButtonBox::StandardButton db) { return static_cast(int(db)); } diff --git a/apps/launcher/utils/checkablemessagebox.hpp b/apps/launcher/utils/checkablemessagebox.hpp index 93fd43fe1..09a501b9c 100644 --- a/apps/launcher/utils/checkablemessagebox.hpp +++ b/apps/launcher/utils/checkablemessagebox.hpp @@ -34,67 +34,83 @@ #include #include -class CheckableMessageBoxPrivate; +class QCheckBox; -class CheckableMessageBox : public QDialog +namespace Launcher { - Q_OBJECT - Q_PROPERTY(QString text READ text WRITE setText) - Q_PROPERTY(QPixmap iconPixmap READ iconPixmap WRITE setIconPixmap) - Q_PROPERTY(bool isChecked READ isChecked WRITE setChecked) - Q_PROPERTY(QString checkBoxText READ checkBoxText WRITE setCheckBoxText) - Q_PROPERTY(QDialogButtonBox::StandardButtons buttons READ standardButtons WRITE setStandardButtons) - Q_PROPERTY(QDialogButtonBox::StandardButton defaultButton READ defaultButton WRITE setDefaultButton) - -public: - explicit CheckableMessageBox(QWidget *parent); - virtual ~CheckableMessageBox(); - - static QDialogButtonBox::StandardButton - question(QWidget *parent, - const QString &title, - const QString &question, - const QString &checkBoxText, - bool *checkBoxSetting, - QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Yes|QDialogButtonBox::No, - QDialogButtonBox::StandardButton defaultButton = QDialogButtonBox::No); - - QString text() const; - void setText(const QString &); - - bool isChecked() const; - void setChecked(bool s); - - QString checkBoxText() const; - void setCheckBoxText(const QString &); - - bool isCheckBoxVisible() const; - void setCheckBoxVisible(bool); - - QDialogButtonBox::StandardButtons standardButtons() const; - void setStandardButtons(QDialogButtonBox::StandardButtons s); - QPushButton *button(QDialogButtonBox::StandardButton b) const; - QPushButton *addButton(const QString &text, QDialogButtonBox::ButtonRole role); - - QDialogButtonBox::StandardButton defaultButton() const; - void setDefaultButton(QDialogButtonBox::StandardButton s); - - // See static QMessageBox::standardPixmap() - QPixmap iconPixmap() const; - void setIconPixmap (const QPixmap &p); - - // Query the result - QAbstractButton *clickedButton() const; - QDialogButtonBox::StandardButton clickedStandardButton() const; - - // Conversion convenience - static QMessageBox::StandardButton dialogButtonBoxToMessageBoxButton(QDialogButtonBox::StandardButton); - -private slots: - void slotClicked(QAbstractButton *b); - -private: - CheckableMessageBoxPrivate *d; -}; - + class CheckableMessageBoxPrivate + { + public: + + QLabel *pixmapLabel; + QLabel *messageLabel; + QCheckBox *checkBox; + QDialogButtonBox *buttonBox; + QAbstractButton *clickedButton; + + public: + CheckableMessageBoxPrivate(QDialog *q); + }; + + class CheckableMessageBox : public QDialog + { + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(QPixmap iconPixmap READ iconPixmap WRITE setIconPixmap) + Q_PROPERTY(bool isChecked READ isChecked WRITE setChecked) + Q_PROPERTY(QString checkBoxText READ checkBoxText WRITE setCheckBoxText) + Q_PROPERTY(QDialogButtonBox::StandardButtons buttons READ standardButtons WRITE setStandardButtons) + Q_PROPERTY(QDialogButtonBox::StandardButton defaultButton READ defaultButton WRITE setDefaultButton) + + public: + explicit CheckableMessageBox(QWidget *parent); + virtual ~CheckableMessageBox(); + + static QDialogButtonBox::StandardButton + question(QWidget *parent, + const QString &title, + const QString &question, + const QString &checkBoxText, + bool *checkBoxSetting, + QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Yes|QDialogButtonBox::No, + QDialogButtonBox::StandardButton defaultButton = QDialogButtonBox::No); + + QString text() const; + void setText(const QString &); + + bool isChecked() const; + void setChecked(bool s); + + QString checkBoxText() const; + void setCheckBoxText(const QString &); + + bool isCheckBoxVisible() const; + void setCheckBoxVisible(bool); + + QDialogButtonBox::StandardButtons standardButtons() const; + void setStandardButtons(QDialogButtonBox::StandardButtons s); + QPushButton *button(QDialogButtonBox::StandardButton b) const; + QPushButton *addButton(const QString &text, QDialogButtonBox::ButtonRole role); + + QDialogButtonBox::StandardButton defaultButton() const; + void setDefaultButton(QDialogButtonBox::StandardButton s); + + // See static QMessageBox::standardPixmap() + QPixmap iconPixmap() const; + void setIconPixmap (const QPixmap &p); + + // Query the result + QAbstractButton *clickedButton() const; + QDialogButtonBox::StandardButton clickedStandardButton() const; + + // Conversion convenience + static QMessageBox::StandardButton dialogButtonBoxToMessageBoxButton(QDialogButtonBox::StandardButton); + + private slots: + void slotClicked(QAbstractButton *b); + + private: + CheckableMessageBoxPrivate *d; + }; +} #endif // CHECKABLEMESSAGEBOX_HPP diff --git a/apps/launcher/utils/textinputdialog.cpp b/apps/launcher/utils/textinputdialog.cpp index 9957e7dda..76cbe32d0 100644 --- a/apps/launcher/utils/textinputdialog.cpp +++ b/apps/launcher/utils/textinputdialog.cpp @@ -7,7 +7,7 @@ #include #include -TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWidget *parent) : +Launcher::TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWidget *parent) : QDialog(parent) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); @@ -45,19 +45,19 @@ TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWid } -int TextInputDialog::exec() +int Launcher::TextInputDialog::exec() { mLineEdit->clear(); mLineEdit->setFocus(); return QDialog::exec(); } -QString TextInputDialog::getText() const +QString Launcher::TextInputDialog::getText() const { return mLineEdit->text(); } -void TextInputDialog::slotUpdateOkButton(QString text) +void Launcher::TextInputDialog::slotUpdateOkButton(QString text) { bool enabled = !(text.isEmpty()); mButtonBox->button(QDialogButtonBox::Ok)->setEnabled(enabled); @@ -73,7 +73,7 @@ void TextInputDialog::slotUpdateOkButton(QString text) } } -TextInputDialog::DialogLineEdit::DialogLineEdit (QWidget *parent) : +Launcher::TextInputDialog::DialogLineEdit::DialogLineEdit (QWidget *parent) : LineEdit (parent) { int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); diff --git a/apps/launcher/utils/textinputdialog.hpp b/apps/launcher/utils/textinputdialog.hpp index 148bbd152..bb01778be 100644 --- a/apps/launcher/utils/textinputdialog.hpp +++ b/apps/launcher/utils/textinputdialog.hpp @@ -7,33 +7,34 @@ class QDialogButtonBox; -class LineEdit; - -class TextInputDialog : public QDialog +namespace Launcher { - Q_OBJECT - - class DialogLineEdit : public LineEdit + class TextInputDialog : public QDialog { - public: - explicit DialogLineEdit (QWidget *parent = 0); - }; + Q_OBJECT - DialogLineEdit *mLineEdit; - QDialogButtonBox *mButtonBox; + class DialogLineEdit : public LineEdit + { + public: + explicit DialogLineEdit (QWidget *parent = 0); + }; -public: + DialogLineEdit *mLineEdit; + QDialogButtonBox *mButtonBox; - explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0); - ~TextInputDialog () {} + public: + + explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0); + ~TextInputDialog () {} - QString getText() const; + QString getText() const; - int exec(); + int exec(); -private slots: - void slotUpdateOkButton(QString text); - -}; + private slots: + void slotUpdateOkButton(QString text); + + }; +} #endif // TEXTINPUTDIALOG_HPP From ba365ff49ed9be07af0244389077c3fc71b36d7a Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 25 Oct 2013 19:23:03 -0500 Subject: [PATCH 099/118] Fixed merge conflicts with saving branch --- apps/launcher/datafilespage.cpp | 34 ------------------- apps/opencs/editor.cpp | 8 ++--- apps/opencs/editor.hpp | 2 +- apps/opencs/model/doc/document.cpp | 2 +- apps/opencs/model/world/idcollection.hpp | 2 +- apps/opencs/view/doc/filedialog.cpp | 42 +++++++++++------------- apps/opencs/view/doc/filedialog.hpp | 9 +++-- 7 files changed, 31 insertions(+), 68 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index d36ab65e9..e246b4515 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -161,42 +161,8 @@ void Launcher::DataFilesPage::slotProfileDeleted (const QString &item) void Launcher::DataFilesPage::slotProfileChangedByUser(const QString &previous, const QString ¤t) { -<<<<<<< HEAD setProfile(previous, current, true); emit signalProfileChanged (ui.profilesComboBox->findText(current)); -======= - if (mContentModel->rowCount() < 1) - return; - - QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); - - if (profile.isEmpty()) { - profile = profilesComboBox->currentText(); - mLauncherSettings.setValue(QString("Profiles/currentprofile"), profile); - } - - mLauncherSettings.remove(QString("Profiles/") + profile + QString("/master")); - mLauncherSettings.remove(QString("Profiles/") + profile + QString("/plugin")); - - mGameSettings.remove(QString("master")); - mGameSettings.remove(QString("plugins")); - mGameSettings.remove(QString("content")); - - ContentSelectorModel::ContentFileList items = mContentModel->checkedItems(); - - foreach(const ContentSelectorModel::EsmFile *item, items) { - - if (item->gameFiles().size() == 0) { - mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/master"), item->fileName()); - mGameSettings.setMultiValue(QString("content"), item->fileName()); - - } else { - mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/plugin"), item->fileName()); - mGameSettings.setMultiValue(QString("content"), item->fileName()); - } - } - ->>>>>>> 3146af34d642a28b15b55f7eb9999d8ac50168a0 } void Launcher::DataFilesPage::slotProfileRenamed(const QString &previous, const QString ¤t) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 03758b16e..51cc490c7 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -10,6 +10,7 @@ #include "model/world/data.hpp" #include +#include CS::Editor::Editor() : mDocumentManager (mCfgMgr), mViewManager (mDocumentManager) @@ -19,7 +20,6 @@ CS::Editor::Editor() setupDataFiles(); mNewGame.setLocalData (mLocal); - mFileDialog.setLocalData (mLocal); connect (&mViewManager, SIGNAL (newGameRequest ()), this, SLOT (createGame ())); connect (&mViewManager, SIGNAL (newAddonRequest ()), this, SLOT (createAddon ())); @@ -32,8 +32,8 @@ CS::Editor::Editor() connect (&mStartup, SIGNAL (editConfig()), this, SLOT (showSettings ())); connect (&mFileDialog, SIGNAL(openFiles()), this, SLOT(openFiles())); - connect (&mFileDialog, SIGNAL(createNewFile (const boost::filesystem::path&)), - this, SLOT(createNewFile (const boost::filesystem::path&))); + connect (&mFileDialog, SIGNAL(createNewFile ()), + this, SLOT(createNewFile ())); connect (&mNewGame, SIGNAL (createRequest (const boost::filesystem::path&)), this, SLOT (createNewGame (const boost::filesystem::path&))); @@ -141,7 +141,7 @@ void CS::Editor::openFiles() mFileDialog.hide(); } -void CS::Editor::createNewFile (const boost::filesystem::path& savePath) +void CS::Editor::createNewFile () { std::vector files; diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 16f6b9516..ef013bc8f 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -60,7 +60,7 @@ namespace CS void loadDocument(); void openFiles(); - void createNewFile (const boost::filesystem::path& savePath); + void createNewFile (); void createNewGame (const boost::filesystem::path& file); void showStartup(); diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index cc886f9cc..590a19439 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2246,7 +2246,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, co mData.setAuthor (""); } /// \todo un-outcomment the else, once loading an existing content file works properly again. -// else + else { if (boost::filesystem::exists (mProjectPath)) { diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 0d723bef1..a7b37be5b 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -111,7 +111,7 @@ namespace CSMWorld else { record.mState = RecordBase::State_Deleted; - setRecord (index, record); + this->setRecord (index, record); } return true; diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 0bf7c6951..fb6c0a0e8 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -17,8 +17,6 @@ #include "filewidget.hpp" #include "adjusterwidget.hpp" -#include - CSVDoc::FileDialog::FileDialog(QWidget *parent) : QDialog(parent), mSelector (0) { @@ -61,6 +59,13 @@ void CSVDoc::FileDialog::showDialog(DialogType dialogType) break; } + //connections common to both dialog view flavors + connect (mSelector, SIGNAL (signalCurrentGamefileIndexChanged (int)), + this, SLOT (slotUpdateAcceptButton (int))); + + connect (ui.projectButtonBox, SIGNAL (accepted()), this, SIGNAL (createNewFile())); + connect (ui.projectButtonBox, SIGNAL (rejected()), this, SLOT (slotRejected())); + show(); raise(); activateWindow(); @@ -82,13 +87,7 @@ void CSVDoc::FileDialog::buildNewFileView() ui.projectGroupBoxLayout->insertWidget (0, mFileWidget); connect (mFileWidget, SIGNAL (nameChanged(const QString &, bool)), - this, SLOT (slotUpdateCreateButton(const QString &, bool))); - - connect (mSelector, SIGNAL (signalCurrentGamefileIndexChanged (int)), - this, SLOT (slotUpdateCreateButton (int))); - - connect (ui.projectButtonBox, SIGNAL (accepted()), this, SIGNAL (createNewFile())); - connect (ui.projectButtonBox, SIGNAL (rejected()), this, SLOT (slotRejected())); + this, SLOT (slotUpdateAcceptButton(const QString &, bool))); } void CSVDoc::FileDialog::buildOpenFileView() @@ -96,21 +95,25 @@ void CSVDoc::FileDialog::buildOpenFileView() setWindowTitle(tr("Open")); ui.projectGroupBox->setTitle (QString("")); - connect (ui.projectButtonBox, SIGNAL (accepted()), this, SIGNAL (openFiles())); - connect (ui.projectButtonBox, SIGNAL (rejected()), this, SLOT (slotRejected())); + ui.projectButtonBox->button(QDialogButtonBox::Ok)->setEnabled (false); } -void CSVDoc::FileDialog::slotUpdateCreateButton (int) +void CSVDoc::FileDialog::slotUpdateAcceptButton (int) { - slotUpdateCreateButton (mFileWidget->getName(), true); + QString name = ""; + + if (mDialogType == DialogType_New) + name = mFileWidget->getName(); + + slotUpdateAcceptButton (name, true); } -void CSVDoc::FileDialog::slotUpdateCreateButton(const QString &name, bool) +void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool) { - if (!(mDialogType == DialogType_New)) - return; + bool success = (mSelector->selectedFiles().size() > 0); - bool success = (!name.isEmpty() && mSelector->selectedFiles().size() > 0); + if (mDialogType == DialogType_New) + success = success && !(name.isEmpty()); ui.projectButtonBox->button (QDialogButtonBox::Ok)->setEnabled (success); } @@ -128,8 +131,3 @@ void CSVDoc::FileDialog::slotRejected() emit rejected(); close(); } - -void CSVDoc::FileDialog::createNewFile() -{ - emit createNewFile (mAdjusterWidget->getPath()); -} diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index be268f372..30f2f5d56 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -55,15 +55,14 @@ namespace CSVDoc signals: void openFiles(); - void createNewFile (const boost::filesystem::path& savePath); + void createNewFile (); - void signalUpdateCreateButton (bool, int); - void signalUpdateCreateButtonFlags(int); + void signalUpdateAcceptButton (bool, int); private slots: - void slotUpdateCreateButton (int); - void slotUpdateCreateButton (const QString &, bool); + void slotUpdateAcceptButton (int); + void slotUpdateAcceptButton (const QString &, bool); void slotRejected(); }; } From 9b483c3ae31f0ce11ea9a47fbada16441cf2c4ae Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 26 Oct 2013 22:55:44 -0500 Subject: [PATCH 100/118] Fix for file path issues --- apps/opencs/editor.cpp | 20 +++++++-------- apps/opencs/editor.hpp | 4 +-- apps/opencs/view/doc/filedialog.cpp | 39 ++++++++++++++++++++++++++--- apps/opencs/view/doc/filedialog.hpp | 17 +++++++++++-- files/ui/filedialog.ui | 4 +-- 5 files changed, 64 insertions(+), 20 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 51cc490c7..a8006d2b4 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -20,6 +20,7 @@ CS::Editor::Editor() setupDataFiles(); mNewGame.setLocalData (mLocal); + mFileDialog.setLocalData (mLocal); connect (&mViewManager, SIGNAL (newGameRequest ()), this, SLOT (createGame ())); connect (&mViewManager, SIGNAL (newAddonRequest ()), this, SLOT (createAddon ())); @@ -31,9 +32,11 @@ CS::Editor::Editor() connect (&mStartup, SIGNAL (loadDocument()), this, SLOT (loadDocument ())); connect (&mStartup, SIGNAL (editConfig()), this, SLOT (showSettings ())); - connect (&mFileDialog, SIGNAL(openFiles()), this, SLOT(openFiles())); - connect (&mFileDialog, SIGNAL(createNewFile ()), - this, SLOT(createNewFile ())); + connect (&mFileDialog, SIGNAL(signalOpenFiles (const boost::filesystem::path&)), + this, SLOT(openFiles (const boost::filesystem::path&))); + + connect (&mFileDialog, SIGNAL(signalCreateNewFile (const boost::filesystem::path&)), + this, SLOT(createNewFile (const boost::filesystem::path&))); connect (&mNewGame, SIGNAL (createRequest (const boost::filesystem::path&)), this, SLOT (createNewGame (const boost::filesystem::path&))); @@ -125,15 +128,12 @@ void CS::Editor::loadDocument() mFileDialog.showDialog (CSVDoc::FileDialog::DialogType_Open); } -void CS::Editor::openFiles() +void CS::Editor::openFiles (const boost::filesystem::path &savePath) { std::vector files; - foreach (const QString &path, mFileDialog.selectedFilePaths()) { + foreach (const QString &path, mFileDialog.selectedFilePaths()) files.push_back(path.toStdString()); - } - - boost::filesystem::path savePath = mFileDialog.filename().toStdString(); CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, false); @@ -141,7 +141,7 @@ void CS::Editor::openFiles() mFileDialog.hide(); } -void CS::Editor::createNewFile () +void CS::Editor::createNewFile (const boost::filesystem::path &savePath) { std::vector files; @@ -151,8 +151,6 @@ void CS::Editor::createNewFile () files.push_back(mFileDialog.filename().toStdString()); - boost::filesystem::path savePath = mFileDialog.filename().toStdString(); - CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, true); mViewManager.addView (document); diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index ef013bc8f..930aa9d64 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -59,8 +59,8 @@ namespace CS void createAddon(); void loadDocument(); - void openFiles(); - void createNewFile (); + void openFiles (const boost::filesystem::path &path); + void createNewFile (const boost::filesystem::path& path); void createNewGame (const boost::filesystem::path& file); void showStartup(); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index fb6c0a0e8..eb94aa5f4 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -17,14 +17,17 @@ #include "filewidget.hpp" #include "adjusterwidget.hpp" +#include + CSVDoc::FileDialog::FileDialog(QWidget *parent) : - QDialog(parent), mSelector (0) + QDialog(parent), mSelector (0), mFileWidget (0), mAdjusterWidget (0) { ui.setupUi (this); resize(400, 400); setObjectName ("FileDialog"); mSelector = new ContentSelectorView::ContentSelector (ui.contentSelectorWidget); + mAdjusterWidget = new AdjusterWidget (this); } void CSVDoc::FileDialog::addFiles(const QString &path) @@ -42,6 +45,14 @@ QStringList CSVDoc::FileDialog::selectedFilePaths() return filePaths; } +void CSVDoc::FileDialog::setLocalData (const boost::filesystem::path& localData) +{ + if (mDialogType != DialogType_New) + return; + + mAdjusterWidget->setLocalData (localData); +} + void CSVDoc::FileDialog::showDialog(DialogType dialogType) { mDialogType = dialogType; @@ -63,7 +74,6 @@ void CSVDoc::FileDialog::showDialog(DialogType dialogType) connect (mSelector, SIGNAL (signalCurrentGamefileIndexChanged (int)), this, SLOT (slotUpdateAcceptButton (int))); - connect (ui.projectButtonBox, SIGNAL (accepted()), this, SIGNAL (createNewFile())); connect (ui.projectButtonBox, SIGNAL (rejected()), this, SLOT (slotRejected())); show(); @@ -85,17 +95,26 @@ void CSVDoc::FileDialog::buildNewFileView() mFileWidget->extensionLabelIsVisible(true); ui.projectGroupBoxLayout->insertWidget (0, mFileWidget); + ui.projectGroupBoxLayout->insertWidget (1, mAdjusterWidget); + + connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)), + mAdjusterWidget, SLOT (setName (const QString&, bool))); connect (mFileWidget, SIGNAL (nameChanged(const QString &, bool)), this, SLOT (slotUpdateAcceptButton(const QString &, bool))); + + connect (ui.projectButtonBox, SIGNAL (accepted()), this, SLOT (slotNewFile())); } void CSVDoc::FileDialog::buildOpenFileView() { setWindowTitle(tr("Open")); ui.projectGroupBox->setTitle (QString("")); + ui.projectGroupBox->layout()->addWidget (mAdjusterWidget); ui.projectButtonBox->button(QDialogButtonBox::Ok)->setEnabled (false); + + connect (ui.projectButtonBox, SIGNAL (accepted()), this, SLOT (slotOpenFile())); } void CSVDoc::FileDialog::slotUpdateAcceptButton (int) @@ -121,7 +140,7 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool) QString CSVDoc::FileDialog::filename() const { if (mDialogType == DialogType_New) - return mFileWidget->getName(); + return ""; return mSelector->currentFile(); } @@ -131,3 +150,17 @@ void CSVDoc::FileDialog::slotRejected() emit rejected(); close(); } + +void CSVDoc::FileDialog::slotNewFile() +{ + emit signalCreateNewFile (mAdjusterWidget->getPath()); +} + +void CSVDoc::FileDialog::slotOpenFile() +{ + ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back(); + + mAdjusterWidget->setName (file->fileName(), !file->isGameFile()); + + emit signalOpenFiles (mAdjusterWidget->getPath()); +} diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 30f2f5d56..777ee31e4 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -4,6 +4,13 @@ #include #include +#include + +#ifndef CS_QT_BOOST_FILESYSTEM_PATH_DECLARED +#define CS_QT_BOOST_FILESYSTEM_PATH_DECLARED +Q_DECLARE_METATYPE (boost::filesystem::path) +#endif + #include "ui_filedialog.h" class DataFilesModel; @@ -17,6 +24,7 @@ namespace ContentSelectorView namespace CSVDoc { class FileWidget; + class AdjusterWidget; class FileDialog : public QDialog { @@ -36,6 +44,7 @@ namespace CSVDoc Ui::FileDialog ui; DialogType mDialogType; FileWidget *mFileWidget; + AdjusterWidget *mAdjusterWidget; public: @@ -47,6 +56,8 @@ namespace CSVDoc QString filename() const; QStringList selectedFilePaths(); + void setLocalData (const boost::filesystem::path& localData); + private: void buildNewFileView(); @@ -54,13 +65,15 @@ namespace CSVDoc signals: - void openFiles(); - void createNewFile (); + void signalOpenFiles (const boost::filesystem::path &path); + void signalCreateNewFile (const boost::filesystem::path &path); void signalUpdateAcceptButton (bool, int); private slots: + void slotNewFile(); + void slotOpenFile(); void slotUpdateAcceptButton (int); void slotUpdateAcceptButton (const QString &, bool); void slotRejected(); diff --git a/files/ui/filedialog.ui b/files/ui/filedialog.ui index 114345e53..b3af166da 100644 --- a/files/ui/filedialog.ui +++ b/files/ui/filedialog.ui @@ -7,7 +7,7 @@ 0 0 518 - 108 + 109
@@ -52,7 +52,7 @@ - + From 5e123d3f52bafc42d63455f91d30d7b2677a9389 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 26 Oct 2013 22:57:22 -0500 Subject: [PATCH 101/118] Hide adjusterwidget for open files view --- apps/opencs/view/doc/filedialog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index eb94aa5f4..903e78cf1 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -112,6 +112,8 @@ void CSVDoc::FileDialog::buildOpenFileView() ui.projectGroupBox->setTitle (QString("")); ui.projectGroupBox->layout()->addWidget (mAdjusterWidget); + mAdjusterWidget->setVisible (false); + ui.projectButtonBox->button(QDialogButtonBox::Ok)->setEnabled (false); connect (ui.projectButtonBox, SIGNAL (accepted()), this, SLOT (slotOpenFile())); From ea7a8eb2a4e7367530831c8172e159d6a9acf663 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sat, 26 Oct 2013 23:04:39 -0500 Subject: [PATCH 102/118] last commit --- apps/opencs/editor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index a8006d2b4..1c861ed67 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -135,6 +135,7 @@ void CS::Editor::openFiles (const boost::filesystem::path &savePath) foreach (const QString &path, mFileDialog.selectedFilePaths()) files.push_back(path.toStdString()); + qDebug() << "save file path: " << savePath.c_str(); CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, false); mViewManager.addView (document); From 489475a32f14e24e4554b393261280abc947c194 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sun, 27 Oct 2013 19:57:05 +0100 Subject: [PATCH 103/118] Corrected compilation error (g++ 4.8.2) triggered by not found declaration in argument-dependent lookup at the point of instantiation. Signed-off-by: Lukasz Gromanowski --- apps/opencs/model/world/idcollection.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 0d723bef1..a7b37be5b 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -111,7 +111,7 @@ namespace CSMWorld else { record.mState = RecordBase::State_Deleted; - setRecord (index, record); + this->setRecord (index, record); } return true; From d51c9b64dd2c4df61b03ce5dadfb724bcb6dc07f Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sun, 27 Oct 2013 20:03:12 +0100 Subject: [PATCH 104/118] Issue #913: Merge --master and --plugin switches Launcher part of master/plugin switches merge. Signed-off-by: Lukasz Gromanowski --- apps/launcher/datafilespage.cpp | 28 ++++-------------- apps/launcher/maindialog.cpp | 16 +++------- apps/launcher/settings/gamesettings.cpp | 29 ++++++++++++------- apps/launcher/settings/gamesettings.hpp | 10 +++++-- .../contentselector/model/contentmodel.cpp | 10 ++++++- 5 files changed, 44 insertions(+), 49 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 43f09d168..5e19ba9c9 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -185,9 +185,6 @@ void DataFilesPage::loadSettings() // mContentSelector. mContentModel->uncheckAll(); - - 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() @@ -202,27 +199,14 @@ void DataFilesPage::saveSettings() mLauncherSettings.setValue(QString("Profiles/currentprofile"), profile); } - mLauncherSettings.remove(QString("Profiles/") + profile + QString("/master")); - mLauncherSettings.remove(QString("Profiles/") + profile + QString("/plugin")); - - mGameSettings.remove(QString("master")); - mGameSettings.remove(QString("plugins")); + mLauncherSettings.remove(QString("Profiles/") + profile + QString("/content")); mGameSettings.remove(QString("content")); ContentSelectorModel::ContentFileList items = mContentModel->checkedItems(); - foreach(const ContentSelectorModel::EsmFile *item, items) { - - if (item->gameFiles().size() == 0) { - mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/master"), item->fileName()); - mGameSettings.setMultiValue(QString("content"), item->fileName()); - - } else { - mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/plugin"), item->fileName()); - mGameSettings.setMultiValue(QString("content"), item->fileName()); - } + mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/content"), item->fileName()); + mGameSettings.setMultiValue(QString("content"), item->fileName()); } - } void DataFilesPage::updateOkButton(const QString &text) @@ -281,8 +265,7 @@ void DataFilesPage::on_deleteProfileAction_triggered() msgBox.exec(); if (msgBox.clickedButton() == deleteButton) { - mLauncherSettings.remove(QString("Profiles/") + profile + QString("/master")); - mLauncherSettings.remove(QString("Profiles/") + profile + QString("/plugin")); + mLauncherSettings.remove(QString("Profiles/") + profile + QString("/content")); // Remove the profile from the combobox profilesComboBox->removeItem(profilesComboBox->findText(profile)); @@ -348,8 +331,7 @@ void DataFilesPage::profileRenamed(const QString &previous, const QString &curre saveSettings(); // Remove the old one - mLauncherSettings.remove(QString("Profiles/") + previous + QString("/master")); - mLauncherSettings.remove(QString("Profiles/") + previous + QString("/plugin")); + mLauncherSettings.remove(QString("Profiles/") + previous + QString("/content")); // Remove the profile from the combobox profilesComboBox->removeItem(profilesComboBox->findText(previous)); diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 032f70916..0f59b3aaf 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -261,19 +261,11 @@ bool MainDialog::showFirstRunDialog() // Add a new profile if (msgBox.isChecked()) { mLauncherSettings.setValue(QString("Profiles/currentprofile"), QString("Imported")); + mLauncherSettings.remove(QString("Profiles/Imported/content")); - mLauncherSettings.remove(QString("Profiles/Imported/master")); - mLauncherSettings.remove(QString("Profiles/Imported/plugin")); - - QStringList masters = mGameSettings.values(QString("master")); - QStringList plugins = mGameSettings.values(QString("plugin")); - - foreach (const QString &master, masters) { - mLauncherSettings.setMultiValue(QString("Profiles/Imported/master"), master); - } - - foreach (const QString &plugin, plugins) { - mLauncherSettings.setMultiValue(QString("Profiles/Imported/plugin"), plugin); + QStringList contents = mGameSettings.values(QString("content")); + foreach (const QString &content, contents) { + mLauncherSettings.setMultiValue(QString("Profiles/Imported/content"), content); } } diff --git a/apps/launcher/settings/gamesettings.cpp b/apps/launcher/settings/gamesettings.cpp index 7b2356cd0..211e31927 100644 --- a/apps/launcher/settings/gamesettings.cpp +++ b/apps/launcher/settings/gamesettings.cpp @@ -139,13 +139,13 @@ bool GameSettings::writeFile(QTextStream &stream) while (i.hasPrevious()) { i.previous(); - if (i.key() == QLatin1String("master") || i.key() == QLatin1String("plugin")) + if (i.key() == QLatin1String("content")) continue; // Quote paths with spaces if (i.key() == QLatin1String("data") - || i.key() == QLatin1String("data-local") - || i.key() == QLatin1String("resources")) + || i.key() == QLatin1String("data-local") + || i.key() == QLatin1String("resources")) { if (i.value().contains(QChar(' '))) { @@ -161,15 +161,24 @@ bool GameSettings::writeFile(QTextStream &stream) } - QStringList masters = mSettings.values(QString("master")); - for (int i = masters.count(); i--;) { - stream << "content=" << masters.at(i) << "\n"; + QStringList content = mSettings.values(QString("content")); + for (int i = content.count(); i--;) { + stream << "content=" << content.at(i) << "\n"; } - QStringList plugins = mSettings.values(QString("plugin")); - for (int i = plugins.count(); i--;) { - stream << "content=" << plugins.at(i) << "\n"; + return true; +} + +bool GameSettings::hasMaster() +{ + bool result = false; + QStringList content = mSettings.values(QString("content")); + for (int i = 0; i < content.count(); ++i) { + if (content.at(i).contains(".omwgame") || content.at(i).contains(".esm")) { + result = true; + break; } + } - return true; + return result; } diff --git a/apps/launcher/settings/gamesettings.hpp b/apps/launcher/settings/gamesettings.hpp index 55b2107e2..c009c30ed 100644 --- a/apps/launcher/settings/gamesettings.hpp +++ b/apps/launcher/settings/gamesettings.hpp @@ -8,8 +8,11 @@ #include -namespace Files { typedef std::vector PathContainer; - struct ConfigurationManager;} +namespace Files +{ + typedef std::vector PathContainer; + struct ConfigurationManager; +} class GameSettings { @@ -43,7 +46,8 @@ public: inline QStringList getDataDirs() { return mDataDirs; } inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); } inline QString getDataLocal() {return mDataLocal; } - inline bool hasMaster() { return mSettings.count(QString("master")) > 0; } + + bool hasMaster(); QStringList values(const QString &key, const QStringList &defaultValues = QStringList()); bool readFile(QTextStream &stream); diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index b85da25c6..fb011198c 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -461,9 +461,17 @@ ContentSelectorModel::ContentFileList ContentSelectorModel::ContentModel::checke { ContentFileList list; + // First search for game files and next addons, + // so we get more or less correct game files vs addons order. foreach (EsmFile *file, mFiles) { - if (isChecked(file->fileName())) + if (isChecked(file->fileName()) && file->isGameFile()) + list << file; + } + + foreach (EsmFile *file, mFiles) + { + if (isChecked(file->fileName()) && !file->isGameFile()) list << file; } From b51bef0d98687c95d35f69a8b02b5b2fac6d48a5 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 27 Oct 2013 20:21:19 -0500 Subject: [PATCH 105/118] fixed missing adjuster widget in file dialog open view --- apps/opencs/view/doc/adjusterwidget.cpp | 13 +++++++++- apps/opencs/view/doc/adjusterwidget.hpp | 11 +++++++++ apps/opencs/view/doc/filedialog.cpp | 24 ++++++++++++------- apps/opencs/view/doc/filedialog.hpp | 14 +++-------- .../contentselector/view/contentselector.cpp | 12 ++++++++-- .../contentselector/view/contentselector.hpp | 2 ++ 6 files changed, 53 insertions(+), 23 deletions(-) diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp index b1eec63c3..332d46075 100644 --- a/apps/opencs/view/doc/adjusterwidget.cpp +++ b/apps/opencs/view/doc/adjusterwidget.cpp @@ -11,7 +11,7 @@ #include CSVDoc::AdjusterWidget::AdjusterWidget (QWidget *parent) -: QWidget (parent), mValid (false) + : QWidget (parent), mValid (false), mAction (ContentAction_Undefined) { QHBoxLayout *layout = new QHBoxLayout (this); @@ -30,6 +30,11 @@ CSVDoc::AdjusterWidget::AdjusterWidget (QWidget *parent) setLayout (layout); } +void CSVDoc::AdjusterWidget::setAction (ContentAction action) +{ + mAction = action; +} + void CSVDoc::AdjusterWidget::setLocalData (const boost::filesystem::path& localData) { mLocalData = localData; @@ -51,6 +56,12 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) { QString message; + if (mAction == ContentAction_Undefined) + { + throw std::runtime_error("ContentAction_Undefined when AdjusterWidget::setName() called."); + return; + } + if (name.isEmpty()) { mValid = false; diff --git a/apps/opencs/view/doc/adjusterwidget.hpp b/apps/opencs/view/doc/adjusterwidget.hpp index 461cfb345..627f89c1f 100644 --- a/apps/opencs/view/doc/adjusterwidget.hpp +++ b/apps/opencs/view/doc/adjusterwidget.hpp @@ -9,21 +9,32 @@ class QLabel; namespace CSVDoc { + enum ContentAction + { + ContentAction_New, + ContentAction_Edit, + ContentAction_Undefined + }; + class AdjusterWidget : public QWidget { Q_OBJECT + public: + boost::filesystem::path mLocalData; QLabel *mMessage; QLabel *mIcon; bool mValid; boost::filesystem::path mResultPath; + ContentAction mAction; public: AdjusterWidget (QWidget *parent = 0); void setLocalData (const boost::filesystem::path& localData); + void setAction (ContentAction action); bool isValid() const; diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 903e78cf1..57b61ff8b 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -53,17 +53,19 @@ void CSVDoc::FileDialog::setLocalData (const boost::filesystem::path& localData) mAdjusterWidget->setLocalData (localData); } -void CSVDoc::FileDialog::showDialog(DialogType dialogType) +void CSVDoc::FileDialog::showDialog (ContentAction action) { - mDialogType = dialogType; + mAction = action; - switch (mDialogType) + ui.projectGroupBoxLayout->insertWidget (0, mAdjusterWidget); + + switch (mAction) { - case DialogType_New: + case ContentAction_New: buildNewFileView(); break; - case DialogType_Open: + case ContentAction_Edit: buildOpenFileView(); break; default: @@ -95,7 +97,6 @@ void CSVDoc::FileDialog::buildNewFileView() mFileWidget->extensionLabelIsVisible(true); ui.projectGroupBoxLayout->insertWidget (0, mFileWidget); - ui.projectGroupBoxLayout->insertWidget (1, mAdjusterWidget); connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)), mAdjusterWidget, SLOT (setName (const QString&, bool))); @@ -110,12 +111,12 @@ void CSVDoc::FileDialog::buildOpenFileView() { setWindowTitle(tr("Open")); ui.projectGroupBox->setTitle (QString("")); - ui.projectGroupBox->layout()->addWidget (mAdjusterWidget); - - mAdjusterWidget->setVisible (false); ui.projectButtonBox->button(QDialogButtonBox::Ok)->setEnabled (false); + connect (mSelector, SIGNAL (signalAddonFileSelected (int)), this, SLOT (slotUpdateAcceptButton (int))); + connect (mSelector, SIGNAL (signalAddonFileUnselected (int)), this, SLOT (slotUpdateAcceptButton (int))); + connect (ui.projectButtonBox, SIGNAL (accepted()), this, SLOT (slotOpenFile())); } @@ -135,6 +136,11 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool) if (mDialogType == DialogType_New) success = success && !(name.isEmpty()); + else + { + ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back(); + mAdjusterWidget->setName (file->fileName(), !file->isGameFile()); + } ui.projectButtonBox->button (QDialogButtonBox::Ok)->setEnabled (success); } diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 777ee31e4..d9fd56943 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -5,6 +5,7 @@ #include #include +#include "adjusterwidget.hpp" #ifndef CS_QT_BOOST_FILESYSTEM_PATH_DECLARED #define CS_QT_BOOST_FILESYSTEM_PATH_DECLARED @@ -24,32 +25,23 @@ namespace ContentSelectorView namespace CSVDoc { class FileWidget; - class AdjusterWidget; class FileDialog : public QDialog { Q_OBJECT - public: - - enum DialogType - { - DialogType_New, - DialogType_Open - }; - private: ContentSelectorView::ContentSelector *mSelector; Ui::FileDialog ui; - DialogType mDialogType; + ContentAction mAction; FileWidget *mFileWidget; AdjusterWidget *mAdjusterWidget; public: explicit FileDialog(QWidget *parent = 0); - void showDialog (DialogType dialogType); + void showDialog (ContentAction action); void addFiles (const QString &path); diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index 33b31b00c..b9e518931 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -151,8 +151,16 @@ void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QMode { QAbstractItemModel *const model = ui.addonView->model(); + Qt::CheckState checkState = Qt::Unchecked; + if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked) - model->setData(index, Qt::Checked, Qt::CheckStateRole); + checkState = Qt::Checked; + + model->setData(index, checkState, Qt::CheckStateRole); + + if (checkState == Qt::Checked) + emit signalAddonFileSelected (index.row()); else - model->setData(index, Qt::Unchecked, Qt::CheckStateRole); + emit signalAddonFileUnselected (index.row()); + } diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index 1e24a5523..da1c39973 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -54,6 +54,8 @@ namespace ContentSelectorView signals: void signalCurrentGamefileIndexChanged (int); + void signalAddonFileSelected (int); + void signalAddonFileUnselected (int); private slots: From 632a53ead4f175e5b2769db4649b9ead93131019 Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Tue, 29 Oct 2013 13:28:43 +0100 Subject: [PATCH 106/118] Support packing the OpenCS into windows builds --- CMakeLists.txt | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 625239aa0..5a87a1a40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -458,10 +458,20 @@ if(WIN32) "${OpenMW_SOURCE_DIR}/Daedric Font License.txt" "${OpenMW_BINARY_DIR}/settings-default.cfg" "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" - "${OpenMW_BINARY_DIR}/Release/mwiniimport.exe" - "${OpenMW_BINARY_DIR}/Release/omwlauncher.exe" "${OpenMW_BINARY_DIR}/Release/openmw.exe" DESTINATION ".") + + IF(BUILD_LAUNCHER) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/omwlauncher.exe" DESTINATION ".") + ENDIF(BUILD_LAUNCHER) + IF(BUILD_MWINIIMPORTER) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/mwiniimport.exe" DESTINATION ".") + ENDIF(BUILD_MWINIIMPORTER) + IF(BUILD_OPENCS) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/opencs.exe" DESTINATION ".") + INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.cfg" DESTINATION ".") + ENDIF(BUILD_OPENCS) + INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".") SET(CPACK_GENERATOR "NSIS") @@ -471,7 +481,13 @@ if(WIN32) SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR}) SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINOR}) SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE}) - SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;omwlauncher;OpenMW Launcher") + SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW") + IF(BUILD_LAUNCHER) + SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};omwlauncher;OpenMW Launcher") + ENDIF(BUILD_LAUNCHER) + IF(BUILD_OPENCS) + SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};opencs;OpenMW Construction Set") + ENDIF(BUILD_OPENCS) SET(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'") SET(CPACK_NSIS_DELETE_ICONS_EXTRA " !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP From 0cb591e4f61a3f2caeb84cfc73c0b68ff187a244 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Thu, 31 Oct 2013 18:12:13 -0500 Subject: [PATCH 107/118] Fixed path problem with adjuster widget and local data path. --- apps/opencs/editor.cpp | 7 ++--- apps/opencs/view/doc/adjusterwidget.cpp | 35 ++++++++++++++++--------- apps/opencs/view/doc/adjusterwidget.hpp | 2 ++ apps/opencs/view/doc/filedialog.cpp | 18 ++++++------- 4 files changed, 35 insertions(+), 27 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 1c861ed67..63afe7a9d 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -10,8 +10,6 @@ #include "model/world/data.hpp" #include -#include - CS::Editor::Editor() : mDocumentManager (mCfgMgr), mViewManager (mDocumentManager) { @@ -119,13 +117,13 @@ void CS::Editor::createGame() void CS::Editor::createAddon() { mStartup.hide(); - mFileDialog.showDialog (CSVDoc::FileDialog::DialogType_New); + mFileDialog.showDialog (CSVDoc::ContentAction_New); } void CS::Editor::loadDocument() { mStartup.hide(); - mFileDialog.showDialog (CSVDoc::FileDialog::DialogType_Open); + mFileDialog.showDialog (CSVDoc::ContentAction_Edit); } void CS::Editor::openFiles (const boost::filesystem::path &savePath) @@ -135,7 +133,6 @@ void CS::Editor::openFiles (const boost::filesystem::path &savePath) foreach (const QString &path, mFileDialog.selectedFilePaths()) files.push_back(path.toStdString()); - qDebug() << "save file path: " << savePath.c_str(); CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, false); mViewManager.addView (document); diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp index 332d46075..09e58690f 100644 --- a/apps/opencs/view/doc/adjusterwidget.cpp +++ b/apps/opencs/view/doc/adjusterwidget.cpp @@ -52,47 +52,56 @@ bool CSVDoc::AdjusterWidget::isValid() const { return mValid; } + +void CSVDoc::AdjusterWidget::setFilenameCheck (bool doCheck) +{ + mDoFilenameCheck = doCheck; +} + void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) { QString message; - if (mAction == ContentAction_Undefined) - { - throw std::runtime_error("ContentAction_Undefined when AdjusterWidget::setName() called."); - return; - } + mValid = (!name.isEmpty()); - if (name.isEmpty()) + if (!mValid) { - mValid = false; message = "No name."; } else { boost::filesystem::path path (name.toUtf8().data()); - path.replace_extension (addon ? ".omwaddon" : ".omwgame"); + bool isLegacyPath = (path.extension() == ".esm" || + path.extension() == ".esp"); + + bool isFilePathChanged = (path.parent_path().string() != mLocalData.string()); + + if (isLegacyPath) + path.replace_extension (addon ? ".omwaddon" : ".omwgame"); - if (path.parent_path().string()==mLocalData.string()) + //if the file came from data-local and is not a legacy file to be converted, + //don't worry about doing a file check. + if (!isFilePathChanged && !isLegacyPath) { // path already points to the local data directory message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); mResultPath = path; - mValid = true; } + //in all other cases, ensure the path points to data-local and do an existing file check else { // path points somewhere else or is a leaf name. - path = mLocalData / path.filename(); + if (isFilePathChanged) + path = mLocalData / path.filename(); message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str()); mResultPath = path; - mValid = true; if (boost::filesystem::exists (path)) { /// \todo add an user setting to make this an error. - message += "

But a file with the same name already exists. If you continue, it will be overwritten."; + message += "

A file with the same name already exists. If you continue, it will be overwritten."; } } } diff --git a/apps/opencs/view/doc/adjusterwidget.hpp b/apps/opencs/view/doc/adjusterwidget.hpp index 627f89c1f..91e308236 100644 --- a/apps/opencs/view/doc/adjusterwidget.hpp +++ b/apps/opencs/view/doc/adjusterwidget.hpp @@ -28,6 +28,7 @@ namespace CSVDoc bool mValid; boost::filesystem::path mResultPath; ContentAction mAction; + bool mDoFilenameCheck; public: @@ -36,6 +37,7 @@ namespace CSVDoc void setLocalData (const boost::filesystem::path& localData); void setAction (ContentAction action); + void setFilenameCheck (bool doCheck); bool isValid() const; boost::filesystem::path getPath() const; diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 57b61ff8b..c0cda26dc 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -17,8 +17,6 @@ #include "filewidget.hpp" #include "adjusterwidget.hpp" -#include - CSVDoc::FileDialog::FileDialog(QWidget *parent) : QDialog(parent), mSelector (0), mFileWidget (0), mAdjusterWidget (0) { @@ -47,9 +45,6 @@ QStringList CSVDoc::FileDialog::selectedFilePaths() void CSVDoc::FileDialog::setLocalData (const boost::filesystem::path& localData) { - if (mDialogType != DialogType_New) - return; - mAdjusterWidget->setLocalData (localData); } @@ -68,10 +63,13 @@ void CSVDoc::FileDialog::showDialog (ContentAction action) case ContentAction_Edit: buildOpenFileView(); break; + default: break; } + mAdjusterWidget->setFilenameCheck (mAction == ContentAction_New); + //connections common to both dialog view flavors connect (mSelector, SIGNAL (signalCurrentGamefileIndexChanged (int)), this, SLOT (slotUpdateAcceptButton (int))); @@ -124,7 +122,7 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton (int) { QString name = ""; - if (mDialogType == DialogType_New) + if (mAction == ContentAction_New) name = mFileWidget->getName(); slotUpdateAcceptButton (name, true); @@ -134,11 +132,13 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool) { bool success = (mSelector->selectedFiles().size() > 0); - if (mDialogType == DialogType_New) + bool isNew = (mAction == ContentAction_New); + + if (isNew) success = success && !(name.isEmpty()); else { - ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back(); + ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back();; mAdjusterWidget->setName (file->fileName(), !file->isGameFile()); } @@ -147,7 +147,7 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool) QString CSVDoc::FileDialog::filename() const { - if (mDialogType == DialogType_New) + if (mAction == ContentAction_New) return ""; return mSelector->currentFile(); From cddece4f9e84de70e7861c24373c62a37d4356ad Mon Sep 17 00:00:00 2001 From: graffy76 Date: Fri, 1 Nov 2013 21:47:26 -0500 Subject: [PATCH 108/118] Another stab at fixing the pathing problem... --- apps/opencs/view/doc/adjusterwidget.cpp | 6 ++++- apps/opencs/view/doc/filedialog.cpp | 9 ++++--- .../contentselector/model/contentmodel.cpp | 27 ++++++++++++------- components/contentselector/model/esmfile.cpp | 6 ++--- components/contentselector/model/esmfile.hpp | 6 ++--- .../contentselector/view/contentselector.cpp | 5 ++-- 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp index 09e58690f..5ebfacd03 100644 --- a/apps/opencs/view/doc/adjusterwidget.cpp +++ b/apps/opencs/view/doc/adjusterwidget.cpp @@ -10,6 +10,9 @@ #include #include +#include + + CSVDoc::AdjusterWidget::AdjusterWidget (QWidget *parent) : QWidget (parent), mValid (false), mAction (ContentAction_Undefined) { @@ -76,7 +79,8 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) path.extension() == ".esp"); bool isFilePathChanged = (path.parent_path().string() != mLocalData.string()); - + qDebug() << "current path: " << path.parent_path().c_str(); + qDebug() << "data-local: " << mLocalData.c_str(); if (isLegacyPath) path.replace_extension (addon ? ".omwaddon" : ".omwgame"); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index c0cda26dc..ce7d7dfb0 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -17,6 +17,8 @@ #include "filewidget.hpp" #include "adjusterwidget.hpp" +#include + CSVDoc::FileDialog::FileDialog(QWidget *parent) : QDialog(parent), mSelector (0), mFileWidget (0), mAdjusterWidget (0) { @@ -38,7 +40,7 @@ QStringList CSVDoc::FileDialog::selectedFilePaths() QStringList filePaths; foreach (ContentSelectorModel::EsmFile *file, mSelector->selectedFiles() ) - filePaths.append(file->path()); + filePaths.append(file->filePath()); return filePaths; } @@ -139,7 +141,8 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool) else { ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back();; - mAdjusterWidget->setName (file->fileName(), !file->isGameFile()); + mAdjusterWidget->setName (file->filePath(), !file->isGameFile()); + qDebug() << "setting filepath " << file->filePath(); } ui.projectButtonBox->button (QDialogButtonBox::Ok)->setEnabled (success); @@ -168,7 +171,7 @@ void CSVDoc::FileDialog::slotOpenFile() { ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back(); - mAdjusterWidget->setName (file->fileName(), !file->isGameFile()); + mAdjusterWidget->setName (file->filePath(), !file->isGameFile()); emit signalOpenFiles (mAdjusterWidget->getPath()); } diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 0674642ee..ea389c2bf 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -69,7 +69,7 @@ const ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(co { foreach (const EsmFile *file, mFiles) { - if (name == file->fileName()) + if (name == file->filePath()) return file; } return 0; @@ -158,7 +158,7 @@ QVariant ContentSelectorModel::ContentModel::data(const QModelIndex &index, int case Qt::CheckStateRole: { if (!file->isGameFile()) - return isChecked(file->fileName()); + return isChecked(file->filePath()); break; } @@ -174,7 +174,7 @@ QVariant ContentSelectorModel::ContentModel::data(const QModelIndex &index, int } case Qt::UserRole + 1: - return isChecked(file->fileName()); + return isChecked(file->filePath()); break; } return QVariant(); @@ -186,7 +186,7 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex &index, const return false; EsmFile *file = item(index.row()); - QString fileName = file->fileName(); + QString fileName = file->filePath(); bool success = false; switch(role) @@ -396,6 +396,7 @@ bool ContentSelectorModel::ContentModel::canBeChecked(const EsmFile *file) const void ContentSelectorModel::ContentModel::addFile(EsmFile *file) { + qDebug() << "adding file: " << file->filePath(); beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); mFiles.append(file); endInsertRows(); @@ -417,6 +418,8 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path) // Create a decoder for non-latin characters in esx metadata QTextDecoder *decoder = codec->makeDecoder(); + qDebug() << "searching path: " << path << " files found: " << dir.entryList().size(); + foreach (const QString &path, dir.entryList()) { QFileInfo info(dir.absoluteFilePath(path)); @@ -430,18 +433,24 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path) fileReader.open(dir.absoluteFilePath(path).toStdString()); foreach (const ESM::Header::MasterData &item, fileReader.getGameFiles()) + { + qDebug() << "adding gamefile: " << item.name.c_str(); file->addGameFile(QString::fromStdString(item.name)); + } file->setAuthor (decoder->toUnicode(fileReader.getAuthor().c_str())); file->setDate (info.lastModified()); file->setFormat (fileReader.getFormat()); - file->setPath (info.absoluteFilePath()); + file->setFilePath (info.absoluteFilePath()); file->setDescription(decoder->toUnicode(fileReader.getDesc().c_str())); // Put the file in the table - if (item(path) == 0) + if (item(file->filePath()) == 0) + { + qDebug () << "adding file " << file->filePath(); addFile(file); + } } catch(std::runtime_error &e) { // An error occurred while reading the .esp @@ -543,8 +552,8 @@ void ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool { if (downstreamFile->gameFiles().contains(name)) { - if (mCheckStates.contains(downstreamFile->fileName())) - mCheckStates[downstreamFile->fileName()] = Qt::Unchecked; + if (mCheckStates.contains(downstreamFile->filePath())) + mCheckStates[downstreamFile->filePath()] = Qt::Unchecked; emit dataChanged(indexFromItem(downstreamFile), indexFromItem(downstreamFile)); } @@ -558,7 +567,7 @@ ContentSelectorModel::ContentFileList ContentSelectorModel::ContentModel::checke foreach (EsmFile *file, mFiles) { - if (isChecked(file->fileName())) + if (isChecked(file->filePath())) list << file; } diff --git a/components/contentselector/model/esmfile.cpp b/components/contentselector/model/esmfile.cpp index 9dfe49eba..35f78386c 100644 --- a/components/contentselector/model/esmfile.cpp +++ b/components/contentselector/model/esmfile.cpp @@ -34,7 +34,7 @@ void ContentSelectorModel::EsmFile::setFormat(int format) mFormat = format; } -void ContentSelectorModel::EsmFile::setPath(const QString &path) +void ContentSelectorModel::EsmFile::setFilePath(const QString &path) { mPath = path; } @@ -81,7 +81,7 @@ QVariant ContentSelectorModel::EsmFile::fileProperty(const FileProperty prop) co return mModified.toString(Qt::ISODate); break; - case FileProperty_Path: + case FileProperty_FilePath: return mPath; break; @@ -118,7 +118,7 @@ void ContentSelectorModel::EsmFile::setFileProperty (const FileProperty prop, co mModified = QDateTime::fromString(value); break; - case FileProperty_Path: + case FileProperty_FilePath: mPath = value; break; diff --git a/components/contentselector/model/esmfile.hpp b/components/contentselector/model/esmfile.hpp index 743b1c5a6..fc0cca8a2 100644 --- a/components/contentselector/model/esmfile.hpp +++ b/components/contentselector/model/esmfile.hpp @@ -23,7 +23,7 @@ namespace ContentSelectorModel FileProperty_Author = 1, FileProperty_Format = 2, FileProperty_DateModified = 3, - FileProperty_Path = 4, + FileProperty_FilePath = 4, FileProperty_Description = 5, FileProperty_GameFile = 6 }; @@ -41,7 +41,7 @@ namespace ContentSelectorModel void setSize(const int size); void setDate(const QDateTime &modified); void setFormat(const int format); - void setPath(const QString &path); + void setFilePath(const QString &path); void setGameFiles(const QStringList &gameFiles); void setDescription(const QString &description); @@ -52,7 +52,7 @@ namespace ContentSelectorModel 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 QString filePath() const { return mPath; } inline const QStringList &gameFiles() const { return mGameFiles; } inline QString description() const { return mDescription; } inline QString toolTip() const { return sToolTip.arg(mAuthor) diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index b9e518931..d12c8cb24 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -42,9 +42,6 @@ void ContentSelectorView::ContentSelector::buildGameFileView() connect (ui.gameFileView, SIGNAL (currentIndexChanged(int)), this, SLOT (slotCurrentGameFileIndexChanged(int))); - connect (ui.gameFileView, SIGNAL (currentIndexChanged (int)), - this, SIGNAL (signalCurrentGamefileIndexChanged (int))); - ui.gameFileView->setCurrentIndex(-1); ui.gameFileView->setCurrentIndex(0); } @@ -145,6 +142,8 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i if (proxy) proxy->setDynamicSortFilter(true); + + emit signalCurrentGamefileIndexChanged (index); } void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QModelIndex &index) From afce10cf37d261cf749faeed509e5c2fd63f5131 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Sat, 2 Nov 2013 16:20:40 +0100 Subject: [PATCH 109/118] Fixes #597: Assertion `dialogue->mId == id' failed in esmstore.cpp It seems that assertion was unnecessary, after removing it, dialogs related to moon-and-star in "Path of the Incarnate" quest were correctly loaded (dumped DialInfo records were correct). Signed-off-by: Lukasz Gromanowski --- apps/openmw/mwworld/esmstore.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 7703f2d23..5cee7efd9 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -100,11 +100,7 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener) it->second->load(esm, id); if (n.val==ESM::REC_DIAL) { - // dirty hack, but it is better than non-const search() - // or friends - //dialogue = &mDialogs.mStatic.back(); dialogue = const_cast(mDialogs.find(id)); - assert (dialogue->mId == id); } else { dialogue = 0; } From 973803eb2f6cdbdaded0649250092e7adcc526bc Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 3 Nov 2013 00:02:46 -0500 Subject: [PATCH 110/118] Fixed pathing issues in launcher --- apps/launcher/datafilespage.cpp | 44 +++++++++++-- apps/launcher/datafilespage.hpp | 58 ++++++++++++++++ apps/launcher/settings/gamesettings.cpp | 2 +- apps/launcher/settings/gamesettings.hpp | 5 -- apps/opencs/view/doc/adjusterwidget.cpp | 6 +- apps/opencs/view/doc/filedialog.cpp | 3 - .../contentselector/model/contentmodel.cpp | 66 +++++++++---------- .../contentselector/model/contentmodel.hpp | 3 +- components/contentselector/model/esmfile.cpp | 5 +- components/contentselector/model/esmfile.hpp | 1 + .../contentselector/view/contentselector.cpp | 12 ++-- 11 files changed, 143 insertions(+), 62 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index e246b4515..71d072599 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include @@ -37,6 +36,10 @@ Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSet void Launcher::DataFilesPage::loadSettings() { + QStringList paths = mGameSettings.getDataDirs(); + paths.insert (0, mDataLocal); + PathIterator pathIterator (paths); + QString profileName = ui.profilesComboBox->currentText(); QStringList files = mLauncherSettings.values(QString("Profiles/") + profileName + QString("/game"), Qt::MatchExactly); @@ -47,10 +50,37 @@ void Launcher::DataFilesPage::loadSettings() QString gameFile (""); if (files.size()>0) - gameFile = files.at (0); + { + gameFile = pathIterator.findFirstPath (files.at(0)); + + if (!gameFile.isEmpty()) + mSelector->setGameFile (gameFile); +/* else + { + //throw gamefile error here. + }*/ + } + + QStringList missingFiles; + QStringList foundFiles; - mSelector->setGameFile(gameFile); - mSelector->setCheckStates(addons); + foreach (const QString &addon, addons) + { + QString filePath = pathIterator.findFirstPath (addon); + + if (filePath.isEmpty()) + missingFiles << addon; + else + foundFiles << filePath; + } +/* + if (missingFiles.size() > 0) + { + //throw addons error here. + } +*/ + if (foundFiles.size() > 0) + mSelector->setCheckStates (foundFiles); } void Launcher::DataFilesPage::saveSettings(const QString &profile) @@ -191,10 +221,10 @@ void Launcher::DataFilesPage::setupDataFiles() foreach (const QString &path, paths) mSelector->addFiles(path); - QString dataLocal = mGameSettings.getDataLocal(); + mDataLocal = mGameSettings.getDataLocal(); - if (!dataLocal.isEmpty()) - mSelector->addFiles(dataLocal); + if (!mDataLocal.isEmpty()) + mSelector->addFiles(mDataLocal); QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/")); QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index e394e6f41..37603a210 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -4,6 +4,10 @@ #include "ui_datafilespage.h" #include + +#include +#include + class QSortFilterProxyModel; class QAbstractItemModel; class QMenu; @@ -61,6 +65,8 @@ namespace Launcher GameSettings &mGameSettings; LauncherSettings &mLauncherSettings; + QString mDataLocal; + void setPluginsCheckstates(Qt::CheckState state); void buildView(); @@ -73,6 +79,58 @@ namespace Launcher bool showDeleteMessageBox (const QString &text); void addProfile (const QString &profile, bool setAsCurrent); void checkForDefaultProfile(); + + class PathIterator + { + QStringList::ConstIterator mCitEnd; + QStringList::ConstIterator mCitCurrent; + QStringList::ConstIterator mCitBegin; + QString mFile; + QString mFilePath; + + public: + PathIterator (const QStringList &list) + { + mCitBegin = list.constBegin(); + mCitCurrent = mCitBegin; + mCitEnd = list.constEnd(); + } + + QString findFirstPath (const QString &file) + { + mCitCurrent = mCitBegin; + mFile = file; + return path(); + } + + QString findNextPath () { return path(); } + + private: + + QString path () + { + bool success = false; + QDir dir; + QFileInfo file; + + while (!success) + { + if (mCitCurrent == mCitEnd) + break; + + dir.setPath (*(mCitCurrent++)); + file.setFile (dir.absoluteFilePath (mFile)); + + success = file.exists(); + } + + if (success) + return file.absoluteFilePath(); + + return ""; + } + + }; }; } #endif diff --git a/apps/launcher/settings/gamesettings.cpp b/apps/launcher/settings/gamesettings.cpp index 32eb2071f..83c099529 100644 --- a/apps/launcher/settings/gamesettings.cpp +++ b/apps/launcher/settings/gamesettings.cpp @@ -169,7 +169,7 @@ bool Launcher::GameSettings::writeFile(QTextStream &stream) return true; } -bool GameSettings::hasMaster() +bool Launcher::GameSettings::hasMaster() { bool result = false; QStringList content = mSettings.values(QString("content")); diff --git a/apps/launcher/settings/gamesettings.hpp b/apps/launcher/settings/gamesettings.hpp index 56917a79f..60236200a 100644 --- a/apps/launcher/settings/gamesettings.hpp +++ b/apps/launcher/settings/gamesettings.hpp @@ -51,11 +51,6 @@ namespace Launcher bool hasMaster(); - inline QStringList getDataDirs() { return mDataDirs; } - inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); } - inline QString getDataLocal() {return mDataLocal; } - inline bool hasMaster() { return mSettings.count(QString("master")) > 0; } - QStringList values(const QString &key, const QStringList &defaultValues = QStringList()); bool readFile(QTextStream &stream); bool writeFile(QTextStream &stream); diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp index 5ebfacd03..09e58690f 100644 --- a/apps/opencs/view/doc/adjusterwidget.cpp +++ b/apps/opencs/view/doc/adjusterwidget.cpp @@ -10,9 +10,6 @@ #include #include -#include - - CSVDoc::AdjusterWidget::AdjusterWidget (QWidget *parent) : QWidget (parent), mValid (false), mAction (ContentAction_Undefined) { @@ -79,8 +76,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) path.extension() == ".esp"); bool isFilePathChanged = (path.parent_path().string() != mLocalData.string()); - qDebug() << "current path: " << path.parent_path().c_str(); - qDebug() << "data-local: " << mLocalData.c_str(); + if (isLegacyPath) path.replace_extension (addon ? ".omwaddon" : ".omwgame"); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index ce7d7dfb0..80b3066dd 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -17,8 +17,6 @@ #include "filewidget.hpp" #include "adjusterwidget.hpp" -#include - CSVDoc::FileDialog::FileDialog(QWidget *parent) : QDialog(parent), mSelector (0), mFileWidget (0), mAdjusterWidget (0) { @@ -142,7 +140,6 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool) { ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back();; mAdjusterWidget->setName (file->filePath(), !file->isGameFile()); - qDebug() << "setting filepath " << file->filePath(); } ui.projectButtonBox->button (QDialogButtonBox::Ok)->setEnabled (success); diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 065b9c497..7661f9608 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -3,9 +3,11 @@ #include #include -#include +#include #include +#include "components/esm/esmreader.hpp" + ContentSelectorModel::ContentModel::ContentModel(QObject *parent) : QAbstractTableModel(parent), mMimeType ("application/omwcontent"), @@ -380,15 +382,18 @@ bool ContentSelectorModel::ContentModel::canBeChecked(const EsmFile *file) const //addon can be checked if its gamefile is foreach (const QString &fileName, file->gameFiles()) { - const EsmFile *dependency = item(fileName); - - if (!dependency) - continue; - - if (dependency->isGameFile()) + foreach (EsmFile *dependency, mFiles) { - if (isChecked(fileName)) - return true; + //compare filenames only. Multiple instances + //of the filename (with different paths) is not relevant here. + if (!(dependency->fileName() == fileName)) + continue; + + if (dependency->isGameFile()) + { + if (isChecked(dependency->filePath())) + return true; + } } } return false; @@ -396,7 +401,6 @@ bool ContentSelectorModel::ContentModel::canBeChecked(const EsmFile *file) const void ContentSelectorModel::ContentModel::addFile(EsmFile *file) { - qDebug() << "adding file: " << file->filePath(); beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); mFiles.append(file); endInsertRows(); @@ -418,8 +422,6 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path) // Create a decoder for non-latin characters in esx metadata QTextDecoder *decoder = codec->makeDecoder(); - qDebug() << "searching path: " << path << " files found: " << dir.entryList().size(); - foreach (const QString &path, dir.entryList()) { QFileInfo info(dir.absoluteFilePath(path)); @@ -433,10 +435,7 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path) fileReader.open(dir.absoluteFilePath(path).toStdString()); foreach (const ESM::Header::MasterData &item, fileReader.getGameFiles()) - { - qDebug() << "adding gamefile: " << item.name.c_str(); file->addGameFile(QString::fromStdString(item.name)); - } file->setAuthor (decoder->toUnicode(fileReader.getAuthor().c_str())); file->setDate (info.lastModified()); @@ -447,10 +446,7 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path) // Put the file in the table if (item(file->filePath()) == 0) - { - qDebug () << "adding file " << file->filePath(); addFile(file); - } } catch(std::runtime_error &e) { // An error occurred while reading the .esp @@ -510,10 +506,23 @@ bool ContentSelectorModel::ContentModel::isChecked(const QString& name) const return false; } -void ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool checkState) +void ContentSelectorModel::ContentModel::setCheckStates (const QStringList &fileList, bool isChecked) +{ + foreach (const QString &file, fileList) + { + setCheckState (file, isChecked); + } +} + +bool ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool checkState) { if (name.isEmpty()) - return; + return false; + + const EsmFile *file = item(name); + + if (!file) + return false; Qt::CheckState state = Qt::Unchecked; @@ -523,8 +532,6 @@ void ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool mCheckStates[name] = state; emit dataChanged(indexFromItem(item(name)), indexFromItem(item(name))); - const EsmFile *file = item(name); - if (file->isGameFile()) emit dataChanged (index(0,0), index(rowCount()-1,0)); @@ -559,29 +566,20 @@ void ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool } } } + + return true; } ContentSelectorModel::ContentFileList ContentSelectorModel::ContentModel::checkedItems() const { ContentFileList list; + // TODO: // First search for game files and next addons, // so we get more or less correct game files vs addons order. foreach (EsmFile *file, mFiles) - { -<<<<<<< HEAD if (isChecked(file->filePath())) -======= - if (isChecked(file->fileName()) && file->isGameFile()) - list << file; - } - - foreach (EsmFile *file, mFiles) - { - if (isChecked(file->fileName()) && !file->isGameFile()) ->>>>>>> f5fbe7361fad698e8dd3330e9820a157800be8ae list << file; - } return list; } diff --git a/components/contentselector/model/contentmodel.hpp b/components/contentselector/model/contentmodel.hpp index 0d6c52cc6..ae49dd27d 100644 --- a/components/contentselector/model/contentmodel.hpp +++ b/components/contentselector/model/contentmodel.hpp @@ -45,7 +45,8 @@ namespace ContentSelectorModel const EsmFile *item(const QString &name) const; bool isChecked(const QString &name) const; - void setCheckState(const QString &name, bool isChecked); + bool setCheckState(const QString &name, bool isChecked); + void setCheckStates (const QStringList &fileList, bool isChecked); ContentFileList checkedItems() const; void uncheckAll(); diff --git a/components/contentselector/model/esmfile.cpp b/components/contentselector/model/esmfile.cpp index 35f78386c..a0a09105a 100644 --- a/components/contentselector/model/esmfile.cpp +++ b/components/contentselector/model/esmfile.cpp @@ -6,8 +6,9 @@ int ContentSelectorModel::EsmFile::sPropertyCount = 7; QString ContentSelectorModel::EsmFile::sToolTip = QString("Author: %1
\ Version: %2
\ -
Description:
%3
\ -
Dependencies: %4
"); + Path:
%3
\ +
Description:
%4
\ +
Dependencies: %5
"); ContentSelectorModel::EsmFile::EsmFile(QString fileName, ModelItem *parent) diff --git a/components/contentselector/model/esmfile.hpp b/components/contentselector/model/esmfile.hpp index fc0cca8a2..ca24b52d1 100644 --- a/components/contentselector/model/esmfile.hpp +++ b/components/contentselector/model/esmfile.hpp @@ -57,6 +57,7 @@ namespace ContentSelectorModel inline QString description() const { return mDescription; } inline QString toolTip() const { return sToolTip.arg(mAuthor) .arg(mFormat) + .arg(mPath) .arg(mDescription) .arg(mGameFiles.join(", ")); } diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index d12c8cb24..4758dd5a0 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -67,10 +67,15 @@ void ContentSelectorView::ContentSelector::setGameFile(const QString &filename) if (!filename.isEmpty()) { - index = ui.gameFileView->findText(filename); + const ContentSelectorModel::EsmFile *file = mContentModel->item (filename); + index = ui.gameFileView->findText (file->fileName()); //verify that the current index is also checked in the model - mContentModel->setCheckState(filename, true); + if (!mContentModel->setCheckState(filename, true)) + { + //throw error in case file not found? + return; + } } ui.gameFileView->setCurrentIndex(index); @@ -86,8 +91,7 @@ void ContentSelectorView::ContentSelector::setCheckStates(const QStringList &lis if (list.isEmpty()) return; - foreach (const QString &file, list) - mContentModel->setCheckState(file, Qt::Checked); + mContentModel->setCheckStates (list, true); } ContentSelectorModel::ContentFileList From 12c06a56152bd0452c0239b07acf8610a0f6a6b8 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 3 Nov 2013 06:21:28 -0600 Subject: [PATCH 111/118] Fixed broken dependency check --- apps/opencs/view/doc/filedialog.cpp | 2 +- components/contentselector/model/contentmodel.cpp | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 80b3066dd..ab56415a1 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -138,7 +138,7 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool) success = success && !(name.isEmpty()); else { - ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back();; + ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back(); mAdjusterWidget->setName (file->filePath(), !file->isGameFile()); } diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 7661f9608..0fb1b4216 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include "components/esm/esmreader.hpp" @@ -69,9 +68,14 @@ ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(int row) } const ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(const QString &name) const { + EsmFile::FileProperty fp = EsmFile::FileProperty_FileName; + + if (name.contains ('/')) + fp = EsmFile::FileProperty_FilePath; + foreach (const EsmFile *file, mFiles) { - if (name == file->filePath()) + if (name == file->fileProperty (fp).toString()) return file; } return 0; @@ -538,15 +542,15 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool //if we're checking an item, ensure all "upstream" files (dependencies) are checked as well. if (state == Qt::Checked) { - foreach (const QString &upstreamName, file->gameFiles()) + foreach (QString upstreamName, file->gameFiles()) { const EsmFile *upstreamFile = item(upstreamName); if (!upstreamFile) continue; - if (!isChecked(upstreamName)) - mCheckStates[upstreamName] = Qt::Checked; + if (!isChecked(upstreamFile->filePath())) + mCheckStates[upstreamFile->filePath()] = Qt::Checked; emit dataChanged(indexFromItem(upstreamFile), indexFromItem(upstreamFile)); From 1d4b5a2425c8a627b6489db5af7c2b63798542e8 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 3 Nov 2013 14:02:41 -0600 Subject: [PATCH 112/118] Fix broken launcher content file display / selection scheme Disable selection of content files with missing dependencies (grayed out) --- apps/launcher/datafilespage.cpp | 11 +- apps/launcher/utils/profilescombobox.hpp | 7 ++ .../contentselector/model/contentmodel.cpp | 104 +++++++++++------- .../contentselector/model/contentmodel.hpp | 5 +- .../contentselector/view/contentselector.cpp | 20 +++- 5 files changed, 93 insertions(+), 54 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 71d072599..5ae850566 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -79,8 +79,7 @@ void Launcher::DataFilesPage::loadSettings() //throw addons error here. } */ - if (foundFiles.size() > 0) - mSelector->setCheckStates (foundFiles); + mSelector->setCheckStates (foundFiles); } void Launcher::DataFilesPage::saveSettings(const QString &profile) @@ -177,7 +176,7 @@ void Launcher::DataFilesPage::setProfile (const QString &previous, const QString if (!previous.isEmpty() && savePrevious) saveSettings (previous); - ui.profilesComboBox->setCurrentIndex (ui.profilesComboBox->findText (current)); + ui.profilesComboBox->setCurrentProfile (ui.profilesComboBox->findText (current)); loadSettings(); @@ -232,7 +231,7 @@ void Launcher::DataFilesPage::setupDataFiles() foreach (const QString &item, profiles) addProfile (item, false); - addProfile (profile, true); + setProfile (ui.profilesComboBox->findText(profile), false); loadSettings(); } @@ -289,6 +288,10 @@ void Launcher::DataFilesPage::on_deleteProfileAction_triggered() // Remove the profile from the combobox ui.profilesComboBox->removeItem (ui.profilesComboBox->findText (profile)); + removeProfile(profile); + + saveSettings(); + loadSettings(); checkForDefaultProfile(); diff --git a/apps/launcher/utils/profilescombobox.hpp b/apps/launcher/utils/profilescombobox.hpp index 1e27f66a9..7b83c41b2 100644 --- a/apps/launcher/utils/profilescombobox.hpp +++ b/apps/launcher/utils/profilescombobox.hpp @@ -4,6 +4,8 @@ #include "components/contentselector/view/combobox.hpp" #include "lineedit.hpp" +#include + class QString; class ProfilesComboBox : public ContentSelectorView::ComboBox @@ -21,6 +23,11 @@ public: explicit ProfilesComboBox(QWidget *parent = 0); void setEditEnabled(bool editable); + void setCurrentProfile(int index) + { + ComboBox::setCurrentIndex(index); + mOldProfile = currentText(); + } signals: void signalProfileTextChanged(const QString &item); diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 0fb1b4216..5f3575eb4 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -13,7 +13,6 @@ ContentSelectorModel::ContentModel::ContentModel(QObject *parent) : mMimeTypes (QStringList() << mMimeType), mColumnCount (1), mDragDropFlags (Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled), - mDefaultFlags (Qt::ItemIsDropEnabled | Qt::ItemIsSelectable), mDropActions (Qt::CopyAction | Qt::MoveAction) { setEncoding ("win1252"); @@ -102,10 +101,53 @@ Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex &index if (!file) return Qt::NoItemFlags; - if (canBeChecked(file)) - return Qt::ItemIsEnabled | mDragDropFlags | mDefaultFlags; + //game files can always be checked + if (file->isGameFile()) + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + + Qt::ItemFlags returnFlags; + bool allDependenciesFound = true; + bool gamefileChecked = false; + + //addon can be checked if its gamefile is and all other dependencies exist + foreach (const QString &fileName, file->gameFiles()) + { + bool depFound = false; + foreach (EsmFile *dependency, mFiles) + { + //compare filenames only. Multiple instances + //of the filename (with different paths) is not relevant here. + depFound = (dependency->fileName() == fileName); + + if (!depFound) + continue; + + if (!gamefileChecked) + { + if (isChecked (dependency->filePath())) + gamefileChecked = (dependency->isGameFile()); + } - return Qt::NoItemFlags; + // force it to iterate all files in cases where the current + // dependency is a game file to ensure that a later duplicate + // game file is / is not checked. + // (i.e., break only if it's not a gamefile or the game file has been checked previously) + if (gamefileChecked || !(dependency->isGameFile())) + break; + } + + allDependenciesFound = allDependenciesFound && depFound; + } + + if (gamefileChecked) + { + if (allDependenciesFound) + returnFlags = returnFlags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | mDragDropFlags; + else + returnFlags = Qt::ItemIsSelectable; + } + + return returnFlags; } QVariant ContentSelectorModel::ContentModel::data(const QModelIndex &index, int role) const @@ -173,7 +215,7 @@ QVariant ContentSelectorModel::ContentModel::data(const QModelIndex &index, int if (file->isGameFile()) return ContentType_GameFile; else - if (flags(index) & mDefaultFlags) + if (flags(index)) return ContentType_Addon; break; @@ -215,19 +257,13 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex &index, const case Qt::UserRole+1: { - setCheckState(fileName, value.toBool()); - - emit dataChanged(index, index); + success = (flags (index) & Qt::ItemIsEnabled); - foreach (EsmFile *file, mFiles) + if (success) { - if (file->gameFiles().contains(fileName)) - { - QModelIndex idx = indexFromItem(file); - emit dataChanged(idx, idx); - } + success = setCheckState(fileName, value.toBool()); + emit dataChanged(index, index); } - success = true; } break; @@ -377,32 +413,6 @@ bool ContentSelectorModel::ContentModel::dropMimeData(const QMimeData *data, Qt: return true; } -bool ContentSelectorModel::ContentModel::canBeChecked(const EsmFile *file) const -{ - //game files can always be checked - if (file->isGameFile()) - return true; - - //addon can be checked if its gamefile is - foreach (const QString &fileName, file->gameFiles()) - { - foreach (EsmFile *dependency, mFiles) - { - //compare filenames only. Multiple instances - //of the filename (with different paths) is not relevant here. - if (!(dependency->fileName() == fileName)) - continue; - - if (dependency->isGameFile()) - { - if (isChecked(dependency->filePath())) - return true; - } - } - } - return false; -} - void ContentSelectorModel::ContentModel::addFile(EsmFile *file) { beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); @@ -510,6 +520,11 @@ bool ContentSelectorModel::ContentModel::isChecked(const QString& name) const return false; } +bool ContentSelectorModel::ContentModel::isEnabled (QModelIndex index) const +{ + return (flags(index) & Qt::ItemIsEnabled); +} + void ContentSelectorModel::ContentModel::setCheckStates (const QStringList &fileList, bool isChecked) { foreach (const QString &file, fileList) @@ -518,6 +533,11 @@ void ContentSelectorModel::ContentModel::setCheckStates (const QStringList &file } } +void ContentSelectorModel::ContentModel::refreshModel() +{ + emit dataChanged (index(0,0), index(rowCount()-1,0)); +} + bool ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool checkState) { if (name.isEmpty()) @@ -537,7 +557,7 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool emit dataChanged(indexFromItem(item(name)), indexFromItem(item(name))); if (file->isGameFile()) - emit dataChanged (index(0,0), index(rowCount()-1,0)); + refreshModel(); //if we're checking an item, ensure all "upstream" files (dependencies) are checked as well. if (state == Qt::Checked) diff --git a/components/contentselector/model/contentmodel.hpp b/components/contentselector/model/contentmodel.hpp index ae49dd27d..8c8c2124b 100644 --- a/components/contentselector/model/contentmodel.hpp +++ b/components/contentselector/model/contentmodel.hpp @@ -44,19 +44,21 @@ namespace ContentSelectorModel QModelIndex indexFromItem(const EsmFile *item) const; const EsmFile *item(const QString &name) const; + bool isEnabled (QModelIndex index) const; bool isChecked(const QString &name) const; bool setCheckState(const QString &name, bool isChecked); void setCheckStates (const QStringList &fileList, bool isChecked); ContentFileList checkedItems() const; void uncheckAll(); + void refreshModel(); + private: void addFile(EsmFile *file); const EsmFile *item(int row) const; EsmFile *item(int row); - bool canBeChecked(const EsmFile *file) const; void sortFiles(); ContentFileList mFiles; @@ -69,7 +71,6 @@ namespace ContentSelectorModel QStringList mMimeTypes; int mColumnCount; Qt::ItemFlags mDragDropFlags; - Qt::ItemFlags mDefaultFlags; Qt::DropActions mDropActions; }; } diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index 4758dd5a0..b962fa9ce 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -12,6 +12,8 @@ #include #include +#include + ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) : QObject(parent) { @@ -89,9 +91,12 @@ void ContentSelectorView::ContentSelector::clearCheckStates() void ContentSelectorView::ContentSelector::setCheckStates(const QStringList &list) { if (list.isEmpty()) - return; - - mContentModel->setCheckStates (list, true); + { + qDebug() << "refreshing model"; + slotCurrentGameFileIndexChanged (ui.gameFileView->currentIndex()); + } + else + mContentModel->setCheckStates (list, true); } ContentSelectorModel::ContentFileList @@ -152,14 +157,17 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QModelIndex &index) { - QAbstractItemModel *const model = ui.addonView->model(); + QModelIndex sourceIndex = mAddonProxyModel->mapToSource (index); + + if (!mContentModel->isEnabled (sourceIndex)) + return; Qt::CheckState checkState = Qt::Unchecked; - if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked) + if (mContentModel->data(sourceIndex, Qt::CheckStateRole).toInt() == Qt::Unchecked) checkState = Qt::Checked; - model->setData(index, checkState, Qt::CheckStateRole); + mContentModel->setData(sourceIndex, checkState, Qt::CheckStateRole); if (checkState == Qt::Checked) emit signalAddonFileSelected (index.row()); From 3ac58b387b1cbc07ec76a5d82fe77008dc6fd4b2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 3 Nov 2013 22:08:38 +0100 Subject: [PATCH 113/118] fixed wording of an error message --- apps/launcher/maindialog.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 273494ff3..4012a1fbd 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -496,12 +496,12 @@ bool Launcher::MainDialog::setupGameSettings() QAbstractButton *dirSelectButton = msgBox.addButton(QObject::tr("Browse to &Install..."), QMessageBox::ActionRole); - + #ifndef WIN32 - QAbstractButton *cdSelectButton = + QAbstractButton *cdSelectButton = msgBox.addButton(QObject::tr("Browse to &CD..."), QMessageBox::ActionRole); #endif - + msgBox.exec(); @@ -516,14 +516,14 @@ bool Launcher::MainDialog::setupGameSettings() #ifndef WIN32 else if(msgBox.clickedButton() == cdSelectButton) { UnshieldThread cd; - + { TextSlotMsgBox cdbox; - cdbox.setStandardButtons(QMessageBox::Cancel); + cdbox.setStandardButtons(QMessageBox::Cancel); QObject::connect(&cd,SIGNAL(signalGUI(const QString&)), &cdbox, SLOT(setTextSlot(const QString&))); QObject::connect(&cd,SIGNAL(close()), &cdbox, SLOT(reject())); - + cd.SetMorrowindPath( QFileDialog::getOpenFileName( NULL, @@ -537,11 +537,11 @@ bool Launcher::MainDialog::setupGameSettings() QObject::tr("Select where to extract files to"), QDir::currentPath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks).toUtf8().constData()); - + cd.start(); cdbox.exec(); } - + while(expansions(cd)); selectedFile = QString::fromStdString(cd.GetMWEsmPath()); @@ -753,11 +753,11 @@ void Launcher::MainDialog::play() if(!mGameSettings.hasMaster()) { QMessageBox msgBox; - msgBox.setWindowTitle(tr("No master file selected")); + msgBox.setWindowTitle(tr("No game file selected")); msgBox.setIcon(QMessageBox::Warning); msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
You do not have any master files selected.

\ - OpenMW will not start without a master file selected.
")); + msgBox.setText(tr("
You do not have no game file selected.

\ + OpenMW will not start without a game file selected.
")); msgBox.exec(); return; } From dace9044900a94eadddeea0442182fad7b152452 Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 3 Nov 2013 16:45:18 -0600 Subject: [PATCH 114/118] changed game/addon to content for writing to openmw.cfg from launcher --- apps/launcher/datafilespage.cpp | 4 ++-- apps/opencs/editor.cpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 5ae850566..5452b7398 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -104,10 +104,10 @@ void Launcher::DataFilesPage::saveSettings(const QString &profile) if (item->gameFiles().size() == 0) { mLauncherSettings.setMultiValue(QString("Profiles/") + profileName + QString("/game"), item->fileName()); - mGameSettings.setMultiValue(QString("game"), item->fileName()); + mGameSettings.setMultiValue(QString("content"), item->fileName()); } else { mLauncherSettings.setMultiValue(QString("Profiles/") + profileName + QString("/addon"), item->fileName()); - mGameSettings.setMultiValue(QString("addon"), item->fileName()); + mGameSettings.setMultiValue(QString("content"), item->fileName()); } } diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 63afe7a9d..e879cb25e 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -94,6 +94,7 @@ void CS::Editor::setupDataFiles() for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) { + QString path = QString::fromStdString(iter->string()); mFileDialog.addFiles(path); } From ed913936f8544d7d1b646e9454e9c26b5f860e3f Mon Sep 17 00:00:00 2001 From: graffy76 Date: Sun, 3 Nov 2013 21:36:41 -0600 Subject: [PATCH 115/118] Eliminated game & addon keys from profile configuration --- apps/launcher/datafilespage.cpp | 65 ++++++++----------- apps/launcher/settings/gamesettings.cpp | 1 + apps/launcher/settings/launchersettings.cpp | 5 +- .../contentselector/view/contentselector.cpp | 32 ++++++++- .../contentselector/view/contentselector.hpp | 1 + 5 files changed, 59 insertions(+), 45 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 5452b7398..734277b97 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -42,44 +42,19 @@ void Launcher::DataFilesPage::loadSettings() QString profileName = ui.profilesComboBox->currentText(); - QStringList files = mLauncherSettings.values(QString("Profiles/") + profileName + QString("/game"), Qt::MatchExactly); - QStringList addons = mLauncherSettings.values(QString("Profiles/") + profileName + QString("/addon"), Qt::MatchExactly); + QStringList files = mLauncherSettings.values(QString("Profiles/") + profileName, Qt::MatchExactly); - mSelector->clearCheckStates(); - - QString gameFile (""); + QStringList filepaths; - if (files.size()>0) + foreach (const QString &file, files) { - gameFile = pathIterator.findFirstPath (files.at(0)); + QString filepath = pathIterator.findFirstPath (file); - if (!gameFile.isEmpty()) - mSelector->setGameFile (gameFile); -/* else - { - //throw gamefile error here. - }*/ + if (!filepath.isEmpty()) + filepaths << filepath; } - QStringList missingFiles; - QStringList foundFiles; - - foreach (const QString &addon, addons) - { - QString filePath = pathIterator.findFirstPath (addon); - - if (filePath.isEmpty()) - missingFiles << addon; - else - foundFiles << filePath; - } -/* - if (missingFiles.size() > 0) - { - //throw addons error here. - } -*/ - mSelector->setCheckStates (foundFiles); + mSelector->setProfileContent (filepaths); } void Launcher::DataFilesPage::saveSettings(const QString &profile) @@ -94,8 +69,7 @@ void Launcher::DataFilesPage::saveSettings(const QString &profile) removeProfile (profileName); - mGameSettings.remove(QString("game")); - mGameSettings.remove(QString("addon")); + mGameSettings.remove(QString("content")); //set the value of the current profile (not necessarily the profile being saved!) mLauncherSettings.setValue(QString("Profiles/currentprofile"), ui.profilesComboBox->currentText()); @@ -103,10 +77,10 @@ void Launcher::DataFilesPage::saveSettings(const QString &profile) foreach(const ContentSelectorModel::EsmFile *item, items) { if (item->gameFiles().size() == 0) { - mLauncherSettings.setMultiValue(QString("Profiles/") + profileName + QString("/game"), item->fileName()); + mLauncherSettings.setMultiValue(QString("Profiles/") + profileName, item->fileName()); mGameSettings.setMultiValue(QString("content"), item->fileName()); } else { - mLauncherSettings.setMultiValue(QString("Profiles/") + profileName + QString("/addon"), item->fileName()); + mLauncherSettings.setMultiValue(QString("Profiles/") + profileName, item->fileName()); mGameSettings.setMultiValue(QString("content"), item->fileName()); } } @@ -225,13 +199,26 @@ void Launcher::DataFilesPage::setupDataFiles() if (!mDataLocal.isEmpty()) mSelector->addFiles(mDataLocal); - QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/")); - QString profile = mLauncherSettings.value(QString("Profiles/currentprofile")); + QStringList profiles; + QString currentProfile = mLauncherSettings.getSettings().value("Profiles/currentprofile"); + + foreach (QString key, mLauncherSettings.getSettings().keys()) + { + if (key.contains("Profiles/")) + { + QString profile = key.mid (9); + if (profile != "currentprofile") + { + if (!profiles.contains(profile)) + profiles << profile; + } + } + } foreach (const QString &item, profiles) addProfile (item, false); - setProfile (ui.profilesComboBox->findText(profile), false); + setProfile (ui.profilesComboBox->findText(currentProfile), false); loadSettings(); } diff --git a/apps/launcher/settings/gamesettings.cpp b/apps/launcher/settings/gamesettings.cpp index 83c099529..41113c35a 100644 --- a/apps/launcher/settings/gamesettings.cpp +++ b/apps/launcher/settings/gamesettings.cpp @@ -9,6 +9,7 @@ #include #include + /** * Workaround for problems with whitespaces in paths in older versions of Boost library */ diff --git a/apps/launcher/settings/launchersettings.cpp b/apps/launcher/settings/launchersettings.cpp index 7c97144ea..705453555 100644 --- a/apps/launcher/settings/launchersettings.cpp +++ b/apps/launcher/settings/launchersettings.cpp @@ -5,6 +5,8 @@ #include #include +#include + Launcher::LauncherSettings::LauncherSettings() { } @@ -44,12 +46,9 @@ QStringList Launcher::LauncherSettings::subKeys(const QString &key) QStringList result; foreach (const QString ¤tKey, keys) { - if (keyRe.indexIn(currentKey) != -1) { - QString prefixedKey = keyRe.cap(1); if(prefixedKey.startsWith(key)) { - QString subKey = prefixedKey.remove(key); if (!subKey.isEmpty()) result.append(subKey); diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index b962fa9ce..e9599de49 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -12,8 +12,6 @@ #include #include -#include - ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent) : QObject(parent) { @@ -63,6 +61,35 @@ void ContentSelectorView::ContentSelector::buildAddonView() connect(ui.addonView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotAddonTableItemClicked(const QModelIndex &))); } +void ContentSelectorView::ContentSelector::setProfileContent(const QStringList &fileList) +{ + clearCheckStates(); + bool foundGamefile = false; + + foreach (const QString &filepath, fileList) + { + if (!foundGamefile) + { + const ContentSelectorModel::EsmFile *file = mContentModel->item(filepath); + + foundGamefile = (file->isGameFile()); + + if (foundGamefile) + { + setGameFile (filepath); + break; + } + } + } + +/* if (!foundGameFile) + { + //throw gamefile error here. + }*/ + + setCheckStates (fileList); +} + void ContentSelectorView::ContentSelector::setGameFile(const QString &filename) { int index = -1; @@ -92,7 +119,6 @@ void ContentSelectorView::ContentSelector::setCheckStates(const QStringList &lis { if (list.isEmpty()) { - qDebug() << "refreshing model"; slotCurrentGameFileIndexChanged (ui.gameFileView->currentIndex()); } else diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index da1c39973..a25eb20ae 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -29,6 +29,7 @@ namespace ContentSelectorView QString currentFile() const; void addFiles(const QString &path); + void setProfileContent (const QStringList &fileList); void clearCheckStates(); void setCheckStates (const QStringList &list); From 8e439c290d616b1f6af2488bf9e3be4cb54f42e5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 4 Nov 2013 09:22:23 +0100 Subject: [PATCH 116/118] updated changelog --- readme.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/readme.txt b/readme.txt index c4d9d2746..a790ca9e3 100644 --- a/readme.txt +++ b/readme.txt @@ -82,6 +82,31 @@ Allowed options: CHANGELOG +0.27.0 + +Bug #597: Assertion `dialogue->mId == id' failed in esmstore.cpp +Bug #794: incorrect display of decimal numbers +Bug #840: First-person sneaking camera height +Bug #887: Ambient sounds playing while paused +Bug #902: Problems with Polish character encoding +Bug #907: Entering third person using the mousewheel is possible even if it's impossible using the key +Bug #917: Quick character creation plugin does not work +Bug #918: Fatigue does not refill +Bug #919: The PC falls dead in Beshara - OpenMW nightly Win64 (708CDE2) +Feature #57: Acrobatics Skill +Feature #462: Editor: Start Dialogue +Feature #546: Modify ESX selector to handle new content file scheme +Feature #588: Editor: Adjust name/path of edited content files +Feature #644: Editor: Save +Feature #710: Editor: Configure script compiler context +Feature #790: God Mode +Feature #881: Editor: Allow only one instance of OpenCS +Feature #889: Editor: Record filtering +Feature #895: Extinguish torches +Feature #898: Breath meter enhancements +Feature #901: Editor: Default record filter +Feature #913: Merge --master and --plugin switches + 0.26.0 Bug #274: Inconsistencies in the terrain From 468e8e3635d6532fb334d17cabd5b7bf52a5ecc1 Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Mon, 4 Nov 2013 10:36:22 +0100 Subject: [PATCH 117/118] Missing iostream include --- apps/openmw/mwworld/contentloader.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwworld/contentloader.hpp b/apps/openmw/mwworld/contentloader.hpp index c57935c90..46bd7d3f9 100644 --- a/apps/openmw/mwworld/contentloader.hpp +++ b/apps/openmw/mwworld/contentloader.hpp @@ -2,6 +2,7 @@ #define CONTENTLOADER_HPP #include +#include #include #include "components/loadinglistener/loadinglistener.hpp" From 8bacdc8ab8910f613fa7de32849998e31218bad7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 4 Nov 2013 14:19:58 +0100 Subject: [PATCH 118/118] updated changelog --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index a790ca9e3..afcfadea3 100644 --- a/readme.txt +++ b/readme.txt @@ -90,6 +90,7 @@ Bug #840: First-person sneaking camera height Bug #887: Ambient sounds playing while paused Bug #902: Problems with Polish character encoding Bug #907: Entering third person using the mousewheel is possible even if it's impossible using the key +Bug #910: Some CDs not working correctly with Unshield installer Bug #917: Quick character creation plugin does not work Bug #918: Fatigue does not refill Bug #919: The PC falls dead in Beshara - OpenMW nightly Win64 (708CDE2)