mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-21 12:09:41 +00:00
Merge remote-tracking branch 'graffy76/esxSelector' into saving
This commit is contained in:
commit
d4b2a6b9f1
72 changed files with 2015 additions and 1519 deletions
|
@ -167,6 +167,7 @@ if(USE_SYSTEM_TINYXML)
|
||||||
find_library(TINYXML_LIBRARIES tinyxml)
|
find_library(TINYXML_LIBRARIES tinyxml)
|
||||||
find_path(TINYXML_INCLUDE_DIR tinyxml.h)
|
find_path(TINYXML_INCLUDE_DIR tinyxml.h)
|
||||||
message(STATUS "Found TinyXML: ${TINYXML_LIBRARIES} ${TINYXML_INCLUDE_DIR}")
|
message(STATUS "Found TinyXML: ${TINYXML_LIBRARIES} ${TINYXML_INCLUDE_DIR}")
|
||||||
|
add_definitions (-DTIXML_USE_STL)
|
||||||
if(TINYXML_LIBRARIES AND TINYXML_INCLUDE_DIR)
|
if(TINYXML_LIBRARIES AND TINYXML_INCLUDE_DIR)
|
||||||
include_directories(${TINYXML_INCLUDE_DIR})
|
include_directories(${TINYXML_INCLUDE_DIR})
|
||||||
message(STATUS "Using system TinyXML library.")
|
message(STATUS "Using system TinyXML library.")
|
||||||
|
|
|
@ -305,14 +305,14 @@ int load(Arguments& info)
|
||||||
|
|
||||||
info.data.author = esm.getAuthor();
|
info.data.author = esm.getAuthor();
|
||||||
info.data.description = esm.getDesc();
|
info.data.description = esm.getDesc();
|
||||||
info.data.masters = esm.getMasters();
|
info.data.masters = esm.getGameFiles();
|
||||||
|
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
{
|
{
|
||||||
std::cout << "Author: " << esm.getAuthor() << std::endl
|
std::cout << "Author: " << esm.getAuthor() << std::endl
|
||||||
<< "Description: " << esm.getDesc() << std::endl
|
<< "Description: " << esm.getDesc() << std::endl
|
||||||
<< "File format version: " << esm.getFVer() << 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())
|
if (!m.empty())
|
||||||
{
|
{
|
||||||
std::cout << "Masters:" << std::endl;
|
std::cout << "Masters:" << std::endl;
|
||||||
|
|
|
@ -4,141 +4,146 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
#include <components/fileorderlist/model/datafilesmodel.hpp>
|
#include <components/contentselector/model/esmfile.hpp>
|
||||||
#include <components/fileorderlist/model/pluginsproxymodel.hpp>
|
|
||||||
#include <components/fileorderlist/model/esm/esmfile.hpp>
|
|
||||||
|
|
||||||
#include <components/fileorderlist/utils/lineedit.hpp>
|
#include <components/contentselector/view/lineedit.hpp>
|
||||||
#include <components/fileorderlist/utils/naturalsort.hpp>
|
#include <components/contentselector/model/naturalsort.hpp>
|
||||||
#include <components/fileorderlist/utils/profilescombobox.hpp>
|
#include <components/contentselector/view/profilescombobox.hpp>
|
||||||
|
|
||||||
#include "settings/gamesettings.hpp"
|
#include "settings/gamesettings.hpp"
|
||||||
#include "settings/launchersettings.hpp"
|
#include "settings/launchersettings.hpp"
|
||||||
|
|
||||||
#include "utils/textinputdialog.hpp"
|
#include "utils/textinputdialog.hpp"
|
||||||
|
#include "components/contentselector/view/contentselector.hpp"
|
||||||
|
#include "components/contentselector/model/contentmodel.hpp"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent)
|
DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent)
|
||||||
: mCfgMgr(cfg)
|
: mCfgMgr(cfg)
|
||||||
, mGameSettings(gameSettings)
|
, mGameSettings(gameSettings)
|
||||||
, mLauncherSettings(launcherSettings)
|
, mLauncherSettings(launcherSettings)
|
||||||
, QWidget(parent)
|
|
||||||
{
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
// mContentSelector.setParent(parent);
|
||||||
|
|
||||||
// Models
|
// QMetaObject::connectSlotsByName(this);
|
||||||
mDataFilesModel = new DataFilesModel(this);
|
|
||||||
|
|
||||||
mMastersProxyModel = new QSortFilterProxyModel();
|
projectGroupBox->hide();
|
||||||
mMastersProxyModel->setFilterRegExp(QString("^.*\\.esm"));
|
|
||||||
mMastersProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
||||||
mMastersProxyModel->setSourceModel(mDataFilesModel);
|
|
||||||
|
|
||||||
mPluginsProxyModel = new PluginsProxyModel();
|
|
||||||
mPluginsProxyModel->setFilterRegExp(QString("^.*\\.esp"));
|
|
||||||
mPluginsProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
||||||
mPluginsProxyModel->setSourceModel(mDataFilesModel);
|
|
||||||
|
|
||||||
mFilterProxyModel = new QSortFilterProxyModel();
|
|
||||||
mFilterProxyModel->setDynamicSortFilter(true);
|
|
||||||
mFilterProxyModel->setSourceModel(mPluginsProxyModel);
|
|
||||||
|
|
||||||
QCheckBox checkBox;
|
|
||||||
unsigned int height = checkBox.sizeHint().height() + 4;
|
|
||||||
|
|
||||||
mastersTable->setModel(mMastersProxyModel);
|
|
||||||
mastersTable->setObjectName("MastersTable");
|
|
||||||
mastersTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
mastersTable->setSortingEnabled(false);
|
|
||||||
mastersTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
||||||
mastersTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
||||||
mastersTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
||||||
mastersTable->setAlternatingRowColors(true);
|
|
||||||
mastersTable->horizontalHeader()->setStretchLastSection(true);
|
|
||||||
mastersTable->horizontalHeader()->hide();
|
|
||||||
|
|
||||||
// Set the row height to the size of the checkboxes
|
|
||||||
mastersTable->verticalHeader()->setDefaultSectionSize(height);
|
|
||||||
mastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed);
|
|
||||||
mastersTable->verticalHeader()->hide();
|
|
||||||
|
|
||||||
pluginsTable->setModel(mFilterProxyModel);
|
|
||||||
pluginsTable->setObjectName("PluginsTable");
|
|
||||||
pluginsTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
pluginsTable->setSortingEnabled(false);
|
|
||||||
pluginsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
||||||
pluginsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
||||||
pluginsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
||||||
pluginsTable->setAlternatingRowColors(true);
|
|
||||||
pluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
|
|
||||||
pluginsTable->horizontalHeader()->setStretchLastSection(true);
|
|
||||||
pluginsTable->horizontalHeader()->hide();
|
|
||||||
|
|
||||||
pluginsTable->verticalHeader()->setDefaultSectionSize(height);
|
|
||||||
pluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed);
|
|
||||||
|
|
||||||
// Adjust the tableview widths inside the splitter
|
|
||||||
QList<int> sizeList;
|
|
||||||
sizeList << mLauncherSettings.value(QString("General/MastersTable/width"), QString("200")).toInt();
|
|
||||||
sizeList << mLauncherSettings.value(QString("General/PluginTable/width"), QString("340")).toInt();
|
|
||||||
|
|
||||||
splitter->setSizes(sizeList);
|
|
||||||
|
|
||||||
// Create a dialog for the new profile name input
|
// Create a dialog for the new profile name input
|
||||||
mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this);
|
mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this);
|
||||||
|
|
||||||
connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentIndexChanged(int)));
|
|
||||||
|
|
||||||
connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString)));
|
connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString)));
|
||||||
|
|
||||||
connect(pluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
|
|
||||||
connect(mastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
|
|
||||||
|
|
||||||
connect(pluginsTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
|
|
||||||
connect(mastersTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
|
|
||||||
|
|
||||||
connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews()));
|
buildContentModel();
|
||||||
|
buildGameFileView();
|
||||||
|
buildAddonView();
|
||||||
|
buildProfilesView();
|
||||||
|
|
||||||
connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
|
|
||||||
|
|
||||||
connect(splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(updateSplitter()));
|
|
||||||
|
|
||||||
createActions();
|
createActions();
|
||||||
setupDataFiles();
|
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()
|
void DataFilesPage::createActions()
|
||||||
{
|
{
|
||||||
|
|
||||||
// Add the actions to the toolbuttons
|
// Add the actions to the toolbuttons
|
||||||
newProfileButton->setDefaultAction(newProfileAction);
|
newProfileButton->setDefaultAction(newProfileAction);
|
||||||
deleteProfileButton->setDefaultAction(deleteProfileAction);
|
deleteProfileButton->setDefaultAction(deleteProfileAction);
|
||||||
|
|
||||||
// Context menu actions
|
|
||||||
mContextMenu = new QMenu(this);
|
|
||||||
mContextMenu->addAction(checkAction);
|
|
||||||
mContextMenu->addAction(uncheckAction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesPage::setupDataFiles()
|
void DataFilesPage::setupDataFiles()
|
||||||
{
|
{
|
||||||
// Set the encoding to the one found in openmw.cfg or the default
|
// Set the encoding to the one found in openmw.cfg or the default
|
||||||
mDataFilesModel->setEncoding(mGameSettings.value(QString("encoding"), QString("win1252")));
|
//mContentSelector.setEncoding(mGameSettings.value(QString("encoding"), QString("win1252")));
|
||||||
|
|
||||||
QStringList paths = mGameSettings.getDataDirs();
|
QStringList paths = mGameSettings.getDataDirs();
|
||||||
|
|
||||||
foreach (const QString &path, paths) {
|
foreach (const QString &path, paths) {
|
||||||
mDataFilesModel->addFiles(path);
|
//mContentSelector.
|
||||||
|
mContentModel->addFiles(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString dataLocal = mGameSettings.getDataLocal();
|
QString dataLocal = mGameSettings.getDataLocal();
|
||||||
if (!dataLocal.isEmpty())
|
if (!dataLocal.isEmpty())
|
||||||
mDataFilesModel->addFiles(dataLocal);
|
//mContentSelector.
|
||||||
|
mContentModel->addFiles(dataLocal);
|
||||||
|
|
||||||
// Sort by date accessed for now
|
// Sort by date accessed for now
|
||||||
mDataFilesModel->sort(3);
|
//mContentSelector->sort(3);
|
||||||
|
|
||||||
QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/"));
|
QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/"));
|
||||||
QString profile = mLauncherSettings.value(QString("Profiles/currentprofile"));
|
QString profile = mLauncherSettings.value(QString("Profiles/currentprofile"));
|
||||||
|
@ -168,6 +173,7 @@ void DataFilesPage::setupDataFiles()
|
||||||
|
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
|
||||||
|
gameFileView->setCurrentIndex(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesPage::loadSettings()
|
void DataFilesPage::loadSettings()
|
||||||
|
@ -177,27 +183,16 @@ void DataFilesPage::loadSettings()
|
||||||
if (profile.isEmpty())
|
if (profile.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mDataFilesModel->uncheckAll();
|
// mContentSelector.
|
||||||
|
mContentModel->uncheckAll();
|
||||||
|
|
||||||
QStringList masters = mLauncherSettings.values(QString("Profiles/") + profile + QString("/master"), Qt::MatchExactly);
|
QStringList gameFiles = mLauncherSettings.values(QString("Profiles/") + profile + QString("/master"), Qt::MatchExactly);
|
||||||
QStringList plugins = mLauncherSettings.values(QString("Profiles/") + profile + QString("/plugin"), Qt::MatchExactly);
|
QStringList addons = 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesPage::saveSettings()
|
void DataFilesPage::saveSettings()
|
||||||
{
|
{
|
||||||
if (mDataFilesModel->rowCount() < 1)
|
if (mContentModel->rowCount() < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString profile = mLauncherSettings.value(QString("Profiles/currentprofile"));
|
QString profile = mLauncherSettings.value(QString("Profiles/currentprofile"));
|
||||||
|
@ -213,17 +208,17 @@ void DataFilesPage::saveSettings()
|
||||||
mGameSettings.remove(QString("master"));
|
mGameSettings.remove(QString("master"));
|
||||||
mGameSettings.remove(QString("plugin"));
|
mGameSettings.remove(QString("plugin"));
|
||||||
|
|
||||||
QStringList items = mDataFilesModel->checkedItems();
|
ContentSelectorModel::ContentFileList items = mContentModel->checkedItems();
|
||||||
|
|
||||||
foreach(const QString &item, items) {
|
foreach(const ContentSelectorModel::EsmFile *item, items) {
|
||||||
|
|
||||||
if (item.endsWith(QString(".esm"), Qt::CaseInsensitive)) {
|
if (item->gameFiles().size() == 0) {
|
||||||
mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/master"), item);
|
mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/master"), item->fileName());
|
||||||
mGameSettings.setMultiValue(QString("master"), item);
|
mGameSettings.setMultiValue(QString("master"), item->fileName());
|
||||||
|
|
||||||
} else if (item.endsWith(QString(".esp"), Qt::CaseInsensitive)) {
|
} else {
|
||||||
mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/plugin"), item);
|
mLauncherSettings.setMultiValue(QString("Profiles/") + profile + QString("/plugin"), item->fileName());
|
||||||
mGameSettings.setMultiValue(QString("plugin"), item);
|
mGameSettings.setMultiValue(QString("plugin"), item->fileName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,48 +237,11 @@ void DataFilesPage::updateOkButton(const QString &text)
|
||||||
: mNewProfileDialog->setOkButtonEnabled(false);
|
: mNewProfileDialog->setOkButtonEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesPage::updateSplitter()
|
|
||||||
{
|
|
||||||
// Sigh, update the saved splitter size in settings only when moved
|
|
||||||
// Since getting mSplitter->sizes() if page is hidden returns invalid values
|
|
||||||
QList<int> sizes = splitter->sizes();
|
|
||||||
|
|
||||||
mLauncherSettings.setValue(QString("General/MastersTable/width"), QString::number(sizes.at(0)));
|
|
||||||
mLauncherSettings.setValue(QString("General/PluginsTable/width"), QString::number(sizes.at(1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesPage::updateViews()
|
|
||||||
{
|
|
||||||
// Ensure the columns are hidden because sort() re-enables them
|
|
||||||
mastersTable->setColumnHidden(1, true);
|
|
||||||
mastersTable->setColumnHidden(2, true);
|
|
||||||
mastersTable->setColumnHidden(3, true);
|
|
||||||
mastersTable->setColumnHidden(4, true);
|
|
||||||
mastersTable->setColumnHidden(5, true);
|
|
||||||
mastersTable->setColumnHidden(6, true);
|
|
||||||
mastersTable->setColumnHidden(7, true);
|
|
||||||
mastersTable->setColumnHidden(8, true);
|
|
||||||
|
|
||||||
pluginsTable->setColumnHidden(1, true);
|
|
||||||
pluginsTable->setColumnHidden(2, true);
|
|
||||||
pluginsTable->setColumnHidden(3, true);
|
|
||||||
pluginsTable->setColumnHidden(4, true);
|
|
||||||
pluginsTable->setColumnHidden(5, true);
|
|
||||||
pluginsTable->setColumnHidden(6, true);
|
|
||||||
pluginsTable->setColumnHidden(7, true);
|
|
||||||
pluginsTable->setColumnHidden(8, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesPage::setProfilesComboBoxIndex(int index)
|
void DataFilesPage::setProfilesComboBoxIndex(int index)
|
||||||
{
|
{
|
||||||
profilesComboBox->setCurrentIndex(index);
|
profilesComboBox->setCurrentIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesPage::slotCurrentIndexChanged(int index)
|
|
||||||
{
|
|
||||||
emit profileChanged(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
QAbstractItemModel* DataFilesPage::profilesComboBoxModel()
|
QAbstractItemModel* DataFilesPage::profilesComboBoxModel()
|
||||||
{
|
{
|
||||||
return profilesComboBox->model();
|
return profilesComboBox->model();
|
||||||
|
@ -330,112 +288,30 @@ void DataFilesPage::on_deleteProfileAction_triggered()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesPage::on_checkAction_triggered()
|
|
||||||
{
|
|
||||||
if (pluginsTable->hasFocus())
|
|
||||||
setPluginsCheckstates(Qt::Checked);
|
|
||||||
|
|
||||||
if (mastersTable->hasFocus())
|
|
||||||
setMastersCheckstates(Qt::Checked);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesPage::on_uncheckAction_triggered()
|
|
||||||
{
|
|
||||||
if (pluginsTable->hasFocus())
|
|
||||||
setPluginsCheckstates(Qt::Unchecked);
|
|
||||||
|
|
||||||
if (mastersTable->hasFocus())
|
|
||||||
setMastersCheckstates(Qt::Unchecked);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesPage::setMastersCheckstates(Qt::CheckState state)
|
|
||||||
{
|
|
||||||
if (!mastersTable->selectionModel()->hasSelection()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndexList indexes = mastersTable->selectionModel()->selectedIndexes();
|
|
||||||
|
|
||||||
foreach (const QModelIndex &index, indexes)
|
|
||||||
{
|
|
||||||
if (!index.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QModelIndex sourceIndex = mMastersProxyModel->mapToSource(index);
|
|
||||||
|
|
||||||
if (!sourceIndex.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
mDataFilesModel->setCheckState(sourceIndex, state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesPage::setPluginsCheckstates(Qt::CheckState state)
|
void DataFilesPage::setPluginsCheckstates(Qt::CheckState state)
|
||||||
{
|
{
|
||||||
if (!pluginsTable->selectionModel()->hasSelection()) {
|
if (!addonView->selectionModel()->hasSelection()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndexList indexes = pluginsTable->selectionModel()->selectedIndexes();
|
QModelIndexList indexes = addonView->selectionModel()->selectedIndexes();
|
||||||
|
|
||||||
foreach (const QModelIndex &index, indexes)
|
foreach (const QModelIndex &index, indexes)
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(
|
QModelIndex sourceIndex = mAddonProxyModel->mapToSource(index);
|
||||||
mFilterProxyModel->mapToSource(index));
|
|
||||||
|
|
||||||
if (!sourceIndex.isValid())
|
if (!sourceIndex.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mDataFilesModel->setCheckState(sourceIndex, state);
|
//bool isChecked = ( state == Qt::Checked );
|
||||||
|
|
||||||
|
mContentModel->setData(sourceIndex, state, Qt::CheckStateRole);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataFilesPage::setCheckState(QModelIndex index)
|
|
||||||
{
|
|
||||||
if (!index.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QObject *object = QObject::sender();
|
|
||||||
|
|
||||||
// Not a signal-slot call
|
|
||||||
if (!object)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
if (object->objectName() == QLatin1String("PluginsTable")) {
|
|
||||||
QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(
|
|
||||||
mFilterProxyModel->mapToSource(index));
|
|
||||||
|
|
||||||
if (sourceIndex.isValid()) {
|
|
||||||
(mDataFilesModel->checkState(sourceIndex) == Qt::Checked)
|
|
||||||
? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked)
|
|
||||||
: mDataFilesModel->setCheckState(sourceIndex, Qt::Checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (object->objectName() == QLatin1String("MastersTable")) {
|
|
||||||
QModelIndex sourceIndex = mMastersProxyModel->mapToSource(index);
|
|
||||||
|
|
||||||
if (sourceIndex.isValid()) {
|
|
||||||
(mDataFilesModel->checkState(sourceIndex) == Qt::Checked)
|
|
||||||
? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked)
|
|
||||||
: mDataFilesModel->setCheckState(sourceIndex, Qt::Checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesPage::filterChanged(const QString filter)
|
|
||||||
{
|
|
||||||
QRegExp regExp(filter, Qt::CaseInsensitive, QRegExp::FixedString);
|
|
||||||
mFilterProxyModel->setFilterRegExp(regExp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesPage::profileChanged(const QString &previous, const QString ¤t)
|
void DataFilesPage::profileChanged(const QString &previous, const QString ¤t)
|
||||||
{
|
{
|
||||||
// Prevent the deletion of the default profile
|
// Prevent the deletion of the default profile
|
||||||
|
@ -480,72 +356,51 @@ void DataFilesPage::profileRenamed(const QString &previous, const QString &curre
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
////////////////////////////
|
||||||
|
|
||||||
void DataFilesPage::showContextMenu(const QPoint &point)
|
QStringList DataFilesPage::checkedItemsPaths()
|
||||||
{
|
{
|
||||||
QObject *object = QObject::sender();
|
QStringList itemPaths;
|
||||||
|
|
||||||
// Not a signal-slot call
|
foreach( const ContentSelectorModel::EsmFile *file, mContentModel->checkedItems())
|
||||||
if (!object)
|
itemPaths << file->path();
|
||||||
return;
|
|
||||||
|
|
||||||
if (object->objectName() == QLatin1String("PluginsTable")) {
|
return itemPaths;
|
||||||
if (!pluginsTable->selectionModel()->hasSelection())
|
}
|
||||||
return;
|
|
||||||
|
void DataFilesPage::slotCurrentProfileIndexChanged(int index)
|
||||||
QPoint globalPos = pluginsTable->mapToGlobal(point);
|
{
|
||||||
QModelIndexList indexes = pluginsTable->selectionModel()->selectedIndexes();
|
emit profileChanged(index);
|
||||||
|
}
|
||||||
// Show the check/uncheck actions depending on the state of the selected items
|
|
||||||
uncheckAction->setEnabled(false);
|
void DataFilesPage::slotCurrentGameFileIndexChanged(int index)
|
||||||
checkAction->setEnabled(false);
|
{
|
||||||
|
static int oldIndex = -1;
|
||||||
foreach (const QModelIndex &index, indexes)
|
|
||||||
{
|
QAbstractItemModel *const model = gameFileView->model();
|
||||||
if (!index.isValid())
|
QSortFilterProxyModel *proxy = dynamic_cast<QSortFilterProxyModel *>(model);
|
||||||
return;
|
|
||||||
|
if (proxy)
|
||||||
QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(
|
proxy->setDynamicSortFilter(false);
|
||||||
mFilterProxyModel->mapToSource(index));
|
|
||||||
|
if (oldIndex > -1)
|
||||||
if (!sourceIndex.isValid())
|
model->setData(model->index(oldIndex, 0), false, Qt::UserRole + 1);
|
||||||
return;
|
|
||||||
|
oldIndex = index;
|
||||||
(mDataFilesModel->checkState(sourceIndex) == Qt::Checked)
|
|
||||||
? uncheckAction->setEnabled(true)
|
model->setData(model->index(index, 0), true, Qt::UserRole + 1);
|
||||||
: checkAction->setEnabled(true);
|
|
||||||
}
|
if (proxy)
|
||||||
|
proxy->setDynamicSortFilter(true);
|
||||||
// Show menu
|
}
|
||||||
mContextMenu->exec(globalPos);
|
|
||||||
}
|
void DataFilesPage::slotAddonTableItemClicked(const QModelIndex &index)
|
||||||
|
{
|
||||||
if (object->objectName() == QLatin1String("MastersTable")) {
|
QAbstractItemModel *const model = addonView->model();
|
||||||
if (!mastersTable->selectionModel()->hasSelection())
|
//QSortFilterProxyModel *proxy = dynamic_cast<QSortFilterProxyModel *>(model);
|
||||||
return;
|
|
||||||
|
if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked)
|
||||||
QPoint globalPos = mastersTable->mapToGlobal(point);
|
model->setData(index, Qt::Checked, Qt::CheckStateRole);
|
||||||
QModelIndexList indexes = mastersTable->selectionModel()->selectedIndexes();
|
else
|
||||||
|
model->setData(index, Qt::Unchecked, Qt::CheckStateRole);
|
||||||
// Show the check/uncheck actions depending on the state of the selected items
|
|
||||||
uncheckAction->setEnabled(false);
|
|
||||||
checkAction->setEnabled(false);
|
|
||||||
|
|
||||||
foreach (const QModelIndex &index, indexes)
|
|
||||||
{
|
|
||||||
if (!index.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QModelIndex sourceIndex = mMastersProxyModel->mapToSource(index);
|
|
||||||
|
|
||||||
if (!sourceIndex.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
(mDataFilesModel->checkState(sourceIndex) == Qt::Checked)
|
|
||||||
? uncheckAction->setEnabled(true)
|
|
||||||
: checkAction->setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
mContextMenu->exec(globalPos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,17 +5,17 @@
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
|
|
||||||
#include "ui_datafilespage.h"
|
#include "ui_datafilespage.h"
|
||||||
|
#include "components/contentselector/view/contentselector.hpp"
|
||||||
|
|
||||||
class QSortFilterProxyModel;
|
class QSortFilterProxyModel;
|
||||||
class QAbstractItemModel;
|
class QAbstractItemModel;
|
||||||
class QAction;
|
class QAction;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
|
|
||||||
class DataFilesModel;
|
|
||||||
class TextInputDialog;
|
class TextInputDialog;
|
||||||
class GameSettings;
|
class GameSettings;
|
||||||
class LauncherSettings;
|
class LauncherSettings;
|
||||||
class PluginsProxyModel;
|
|
||||||
|
|
||||||
namespace Files { struct ConfigurationManager; }
|
namespace Files { struct ConfigurationManager; }
|
||||||
|
|
||||||
|
@ -36,44 +36,33 @@ signals:
|
||||||
void profileChanged(int index);
|
void profileChanged(int index);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setCheckState(QModelIndex index);
|
|
||||||
void setProfilesComboBoxIndex(int index);
|
void setProfilesComboBoxIndex(int index);
|
||||||
|
|
||||||
void filterChanged(const QString filter);
|
//void showContextMenu(const QPoint &point);
|
||||||
void showContextMenu(const QPoint &point);
|
|
||||||
void profileChanged(const QString &previous, const QString ¤t);
|
void profileChanged(const QString &previous, const QString ¤t);
|
||||||
void profileRenamed(const QString &previous, const QString ¤t);
|
void profileRenamed(const QString &previous, const QString ¤t);
|
||||||
void updateOkButton(const QString &text);
|
void updateOkButton(const QString &text);
|
||||||
void updateSplitter();
|
|
||||||
void updateViews();
|
void updateViews();
|
||||||
|
|
||||||
// Action slots
|
// Action slots
|
||||||
void on_newProfileAction_triggered();
|
void on_newProfileAction_triggered();
|
||||||
void on_deleteProfileAction_triggered();
|
void on_deleteProfileAction_triggered();
|
||||||
void on_checkAction_triggered();
|
|
||||||
void on_uncheckAction_triggered();
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotCurrentIndexChanged(int index);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DataFilesModel *mDataFilesModel;
|
|
||||||
|
|
||||||
PluginsProxyModel *mPluginsProxyModel;
|
|
||||||
QSortFilterProxyModel *mMastersProxyModel;
|
|
||||||
|
|
||||||
QSortFilterProxyModel *mFilterProxyModel;
|
|
||||||
|
|
||||||
QMenu *mContextMenu;
|
QMenu *mContextMenu;
|
||||||
|
//ContentSelectorView::ContentSelector mContentSelector;
|
||||||
|
ContentSelectorModel::ContentModel *mContentModel;
|
||||||
Files::ConfigurationManager &mCfgMgr;
|
Files::ConfigurationManager &mCfgMgr;
|
||||||
|
|
||||||
GameSettings &mGameSettings;
|
GameSettings &mGameSettings;
|
||||||
LauncherSettings &mLauncherSettings;
|
LauncherSettings &mLauncherSettings;
|
||||||
|
|
||||||
TextInputDialog *mNewProfileDialog;
|
TextInputDialog *mNewProfileDialog;
|
||||||
|
QSortFilterProxyModel *mGameFileProxyModel;
|
||||||
|
QSortFilterProxyModel *mAddonProxyModel;
|
||||||
|
|
||||||
void setMastersCheckstates(Qt::CheckState state);
|
|
||||||
void setPluginsCheckstates(Qt::CheckState state);
|
void setPluginsCheckstates(Qt::CheckState state);
|
||||||
|
|
||||||
void createActions();
|
void createActions();
|
||||||
|
@ -83,6 +72,22 @@ private:
|
||||||
|
|
||||||
void loadSettings();
|
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
|
#endif
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
#include <components/files/ogreplugin.hpp>
|
#include <components/files/ogreplugin.hpp>
|
||||||
|
|
||||||
#include <components/fileorderlist/utils/naturalsort.hpp>
|
#include <components/contentselector/model/naturalsort.hpp>
|
||||||
|
|
||||||
#include "settings/graphicssettings.hpp"
|
#include "settings/graphicssettings.hpp"
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <QValidator>
|
#include <QValidator>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
|
||||||
#include <components/fileorderlist/utils/lineedit.hpp>
|
#include <components/contentselector/view/lineedit.hpp>
|
||||||
|
|
||||||
TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWidget *parent) :
|
TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWidget *parent) :
|
||||||
QDialog(parent)
|
QDialog(parent)
|
||||||
|
@ -19,7 +19,7 @@ TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWid
|
||||||
|
|
||||||
// Line edit
|
// Line edit
|
||||||
QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore
|
QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore
|
||||||
mLineEdit = new LineEdit(this);
|
mLineEdit = new ContentSelectorView::LineEdit(this);
|
||||||
mLineEdit->setValidator(validator);
|
mLineEdit->setValidator(validator);
|
||||||
mLineEdit->setCompleter(0);
|
mLineEdit->setCompleter(0);
|
||||||
|
|
||||||
|
|
|
@ -2,20 +2,23 @@
|
||||||
#define TEXTINPUTDIALOG_HPP
|
#define TEXTINPUTDIALOG_HPP
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
//#include "lineedit.hpp"
|
|
||||||
|
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
class LineEdit;
|
|
||||||
|
namespace ContentSelectorView {
|
||||||
|
class LineEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TextInputDialog : public QDialog
|
class TextInputDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0);
|
explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0);
|
||||||
inline LineEdit *lineEdit() { return mLineEdit; }
|
inline ContentSelectorView::LineEdit *lineEdit() { return mLineEdit; }
|
||||||
void setOkButtonEnabled(bool enabled);
|
void setOkButtonEnabled(bool enabled);
|
||||||
|
|
||||||
LineEdit *mLineEdit;
|
ContentSelectorView::LineEdit *mLineEdit;
|
||||||
|
|
||||||
int exec();
|
int exec();
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,12 @@ opencs_hdrs_noqt (model/doc
|
||||||
|
|
||||||
|
|
||||||
opencs_units (model/world
|
opencs_units (model/world
|
||||||
idtable idtableproxymodel regionmap
|
idtable idtableproxymodel regionmap data
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
opencs_units_noqt (model/world
|
opencs_units_noqt (model/world
|
||||||
universalid data record commands columnbase scriptcontext cell refidcollection
|
universalid record commands columnbase scriptcontext cell refidcollection
|
||||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns
|
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,8 @@ void CS::Editor::setupDataFiles()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the charset for reading the esm/esp files
|
// Set the charset for reading the esm/esp files
|
||||||
QString encoding = QString::fromStdString(variables["encoding"].as<std::string>());
|
// QString encoding = QString::fromStdString(variables["encoding"].as<std::string>());
|
||||||
mFileDialog.setEncoding(encoding);
|
//mFileDialog.setEncoding(encoding);
|
||||||
|
|
||||||
dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end());
|
dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end());
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace CS
|
||||||
CSVDoc::StartupDialogue mStartup;
|
CSVDoc::StartupDialogue mStartup;
|
||||||
CSVDoc::NewGameDialogue mNewGame;
|
CSVDoc::NewGameDialogue mNewGame;
|
||||||
CSVSettings::UserSettingsDialog mSettings;
|
CSVSettings::UserSettingsDialog mSettings;
|
||||||
FileDialog mFileDialog;
|
CSVDoc::FileDialog mFileDialog;
|
||||||
|
|
||||||
Files::ConfigurationManager mCfgMgr;
|
Files::ConfigurationManager mCfgMgr;
|
||||||
boost::filesystem::path mLocal;
|
boost::filesystem::path mLocal;
|
||||||
|
|
|
@ -42,7 +42,7 @@ int main(int argc, char *argv[])
|
||||||
if(!editor.makeIPCServer())
|
if(!editor.makeIPCServer())
|
||||||
{
|
{
|
||||||
editor.connectToIPCServer();
|
editor.connectToIPCServer();
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return editor.run();
|
return editor.run();
|
||||||
|
|
|
@ -107,6 +107,11 @@ namespace CSMWorld
|
||||||
virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const;
|
virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const;
|
||||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||||
|
|
||||||
|
virtual std::vector<std::string> getIds (bool listDeleted = true) const;
|
||||||
|
///< Return a sorted collection of all IDs
|
||||||
|
///
|
||||||
|
/// \param listDeleted include deleted record in the list
|
||||||
|
|
||||||
void addColumn (Column<ESXRecordT> *column);
|
void addColumn (Column<ESXRecordT> *column);
|
||||||
|
|
||||||
void setRecord (int index, const Record<ESXRecordT>& record);
|
void setRecord (int index, const Record<ESXRecordT>& record);
|
||||||
|
@ -293,6 +298,21 @@ namespace CSMWorld
|
||||||
return static_cast<int> (mRecords.size());
|
return static_cast<int> (mRecords.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ESXRecordT, typename IdAccessorT>
|
||||||
|
std::vector<std::string> Collection<ESXRecordT, IdAccessorT>::getIds (bool listDeleted) const
|
||||||
|
{
|
||||||
|
std::vector<std::string> ids;
|
||||||
|
|
||||||
|
for (typename std::map<std::string, int>::const_iterator iter = mIndex.begin();
|
||||||
|
iter!=mIndex.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (listDeleted || !mRecords[iter->second].isDeleted())
|
||||||
|
ids.push_back (IdAccessorT().getId (mRecords[iter->second].get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ESXRecordT, typename IdAccessorT>
|
template<typename ESXRecordT, typename IdAccessorT>
|
||||||
const Record<ESXRecordT>& Collection<ESXRecordT, IdAccessorT>::getRecord (const std::string& id) const
|
const Record<ESXRecordT>& Collection<ESXRecordT, IdAccessorT>::getRecord (const std::string& id) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,8 +78,12 @@ namespace CSMWorld
|
||||||
|
|
||||||
virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const = 0;
|
virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const = 0;
|
||||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||||
};
|
|
||||||
|
|
||||||
|
virtual std::vector<std::string> getIds (bool listDeleted = true) const = 0;
|
||||||
|
///< Return a sorted collection of all IDs
|
||||||
|
///
|
||||||
|
/// \param listDeleted include deleted record in the list
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -2,6 +2,7 @@
|
||||||
#include "data.hpp"
|
#include "data.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
@ -15,13 +16,31 @@
|
||||||
#include "columns.hpp"
|
#include "columns.hpp"
|
||||||
|
|
||||||
void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
||||||
UniversalId::Type type2)
|
UniversalId::Type type2, bool update)
|
||||||
{
|
{
|
||||||
mModels.push_back (model);
|
mModels.push_back (model);
|
||||||
mModelIndex.insert (std::make_pair (type1, model));
|
mModelIndex.insert (std::make_pair (type1, model));
|
||||||
|
|
||||||
if (type2!=UniversalId::Type_None)
|
if (type2!=UniversalId::Type_None)
|
||||||
mModelIndex.insert (std::make_pair (type2, model));
|
mModelIndex.insert (std::make_pair (type2, model));
|
||||||
|
|
||||||
|
if (update)
|
||||||
|
{
|
||||||
|
connect (model, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
|
this, SLOT (dataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
|
connect (model, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (rowsChanged (const QModelIndex&, int, int)));
|
||||||
|
connect (model, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (rowsChanged (const QModelIndex&, int, int)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::Data::appendIds (std::vector<std::string>& ids, const CollectionBase& collection,
|
||||||
|
bool listDeleted)
|
||||||
|
{
|
||||||
|
std::vector<std::string> ids2 = collection.getIds (listDeleted);
|
||||||
|
|
||||||
|
ids.insert (ids.end(), ids2.begin(), ids2.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::Data::Data() : mRefs (mCells)
|
CSMWorld::Data::Data() : mRefs (mCells)
|
||||||
|
@ -155,7 +174,7 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
||||||
|
|
||||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
||||||
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
|
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
|
||||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill);
|
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill, false);
|
||||||
addModel (new IdTable (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class);
|
addModel (new IdTable (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class);
|
||||||
addModel (new IdTable (&mFactions), UniversalId::Type_Factions, UniversalId::Type_Faction);
|
addModel (new IdTable (&mFactions), UniversalId::Type_Factions, UniversalId::Type_Faction);
|
||||||
addModel (new IdTable (&mRaces), UniversalId::Type_Races, UniversalId::Type_Race);
|
addModel (new IdTable (&mRaces), UniversalId::Type_Races, UniversalId::Type_Race);
|
||||||
|
@ -167,8 +186,8 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
||||||
addModel (new IdTable (&mCells), UniversalId::Type_Cells, UniversalId::Type_Cell);
|
addModel (new IdTable (&mCells), UniversalId::Type_Cells, UniversalId::Type_Cell);
|
||||||
addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables,
|
addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables,
|
||||||
UniversalId::Type_Referenceable);
|
UniversalId::Type_Referenceable);
|
||||||
addModel (new IdTable (&mRefs), UniversalId::Type_References, UniversalId::Type_Reference);
|
addModel (new IdTable (&mRefs), UniversalId::Type_References, UniversalId::Type_Reference, false);
|
||||||
addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter);
|
addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::Data::~Data()
|
CSMWorld::Data::~Data()
|
||||||
|
@ -341,7 +360,7 @@ QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id)
|
||||||
{
|
{
|
||||||
RegionMap *table = 0;
|
RegionMap *table = 0;
|
||||||
addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap,
|
addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap,
|
||||||
UniversalId::Type_None);
|
UniversalId::Type_None, false);
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
throw std::logic_error ("No table model available for " + id.toString());
|
throw std::logic_error ("No table model available for " + id.toString());
|
||||||
|
@ -440,3 +459,36 @@ bool CSMWorld::Data::hasId (const std::string& id) const
|
||||||
getCells().searchId (id)!=-1 ||
|
getCells().searchId (id)!=-1 ||
|
||||||
getReferenceables().searchId (id)!=-1;
|
getReferenceables().searchId (id)!=-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> CSMWorld::Data::getIds (bool listDeleted) const
|
||||||
|
{
|
||||||
|
std::vector<std::string> ids;
|
||||||
|
|
||||||
|
appendIds (ids, mGlobals, listDeleted);
|
||||||
|
appendIds (ids, mGmsts, listDeleted);
|
||||||
|
appendIds (ids, mClasses, listDeleted);
|
||||||
|
appendIds (ids, mFactions, listDeleted);
|
||||||
|
appendIds (ids, mRaces, listDeleted);
|
||||||
|
appendIds (ids, mSounds, listDeleted);
|
||||||
|
appendIds (ids, mScripts, listDeleted);
|
||||||
|
appendIds (ids, mRegions, listDeleted);
|
||||||
|
appendIds (ids, mBirthsigns, listDeleted);
|
||||||
|
appendIds (ids, mSpells, listDeleted);
|
||||||
|
appendIds (ids, mCells, listDeleted);
|
||||||
|
appendIds (ids, mReferenceables, listDeleted);
|
||||||
|
|
||||||
|
std::sort (ids.begin(), ids.end());
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::Data::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
if (topLeft.column()<=0)
|
||||||
|
emit idListChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::Data::rowsChanged (const QModelIndex& parent, int start, int end)
|
||||||
|
{
|
||||||
|
emit idListChanged();
|
||||||
|
}
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QModelIndex>
|
||||||
|
|
||||||
#include <components/esm/loadglob.hpp>
|
#include <components/esm/loadglob.hpp>
|
||||||
#include <components/esm/loadgmst.hpp>
|
#include <components/esm/loadgmst.hpp>
|
||||||
#include <components/esm/loadskil.hpp>
|
#include <components/esm/loadskil.hpp>
|
||||||
|
@ -30,8 +33,10 @@ class QAbstractItemModel;
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
class Data
|
class Data : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
IdCollection<ESM::Global> mGlobals;
|
IdCollection<ESM::Global> mGlobals;
|
||||||
IdCollection<ESM::GameSetting> mGmsts;
|
IdCollection<ESM::GameSetting> mGmsts;
|
||||||
IdCollection<ESM::Skill> mSkills;
|
IdCollection<ESM::Skill> mSkills;
|
||||||
|
@ -55,13 +60,17 @@ namespace CSMWorld
|
||||||
Data& operator= (const Data&);
|
Data& operator= (const Data&);
|
||||||
|
|
||||||
void addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
void addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
||||||
UniversalId::Type type2 = UniversalId::Type_None);
|
UniversalId::Type type2 = UniversalId::Type_None, bool update = true);
|
||||||
|
|
||||||
|
static void appendIds (std::vector<std::string>& ids, const CollectionBase& collection,
|
||||||
|
bool listDeleted);
|
||||||
|
///< Append all IDs from collection to \a ids.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Data();
|
Data();
|
||||||
|
|
||||||
~Data();
|
virtual ~Data();
|
||||||
|
|
||||||
const IdCollection<ESM::Global>& getGlobals() const;
|
const IdCollection<ESM::Global>& getGlobals() const;
|
||||||
|
|
||||||
|
@ -136,6 +145,21 @@ namespace CSMWorld
|
||||||
///< Merging content of a file into base or modified.
|
///< Merging content of a file into base or modified.
|
||||||
|
|
||||||
bool hasId (const std::string& id) const;
|
bool hasId (const std::string& id) const;
|
||||||
|
|
||||||
|
std::vector<std::string> getIds (bool listDeleted = true) const;
|
||||||
|
///< Return a sorted collection of all IDs that are not internal to the editor.
|
||||||
|
///
|
||||||
|
/// \param listDeleted include deleted record in the list
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void idListChanged();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
void rowsChanged (const QModelIndex& parent, int start, int end);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -534,3 +534,8 @@ int CSMWorld::RefIdCollection::getAppendIndex (UniversalId::Type type) const
|
||||||
{
|
{
|
||||||
return mData.getAppendIndex (type);
|
return mData.getAppendIndex (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> CSMWorld::RefIdCollection::getIds (bool listDeleted) const
|
||||||
|
{
|
||||||
|
return mData.getIds (listDeleted);
|
||||||
|
}
|
||||||
|
|
|
@ -89,6 +89,11 @@ namespace CSMWorld
|
||||||
|
|
||||||
virtual int getAppendIndex (UniversalId::Type type) const;
|
virtual int getAppendIndex (UniversalId::Type type) const;
|
||||||
///< \param type Will be ignored, unless the collection supports multiple record types
|
///< \param type Will be ignored, unless the collection supports multiple record types
|
||||||
|
|
||||||
|
virtual std::vector<std::string> getIds (bool listDeleted) const;
|
||||||
|
///< Return a sorted collection of all IDs
|
||||||
|
///
|
||||||
|
/// \param listDeleted include deleted record in the list
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,3 +196,25 @@ int CSMWorld::RefIdData::getSize() const
|
||||||
{
|
{
|
||||||
return mIndex.size();
|
return mIndex.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> CSMWorld::RefIdData::getIds (bool listDeleted) const
|
||||||
|
{
|
||||||
|
std::vector<std::string> ids;
|
||||||
|
|
||||||
|
for (std::map<std::string, LocalIndex>::const_iterator iter (mIndex.begin()); iter!=mIndex.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
if (listDeleted || !getRecord (iter->second).isDeleted())
|
||||||
|
{
|
||||||
|
std::map<UniversalId::Type, RefIdDataContainerBase *>::const_iterator container =
|
||||||
|
mRecordContainers.find (iter->second.second);
|
||||||
|
|
||||||
|
if (container==mRecordContainers.end())
|
||||||
|
throw std::logic_error ("Invalid referenceable ID type");
|
||||||
|
|
||||||
|
ids.push_back (container->second->getId (iter->second.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
|
@ -182,6 +182,11 @@ namespace CSMWorld
|
||||||
void load (const LocalIndex& index, ESM::ESMReader& reader, bool base);
|
void load (const LocalIndex& index, ESM::ESMReader& reader, bool base);
|
||||||
|
|
||||||
int getSize() const;
|
int getSize() const;
|
||||||
|
|
||||||
|
std::vector<std::string> getIds (bool listDeleted = true) const;
|
||||||
|
///< Return a sorted collection of all IDs
|
||||||
|
///
|
||||||
|
/// \param listDeleted include deleted record in the list
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
|
|
||||||
#include "scriptcontext.hpp"
|
#include "scriptcontext.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
|
#include "data.hpp"
|
||||||
|
|
||||||
|
CSMWorld::ScriptContext::ScriptContext (const Data& data) : mData (data), mIdsUpdated (false) {}
|
||||||
|
|
||||||
bool CSMWorld::ScriptContext::canDeclareLocals() const
|
bool CSMWorld::ScriptContext::canDeclareLocals() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -18,5 +26,19 @@ char CSMWorld::ScriptContext::getMemberType (const std::string& name, const std:
|
||||||
|
|
||||||
bool CSMWorld::ScriptContext::isId (const std::string& name) const
|
bool CSMWorld::ScriptContext::isId (const std::string& name) const
|
||||||
{
|
{
|
||||||
return false;
|
if (!mIdsUpdated)
|
||||||
|
{
|
||||||
|
mIds = mData.getIds();
|
||||||
|
|
||||||
|
std::for_each (mIds.begin(), mIds.end(), &Misc::StringUtils::lowerCase);
|
||||||
|
|
||||||
|
mIdsUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::binary_search (mIds.begin(), mIds.end(), Misc::StringUtils::lowerCase (name));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMWorld::ScriptContext::invalidateIds()
|
||||||
|
{
|
||||||
|
mIdsUpdated = false;
|
||||||
}
|
}
|
|
@ -1,14 +1,25 @@
|
||||||
#ifndef CSM_WORLD_SCRIPTCONTEXT_H
|
#ifndef CSM_WORLD_SCRIPTCONTEXT_H
|
||||||
#define CSM_WORLD_SCRIPTCONTEXT_H
|
#define CSM_WORLD_SCRIPTCONTEXT_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <components/compiler/context.hpp>
|
#include <components/compiler/context.hpp>
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
|
class Data;
|
||||||
|
|
||||||
class ScriptContext : public Compiler::Context
|
class ScriptContext : public Compiler::Context
|
||||||
{
|
{
|
||||||
|
const Data& mData;
|
||||||
|
mutable std::vector<std::string> mIds;
|
||||||
|
mutable bool mIdsUpdated;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
ScriptContext (const Data& data);
|
||||||
|
|
||||||
virtual bool canDeclareLocals() const;
|
virtual bool canDeclareLocals() const;
|
||||||
///< Is the compiler allowed to declare local variables?
|
///< Is the compiler allowed to declare local variables?
|
||||||
|
|
||||||
|
@ -20,6 +31,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
virtual bool isId (const std::string& name) const;
|
virtual bool isId (const std::string& name) const;
|
||||||
///< Does \a name match an ID, that can be referenced?
|
///< Does \a name match an ID, that can be referenced?
|
||||||
|
|
||||||
|
void invalidateIds();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,10 @@ boost::filesystem::path CSVDoc::AdjusterWidget::getPath() const
|
||||||
return mResultPath;
|
return mResultPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSVDoc::AdjusterWidget::isValid() const
|
||||||
|
{
|
||||||
|
return mValid;
|
||||||
|
}
|
||||||
void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
|
void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
|
||||||
{
|
{
|
||||||
QString message;
|
QString message;
|
||||||
|
@ -88,4 +92,4 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
|
||||||
pixmap (QSize (16, 16)));
|
pixmap (QSize (16, 16)));
|
||||||
|
|
||||||
emit stateChanged (mValid);
|
emit stateChanged (mValid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@ namespace CSVDoc
|
||||||
|
|
||||||
void setLocalData (const boost::filesystem::path& localData);
|
void setLocalData (const boost::filesystem::path& localData);
|
||||||
|
|
||||||
|
QString getText() const;
|
||||||
|
bool isValid() const;
|
||||||
|
|
||||||
boost::filesystem::path getPath() const;
|
boost::filesystem::path getPath() const;
|
||||||
///< This function must not be called if there is no valid path.
|
///< This function must not be called if there is no valid path.
|
||||||
|
|
||||||
|
@ -38,4 +41,4 @@ namespace CSVDoc
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,145 +9,48 @@
|
||||||
#include <QSpacerItem>
|
#include <QSpacerItem>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QGroupBox>
|
||||||
|
|
||||||
#include <components/fileorderlist/model/datafilesmodel.hpp>
|
#include <components/contentselector/model/esmfile.hpp>
|
||||||
#include <components/fileorderlist/model/pluginsproxymodel.hpp>
|
#include <components/contentselector/view/lineedit.hpp>
|
||||||
#include <components/fileorderlist/model/esm/esmfile.hpp>
|
|
||||||
|
|
||||||
#include <components/fileorderlist/utils/lineedit.hpp>
|
#include "filewidget.hpp"
|
||||||
|
#include "adjusterwidget.hpp"
|
||||||
|
|
||||||
FileDialog::FileDialog(QWidget *parent) :
|
#include <QDebug>
|
||||||
QDialog(parent)
|
|
||||||
|
CSVDoc::FileDialog::FileDialog(QWidget *parent) :
|
||||||
|
ContentSelector(parent),
|
||||||
|
mFileWidget (new FileWidget (this)),
|
||||||
|
mAdjusterWidget (new AdjusterWidget (this)),
|
||||||
|
mEnable_1(false),
|
||||||
|
mEnable_2(false)
|
||||||
{
|
{
|
||||||
setupUi(this);
|
|
||||||
|
|
||||||
// Models
|
|
||||||
mDataFilesModel = new DataFilesModel(this);
|
|
||||||
|
|
||||||
mMastersProxyModel = new QSortFilterProxyModel();
|
|
||||||
mMastersProxyModel->setFilterRegExp(QString("^.*\\.esm"));
|
|
||||||
mMastersProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
||||||
mMastersProxyModel->setSourceModel(mDataFilesModel);
|
|
||||||
|
|
||||||
mPluginsProxyModel = new PluginsProxyModel();
|
|
||||||
mPluginsProxyModel->setFilterRegExp(QString("^.*\\.esp"));
|
|
||||||
mPluginsProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
||||||
mPluginsProxyModel->setSourceModel(mDataFilesModel);
|
|
||||||
|
|
||||||
mFilterProxyModel = new QSortFilterProxyModel();
|
|
||||||
mFilterProxyModel->setDynamicSortFilter(true);
|
|
||||||
mFilterProxyModel->setSourceModel(mPluginsProxyModel);
|
|
||||||
|
|
||||||
QCheckBox checkBox;
|
|
||||||
unsigned int height = checkBox.sizeHint().height() + 4;
|
|
||||||
|
|
||||||
mastersTable->setModel(mMastersProxyModel);
|
|
||||||
mastersTable->setObjectName("MastersTable");
|
|
||||||
mastersTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
mastersTable->setSortingEnabled(false);
|
|
||||||
mastersTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
||||||
mastersTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
||||||
mastersTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
||||||
mastersTable->setAlternatingRowColors(true);
|
|
||||||
mastersTable->horizontalHeader()->setStretchLastSection(true);
|
|
||||||
|
|
||||||
// Set the row height to the size of the checkboxes
|
|
||||||
mastersTable->verticalHeader()->setDefaultSectionSize(height);
|
|
||||||
mastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed);
|
|
||||||
mastersTable->verticalHeader()->hide();
|
|
||||||
|
|
||||||
pluginsTable->setModel(mFilterProxyModel);
|
|
||||||
pluginsTable->setObjectName("PluginsTable");
|
|
||||||
pluginsTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
pluginsTable->setSortingEnabled(false);
|
|
||||||
pluginsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
||||||
pluginsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
||||||
pluginsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
||||||
pluginsTable->setAlternatingRowColors(true);
|
|
||||||
pluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
|
|
||||||
pluginsTable->horizontalHeader()->setStretchLastSection(true);
|
|
||||||
|
|
||||||
pluginsTable->verticalHeader()->setDefaultSectionSize(height);
|
|
||||||
pluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed);
|
|
||||||
|
|
||||||
// Hide the profile elements
|
// Hide the profile elements
|
||||||
profileLabel->hide();
|
profileGroupBox->hide();
|
||||||
profilesComboBox->hide();
|
addonView->showColumn(2);
|
||||||
newProfileButton->hide();
|
|
||||||
deleteProfileButton->hide();
|
|
||||||
|
|
||||||
// Add some extra widgets
|
resize(400, 400);
|
||||||
QHBoxLayout *nameLayout = new QHBoxLayout();
|
|
||||||
QSpacerItem *spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
||||||
|
|
||||||
mNameLabel = new QLabel(tr("File Name:"), this);
|
mFileWidget->setType(true);
|
||||||
|
mFileWidget->extensionLabelIsVisible(false);
|
||||||
|
|
||||||
QRegExpValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9\\s]*$"));
|
connect(projectCreateButton, SIGNAL(clicked()), this, SIGNAL(createNewFile()));
|
||||||
mNameLineEdit = new LineEdit(this);
|
|
||||||
mNameLineEdit->setValidator(validator);
|
|
||||||
|
|
||||||
nameLayout->addSpacerItem(spacer);
|
connect(projectButtonBox, SIGNAL(accepted()), this, SIGNAL(openFiles()));
|
||||||
nameLayout->addWidget(mNameLabel);
|
connect(projectButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||||
nameLayout->addWidget(mNameLineEdit);
|
|
||||||
|
|
||||||
mButtonBox = new QDialogButtonBox(this);
|
connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)),
|
||||||
|
mAdjusterWidget, SLOT (setName (const QString&, bool)));
|
||||||
|
|
||||||
mCreateButton = new QPushButton(tr("Create"), this);
|
connect (mAdjusterWidget, SIGNAL (stateChanged (bool)), this, SLOT (slotAdjusterChanged(bool)));
|
||||||
mCreateButton->setEnabled(false);
|
connect (this, SIGNAL (signalGameFileChanged(int)), this, SLOT (slotGameFileSelected(int)));
|
||||||
|
connect (this, SIGNAL (signalUpdateCreateButton(bool, int)), this, SLOT (slotEnableCreateButton(bool, int)));
|
||||||
verticalLayout->addLayout(nameLayout);
|
|
||||||
verticalLayout->addWidget(mButtonBox);
|
|
||||||
|
|
||||||
// Set sizes
|
|
||||||
QList<int> sizeList;
|
|
||||||
sizeList << 175;
|
|
||||||
sizeList << 200;
|
|
||||||
|
|
||||||
splitter->setSizes(sizeList);
|
|
||||||
|
|
||||||
resize(600, 400);
|
|
||||||
|
|
||||||
connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews()));
|
|
||||||
connect(mDataFilesModel, SIGNAL(checkedItemsChanged(QStringList)), this, SLOT(updateOpenButton(QStringList)));
|
|
||||||
connect(mNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateCreateButton(QString)));
|
|
||||||
|
|
||||||
connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
|
|
||||||
|
|
||||||
connect(pluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
|
|
||||||
connect(mastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
|
|
||||||
|
|
||||||
connect(mCreateButton, SIGNAL(clicked()), this, SLOT(createButtonClicked()));
|
|
||||||
|
|
||||||
connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
|
||||||
connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDialog::updateViews()
|
void CSVDoc::FileDialog::updateOpenButton(const QStringList &items)
|
||||||
{
|
{
|
||||||
// Ensure the columns are hidden because sort() re-enables them
|
QPushButton *openButton = projectButtonBox->button(QDialogButtonBox::Open);
|
||||||
mastersTable->setColumnHidden(1, true);
|
|
||||||
mastersTable->setColumnHidden(3, true);
|
|
||||||
mastersTable->setColumnHidden(4, true);
|
|
||||||
mastersTable->setColumnHidden(5, true);
|
|
||||||
mastersTable->setColumnHidden(6, true);
|
|
||||||
mastersTable->setColumnHidden(7, true);
|
|
||||||
mastersTable->setColumnHidden(8, true);
|
|
||||||
mastersTable->resizeColumnsToContents();
|
|
||||||
|
|
||||||
pluginsTable->setColumnHidden(1, true);
|
|
||||||
pluginsTable->setColumnHidden(3, true);
|
|
||||||
pluginsTable->setColumnHidden(4, true);
|
|
||||||
pluginsTable->setColumnHidden(5, true);
|
|
||||||
pluginsTable->setColumnHidden(6, true);
|
|
||||||
pluginsTable->setColumnHidden(7, true);
|
|
||||||
pluginsTable->setColumnHidden(8, true);
|
|
||||||
pluginsTable->resizeColumnsToContents();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileDialog::updateOpenButton(const QStringList &items)
|
|
||||||
{
|
|
||||||
QPushButton *openButton = mButtonBox->button(QDialogButtonBox::Open);
|
|
||||||
|
|
||||||
if (!openButton)
|
if (!openButton)
|
||||||
return;
|
return;
|
||||||
|
@ -155,118 +58,60 @@ void FileDialog::updateOpenButton(const QStringList &items)
|
||||||
openButton->setEnabled(!items.isEmpty());
|
openButton->setEnabled(!items.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDialog::updateCreateButton(const QString &name)
|
void CSVDoc::FileDialog::slotEnableCreateButton(bool enable, int widgetNumber)
|
||||||
{
|
{
|
||||||
if (!mCreateButton->isVisible())
|
|
||||||
return;
|
|
||||||
|
|
||||||
mCreateButton->setEnabled(!name.isEmpty());
|
if (widgetNumber == 1)
|
||||||
|
mEnable_1 = enable;
|
||||||
|
|
||||||
|
if (widgetNumber == 2)
|
||||||
|
mEnable_2 = enable;
|
||||||
|
|
||||||
|
qDebug() << "update enabled" << mEnable_1 << mEnable_2 << enable;
|
||||||
|
projectCreateButton->setEnabled(mEnable_1 && mEnable_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDialog::filterChanged(const QString &filter)
|
QString CSVDoc::FileDialog::fileName()
|
||||||
{
|
{
|
||||||
QRegExp filterRe(filter, Qt::CaseInsensitive, QRegExp::FixedString);
|
return mFileWidget->getName();
|
||||||
mFilterProxyModel->setFilterRegExp(filterRe);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDialog::addFiles(const QString &path)
|
void CSVDoc::FileDialog::openFile()
|
||||||
{
|
|
||||||
mDataFilesModel->addFiles(path);
|
|
||||||
mDataFilesModel->sort(3); // Sort by date accessed
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileDialog::setEncoding(const QString &encoding)
|
|
||||||
{
|
|
||||||
mDataFilesModel->setEncoding(encoding);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileDialog::setCheckState(QModelIndex index)
|
|
||||||
{
|
|
||||||
if (!index.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QObject *object = QObject::sender();
|
|
||||||
|
|
||||||
// Not a signal-slot call
|
|
||||||
if (!object)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
if (object->objectName() == QLatin1String("PluginsTable")) {
|
|
||||||
QModelIndex sourceIndex = mPluginsProxyModel->mapToSource(
|
|
||||||
mFilterProxyModel->mapToSource(index));
|
|
||||||
|
|
||||||
if (sourceIndex.isValid()) {
|
|
||||||
(mDataFilesModel->checkState(sourceIndex) == Qt::Checked)
|
|
||||||
? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked)
|
|
||||||
: mDataFilesModel->setCheckState(sourceIndex, Qt::Checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (object->objectName() == QLatin1String("MastersTable")) {
|
|
||||||
QModelIndex sourceIndex = mMastersProxyModel->mapToSource(index);
|
|
||||||
|
|
||||||
if (sourceIndex.isValid()) {
|
|
||||||
(mDataFilesModel->checkState(sourceIndex) == Qt::Checked)
|
|
||||||
? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked)
|
|
||||||
: mDataFilesModel->setCheckState(sourceIndex, Qt::Checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList FileDialog::checkedItemsPaths()
|
|
||||||
{
|
|
||||||
return mDataFilesModel->checkedItemsPaths();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString FileDialog::fileName()
|
|
||||||
{
|
|
||||||
return mNameLineEdit->text();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileDialog::openFile()
|
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("Open"));
|
setWindowTitle(tr("Open"));
|
||||||
|
|
||||||
mNameLabel->hide();
|
mFileWidget->hide();
|
||||||
mNameLineEdit->hide();
|
adjusterWidgetFrame->hide();
|
||||||
mCreateButton->hide();
|
projectCreateButton->hide();
|
||||||
|
projectGroupBox->setTitle(tr(""));
|
||||||
mButtonBox->removeButton(mCreateButton);
|
projectButtonBox->button(QDialogButtonBox::Open)->setEnabled(false);
|
||||||
mButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Open);
|
|
||||||
QPushButton *openButton = mButtonBox->button(QDialogButtonBox::Open);
|
|
||||||
openButton->setEnabled(false);
|
|
||||||
|
|
||||||
show();
|
show();
|
||||||
raise();
|
raise();
|
||||||
activateWindow();
|
activateWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDialog::newFile()
|
void CSVDoc::FileDialog::newFile()
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("New"));
|
setWindowTitle(tr("New"));
|
||||||
|
|
||||||
mNameLabel->show();
|
fileWidgetFrame->layout()->addWidget(mFileWidget);
|
||||||
mNameLineEdit->clear();
|
adjusterWidgetFrame->layout()->addWidget(mAdjusterWidget);
|
||||||
mNameLineEdit->show();
|
|
||||||
mCreateButton->show();
|
|
||||||
|
|
||||||
mButtonBox->setStandardButtons(QDialogButtonBox::Cancel);
|
projectButtonBox->setStandardButtons(QDialogButtonBox::Cancel);
|
||||||
mButtonBox->addButton(mCreateButton, QDialogButtonBox::ActionRole);
|
projectButtonBox->addButton(projectCreateButton, QDialogButtonBox::ActionRole);
|
||||||
|
|
||||||
show();
|
show();
|
||||||
raise();
|
raise();
|
||||||
activateWindow();
|
activateWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDialog::accept()
|
void CSVDoc::FileDialog::slotAdjusterChanged(bool value)
|
||||||
{
|
{
|
||||||
emit openFiles();
|
emit signalUpdateCreateButton(mAdjusterWidget->isValid(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDialog::createButtonClicked()
|
void CSVDoc::FileDialog::slotGameFileSelected(int value)
|
||||||
{
|
{
|
||||||
emit createNewFile();
|
emit signalUpdateCreateButton(value > -1, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
|
|
||||||
|
#include "components/contentselector/view/contentselector.hpp"
|
||||||
#include "ui_datafilespage.h"
|
#include "ui_datafilespage.h"
|
||||||
|
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
|
@ -13,54 +14,54 @@ class QPushButton;
|
||||||
class QStringList;
|
class QStringList;
|
||||||
class QString;
|
class QString;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
|
class QLabel;
|
||||||
|
|
||||||
class DataFilesModel;
|
class DataFilesModel;
|
||||||
class PluginsProxyModel;
|
class PluginsProxyModel;
|
||||||
|
|
||||||
class FileDialog : public QDialog, private Ui::DataFilesPage
|
namespace ContentSelectorView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
class LineEdit;
|
||||||
public:
|
}
|
||||||
explicit FileDialog(QWidget *parent = 0);
|
|
||||||
void addFiles(const QString &path);
|
|
||||||
void setEncoding(const QString &encoding);
|
|
||||||
|
|
||||||
void openFile();
|
namespace CSVDoc
|
||||||
void newFile();
|
{
|
||||||
void accepted();
|
class FileWidget;
|
||||||
|
class AdjusterWidget;
|
||||||
|
|
||||||
QStringList checkedItemsPaths();
|
class FileDialog : public ContentSelectorView::ContentSelector
|
||||||
QString fileName();
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
signals:
|
FileWidget *mFileWidget;
|
||||||
void openFiles();
|
AdjusterWidget *mAdjusterWidget;
|
||||||
void createNewFile();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void accept();
|
|
||||||
|
|
||||||
private slots:
|
bool mEnable_1;
|
||||||
void updateViews();
|
bool mEnable_2;
|
||||||
void updateOpenButton(const QStringList &items);
|
|
||||||
void updateCreateButton(const QString &name);
|
|
||||||
void setCheckState(QModelIndex index);
|
|
||||||
|
|
||||||
void filterChanged(const QString &filter);
|
public:
|
||||||
|
explicit FileDialog(QWidget *parent = 0);
|
||||||
|
|
||||||
void createButtonClicked();
|
void openFile();
|
||||||
|
void newFile();
|
||||||
|
|
||||||
private:
|
QString fileName();
|
||||||
QLabel *mNameLabel;
|
|
||||||
LineEdit *mNameLineEdit;
|
|
||||||
|
|
||||||
QPushButton *mCreateButton;
|
signals:
|
||||||
QDialogButtonBox *mButtonBox;
|
void openFiles();
|
||||||
|
void createNewFile();
|
||||||
|
|
||||||
DataFilesModel *mDataFilesModel;
|
void signalUpdateCreateButton (bool, int);
|
||||||
|
void signalUpdateCreateButtonFlags(int);
|
||||||
|
|
||||||
PluginsProxyModel *mPluginsProxyModel;
|
public slots:
|
||||||
QSortFilterProxyModel *mMastersProxyModel;
|
|
||||||
QSortFilterProxyModel *mFilterProxyModel;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
//void updateViews();
|
||||||
|
void updateOpenButton(const QStringList &items);
|
||||||
|
void slotEnableCreateButton(bool enable, int widgetNumber);
|
||||||
|
void slotAdjusterChanged(bool value);
|
||||||
|
void slotGameFileSelected(int value);
|
||||||
|
};
|
||||||
|
}
|
||||||
#endif // FILEDIALOG_HPP
|
#endif // FILEDIALOG_HPP
|
||||||
|
|
|
@ -50,4 +50,9 @@ QString CSVDoc::FileWidget::getName() const
|
||||||
void CSVDoc::FileWidget::textChanged (const QString& text)
|
void CSVDoc::FileWidget::textChanged (const QString& text)
|
||||||
{
|
{
|
||||||
emit nameChanged (getName(), mAddon);
|
emit nameChanged (getName(), mAddon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVDoc::FileWidget::extensionLabelIsVisible(bool visible)
|
||||||
|
{
|
||||||
|
mType->setVisible(visible);
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ namespace CSVDoc
|
||||||
|
|
||||||
QString getName() const;
|
QString getName() const;
|
||||||
|
|
||||||
|
void extensionLabelIsVisible(bool visible);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void textChanged (const QString& text);
|
void textChanged (const QString& text);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <components/compiler/scanner.hpp>
|
#include <components/compiler/scanner.hpp>
|
||||||
|
#include <components/compiler/extensions0.hpp>
|
||||||
|
|
||||||
bool CSVWorld::ScriptHighlighter::parseInt (int value, const Compiler::TokenLoc& loc,
|
bool CSVWorld::ScriptHighlighter::parseInt (int value, const Compiler::TokenLoc& loc,
|
||||||
Compiler::Scanner& scanner)
|
Compiler::Scanner& scanner)
|
||||||
|
@ -22,7 +23,7 @@ bool CSVWorld::ScriptHighlighter::parseFloat (float value, const Compiler::Token
|
||||||
bool CSVWorld::ScriptHighlighter::parseName (const std::string& name, const Compiler::TokenLoc& loc,
|
bool CSVWorld::ScriptHighlighter::parseName (const std::string& name, const Compiler::TokenLoc& loc,
|
||||||
Compiler::Scanner& scanner)
|
Compiler::Scanner& scanner)
|
||||||
{
|
{
|
||||||
highlight (loc, Type_Name);
|
highlight (loc, mContext.isId (name) ? Type_Id : Type_Name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,10 +63,10 @@ void CSVWorld::ScriptHighlighter::highlight (const Compiler::TokenLoc& loc, Type
|
||||||
setFormat (index, length, mScheme[type]);
|
setFormat (index, length, mScheme[type]);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVWorld::ScriptHighlighter::ScriptHighlighter (QTextDocument *parent)
|
CSVWorld::ScriptHighlighter::ScriptHighlighter (const CSMWorld::Data& data, QTextDocument *parent)
|
||||||
: QSyntaxHighlighter (parent), Compiler::Parser (mErrorHandler, mContext)
|
: QSyntaxHighlighter (parent), Compiler::Parser (mErrorHandler, mContext), mContext (data)
|
||||||
{
|
{
|
||||||
/// \ŧodo replace this with user settings
|
/// \todo replace this with user settings
|
||||||
{
|
{
|
||||||
QTextCharFormat format;
|
QTextCharFormat format;
|
||||||
format.setForeground (Qt::darkMagenta);
|
format.setForeground (Qt::darkMagenta);
|
||||||
|
@ -101,6 +102,16 @@ CSVWorld::ScriptHighlighter::ScriptHighlighter (QTextDocument *parent)
|
||||||
format.setForeground (Qt::green);
|
format.setForeground (Qt::green);
|
||||||
mScheme.insert (std::make_pair (Type_Comment, format));
|
mScheme.insert (std::make_pair (Type_Comment, format));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QTextCharFormat format;
|
||||||
|
format.setForeground (Qt::blue);
|
||||||
|
mScheme.insert (std::make_pair (Type_Id, format));
|
||||||
|
}
|
||||||
|
|
||||||
|
// configure compiler
|
||||||
|
Compiler::registerExtensions (mExtensions);
|
||||||
|
mContext.setExtensions (&mExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text)
|
void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text)
|
||||||
|
@ -114,5 +125,9 @@ void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text)
|
||||||
scanner.scan (*this);
|
scanner.scan (*this);
|
||||||
}
|
}
|
||||||
catch (...) {} // ignore syntax errors
|
catch (...) {} // ignore syntax errors
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ScriptHighlighter::invalidateIds()
|
||||||
|
{
|
||||||
|
mContext.invalidateIds();
|
||||||
}
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <components/compiler/nullerrorhandler.hpp>
|
#include <components/compiler/nullerrorhandler.hpp>
|
||||||
#include <components/compiler/parser.hpp>
|
#include <components/compiler/parser.hpp>
|
||||||
|
#include <components/compiler/extensions.hpp>
|
||||||
|
|
||||||
#include "../../model/world/scriptcontext.hpp"
|
#include "../../model/world/scriptcontext.hpp"
|
||||||
|
|
||||||
|
@ -23,12 +24,14 @@ namespace CSVWorld
|
||||||
Type_Name,
|
Type_Name,
|
||||||
Type_Keyword,
|
Type_Keyword,
|
||||||
Type_Special,
|
Type_Special,
|
||||||
Type_Comment
|
Type_Comment,
|
||||||
|
Type_Id
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Compiler::NullErrorHandler mErrorHandler;
|
Compiler::NullErrorHandler mErrorHandler;
|
||||||
|
Compiler::Extensions mExtensions;
|
||||||
CSMWorld::ScriptContext mContext;
|
CSMWorld::ScriptContext mContext;
|
||||||
std::map<Type, QTextCharFormat> mScheme;
|
std::map<Type, QTextCharFormat> mScheme;
|
||||||
|
|
||||||
|
@ -71,9 +74,11 @@ namespace CSVWorld
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ScriptHighlighter (QTextDocument *parent);
|
ScriptHighlighter (const CSMWorld::Data& data, QTextDocument *parent);
|
||||||
|
|
||||||
virtual void highlightBlock (const QString& text);
|
virtual void highlightBlock (const QString& text);
|
||||||
|
|
||||||
|
void invalidateIds();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,13 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc:
|
||||||
connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int)));
|
this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
|
||||||
new ScriptHighlighter (mEditor->document());
|
connect (&document.getData(), SIGNAL (idListChanged()), this, SLOT (idListChanged()));
|
||||||
|
|
||||||
|
mHighlighter = new ScriptHighlighter (document.getData(), mEditor->document());
|
||||||
|
|
||||||
|
connect (&mUpdateTimer, SIGNAL (timeout()), this, SLOT (updateHighlighting()));
|
||||||
|
|
||||||
|
mUpdateTimer.setSingleShot (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::ScriptSubView::setEditLock (bool locked)
|
void CSVWorld::ScriptSubView::setEditLock (bool locked)
|
||||||
|
@ -66,8 +72,19 @@ void CSVWorld::ScriptSubView::setEditLock (bool locked)
|
||||||
mEditor->setReadOnly (locked);
|
mEditor->setReadOnly (locked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ScriptSubView::idListChanged()
|
||||||
|
{
|
||||||
|
mHighlighter->invalidateIds();
|
||||||
|
|
||||||
|
if (!mUpdateTimer.isActive())
|
||||||
|
mUpdateTimer.start (0);
|
||||||
|
}
|
||||||
|
|
||||||
void CSVWorld::ScriptSubView::textChanged()
|
void CSVWorld::ScriptSubView::textChanged()
|
||||||
{
|
{
|
||||||
|
if (mChangeLocked)
|
||||||
|
return;
|
||||||
|
|
||||||
ChangeLock lock (*this);
|
ChangeLock lock (*this);
|
||||||
|
|
||||||
mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*mModel,
|
mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*mModel,
|
||||||
|
@ -79,6 +96,8 @@ void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QMo
|
||||||
if (mChangeLocked)
|
if (mChangeLocked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ChangeLock lock (*this);
|
||||||
|
|
||||||
QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn);
|
QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn);
|
||||||
|
|
||||||
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row() &&
|
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row() &&
|
||||||
|
@ -96,4 +115,14 @@ void CSVWorld::ScriptSubView::rowsAboutToBeRemoved (const QModelIndex& parent, i
|
||||||
|
|
||||||
if (!parent.isValid() && index.row()>=start && index.row()<=end)
|
if (!parent.isValid() && index.row()>=start && index.row()<=end)
|
||||||
deleteLater();
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::ScriptSubView::updateHighlighting()
|
||||||
|
{
|
||||||
|
if (mChangeLocked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ChangeLock lock (*this);
|
||||||
|
|
||||||
|
mHighlighter->rehighlight();
|
||||||
}
|
}
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include "../doc/subview.hpp"
|
#include "../doc/subview.hpp"
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
class QTextEdit;
|
class QTextEdit;
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
|
|
||||||
|
@ -18,6 +20,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
namespace CSVWorld
|
namespace CSVWorld
|
||||||
{
|
{
|
||||||
|
class ScriptHighlighter;
|
||||||
|
|
||||||
class ScriptSubView : public CSVDoc::SubView
|
class ScriptSubView : public CSVDoc::SubView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -27,6 +31,8 @@ namespace CSVWorld
|
||||||
CSMWorld::IdTable *mModel;
|
CSMWorld::IdTable *mModel;
|
||||||
int mColumn;
|
int mColumn;
|
||||||
int mChangeLocked;
|
int mChangeLocked;
|
||||||
|
ScriptHighlighter *mHighlighter;
|
||||||
|
QTimer mUpdateTimer;
|
||||||
|
|
||||||
class ChangeLock
|
class ChangeLock
|
||||||
{
|
{
|
||||||
|
@ -49,13 +55,19 @@ namespace CSVWorld
|
||||||
|
|
||||||
virtual void setEditLock (bool locked);
|
virtual void setEditLock (bool locked);
|
||||||
|
|
||||||
private slots:
|
public slots:
|
||||||
|
|
||||||
|
void idListChanged();
|
||||||
|
|
||||||
void textChanged();
|
void textChanged();
|
||||||
|
|
||||||
void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
void rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
void rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void updateHighlighting();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,10 @@ target_link_libraries(openmw
|
||||||
components
|
components
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (USE_SYSTEM_TINYXML)
|
||||||
|
target_link_libraries(openmw ${TINYXML_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
if (NOT UNIX)
|
if (NOT UNIX)
|
||||||
target_link_libraries(openmw ${SDL2MAIN_LIBRARY})
|
target_link_libraries(openmw ${SDL2MAIN_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -396,6 +396,8 @@ namespace MWBase
|
||||||
/// It only applies to the current form the NPC is in.
|
/// It only applies to the current form the NPC is in.
|
||||||
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0;
|
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0;
|
||||||
|
|
||||||
|
virtual bool getGodModeState() = 0;
|
||||||
|
|
||||||
virtual bool toggleGodMode() = 0;
|
virtual bool toggleGodMode() = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,6 +250,7 @@ namespace MWGui
|
||||||
// remove object from the container it was coming from
|
// remove object from the container it was coming from
|
||||||
mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount);
|
mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount);
|
||||||
mDragAndDrop->finish();
|
mDragAndDrop->finish();
|
||||||
|
mDragAndDrop->mSourceModel->update();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -585,7 +585,7 @@ namespace MWInput
|
||||||
mPlayer->pitch(-y/scale);
|
mPlayer->pitch(-y/scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg.zrel)
|
if (arg.zrel && mControlSwitch["playerviewswitch"]) //Check to make sure you are allowed to zoomout and there is a change
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWorld()->changeVanityModeScale(arg.zrel);
|
MWBase::Environment::get().getWorld()->changeVanityModeScale(arg.zrel);
|
||||||
MWBase::Environment::get().getWorld()->setCameraDistance(arg.zrel, true, true);
|
MWBase::Environment::get().getWorld()->setCameraDistance(arg.zrel, true, true);
|
||||||
|
|
|
@ -275,9 +275,8 @@ namespace MWMechanics
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// workaround: always keep player alive for now
|
// If it's the player and God Mode is turned on, keep it alive
|
||||||
// \todo remove workaround, once player death can be handled
|
if(iter->first.getRefData().getHandle()=="player" && MWBase::Environment::get().getWorld()->getGodModeState())
|
||||||
if(iter->first.getRefData().getHandle()=="player")
|
|
||||||
{
|
{
|
||||||
MWMechanics::DynamicStat<float> stat(stats.getHealth());
|
MWMechanics::DynamicStat<float> stat(stats.getHealth());
|
||||||
|
|
||||||
|
|
|
@ -151,8 +151,7 @@ namespace MWMechanics
|
||||||
for (Collection::const_iterator iter (prev.begin()); iter!=prev.end(); ++iter)
|
for (Collection::const_iterator iter (prev.begin()); iter!=prev.end(); ++iter)
|
||||||
{
|
{
|
||||||
Collection::const_iterator other = now.mCollection.find (iter->first);
|
Collection::const_iterator other = now.mCollection.find (iter->first);
|
||||||
|
if (other==now.end())
|
||||||
if (other==prev.end())
|
|
||||||
{
|
{
|
||||||
result.add (iter->first, EffectParam() - iter->second);
|
result.add (iter->first, EffectParam() - iter->second);
|
||||||
}
|
}
|
||||||
|
|
|
@ -726,8 +726,7 @@ namespace MWScript
|
||||||
|
|
||||||
bool enabled = MWBase::Environment::get().getWorld()->toggleGodMode();
|
bool enabled = MWBase::Environment::get().getWorld()->toggleGodMode();
|
||||||
|
|
||||||
// context.report (enabled ? "God Mode -> On" : "God Mode -> Off");
|
context.report (enabled ? "God Mode -> On" : "God Mode -> Off");
|
||||||
context.report("Unimplemented");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
|
||||||
// all files/readers used by the engine. This will greaty accelerate
|
// all files/readers used by the engine. This will greaty accelerate
|
||||||
// refnumber mangling, as required for handling moved references.
|
// refnumber mangling, as required for handling moved references.
|
||||||
int index = ~0;
|
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();
|
std::vector<ESM::ESMReader> *allPlugins = esm.getGlobalReaderList();
|
||||||
for (size_t j = 0; j < masters.size(); j++) {
|
for (size_t j = 0; j < masters.size(); j++) {
|
||||||
ESM::Header::MasterData &mast = const_cast<ESM::Header::MasterData&>(masters[j]);
|
ESM::Header::MasterData &mast = const_cast<ESM::Header::MasterData&>(masters[j]);
|
||||||
|
|
|
@ -170,7 +170,7 @@ namespace MWWorld
|
||||||
mSky (true), mCells (mStore, mEsm),
|
mSky (true), mCells (mStore, mEsm),
|
||||||
mActivationDistanceOverride (mActivationDistanceOverride),
|
mActivationDistanceOverride (mActivationDistanceOverride),
|
||||||
mFallback(fallbackMap), mPlayIntro(0), mTeleportEnabled(true),
|
mFallback(fallbackMap), mPlayIntro(0), mTeleportEnabled(true),
|
||||||
mFacedDistance(FLT_MAX)
|
mFacedDistance(FLT_MAX), mGodMode(false)
|
||||||
{
|
{
|
||||||
mPhysics = new PhysicsSystem(renderer);
|
mPhysics = new PhysicsSystem(renderer);
|
||||||
mPhysEngine = mPhysics->getEngine();
|
mPhysEngine = mPhysics->getEngine();
|
||||||
|
@ -1948,9 +1948,16 @@ namespace MWWorld
|
||||||
stats.getSkill(ESM::Skill::Acrobatics).setModified(gmst.find("fWerewolfAcrobatics")->getFloat(), 0);
|
stats.getSkill(ESM::Skill::Acrobatics).setModified(gmst.find("fWerewolfAcrobatics")->getFloat(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool World::getGodModeState()
|
||||||
|
{
|
||||||
|
return mGodMode;
|
||||||
|
}
|
||||||
|
|
||||||
bool World::toggleGodMode()
|
bool World::toggleGodMode()
|
||||||
{
|
{
|
||||||
return false;
|
mGodMode = !mGodMode;
|
||||||
|
|
||||||
|
return mGodMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,8 @@ namespace MWWorld
|
||||||
|
|
||||||
OEngine::Physic::PhysicEngine* mPhysEngine;
|
OEngine::Physic::PhysicEngine* mPhysEngine;
|
||||||
|
|
||||||
|
bool mGodMode;
|
||||||
|
|
||||||
// not implemented
|
// not implemented
|
||||||
World (const World&);
|
World (const World&);
|
||||||
World& operator= (const World&);
|
World& operator= (const World&);
|
||||||
|
@ -440,6 +442,8 @@ namespace MWWorld
|
||||||
|
|
||||||
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor);
|
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
|
virtual bool getGodModeState();
|
||||||
|
|
||||||
virtual bool toggleGodMode();
|
virtual bool toggleGodMode();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
project (Components)
|
project (Components)
|
||||||
|
set (CMAKE_BUILD_TYPE DEBUG)
|
||||||
# source files
|
# source files
|
||||||
|
|
||||||
add_component_dir (settings
|
add_component_dir (settings
|
||||||
|
@ -74,21 +74,26 @@ add_component_dir (loadinglistener
|
||||||
loadinglistener
|
loadinglistener
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/datafilespage.ui
|
||||||
|
)
|
||||||
find_package(Qt4 COMPONENTS QtCore QtGui)
|
find_package(Qt4 COMPONENTS QtCore QtGui)
|
||||||
|
|
||||||
if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY)
|
if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY)
|
||||||
add_component_qt_dir (fileorderlist
|
add_component_qt_dir (contentselector
|
||||||
model/modelitem model/datafilesmodel model/pluginsproxymodel model/esm/esmfile
|
model/modelitem model/esmfile
|
||||||
utils/profilescombobox utils/comboboxlineedit utils/lineedit utils/naturalsort
|
model/naturalsort model/contentmodel
|
||||||
|
view/profilescombobox view/comboboxlineedit
|
||||||
|
view/lineedit view/contentselector
|
||||||
)
|
)
|
||||||
|
|
||||||
include(${QT_USE_FILE})
|
include(${QT_USE_FILE})
|
||||||
|
QT4_WRAP_UI(ESM_UI_HDR ${ESM_UI})
|
||||||
QT4_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES})
|
QT4_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES})
|
||||||
endif(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY)
|
endif(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY)
|
||||||
|
|
||||||
include_directories(${BULLET_INCLUDE_DIRS})
|
include_directories(${BULLET_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS})
|
add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS} ${ESM_UI_HDR})
|
||||||
|
|
||||||
target_link_libraries(components ${Boost_LIBRARIES} ${OGRE_LIBRARIES})
|
target_link_libraries(components ${Boost_LIBRARIES} ${OGRE_LIBRARIES})
|
||||||
|
|
||||||
|
|
478
components/contentselector/model/contentmodel.cpp
Normal file
478
components/contentselector/model/contentmodel.cpp
Normal file
|
@ -0,0 +1,478 @@
|
||||||
|
#include "contentmodel.hpp"
|
||||||
|
#include "esmfile.hpp"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QTextCodec>
|
||||||
|
#include <components/esm/esmreader.hpp>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
ContentSelectorModel::ContentModel::ContentModel(QObject *parent) :
|
||||||
|
QAbstractTableModel(parent),
|
||||||
|
mMimeType ("application/omwcontent"),
|
||||||
|
mMimeTypes (QStringList() << mMimeType),
|
||||||
|
mColumnCount (1),
|
||||||
|
mDragDropFlags (Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled),
|
||||||
|
mDefaultFlags (Qt::ItemIsDropEnabled | Qt::ItemIsSelectable),
|
||||||
|
mDropActions (Qt::CopyAction | Qt::MoveAction)
|
||||||
|
{
|
||||||
|
// setEncoding ("win1252");
|
||||||
|
uncheckAll();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void ContentSelectorModel::ContentModel::setEncoding(const QString &encoding)
|
||||||
|
{
|
||||||
|
if (encoding == QLatin1String("win1252"))
|
||||||
|
mCodec = QTextCodec::codecForName("windows-1252");
|
||||||
|
|
||||||
|
else if (encoding == QLatin1String("win1251"))
|
||||||
|
mCodec = QTextCodec::codecForName("windows-1251");
|
||||||
|
|
||||||
|
else if (encoding == QLatin1String("win1250"))
|
||||||
|
mCodec = QTextCodec::codecForName("windows-1250");
|
||||||
|
|
||||||
|
else
|
||||||
|
return; // This should never happen;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
int ContentSelectorModel::ContentModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
if (parent.isValid())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return mColumnCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ContentSelectorModel::ContentModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
if(parent.isValid())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return mFiles.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(int row) const
|
||||||
|
{
|
||||||
|
if (row >= 0 && row < mFiles.size())
|
||||||
|
return mFiles.at(row);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(int row)
|
||||||
|
{
|
||||||
|
if (row >= 0 && row < mFiles.count())
|
||||||
|
return mFiles.at(row);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::findItem(const QString &name) const
|
||||||
|
{
|
||||||
|
foreach (const EsmFile *file, mFiles)
|
||||||
|
{
|
||||||
|
if (name == file->fileName())
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(non_const_file_ptr),0);
|
||||||
|
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return Qt::NoItemFlags;
|
||||||
|
|
||||||
|
const EsmFile *file = item(index.row());
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
return Qt::NoItemFlags;
|
||||||
|
|
||||||
|
if (canBeChecked(file))
|
||||||
|
return Qt::ItemIsEnabled | mDragDropFlags | mDefaultFlags;
|
||||||
|
|
||||||
|
return mDefaultFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ContentSelectorModel::ContentModel::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:
|
||||||
|
{
|
||||||
|
if (column >=0 && column <=EsmFile::FileProperty_GameFile)
|
||||||
|
return file->fileProperty(static_cast<const EsmFile::FileProperty>(column));
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Qt::ToolTipRole:
|
||||||
|
{
|
||||||
|
if (column != 0)
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
return file->toolTip();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Qt::CheckStateRole:
|
||||||
|
{
|
||||||
|
if (!file->isGameFile())
|
||||||
|
return isChecked(file->fileName());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Qt::UserRole:
|
||||||
|
{
|
||||||
|
if (file->isGameFile())
|
||||||
|
return ContentType_GameFile;
|
||||||
|
else
|
||||||
|
if (flags(index) & Qt::ItemIsEnabled)
|
||||||
|
return ContentType_Addon;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Qt::UserRole + 1:
|
||||||
|
return isChecked(file->fileName());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContentSelectorModel::ContentModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
if(!index.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
EsmFile *file = item(index.row());
|
||||||
|
QString fileName = file->fileName();
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
switch(role)
|
||||||
|
{
|
||||||
|
case Qt::EditRole:
|
||||||
|
{
|
||||||
|
QStringList list = value.toStringList();
|
||||||
|
|
||||||
|
for (int i = 0; i < EsmFile::FileProperty_GameFile; i++)
|
||||||
|
file->setFileProperty(static_cast<EsmFile::FileProperty>(i), 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);
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::UserRole+1:
|
||||||
|
{
|
||||||
|
setCheckState(fileName, value.toBool());
|
||||||
|
|
||||||
|
emit dataChanged(index, index);
|
||||||
|
|
||||||
|
foreach (EsmFile *file, mFiles)
|
||||||
|
{
|
||||||
|
if (file->gameFiles().contains(fileName))
|
||||||
|
{
|
||||||
|
QModelIndex idx = indexFromItem(file);
|
||||||
|
emit dataChanged(idx, idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::CheckStateRole:
|
||||||
|
{
|
||||||
|
int checkValue = value.toInt();
|
||||||
|
bool success = false;
|
||||||
|
bool setState = false;
|
||||||
|
if ((checkValue==Qt::Checked) && !isChecked(fileName))
|
||||||
|
{
|
||||||
|
setState = true;
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
else if ((checkValue == Qt::Checked) && isChecked (fileName))
|
||||||
|
setState = true;
|
||||||
|
else if (checkValue == Qt::Unchecked)
|
||||||
|
setState = true;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContentSelectorModel::ContentModel::insertRows(int position, int rows, const QModelIndex &parent)
|
||||||
|
{
|
||||||
|
if (parent.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
beginInsertRows(parent, position, position+rows-1);
|
||||||
|
{
|
||||||
|
for (int row = 0; row < rows; ++row)
|
||||||
|
mFiles.insert(position, new EsmFile);
|
||||||
|
|
||||||
|
} endInsertRows();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContentSelectorModel::ContentModel::removeRows(int position, int rows, const QModelIndex &parent)
|
||||||
|
{
|
||||||
|
if (parent.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
beginRemoveRows(parent, position, position+rows-1);
|
||||||
|
{
|
||||||
|
for (int row = 0; row < rows; ++row)
|
||||||
|
delete mFiles.takeAt(position);
|
||||||
|
|
||||||
|
} endRemoveRows();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::DropActions ContentSelectorModel::ContentModel::supportedDropActions() const
|
||||||
|
{
|
||||||
|
return mDropActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList ContentSelectorModel::ContentModel::mimeTypes() const
|
||||||
|
{
|
||||||
|
return mMimeTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMimeData *ContentSelectorModel::ContentModel::mimeData(const QModelIndexList &indexes) const
|
||||||
|
{
|
||||||
|
QByteArray encodedData;
|
||||||
|
|
||||||
|
foreach (const QModelIndex &index, indexes)
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
encodedData.append(item(index.row())->encodedData());
|
||||||
|
}
|
||||||
|
|
||||||
|
QMimeData *mimeData = new QMimeData();
|
||||||
|
mimeData->setData(mMimeType, encodedData);
|
||||||
|
|
||||||
|
return mimeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContentSelectorModel::ContentModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
|
||||||
|
{
|
||||||
|
if (action == Qt::IgnoreAction)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (column > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!data->hasFormat(mMimeType))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int beginRow = rowCount();
|
||||||
|
|
||||||
|
if (row != -1)
|
||||||
|
beginRow = row;
|
||||||
|
|
||||||
|
else if (parent.isValid())
|
||||||
|
beginRow = parent.row();
|
||||||
|
|
||||||
|
QByteArray encodedData = data->data(mMimeType);
|
||||||
|
QDataStream stream(&encodedData, QIODevice::ReadOnly);
|
||||||
|
|
||||||
|
while (!stream.atEnd())
|
||||||
|
{
|
||||||
|
|
||||||
|
QString value;
|
||||||
|
QStringList values;
|
||||||
|
QStringList gamefiles;
|
||||||
|
|
||||||
|
for (int i = 0; i < EsmFile::FileProperty_GameFile; ++i)
|
||||||
|
{
|
||||||
|
stream >> value;
|
||||||
|
values << value;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream >> gamefiles;
|
||||||
|
|
||||||
|
insertRows(beginRow, 1);
|
||||||
|
|
||||||
|
QModelIndex idx = index(beginRow++, 0, QModelIndex());
|
||||||
|
setData(idx, QStringList() << values << gamefiles, Qt::EditRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContentSelectorModel::ContentModel::canBeChecked(const EsmFile *file) const
|
||||||
|
{
|
||||||
|
//element can be checked if all its dependencies are
|
||||||
|
foreach (const QString &gamefile, file->gameFiles())
|
||||||
|
if (!isChecked(gamefile))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentSelectorModel::ContentModel::addFile(EsmFile *file)
|
||||||
|
{
|
||||||
|
beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count());
|
||||||
|
mFiles.append(file);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = 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(QString(mCodec->name()).toStdString()));
|
||||||
|
//fileReader.setEncoder(&encoder);
|
||||||
|
fileReader.open(dir.absoluteFilePath(path).toStdString());
|
||||||
|
|
||||||
|
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->setFormat (fileReader.getFormat());
|
||||||
|
file->setPath (info.absoluteFilePath());
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContentSelectorModel::ContentModel::isChecked(const QString& name) const
|
||||||
|
{
|
||||||
|
if (mCheckStates.contains(name))
|
||||||
|
return (mCheckStates[name] == Qt::Checked);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentSelectorModel::ContentModel::setCheckState(const QString &name, bool isChecked)
|
||||||
|
{
|
||||||
|
if (name.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Qt::CheckState state = Qt::Unchecked;
|
||||||
|
|
||||||
|
if (isChecked)
|
||||||
|
state = Qt::Checked;
|
||||||
|
|
||||||
|
mCheckStates[name] = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentSelectorModel::ContentFileList ContentSelectorModel::ContentModel::checkedItems() const
|
||||||
|
{
|
||||||
|
ContentFileList list;
|
||||||
|
|
||||||
|
foreach (EsmFile *file, mFiles)
|
||||||
|
{
|
||||||
|
if (isChecked(file->fileName()))
|
||||||
|
list << file;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentSelectorModel::ContentModel::uncheckAll()
|
||||||
|
{
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
mCheckStates.clear();
|
||||||
|
emit layoutChanged();
|
||||||
|
}
|
73
components/contentselector/model/contentmodel.hpp
Normal file
73
components/contentselector/model/contentmodel.hpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#ifndef CONTENTMODEL_HPP
|
||||||
|
#define CONTENTMODEL_HPP
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
|
||||||
|
|
||||||
|
bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex());
|
||||||
|
bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex());
|
||||||
|
|
||||||
|
Qt::DropActions supportedDropActions() const;
|
||||||
|
QStringList mimeTypes() const;
|
||||||
|
QMimeData *mimeData(const QModelIndexList &indexes) const;
|
||||||
|
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
|
||||||
|
|
||||||
|
void addFiles(const QString &path);
|
||||||
|
|
||||||
|
QModelIndex indexFromItem(const EsmFile *item) const;
|
||||||
|
const EsmFile *findItem(const QString &name) const;
|
||||||
|
|
||||||
|
bool isChecked(const QString &name) const;
|
||||||
|
void setCheckState(const QString &name, bool isChecked);
|
||||||
|
ContentFileList checkedItems() const;
|
||||||
|
void uncheckAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void addFile(EsmFile *file);
|
||||||
|
const EsmFile *item(int row) const;
|
||||||
|
EsmFile *item(int row);
|
||||||
|
bool canBeChecked(const EsmFile *file) const;
|
||||||
|
|
||||||
|
ContentFileList mFiles;
|
||||||
|
QHash<QString, Qt::CheckState> mCheckStates;
|
||||||
|
QTextCodec *mCodec;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QString mMimeType;
|
||||||
|
QStringList mMimeTypes;
|
||||||
|
int mColumnCount;
|
||||||
|
Qt::ItemFlags mDragDropFlags;
|
||||||
|
Qt::ItemFlags mDefaultFlags;
|
||||||
|
Qt::DropActions mDropActions;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // CONTENTMODEL_HPP
|
136
components/contentselector/model/esmfile.cpp
Normal file
136
components/contentselector/model/esmfile.cpp
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
#include "esmfile.hpp"
|
||||||
|
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QDataStream>
|
||||||
|
|
||||||
|
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/>");
|
||||||
|
|
||||||
|
|
||||||
|
ContentSelectorModel::EsmFile::EsmFile(QString fileName, ModelItem *parent)
|
||||||
|
: ModelItem(parent), mFileName(fileName), mFormat(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void ContentSelectorModel::EsmFile::setFileName(const QString &fileName)
|
||||||
|
{
|
||||||
|
mFileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentSelectorModel::EsmFile::setAuthor(const QString &author)
|
||||||
|
{
|
||||||
|
mAuthor = author;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentSelectorModel::EsmFile::setDate(const QDateTime &modified)
|
||||||
|
{
|
||||||
|
mModified = modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentSelectorModel::EsmFile::setFormat(int format)
|
||||||
|
{
|
||||||
|
mFormat = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentSelectorModel::EsmFile::setPath(const QString &path)
|
||||||
|
{
|
||||||
|
mPath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentSelectorModel::EsmFile::setGameFiles(const QStringList &gamefiles)
|
||||||
|
{
|
||||||
|
mGameFiles = gamefiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentSelectorModel::EsmFile::setDescription(const QString &description)
|
||||||
|
{
|
||||||
|
mDescription = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ContentSelectorModel::EsmFile::encodedData() const
|
||||||
|
{
|
||||||
|
QByteArray encodedData;
|
||||||
|
QDataStream stream(&encodedData, QIODevice::WriteOnly);
|
||||||
|
|
||||||
|
stream << mFileName << mAuthor << QString::number(mFormat)
|
||||||
|
<< mModified.toString() << mPath << mDescription
|
||||||
|
<< mGameFiles;
|
||||||
|
|
||||||
|
return encodedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ContentSelectorModel::EsmFile::fileProperty(const FileProperty prop) const
|
||||||
|
{
|
||||||
|
switch (prop)
|
||||||
|
{
|
||||||
|
case FileProperty_FileName:
|
||||||
|
return mFileName;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_Author:
|
||||||
|
return mAuthor;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_Format:
|
||||||
|
return mFormat;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_DateModified:
|
||||||
|
return mModified.toString(Qt::ISODate);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_Path:
|
||||||
|
return mPath;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_Description:
|
||||||
|
return mDescription;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_GameFile:
|
||||||
|
return mGameFiles;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
void ContentSelectorModel::EsmFile::setFileProperty (const FileProperty prop, const QString &value)
|
||||||
|
{
|
||||||
|
switch (prop)
|
||||||
|
{
|
||||||
|
case FileProperty_FileName:
|
||||||
|
mFileName = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_Author:
|
||||||
|
mAuthor = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_Format:
|
||||||
|
mFormat = value.toInt();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_DateModified:
|
||||||
|
mModified = QDateTime::fromString(value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_Path:
|
||||||
|
mPath = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_Description:
|
||||||
|
mDescription = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FileProperty_GameFile:
|
||||||
|
mGameFiles << value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
85
components/contentselector/model/esmfile.hpp
Normal file
85
components/contentselector/model/esmfile.hpp
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#ifndef ESMFILE_HPP
|
||||||
|
#define ESMFILE_HPP
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
#include "modelitem.hpp"
|
||||||
|
|
||||||
|
class QMimeData;
|
||||||
|
|
||||||
|
namespace ContentSelectorModel
|
||||||
|
{
|
||||||
|
class EsmFile : public ModelItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString filename READ fileName)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum FileProperty
|
||||||
|
{
|
||||||
|
FileProperty_FileName = 0,
|
||||||
|
FileProperty_Author = 1,
|
||||||
|
FileProperty_Format = 2,
|
||||||
|
FileProperty_DateModified = 3,
|
||||||
|
FileProperty_Path = 4,
|
||||||
|
FileProperty_Description = 5,
|
||||||
|
FileProperty_GameFile = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
EsmFile(QString fileName = QString(), ModelItem *parent = 0);
|
||||||
|
// EsmFile(const EsmFile &);
|
||||||
|
|
||||||
|
~EsmFile()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void setFileProperty (const FileProperty prop, const QString &value);
|
||||||
|
|
||||||
|
void setFileName(const QString &fileName);
|
||||||
|
void setAuthor(const QString &author);
|
||||||
|
void setSize(const int size);
|
||||||
|
void setDate(const QDateTime &modified);
|
||||||
|
void setFormat(const int format);
|
||||||
|
void setPath(const QString &path);
|
||||||
|
void setGameFiles(const QStringList &gameFiles);
|
||||||
|
void setDescription(const QString &description);
|
||||||
|
|
||||||
|
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 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(mGameFiles.join(", "));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isGameFile() const { return (mGameFiles.size() == 0); }
|
||||||
|
QByteArray encodedData() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static int sPropertyCount;
|
||||||
|
static QString sToolTip;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QString mFileName;
|
||||||
|
QString mAuthor;
|
||||||
|
QDateTime mModified;
|
||||||
|
int mFormat;
|
||||||
|
QString mPath;
|
||||||
|
QStringList mGameFiles;
|
||||||
|
QString mDescription;
|
||||||
|
QString mToolTip;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
39
components/contentselector/model/modelitem.hpp
Normal file
39
components/contentselector/model/modelitem.hpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef MODELITEM_HPP
|
||||||
|
#define MODELITEM_HPP
|
||||||
|
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
namespace ContentSelectorModel
|
||||||
|
{
|
||||||
|
class ModelItem : public QMimeData
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ModelItem(ModelItem *parent = 0);
|
||||||
|
//ModelItem(const ModelItem *parent = 0);
|
||||||
|
|
||||||
|
~ModelItem();
|
||||||
|
|
||||||
|
ModelItem *parent() const;
|
||||||
|
int row() const;
|
||||||
|
|
||||||
|
int childCount() const;
|
||||||
|
int childRow(ModelItem *child) const;
|
||||||
|
ModelItem *child(int row);
|
||||||
|
|
||||||
|
void appendChild(ModelItem *child);
|
||||||
|
void removeChild(int row);
|
||||||
|
|
||||||
|
bool hasFormat(const QString &mimetype) const;
|
||||||
|
|
||||||
|
//virtual bool acceptChild(ModelItem *child);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ModelItem *mParentItem;
|
||||||
|
QList<ModelItem*> mChildItems;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
11
components/contentselector/model/naturalsort.hpp
Normal file
11
components/contentselector/model/naturalsort.hpp
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef NATURALSORT_H
|
||||||
|
#define NATURALSORT_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
bool naturalSortLessThanCS( const QString &left, const QString &right );
|
||||||
|
bool naturalSortLessThanCI( const QString &left, const QString &right );
|
||||||
|
bool naturalSortGreaterThanCS( const QString &left, const QString &right );
|
||||||
|
bool naturalSortGreaterThanCI( const QString &left, const QString &right );
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "comboboxlineedit.hpp"
|
#include "comboboxlineedit.hpp"
|
||||||
|
|
||||||
ComboBoxLineEdit::ComboBoxLineEdit(QWidget *parent)
|
ContentSelectorView::ComboBoxLineEdit::ComboBoxLineEdit(QWidget *parent)
|
||||||
: QLineEdit(parent)
|
: QLineEdit(parent)
|
||||||
{
|
{
|
||||||
mClearButton = new QToolButton(this);
|
mClearButton = new QToolButton(this);
|
||||||
|
@ -21,7 +21,7 @@ ComboBoxLineEdit::ComboBoxLineEdit(QWidget *parent)
|
||||||
setStyleSheet(QString("ComboBoxLineEdit { background-color: transparent; padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1));
|
setStyleSheet(QString("ComboBoxLineEdit { background-color: transparent; padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComboBoxLineEdit::resizeEvent(QResizeEvent *)
|
void ContentSelectorView::ComboBoxLineEdit::resizeEvent(QResizeEvent *)
|
||||||
{
|
{
|
||||||
QSize sz = mClearButton->sizeHint();
|
QSize sz = mClearButton->sizeHint();
|
||||||
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||||
|
@ -29,7 +29,7 @@ void ComboBoxLineEdit::resizeEvent(QResizeEvent *)
|
||||||
(rect().bottom() + 1 - sz.height())/2);
|
(rect().bottom() + 1 - sz.height())/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComboBoxLineEdit::updateClearButton(const QString& text)
|
void ContentSelectorView::ComboBoxLineEdit::updateClearButton(const QString& text)
|
||||||
{
|
{
|
||||||
mClearButton->setVisible(!text.isEmpty());
|
mClearButton->setVisible(!text.isEmpty());
|
||||||
}
|
}
|
|
@ -14,22 +14,24 @@
|
||||||
|
|
||||||
class QToolButton;
|
class QToolButton;
|
||||||
|
|
||||||
class ComboBoxLineEdit : public QLineEdit
|
namespace ContentSelectorView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
class ComboBoxLineEdit : public QLineEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ComboBoxLineEdit(QWidget *parent = 0);
|
ComboBoxLineEdit(QWidget *parent = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent *);
|
void resizeEvent(QResizeEvent *);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateClearButton(const QString &text);
|
void updateClearButton(const QString &text);
|
||||||
|
|
||||||
private:
|
|
||||||
QToolButton *mClearButton;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QToolButton *mClearButton;
|
||||||
|
};
|
||||||
|
}
|
||||||
#endif // LIENEDIT_H
|
#endif // LIENEDIT_H
|
||||||
|
|
137
components/contentselector/view/contentselector.cpp
Normal file
137
components/contentselector/view/contentselector.cpp
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
#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)));
|
||||||
|
connect(gameFileView, SIGNAL(currentIndexChanged(int)), this, SIGNAL(signalGameFileChanged(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);
|
||||||
|
|
||||||
|
emit signalGameFileChanged(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);
|
||||||
|
}
|
53
components/contentselector/view/contentselector.hpp
Normal file
53
components/contentselector/view/contentselector.hpp
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef CONTENTSELECTOR_HPP
|
||||||
|
#define CONTENTSELECTOR_HPP
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include "ui_datafilespage.h"
|
||||||
|
|
||||||
|
namespace ContentSelectorModel { class ContentModel; }
|
||||||
|
|
||||||
|
class QSortFilterProxyModel;
|
||||||
|
|
||||||
|
namespace ContentSelectorView
|
||||||
|
{
|
||||||
|
class ContentSelector : public QDialog, protected Ui::DataFilesPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
ContentSelectorModel::ContentModel *mContentModel;
|
||||||
|
QSortFilterProxyModel *mGameFileProxyModel;
|
||||||
|
QSortFilterProxyModel *mAddonProxyModel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit ContentSelector(QWidget *parent = 0);
|
||||||
|
|
||||||
|
static ContentSelector &cast(QWidget *subject); //static constructor function for singleton performance.
|
||||||
|
|
||||||
|
void addFiles(const QString &path);
|
||||||
|
void setCheckState(QModelIndex index, QSortFilterProxyModel *model);
|
||||||
|
QStringList checkedItemsPaths();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void buildContentModel();
|
||||||
|
void buildGameFileView();
|
||||||
|
void buildAddonView();
|
||||||
|
void buildProfilesView();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void profileChanged(int index);
|
||||||
|
void signalGameFileChanged(int value);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateViews();
|
||||||
|
void slotCurrentProfileIndexChanged(int index);
|
||||||
|
void slotCurrentGameFileIndexChanged(int index);
|
||||||
|
void slotAddonTableItemClicked(const QModelIndex &index);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CONTENTSELECTOR_HPP
|
|
@ -1,9 +1,10 @@
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
|
#include <QStylePainter>
|
||||||
|
|
||||||
#include "lineedit.hpp"
|
#include "lineedit.hpp"
|
||||||
|
|
||||||
LineEdit::LineEdit(QWidget *parent)
|
ContentSelectorView::LineEdit::LineEdit(QWidget *parent)
|
||||||
: QLineEdit(parent)
|
: QLineEdit(parent)
|
||||||
{
|
{
|
||||||
mClearButton = new QToolButton(this);
|
mClearButton = new QToolButton(this);
|
||||||
|
@ -24,7 +25,7 @@ LineEdit::LineEdit(QWidget *parent)
|
||||||
qMax(msz.height(), mClearButton->sizeHint().height() + frameWidth * 2 + 2));
|
qMax(msz.height(), mClearButton->sizeHint().height() + frameWidth * 2 + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineEdit::resizeEvent(QResizeEvent *)
|
void ContentSelectorView::LineEdit::resizeEvent(QResizeEvent *)
|
||||||
{
|
{
|
||||||
QSize sz = mClearButton->sizeHint();
|
QSize sz = mClearButton->sizeHint();
|
||||||
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||||
|
@ -32,7 +33,7 @@ void LineEdit::resizeEvent(QResizeEvent *)
|
||||||
(rect().bottom() + 1 - sz.height())/2);
|
(rect().bottom() + 1 - sz.height())/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineEdit::updateClearButton(const QString& text)
|
void ContentSelectorView::LineEdit::updateClearButton(const QString& text)
|
||||||
{
|
{
|
||||||
mClearButton->setVisible(!text.isEmpty());
|
mClearButton->setVisible(!text.isEmpty());
|
||||||
}
|
}
|
|
@ -14,22 +14,26 @@
|
||||||
|
|
||||||
class QToolButton;
|
class QToolButton;
|
||||||
|
|
||||||
class LineEdit : public QLineEdit
|
namespace ContentSelectorView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
class LineEdit : public QLineEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
QString mPlaceholderText;
|
||||||
LineEdit(QWidget *parent = 0);
|
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
void resizeEvent(QResizeEvent *);
|
LineEdit(QWidget *parent = 0);
|
||||||
|
|
||||||
private slots:
|
protected:
|
||||||
void updateClearButton(const QString &text);
|
void resizeEvent(QResizeEvent *);
|
||||||
|
|
||||||
private:
|
private slots:
|
||||||
QToolButton *mClearButton;
|
void updateClearButton(const QString &text);
|
||||||
};
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QToolButton *mClearButton;
|
||||||
|
};
|
||||||
|
}
|
||||||
#endif // LIENEDIT_H
|
#endif // LIENEDIT_H
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "profilescombobox.hpp"
|
#include "profilescombobox.hpp"
|
||||||
#include "comboboxlineedit.hpp"
|
#include "comboboxlineedit.hpp"
|
||||||
|
|
||||||
ProfilesComboBox::ProfilesComboBox(QWidget *parent) :
|
ContentSelectorView::ProfilesComboBox::ProfilesComboBox(QWidget *parent) :
|
||||||
QComboBox(parent)
|
QComboBox(parent)
|
||||||
{
|
{
|
||||||
mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore
|
mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore
|
||||||
|
@ -21,7 +21,7 @@ ProfilesComboBox::ProfilesComboBox(QWidget *parent) :
|
||||||
setInsertPolicy(QComboBox::NoInsert);
|
setInsertPolicy(QComboBox::NoInsert);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfilesComboBox::setEditEnabled(bool editable)
|
void ContentSelectorView::ProfilesComboBox::setEditEnabled(bool editable)
|
||||||
{
|
{
|
||||||
if (isEditable() == editable)
|
if (isEditable() == editable)
|
||||||
return;
|
return;
|
||||||
|
@ -47,7 +47,7 @@ void ProfilesComboBox::setEditEnabled(bool editable)
|
||||||
SLOT(slotTextChanged(QString)));
|
SLOT(slotTextChanged(QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfilesComboBox::slotTextChanged(const QString &text)
|
void ContentSelectorView::ProfilesComboBox::slotTextChanged(const QString &text)
|
||||||
{
|
{
|
||||||
QPalette *palette = new QPalette();
|
QPalette *palette = new QPalette();
|
||||||
palette->setColor(QPalette::Text,Qt::red);
|
palette->setColor(QPalette::Text,Qt::red);
|
||||||
|
@ -61,7 +61,7 @@ void ProfilesComboBox::slotTextChanged(const QString &text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfilesComboBox::slotEditingFinished()
|
void ContentSelectorView::ProfilesComboBox::slotEditingFinished()
|
||||||
{
|
{
|
||||||
QString current = currentText();
|
QString current = currentText();
|
||||||
QString previous = itemText(currentIndex());
|
QString previous = itemText(currentIndex());
|
||||||
|
@ -82,7 +82,7 @@ void ProfilesComboBox::slotEditingFinished()
|
||||||
emit(profileRenamed(previous, current));
|
emit(profileRenamed(previous, current));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfilesComboBox::slotIndexChanged(int index)
|
void ContentSelectorView::ProfilesComboBox::slotIndexChanged(int index)
|
||||||
{
|
{
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
return;
|
return;
|
||||||
|
@ -90,3 +90,24 @@ void ProfilesComboBox::slotIndexChanged(int index)
|
||||||
emit(profileChanged(mOldProfile, currentText()));
|
emit(profileChanged(mOldProfile, currentText()));
|
||||||
mOldProfile = itemText(index);
|
mOldProfile = itemText(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContentSelectorView::ProfilesComboBox::paintEvent(QPaintEvent *)
|
||||||
|
{
|
||||||
|
QStylePainter painter(this);
|
||||||
|
painter.setPen(palette().color(QPalette::Text));
|
||||||
|
|
||||||
|
// draw the combobox frame, focusrect and selected etc.
|
||||||
|
QStyleOptionComboBox opt;
|
||||||
|
initStyleOption(&opt);
|
||||||
|
painter.drawComplexControl(QStyle::CC_ComboBox, opt);
|
||||||
|
|
||||||
|
// draw the icon and text
|
||||||
|
if (!opt.editable && currentIndex() == -1) // <<< we adjust the text displayed when nothing is selected
|
||||||
|
opt.currentText = mPlaceholderText;
|
||||||
|
painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentSelectorView::ProfilesComboBox::setPlaceholderText(const QString &text)
|
||||||
|
{
|
||||||
|
mPlaceholderText = text;
|
||||||
|
}
|
38
components/contentselector/view/profilescombobox.hpp
Normal file
38
components/contentselector/view/profilescombobox.hpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef PROFILESCOMBOBOX_HPP
|
||||||
|
#define PROFILESCOMBOBOX_HPP
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QStylePainter>
|
||||||
|
class QString;
|
||||||
|
class QRegExpValidator;
|
||||||
|
|
||||||
|
namespace ContentSelectorView
|
||||||
|
{
|
||||||
|
class ProfilesComboBox : public QComboBox
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ProfilesComboBox(QWidget *parent = 0);
|
||||||
|
void setEditEnabled(bool editable);
|
||||||
|
void setPlaceholderText (const QString &text);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void profileChanged(const QString &previous, const QString ¤t);
|
||||||
|
void profileRenamed(const QString &oldName, const QString &newName);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void slotEditingFinished();
|
||||||
|
void slotIndexChanged(int index);
|
||||||
|
void slotTextChanged(const QString &text);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString mOldProfile;
|
||||||
|
QString mPlaceholderText;
|
||||||
|
QRegExpValidator *mValidator;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PROFILESCOMBOBOX_HPP
|
|
@ -34,7 +34,7 @@ public:
|
||||||
float getFVer() const { if(mHeader.mData.version == VER_12) return 1.2; else return 1.3; }
|
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 getAuthor() const { return mHeader.mData.author.toString(); }
|
||||||
const std::string getDesc() const { return mHeader.mData.desc.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;
|
int getFormat() const;
|
||||||
const NAME &retSubName() const { return mCtx.subName; }
|
const NAME &retSubName() const { return mCtx.subName; }
|
||||||
uint32_t getSubSize() const { return mCtx.leftSub; }
|
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.
|
// 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.
|
// In this case, do not spawn a new reference, but overwrite the old one.
|
||||||
ref.mRefnum &= 0x00ffffff; // delete old plugin ID
|
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;
|
global = masters[local-1].index + 1;
|
||||||
ref.mRefnum |= global << 24; // insert global plugin ID
|
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;
|
int local = (mref.mRefnum & 0xff000000) >> 24;
|
||||||
size_t global = esm.getIndex() + 1;
|
size_t global = esm.getIndex() + 1;
|
||||||
mref.mRefnum &= 0x00ffffff; // delete old plugin ID
|
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;
|
global = masters[local-1].index + 1;
|
||||||
mref.mRefnum |= global << 24; // insert global plugin ID
|
mref.mRefnum |= global << 24; // insert global plugin ID
|
||||||
|
|
||||||
|
|
|
@ -1,445 +0,0 @@
|
||||||
#include <QTextDecoder>
|
|
||||||
#include <QTextCodec>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QDir>
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include <components/esm/esmreader.hpp>
|
|
||||||
|
|
||||||
#include "esm/esmfile.hpp"
|
|
||||||
|
|
||||||
#include "datafilesmodel.hpp"
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
DataFilesModel::DataFilesModel(QObject *parent) :
|
|
||||||
QAbstractTableModel(parent)
|
|
||||||
{
|
|
||||||
mEncoding = QString("win1252");
|
|
||||||
}
|
|
||||||
|
|
||||||
DataFilesModel::~DataFilesModel()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesModel::setEncoding(const QString &encoding)
|
|
||||||
{
|
|
||||||
mEncoding = encoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesModel::setCheckState(const QModelIndex &index, Qt::CheckState state)
|
|
||||||
{
|
|
||||||
setData(index, state, Qt::CheckStateRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::CheckState DataFilesModel::checkState(const QModelIndex &index)
|
|
||||||
{
|
|
||||||
EsmFile *file = item(index.row());
|
|
||||||
return mCheckStates[file->fileName()];
|
|
||||||
}
|
|
||||||
|
|
||||||
int DataFilesModel::columnCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
return parent.isValid() ? 0 : 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DataFilesModel::rowCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
return parent.isValid() ? 0 : mFiles.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool 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 DataFilesModel::data(const QModelIndex &index, int role) const
|
|
||||||
{
|
|
||||||
if (!index.isValid())
|
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
EsmFile *file = item(index.row());
|
|
||||||
|
|
||||||
if (!file)
|
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
const int column = index.column();
|
|
||||||
|
|
||||||
switch (role) {
|
|
||||||
case Qt::DisplayRole: {
|
|
||||||
|
|
||||||
switch (column) {
|
|
||||||
case 0:
|
|
||||||
return file->fileName();
|
|
||||||
case 1:
|
|
||||||
return file->author();
|
|
||||||
case 2:
|
|
||||||
return QString("%1 kB").arg(int((file->size() + 1023) / 1024));
|
|
||||||
case 3:
|
|
||||||
//return file->modified().toString(Qt::TextDate);
|
|
||||||
return file->modified().toString(Qt::ISODate);
|
|
||||||
case 4:
|
|
||||||
return file->accessed().toString(Qt::TextDate);
|
|
||||||
case 5:
|
|
||||||
return file->version();
|
|
||||||
case 6:
|
|
||||||
return file->path();
|
|
||||||
case 7:
|
|
||||||
return file->masters().join(", ");
|
|
||||||
case 8:
|
|
||||||
return file->description();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case Qt::TextAlignmentRole: {
|
|
||||||
switch (column) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
return Qt::AlignLeft + Qt::AlignVCenter;
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
return Qt::AlignRight + Qt::AlignVCenter;
|
|
||||||
default:
|
|
||||||
return Qt::AlignLeft + Qt::AlignVCenter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case Qt::CheckStateRole: {
|
|
||||||
if (column != 0)
|
|
||||||
return QVariant();
|
|
||||||
return mCheckStates[file->fileName()];
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::ItemFlags DataFilesModel::flags(const QModelIndex &index) const
|
|
||||||
{
|
|
||||||
if (!index.isValid())
|
|
||||||
return Qt::NoItemFlags;
|
|
||||||
|
|
||||||
EsmFile *file = item(index.row());
|
|
||||||
|
|
||||||
if (!file)
|
|
||||||
return Qt::NoItemFlags;
|
|
||||||
|
|
||||||
if (canBeChecked(file)) {
|
|
||||||
if (index.column() == 0) {
|
|
||||||
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
|
||||||
} else {
|
|
||||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (index.column() == 0) {
|
|
||||||
return Qt::ItemIsUserCheckable | Qt::ItemIsSelectable;
|
|
||||||
} else {
|
|
||||||
return Qt::NoItemFlags | Qt::ItemIsSelectable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant 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");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Show row numbers
|
|
||||||
return ++section;
|
|
||||||
}
|
|
||||||
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DataFilesModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
|
||||||
{
|
|
||||||
if (!index.isValid())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (role == Qt::CheckStateRole) {
|
|
||||||
QString name = item(index.row())->fileName();
|
|
||||||
mCheckStates[name] = static_cast<Qt::CheckState>(value.toInt());
|
|
||||||
|
|
||||||
// Force a redraw of the view since unchecking one item can affect another
|
|
||||||
QModelIndex firstIndex = indexFromItem(mFiles.first());
|
|
||||||
QModelIndex lastIndex = indexFromItem(mFiles.last());
|
|
||||||
|
|
||||||
emit dataChanged(firstIndex, lastIndex);
|
|
||||||
emit checkedItemsChanged(checkedItems());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lessThanEsmFile(const EsmFile *e1, const 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 EsmFile *e1, const EsmFile *e2)
|
|
||||||
{
|
|
||||||
if (e1->modified().toString(Qt::ISODate) < e2->modified().toString(Qt::ISODate)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void 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 DataFilesModel::addFile(EsmFile *file)
|
|
||||||
{
|
|
||||||
emit beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count());
|
|
||||||
mFiles.append(file);
|
|
||||||
emit endInsertRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesModel::addFiles(const QString &path)
|
|
||||||
{
|
|
||||||
QDir dir(path);
|
|
||||||
QStringList filters;
|
|
||||||
filters << "*.esp" << "*.esm";
|
|
||||||
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 esp: " << e.what();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
delete decoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex DataFilesModel::indexFromItem(EsmFile *item) const
|
|
||||||
{
|
|
||||||
if (item)
|
|
||||||
return createIndex(mFiles.indexOf(item), 0);
|
|
||||||
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
EsmFile* DataFilesModel::findItem(const QString &name)
|
|
||||||
{
|
|
||||||
QList<EsmFile *>::ConstIterator it;
|
|
||||||
QList<EsmFile *>::ConstIterator itEnd = mFiles.constEnd();
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (it = mFiles.constBegin(); it != itEnd; ++it) {
|
|
||||||
EsmFile *file = item(i);
|
|
||||||
++i;
|
|
||||||
|
|
||||||
if (name == file->fileName())
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not found
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
EsmFile* DataFilesModel::item(int row) const
|
|
||||||
{
|
|
||||||
if (row >= 0 && row < mFiles.count())
|
|
||||||
return mFiles.at(row);
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList DataFilesModel::checkedItems()
|
|
||||||
{
|
|
||||||
QStringList list;
|
|
||||||
|
|
||||||
QList<EsmFile *>::ConstIterator it;
|
|
||||||
QList<EsmFile *>::ConstIterator itEnd = mFiles.constEnd();
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (it = mFiles.constBegin(); it != itEnd; ++it) {
|
|
||||||
EsmFile *file = item(i);
|
|
||||||
++i;
|
|
||||||
|
|
||||||
QString name = file->fileName();
|
|
||||||
|
|
||||||
// Only add the items that are in the checked list and available
|
|
||||||
if (mCheckStates[name] == Qt::Checked && canBeChecked(file))
|
|
||||||
list << name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList DataFilesModel::checkedItemsPaths()
|
|
||||||
{
|
|
||||||
QStringList list;
|
|
||||||
|
|
||||||
QList<EsmFile *>::ConstIterator it;
|
|
||||||
QList<EsmFile *>::ConstIterator itEnd = mFiles.constEnd();
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (it = mFiles.constBegin(); it != itEnd; ++it) {
|
|
||||||
EsmFile *file = item(i);
|
|
||||||
++i;
|
|
||||||
|
|
||||||
if (mCheckStates[file->fileName()] == Qt::Checked && canBeChecked(file))
|
|
||||||
list << file->path();
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFilesModel::uncheckAll()
|
|
||||||
{
|
|
||||||
emit layoutAboutToBeChanged();
|
|
||||||
mCheckStates.clear();
|
|
||||||
emit layoutChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList DataFilesModel::uncheckedItems()
|
|
||||||
{
|
|
||||||
QStringList list;
|
|
||||||
QStringList checked = checkedItems();
|
|
||||||
|
|
||||||
QList<EsmFile *>::ConstIterator it;
|
|
||||||
QList<EsmFile *>::ConstIterator itEnd = mFiles.constEnd();
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (it = mFiles.constBegin(); it != itEnd; ++it) {
|
|
||||||
EsmFile *file = item(i);
|
|
||||||
++i;
|
|
||||||
|
|
||||||
// Add the items that are not in the checked list
|
|
||||||
if (!checked.contains(file->fileName()))
|
|
||||||
list << file->fileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DataFilesModel::canBeChecked(EsmFile *file) const
|
|
||||||
{
|
|
||||||
//element can be checked if all its dependencies are
|
|
||||||
bool canBeChecked = true;
|
|
||||||
foreach (const QString &master, file->masters())
|
|
||||||
{
|
|
||||||
if (!mCheckStates.contains(master) || mCheckStates[master] != Qt::Checked)
|
|
||||||
{
|
|
||||||
canBeChecked = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return canBeChecked;
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
#ifndef DATAFILESMODEL_HPP
|
|
||||||
#define DATAFILESMODEL_HPP
|
|
||||||
|
|
||||||
#include <QAbstractTableModel>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QString>
|
|
||||||
#include <QHash>
|
|
||||||
|
|
||||||
|
|
||||||
class EsmFile;
|
|
||||||
|
|
||||||
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 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
|
|
||||||
{ return QAbstractTableModel::index(row, column, parent); }
|
|
||||||
|
|
||||||
void setEncoding(const QString &encoding);
|
|
||||||
|
|
||||||
void addFiles(const QString &path);
|
|
||||||
|
|
||||||
void uncheckAll();
|
|
||||||
|
|
||||||
QStringList checkedItems();
|
|
||||||
QStringList uncheckedItems();
|
|
||||||
QStringList checkedItemsPaths();
|
|
||||||
|
|
||||||
Qt::CheckState checkState(const QModelIndex &index);
|
|
||||||
void setCheckState(const QModelIndex &index, Qt::CheckState state);
|
|
||||||
|
|
||||||
QModelIndex indexFromItem(EsmFile *item) const;
|
|
||||||
EsmFile* findItem(const QString &name);
|
|
||||||
EsmFile* item(int row) const;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void checkedItemsChanged(const QStringList &items);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool canBeChecked(EsmFile *file) const;
|
|
||||||
void addFile(EsmFile *file);
|
|
||||||
|
|
||||||
QList<EsmFile *> mFiles;
|
|
||||||
QHash<QString, Qt::CheckState> mCheckStates;
|
|
||||||
|
|
||||||
QString mEncoding;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // DATAFILESMODEL_HPP
|
|
|
@ -1,50 +0,0 @@
|
||||||
#include "esmfile.hpp"
|
|
||||||
|
|
||||||
EsmFile::EsmFile(QString fileName, ModelItem *parent)
|
|
||||||
: ModelItem(parent)
|
|
||||||
{
|
|
||||||
mFileName = fileName;
|
|
||||||
mSize = 0;
|
|
||||||
mVersion = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EsmFile::setFileName(const QString &fileName)
|
|
||||||
{
|
|
||||||
mFileName = fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EsmFile::setAuthor(const QString &author)
|
|
||||||
{
|
|
||||||
mAuthor = author;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EsmFile::setSize(const int size)
|
|
||||||
{
|
|
||||||
mSize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EsmFile::setDates(const QDateTime &modified, const QDateTime &accessed)
|
|
||||||
{
|
|
||||||
mModified = modified;
|
|
||||||
mAccessed = accessed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EsmFile::setVersion(float version)
|
|
||||||
{
|
|
||||||
mVersion = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EsmFile::setPath(const QString &path)
|
|
||||||
{
|
|
||||||
mPath = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EsmFile::setMasters(const QStringList &masters)
|
|
||||||
{
|
|
||||||
mMasters = masters;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EsmFile::setDescription(const QString &description)
|
|
||||||
{
|
|
||||||
mDescription = description;
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
#ifndef ESMFILE_HPP
|
|
||||||
#define ESMFILE_HPP
|
|
||||||
|
|
||||||
#include <QDateTime>
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
#include "../modelitem.hpp"
|
|
||||||
|
|
||||||
class EsmFile : public ModelItem
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(QString filename READ fileName)
|
|
||||||
|
|
||||||
public:
|
|
||||||
EsmFile(QString fileName = QString(), ModelItem *parent = 0);
|
|
||||||
|
|
||||||
~EsmFile()
|
|
||||||
{}
|
|
||||||
|
|
||||||
void setFileName(const QString &fileName);
|
|
||||||
void setAuthor(const QString &author);
|
|
||||||
void setSize(const int size);
|
|
||||||
void setDates(const QDateTime &modified, const QDateTime &accessed);
|
|
||||||
void setVersion(const float version);
|
|
||||||
void setPath(const QString &path);
|
|
||||||
void setMasters(const QStringList &masters);
|
|
||||||
void setDescription(const QString &description);
|
|
||||||
|
|
||||||
inline QString fileName() const { return mFileName; }
|
|
||||||
inline QString author() const { return mAuthor; }
|
|
||||||
inline int size() const { return mSize; }
|
|
||||||
inline QDateTime modified() const { return mModified; }
|
|
||||||
inline QDateTime accessed() const { return mAccessed; }
|
|
||||||
inline float version() const { return mVersion; }
|
|
||||||
inline QString path() const { return mPath; }
|
|
||||||
inline QStringList masters() const { return mMasters; }
|
|
||||||
inline QString description() const { return mDescription; }
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString mFileName;
|
|
||||||
QString mAuthor;
|
|
||||||
int mSize;
|
|
||||||
QDateTime mModified;
|
|
||||||
QDateTime mAccessed;
|
|
||||||
float mVersion;
|
|
||||||
QString mPath;
|
|
||||||
QStringList mMasters;
|
|
||||||
QString mDescription;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,57 +0,0 @@
|
||||||
#include "modelitem.hpp"
|
|
||||||
|
|
||||||
ModelItem::ModelItem(ModelItem *parent)
|
|
||||||
: mParentItem(parent)
|
|
||||||
, QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelItem::~ModelItem()
|
|
||||||
{
|
|
||||||
qDeleteAll(mChildItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ModelItem *ModelItem::parent()
|
|
||||||
{
|
|
||||||
return mParentItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
int 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 ModelItem::childCount() const
|
|
||||||
{
|
|
||||||
return mChildItems.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
int ModelItem::childRow(ModelItem *child) const
|
|
||||||
{
|
|
||||||
Q_ASSERT(child);
|
|
||||||
|
|
||||||
return mChildItems.indexOf(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelItem *ModelItem::child(int row)
|
|
||||||
{
|
|
||||||
return mChildItems.value(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ModelItem::appendChild(ModelItem *item)
|
|
||||||
{
|
|
||||||
mChildItems.append(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelItem::removeChild(int row)
|
|
||||||
{
|
|
||||||
mChildItems.removeAt(row);
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
#ifndef MODELITEM_HPP
|
|
||||||
#define MODELITEM_HPP
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QList>
|
|
||||||
|
|
||||||
class ModelItem : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
ModelItem(ModelItem *parent = 0);
|
|
||||||
~ModelItem();
|
|
||||||
|
|
||||||
ModelItem *parent();
|
|
||||||
int row() const;
|
|
||||||
|
|
||||||
int childCount() const;
|
|
||||||
int childRow(ModelItem *child) const;
|
|
||||||
ModelItem *child(int row);
|
|
||||||
|
|
||||||
void appendChild(ModelItem *child);
|
|
||||||
void removeChild(int row);
|
|
||||||
|
|
||||||
//virtual bool acceptChild(ModelItem *child);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ModelItem *mParentItem;
|
|
||||||
QList<ModelItem*> mChildItems;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,17 +0,0 @@
|
||||||
#include "pluginsproxymodel.hpp"
|
|
||||||
|
|
||||||
PluginsProxyModel::PluginsProxyModel(QObject *parent) :
|
|
||||||
QSortFilterProxyModel(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PluginsProxyModel::~PluginsProxyModel()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant PluginsProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
||||||
{
|
|
||||||
if (orientation != Qt::Vertical || role != Qt::DisplayRole)
|
|
||||||
return QSortFilterProxyModel::headerData(section, orientation, role);
|
|
||||||
return section + 1;
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
#ifndef PLUGINSPROXYMODEL_HPP
|
|
||||||
#define PLUGINSPROXYMODEL_HPP
|
|
||||||
|
|
||||||
#include <QSortFilterProxyModel>
|
|
||||||
|
|
||||||
class QVariant;
|
|
||||||
|
|
||||||
class PluginsProxyModel : public QSortFilterProxyModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit PluginsProxyModel(QObject *parent = 0);
|
|
||||||
~PluginsProxyModel();
|
|
||||||
|
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PLUGINSPROXYMODEL_HPP
|
|
|
@ -1,11 +0,0 @@
|
||||||
#ifndef NATURALSORT_H
|
|
||||||
#define NATURALSORT_H
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
bool naturalSortLessThanCS( const QString &left, const QString &right );
|
|
||||||
bool naturalSortLessThanCI( const QString &left, const QString &right );
|
|
||||||
bool naturalSortGreaterThanCS( const QString &left, const QString &right );
|
|
||||||
bool naturalSortGreaterThanCI( const QString &left, const QString &right );
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,30 +0,0 @@
|
||||||
#ifndef PROFILESCOMBOBOX_HPP
|
|
||||||
#define PROFILESCOMBOBOX_HPP
|
|
||||||
|
|
||||||
#include <QComboBox>
|
|
||||||
|
|
||||||
class QString;
|
|
||||||
class QRegExpValidator;
|
|
||||||
|
|
||||||
class ProfilesComboBox : public QComboBox
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit ProfilesComboBox(QWidget *parent = 0);
|
|
||||||
void setEditEnabled(bool editable);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void profileChanged(const QString &previous, const QString ¤t);
|
|
||||||
void profileRenamed(const QString &oldName, const QString &newName);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void slotEditingFinished();
|
|
||||||
void slotIndexChanged(int index);
|
|
||||||
void slotTextChanged(const QString &text);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString mOldProfile;
|
|
||||||
QRegExpValidator *mValidator;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PROFILESCOMBOBOX_HPP
|
|
|
@ -47,6 +47,7 @@ Marc Bouvier (CramitDeFrog)
|
||||||
Marcin Hulist (Gohan)
|
Marcin Hulist (Gohan)
|
||||||
Mark Siewert (mark76)
|
Mark Siewert (mark76)
|
||||||
Mateusz Kołaczek (PL_kolek)
|
Mateusz Kołaczek (PL_kolek)
|
||||||
|
Michael Hogan (Xethik)
|
||||||
Michael Mc Donnell
|
Michael Mc Donnell
|
||||||
Michael Papageorgiou (werdanith)
|
Michael Papageorgiou (werdanith)
|
||||||
Michał Bień (Glorf)
|
Michał Bień (Glorf)
|
||||||
|
|
|
@ -7,107 +7,260 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>518</width>
|
<width>518</width>
|
||||||
<height>304</height>
|
<height>313</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="contextMenuPolicy">
|
||||||
|
<enum>Qt::DefaultContextMenu</enum>
|
||||||
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="filterLayout">
|
<widget class="QGroupBox" name="contentGroupBox">
|
||||||
<item>
|
<property name="title">
|
||||||
<spacer name="horizontalSpacer">
|
<string>Content</string>
|
||||||
<property name="orientation">
|
</property>
|
||||||
<enum>Qt::Horizontal</enum>
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
</property>
|
<item>
|
||||||
<property name="sizeHint" stdset="0">
|
<layout class="QHBoxLayout" name="filterLayout">
|
||||||
<size>
|
<item>
|
||||||
<width>40</width>
|
<widget class="ContentSelectorView::ProfilesComboBox" name="gameFileView">
|
||||||
<height>20</height>
|
<property name="editable">
|
||||||
</size>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
</layout>
|
||||||
<widget class="QLabel" name="filterLabel">
|
</item>
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Filter:</string>
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
</property>
|
<item>
|
||||||
</widget>
|
<widget class="QTableView" name="addonView">
|
||||||
</item>
|
<property name="sizePolicy">
|
||||||
<item>
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
<widget class="LineEdit" name="filterLineEdit"/>
|
<horstretch>0</horstretch>
|
||||||
</item>
|
<verstretch>0</verstretch>
|
||||||
</layout>
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="contextMenuPolicy">
|
||||||
|
<enum>Qt::DefaultContextMenu</enum>
|
||||||
|
</property>
|
||||||
|
<property name="acceptDrops">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="dragEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="dragDropOverwriteMode">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="dragDropMode">
|
||||||
|
<enum>QAbstractItemView::DragDrop</enum>
|
||||||
|
</property>
|
||||||
|
<property name="defaultDropAction">
|
||||||
|
<enum>Qt::MoveAction</enum>
|
||||||
|
</property>
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::SingleSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
<property name="textElideMode">
|
||||||
|
<enum>Qt::ElideLeft</enum>
|
||||||
|
</property>
|
||||||
|
<property name="showGrid">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="horizontalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="horizontalHeaderStretchLastSection">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="verticalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
<zorder></zorder>
|
||||||
|
<zorder></zorder>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSplitter" name="splitter">
|
<widget class="QGroupBox" name="projectGroupBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="orientation">
|
<property name="title">
|
||||||
<enum>Qt::Horizontal</enum>
|
<string>Project</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="childrenCollapsible">
|
<property name="alignment">
|
||||||
<bool>false</bool>
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QTableView" name="mastersTable"/>
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<widget class="QTableView" name="pluginsTable"/>
|
<item>
|
||||||
|
<widget class="QFrame" name="fileWidgetFrame">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="margin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="projectButtonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Open</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="projectCreateButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Create</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<widget class="QFrame" name="adjusterWidgetFrame">
|
||||||
<item>
|
<property name="sizePolicy">
|
||||||
<widget class="QLabel" name="profileLabel">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
<property name="text">
|
<horstretch>1</horstretch>
|
||||||
<string>Current Profile:</string>
|
<verstretch>0</verstretch>
|
||||||
</property>
|
</sizepolicy>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<property name="frameShape">
|
||||||
<item>
|
<enum>QFrame::NoFrame</enum>
|
||||||
<widget class="ProfilesComboBox" name="profilesComboBox">
|
</property>
|
||||||
<property name="enabled">
|
<property name="frameShadow">
|
||||||
<bool>true</bool>
|
<enum>QFrame::Plain</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="lineWidth">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
<number>0</number>
|
||||||
<horstretch>0</horstretch>
|
</property>
|
||||||
<verstretch>0</verstretch>
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
</sizepolicy>
|
<property name="spacing">
|
||||||
</property>
|
<number>0</number>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<property name="margin">
|
||||||
<item>
|
<number>0</number>
|
||||||
<widget class="QToolButton" name="newProfileButton">
|
</property>
|
||||||
<property name="toolTip">
|
</layout>
|
||||||
<string>New Profile</string>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
<property name="text">
|
<item>
|
||||||
<string>&New Profile</string>
|
<widget class="QGroupBox" name="profileGroupBox">
|
||||||
</property>
|
<property name="focusPolicy">
|
||||||
<property name="autoRaise">
|
<enum>Qt::NoFocus</enum>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</property>
|
<property name="title">
|
||||||
</widget>
|
<string>Profile</string>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="flat">
|
||||||
<widget class="QToolButton" name="deleteProfileButton">
|
<bool>false</bool>
|
||||||
<property name="toolTip">
|
</property>
|
||||||
<string>Delete Profile</string>
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
</property>
|
<property name="spacing">
|
||||||
<property name="text">
|
<number>6</number>
|
||||||
<string>Delete Profile</string>
|
</property>
|
||||||
</property>
|
<property name="leftMargin">
|
||||||
<property name="shortcut">
|
<number>3</number>
|
||||||
<string>Ctrl+D</string>
|
</property>
|
||||||
</property>
|
<property name="topMargin">
|
||||||
<property name="autoRaise">
|
<number>9</number>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</property>
|
<property name="rightMargin">
|
||||||
</widget>
|
<number>0</number>
|
||||||
</item>
|
</property>
|
||||||
</layout>
|
<property name="bottomMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="ContentSelectorView::ProfilesComboBox" name="profilesComboBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="newProfileButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>New Profile</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&New Profile</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="deleteProfileButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Delete Profile</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete Profile</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+D</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
<action name="newProfileAction">
|
<action name="newProfileAction">
|
||||||
|
@ -140,6 +293,9 @@
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="checkAction">
|
<action name="checkAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Check Selection</string>
|
<string>Check Selection</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -152,14 +308,9 @@
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>LineEdit</class>
|
<class>ContentSelectorView::ProfilesComboBox</class>
|
||||||
<extends>QLineEdit</extends>
|
|
||||||
<header location="global">components/fileorderlist/utils/lineedit.hpp</header>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>ProfilesComboBox</class>
|
|
||||||
<extends>QComboBox</extends>
|
<extends>QComboBox</extends>
|
||||||
<header location="global">components/fileorderlist/utils/profilescombobox.hpp</header>
|
<header>components/contentselector/view/profilescombobox.hpp</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|
Loading…
Reference in a new issue