mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-20 15:40:32 +00:00
Renamed esxSelector to contentSelector
Fixed datafilespage model implementation in launcher Filtered addons in table view by selected game file
This commit is contained in:
parent
7b7dfa122d
commit
cfdc19c427
@ -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<ESM::Header::MasterData> m = esm.getMasters();
|
||||
std::vector<ESM::Header::MasterData> m = esm.getGameFiles();
|
||||
if (!m.empty())
|
||||
{
|
||||
std::cout << "Masters:" << std::endl;
|
||||
|
@ -4,22 +4,22 @@
|
||||
#include <QMessageBox>
|
||||
#include <QCheckBox>
|
||||
#include <QMenu>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
|
||||
#include <components/esxselector/model/pluginsproxymodel.hpp>
|
||||
#include <components/esxselector/model/esmfile.hpp>
|
||||
#include <components/contentselector/model/esmfile.hpp>
|
||||
|
||||
#include <components/esxselector/view/lineedit.hpp>
|
||||
#include <components/esxselector/model/naturalsort.hpp>
|
||||
#include <components/esxselector/view/profilescombobox.hpp>
|
||||
#include <components/contentselector/view/lineedit.hpp>
|
||||
#include <components/contentselector/model/naturalsort.hpp>
|
||||
#include <components/contentselector/view/profilescombobox.hpp>
|
||||
|
||||
#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 <QDebug>
|
||||
|
||||
@ -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();
|
||||
// mContentSelector.
|
||||
mContentModel->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);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if (item->masters().size() == 0) {
|
||||
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());
|
||||
|
||||
@ -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<QSortFilterProxyModel *>(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<QSortFilterProxyModel *>(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);
|
||||
}
|
||||
|
@ -5,24 +5,24 @@
|
||||
#include <QModelIndex>
|
||||
|
||||
#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
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/files/ogreplugin.hpp>
|
||||
|
||||
#include <components/esxselector/model/naturalsort.hpp>
|
||||
#include <components/contentselector/model/naturalsort.hpp>
|
||||
|
||||
#include "settings/graphicssettings.hpp"
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include <QValidator>
|
||||
#include <QLabel>
|
||||
|
||||
#include <components/esxselector/view/lineedit.hpp>
|
||||
#include <components/contentselector/view/lineedit.hpp>
|
||||
|
||||
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);
|
||||
|
||||
|
@ -2,11 +2,10 @@
|
||||
#define TEXTINPUTDIALOG_HPP
|
||||
|
||||
#include <QDialog>
|
||||
//#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();
|
||||
|
||||
|
@ -79,8 +79,8 @@ void CS::Editor::setupDataFiles()
|
||||
}
|
||||
|
||||
// Set the charset for reading the esm/esp files
|
||||
QString encoding = QString::fromStdString(variables["encoding"].as<std::string>());
|
||||
mFileDialog.setEncoding(encoding);
|
||||
// QString encoding = QString::fromStdString(variables["encoding"].as<std::string>());
|
||||
//mFileDialog.setEncoding(encoding);
|
||||
|
||||
dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end());
|
||||
|
||||
|
@ -42,7 +42,7 @@ int main(int argc, char *argv[])
|
||||
if(!editor.makeIPCServer())
|
||||
{
|
||||
editor.connectToIPCServer();
|
||||
return 0;
|
||||
// return 0;
|
||||
}
|
||||
|
||||
return editor.run();
|
||||
|
@ -10,24 +10,18 @@
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
|
||||
#include <components/esxselector/model/datafilesmodel.hpp>
|
||||
#include <components/esxselector/model/pluginsproxymodel.hpp>
|
||||
#include <components/esxselector/model/esmfile.hpp>
|
||||
|
||||
#include <components/esxselector/view/lineedit.hpp>
|
||||
|
||||
#include "components/esxselector/model/masterproxymodel.hpp"
|
||||
#include <components/contentselector/model/esmfile.hpp>
|
||||
#include <components/contentselector/view/lineedit.hpp>
|
||||
|
||||
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()));
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <QDialog>
|
||||
#include <QModelIndex>
|
||||
|
||||
#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:
|
||||
|
@ -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<ESM::Header::MasterData> &masters = esm.getMasters();
|
||||
const std::vector<ESM::Header::MasterData> &masters = esm.getGameFiles();
|
||||
std::vector<ESM::ESMReader> *allPlugins = esm.getGlobalReaderList();
|
||||
for (size_t j = 0; j < masters.size(); j++) {
|
||||
ESM::Header::MasterData &mast = const_cast<ESM::Header::MasterData&>(masters[j]);
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <components/esm/esmreader.hpp>
|
||||
#include <QDebug>
|
||||
|
||||
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<EsmFile *>(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<const EsmFile::FileProperty>(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<EsmFile::FileProperty>(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;
|
||||
|
||||
emit dataChanged(index, index);
|
||||
if (setState)
|
||||
{
|
||||
setCheckState(fileName, success);
|
||||
emit dataChanged(index, index);
|
||||
|
||||
}
|
||||
else
|
||||
return success;
|
||||
|
||||
|
||||
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();
|
@ -3,19 +3,26 @@
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QStringList>
|
||||
namespace EsxModel
|
||||
|
||||
namespace ContentSelectorModel
|
||||
{
|
||||
class EsmFile;
|
||||
|
||||
typedef QList<EsmFile *> 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);
|
@ -3,64 +3,65 @@
|
||||
#include <QMimeData>
|
||||
#include <QDataStream>
|
||||
|
||||
int EsxModel::EsmFile::sPropertyCount = 7;
|
||||
QString EsxModel::EsmFile::sToolTip = QString("<b>Author:</b> %1<br/> \
|
||||
int ContentSelectorModel::EsmFile::sPropertyCount = 7;
|
||||
QString ContentSelectorModel::EsmFile::sToolTip = QString("<b>Author:</b> %1<br/> \
|
||||
<b>Version:</b> %2<br/> \
|
||||
<br/><b>Description:</b><br/>%3<br/> \
|
||||
<br/><b>Dependencies: </b>%4<br/>");
|
||||
|
||||
|
||||
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:
|
@ -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
|
69
components/contentselector/model/modelitem.cpp
Normal file
69
components/contentselector/model/modelitem.cpp
Normal file
@ -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<ModelItem*>(this));
|
||||
//return mParentItem->mChildItems.indexOf(const_cast<ModelItem*>(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);
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
#include <QMimeData>
|
||||
#include <QList>
|
||||
|
||||
namespace EsxModel
|
||||
namespace ContentSelectorModel
|
||||
{
|
||||
class ModelItem : public QMimeData
|
||||
{
|
@ -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());
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
|
||||
class QToolButton;
|
||||
|
||||
namespace EsxView
|
||||
namespace ContentSelectorView
|
||||
{
|
||||
class ComboBoxLineEdit : public QLineEdit
|
||||
{
|
134
components/contentselector/view/contentselector.cpp
Normal file
134
components/contentselector/view/contentselector.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
#include "contentselector.hpp"
|
||||
|
||||
#include "../model/contentmodel.hpp"
|
||||
#include "../model/esmfile.hpp"
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMenu>
|
||||
#include <QContextMenuEvent>
|
||||
|
||||
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<QSortFilterProxyModel *>(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<QSortFilterProxyModel *>(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);
|
||||
}
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
|
||||
class QToolButton;
|
||||
|
||||
namespace EsxView
|
||||
namespace ContentSelectorView
|
||||
{
|
||||
class LineEdit : public QLineEdit
|
||||
{
|
@ -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;
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
class QString;
|
||||
class QRegExpValidator;
|
||||
|
||||
namespace EsxView
|
||||
namespace ContentSelectorView
|
||||
{
|
||||
class ProfilesComboBox : public QComboBox
|
||||
{
|
@ -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<Header::MasterData> &getMasters() const { return mHeader.mMaster; }
|
||||
const std::vector<Header::MasterData> &getGameFiles() const { return mHeader.mMaster; }
|
||||
int getFormat() const;
|
||||
const NAME &retSubName() const { return mCtx.subName; }
|
||||
uint32_t getSubSize() const { return mCtx.leftSub; }
|
||||
|
@ -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<Header::MasterData> &masters = esm.getMasters();
|
||||
const std::vector<Header::MasterData> &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<Header::MasterData> &masters = esm.getMasters();
|
||||
const std::vector<Header::MasterData> &masters = esm.getGameFiles();
|
||||
global = masters[local-1].index + 1;
|
||||
mref.mRefnum |= global << 24; // insert global plugin ID
|
||||
|
||||
|
@ -1,608 +0,0 @@
|
||||
#include <QTextDecoder>
|
||||
#include <QTextCodec>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QtAlgorithms>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
|
||||
#include "esmfile.hpp"
|
||||
|
||||
#include "datafilesmodel.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
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("<b>Author:</b> %1<br/> \
|
||||
<b>Version:</b> %2<br/> \
|
||||
<br/><b>Description:</b><br/>%3<br/> \
|
||||
<br/><b>Dependencies: </b>%4<br/>")
|
||||
.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<const EsmFile *>(data))->fileName();
|
||||
// qDebug() << "inserting file: " << droppedfile->fileName() << " ahead of " << file->fileName();
|
||||
insertRows (dropRow, 1, QModelIndex());
|
||||
|
||||
|
||||
const EsmFile *draggedFile = qobject_cast<const EsmFile *>(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<const EsmFile *>(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<ESM::Header::MasterData> 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;
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
#ifndef DATAFILESMODEL_HPP
|
||||
#define DATAFILESMODEL_HPP
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QStringList>
|
||||
#include <QString>
|
||||
#include <QHash>
|
||||
|
||||
namespace EsxModel
|
||||
{
|
||||
class EsmFile;
|
||||
|
||||
typedef QList<const EsmFile *> 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<QString, Qt::CheckState> mCheckStates;
|
||||
|
||||
QString mEncoding;
|
||||
|
||||
};
|
||||
}
|
||||
#endif // DATAFILESMODEL_HPP
|
@ -1,13 +0,0 @@
|
||||
#include "masterproxymodel.hpp"
|
||||
#include <QMimeData>
|
||||
#include <QDebug>
|
||||
|
||||
EsxModel::MasterProxyModel::MasterProxyModel(QObject *parent, QAbstractTableModel* model) :
|
||||
QSortFilterProxyModel(parent)
|
||||
{
|
||||
setFilterRegExp(QString("game"));
|
||||
setFilterRole (Qt::UserRole);
|
||||
|
||||
if (model)
|
||||
setSourceModel (model);
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#ifndef MASTERPROXYMODEL_HPP
|
||||
#define MASTERPROXYMODEL_HPP
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QStringList>
|
||||
#include <QMimeData>
|
||||
|
||||
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
|
@ -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<ModelItem*>(this));
|
||||
//return mParentItem->mChildItems.indexOf(const_cast<ModelItem*>(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);
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#include "pluginsproxymodel.hpp"
|
||||
#include "contentmodel.hpp"
|
||||
#include <QDebug>
|
||||
|
||||
EsxModel::PluginsProxyModel::PluginsProxyModel(QObject *parent, ContentModel *model) :
|
||||
QSortFilterProxyModel(parent)
|
||||
{
|
||||
setFilterRegExp (QString("addon"));
|
||||
setFilterRole (Qt::UserRole);
|
||||
setDynamicSortFilter (true);
|
||||
|
||||
if (model)
|
||||
setSourceModel (model);
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
#ifndef PLUGINSPROXYMODEL_HPP
|
||||
#define PLUGINSPROXYMODEL_HPP
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
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
|
@ -1,6 +0,0 @@
|
||||
#include "sourcemodel.h"
|
||||
|
||||
SourceModel::SourceModel(QObject *parent) :
|
||||
QAbstractTableClass(parent)
|
||||
{
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
#ifndef SOURCEMODEL_H
|
||||
#define SOURCEMODEL_H
|
||||
|
||||
#include <QAbstractTableClass>
|
||||
|
||||
class SourceModel : public QAbstractTableClass
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SourceModel(QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // SOURCEMODEL_H
|
@ -1,148 +0,0 @@
|
||||
#include "contentselector.hpp"
|
||||
|
||||
#include "../model/datafilesmodel.hpp"
|
||||
#include "../model/contentmodel.hpp"
|
||||
#include "../model/esmfile.hpp"
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMenu>
|
||||
#include <QContextMenuEvent>
|
||||
|
||||
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<QSortFilterProxyModel *>(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<QSortFilterProxyModel *>(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);
|
||||
}
|
@ -23,7 +23,7 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="filterLayout">
|
||||
<item>
|
||||
<widget class="EsxView::ProfilesComboBox" name="masterView">
|
||||
<widget class="ContentSelectorView::ProfilesComboBox" name="gameFileView">
|
||||
<property name="editable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
@ -34,7 +34,7 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QTableView" name="pluginView">
|
||||
<widget class="QTableView" name="addonView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
@ -102,7 +102,7 @@
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="EsxView::LineEdit" name="projectNameLineEdit">
|
||||
<widget class="ContentSelectorView::LineEdit" name="projectNameLineEdit">
|
||||
<property name="placeholderText">
|
||||
<string>Enter project name...</string>
|
||||
</property>
|
||||
@ -159,7 +159,7 @@
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="EsxView::ProfilesComboBox" name="profilesComboBox">
|
||||
<widget class="ContentSelectorView::ProfilesComboBox" name="profilesComboBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@ -251,12 +251,12 @@
|
||||
<customwidget>
|
||||
<class>EsxView::ProfilesComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header location="global">components/esxselector/view/profilescombobox.hpp</header>
|
||||
<header location="global">components/contentselector/view/profilescombobox.hpp</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>EsxView::LineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header location="global">components/esxselector/view/lineedit.hpp</header>
|
||||
<header location="global">components/contentselector/view/lineedit.hpp</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user