mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-04 03:40:14 +00:00
Split launcher specific code from DataFilesList back to DataFilesPage.
This commit is contained in:
parent
155cca0c9a
commit
66ec4ca7d9
@ -3,6 +3,9 @@ set(LAUNCHER
|
||||
main.cpp
|
||||
maindialog.cpp
|
||||
playpage.cpp
|
||||
datafilespage.cpp
|
||||
utils/profilescombobox.cpp
|
||||
utils/textinputdialog.cpp
|
||||
|
||||
launcher.rc
|
||||
)
|
||||
@ -11,6 +14,9 @@ set(LAUNCHER_HEADER
|
||||
graphicspage.hpp
|
||||
maindialog.hpp
|
||||
playpage.hpp
|
||||
datafilespage.hpp
|
||||
utils/profilescombobox.hpp
|
||||
utils/textinputdialog.hpp
|
||||
)
|
||||
|
||||
# Headers that must be pre-processed
|
||||
@ -18,6 +24,9 @@ set(LAUNCHER_HEADER_MOC
|
||||
graphicspage.hpp
|
||||
maindialog.hpp
|
||||
playpage.hpp
|
||||
datafilespage.hpp
|
||||
utils/profilescombobox.hpp
|
||||
utils/textinputdialog.hpp
|
||||
)
|
||||
|
||||
source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC})
|
||||
|
533
apps/launcher/datafilespage.cpp
Normal file
533
apps/launcher/datafilespage.cpp
Normal file
@ -0,0 +1,533 @@
|
||||
#include <QtGui>
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/fileorderlist/datafileslist.hpp>
|
||||
#include <components/fileorderlist/utils/lineedit.hpp>
|
||||
#include <components/fileorderlist/utils/naturalsort.hpp>
|
||||
#include <components/fileorderlist/utils/filedialog.hpp>
|
||||
|
||||
////#include "model/datafilesmodel.hpp"
|
||||
////#include "model/esm/esmfile.hpp"
|
||||
|
||||
#include "utils/profilescombobox.hpp"
|
||||
////#include "utils/filedialog.hpp"
|
||||
////#include "utils/naturalsort.hpp"
|
||||
#include "utils/textinputdialog.hpp"
|
||||
|
||||
#include "datafilespage.hpp"
|
||||
|
||||
#include <boost/version.hpp>
|
||||
/**
|
||||
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
||||
*/
|
||||
#if (BOOST_VERSION <= 104600)
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<>
|
||||
inline boost::filesystem::path lexical_cast<boost::filesystem::path, std::string>(const std::string& arg)
|
||||
{
|
||||
return boost::filesystem::path(arg);
|
||||
}
|
||||
|
||||
} /* namespace boost */
|
||||
#endif /* (BOOST_VERSION <= 104600) */
|
||||
|
||||
using namespace ESM;
|
||||
using namespace std;
|
||||
|
||||
DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, mCfgMgr(cfg)
|
||||
{
|
||||
mDataFilesList = new DataFilesList(mCfgMgr, this);
|
||||
|
||||
// Bottom part with profile options
|
||||
QLabel *profileLabel = new QLabel(tr("Current Profile: "), this);
|
||||
|
||||
mProfilesComboBox = new ProfilesComboBox(this);
|
||||
mProfilesComboBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));
|
||||
mProfilesComboBox->setInsertPolicy(QComboBox::NoInsert);
|
||||
mProfilesComboBox->setDuplicatesEnabled(false);
|
||||
mProfilesComboBox->setEditEnabled(false);
|
||||
|
||||
mProfileToolBar = new QToolBar(this);
|
||||
mProfileToolBar->setMovable(false);
|
||||
mProfileToolBar->setIconSize(QSize(16, 16));
|
||||
|
||||
mProfileToolBar->addWidget(profileLabel);
|
||||
mProfileToolBar->addWidget(mProfilesComboBox);
|
||||
|
||||
QVBoxLayout *pageLayout = new QVBoxLayout(this);
|
||||
|
||||
pageLayout->addWidget(mDataFilesList);
|
||||
pageLayout->addWidget(mProfileToolBar);
|
||||
|
||||
// Create a dialog for the new profile name input
|
||||
mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this);
|
||||
|
||||
connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString)));
|
||||
|
||||
connect(mProfilesComboBox, SIGNAL(profileRenamed(QString,QString)), this, SLOT(profileRenamed(QString,QString)));
|
||||
connect(mProfilesComboBox, SIGNAL(profileChanged(QString,QString)), this, SLOT(profileChanged(QString,QString)));
|
||||
|
||||
createActions();
|
||||
setupConfig();
|
||||
}
|
||||
|
||||
void DataFilesPage::createActions()
|
||||
{
|
||||
// Refresh the plugins
|
||||
QAction *refreshAction = new QAction(tr("Refresh"), this);
|
||||
refreshAction->setShortcut(QKeySequence(tr("F5")));
|
||||
connect(refreshAction, SIGNAL(triggered()), this, SLOT(refresh()));
|
||||
|
||||
// Profile actions
|
||||
mNewProfileAction = new QAction(QIcon::fromTheme("document-new"), tr("&New Profile"), this);
|
||||
mNewProfileAction->setToolTip(tr("New Profile"));
|
||||
mNewProfileAction->setShortcut(QKeySequence(tr("Ctrl+N")));
|
||||
connect(mNewProfileAction, SIGNAL(triggered()), this, SLOT(newProfile()));
|
||||
|
||||
mDeleteProfileAction = new QAction(QIcon::fromTheme("edit-delete"), tr("Delete Profile"), this);
|
||||
mDeleteProfileAction->setToolTip(tr("Delete Profile"));
|
||||
mDeleteProfileAction->setShortcut(QKeySequence(tr("Delete")));
|
||||
connect(mDeleteProfileAction, SIGNAL(triggered()), this, SLOT(deleteProfile()));
|
||||
|
||||
// Add the newly created actions to the toolbar
|
||||
mProfileToolBar->addSeparator();
|
||||
mProfileToolBar->addAction(mNewProfileAction);
|
||||
mProfileToolBar->addAction(mDeleteProfileAction);
|
||||
}
|
||||
|
||||
void DataFilesPage::setupConfig()
|
||||
{
|
||||
// Open our config file
|
||||
QString config = QString::fromStdString((mCfgMgr.getUserPath() / "launcher.cfg").string());
|
||||
mLauncherConfig = new QSettings(config, QSettings::IniFormat);
|
||||
|
||||
// Make sure we have no groups open
|
||||
while (!mLauncherConfig->group().isEmpty()) {
|
||||
mLauncherConfig->endGroup();
|
||||
}
|
||||
|
||||
mLauncherConfig->beginGroup("Profiles");
|
||||
QStringList profiles = mLauncherConfig->childGroups();
|
||||
|
||||
// Add the profiles to the combobox
|
||||
foreach (const QString &profile, profiles) {
|
||||
|
||||
if (profile.contains(QRegExp("[^a-zA-Z0-9_]")))
|
||||
continue; // Profile name contains garbage
|
||||
|
||||
|
||||
qDebug() << "adding " << profile;
|
||||
mProfilesComboBox->addItem(profile);
|
||||
}
|
||||
|
||||
// Add a default profile
|
||||
if (mProfilesComboBox->findText(QString("Default")) == -1) {
|
||||
mProfilesComboBox->addItem(QString("Default"));
|
||||
}
|
||||
|
||||
QString currentProfile = mLauncherConfig->value("CurrentProfile").toString();
|
||||
|
||||
if (currentProfile.isEmpty()) {
|
||||
// No current profile selected
|
||||
currentProfile = "Default";
|
||||
}
|
||||
|
||||
const int currentIndex = mProfilesComboBox->findText(currentProfile);
|
||||
if (currentIndex != -1) {
|
||||
// Profile is found
|
||||
mProfilesComboBox->setCurrentIndex(currentIndex);
|
||||
}
|
||||
|
||||
mLauncherConfig->endGroup();
|
||||
}
|
||||
|
||||
|
||||
void DataFilesPage::readConfig()
|
||||
{
|
||||
QString profile = mProfilesComboBox->currentText();
|
||||
|
||||
// Make sure we have no groups open
|
||||
while (!mLauncherConfig->group().isEmpty()) {
|
||||
mLauncherConfig->endGroup();
|
||||
}
|
||||
|
||||
mLauncherConfig->beginGroup("Profiles");
|
||||
mLauncherConfig->beginGroup(profile);
|
||||
|
||||
QStringList childKeys = mLauncherConfig->childKeys();
|
||||
QStringList plugins;
|
||||
|
||||
// Sort the child keys numerical instead of alphabetically
|
||||
// i.e. Plugin1, Plugin2 instead of Plugin1, Plugin10
|
||||
qSort(childKeys.begin(), childKeys.end(), naturalSortLessThanCI);
|
||||
|
||||
foreach (const QString &key, childKeys) {
|
||||
const QString keyValue = mLauncherConfig->value(key).toString();
|
||||
|
||||
mDataFilesList->setCheckState(keyValue, Qt::Checked);
|
||||
}
|
||||
|
||||
qDebug() << plugins;
|
||||
}
|
||||
|
||||
bool DataFilesPage::showDataFilesWarning()
|
||||
{
|
||||
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error detecting Morrowind installation");
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setStandardButtons(QMessageBox::Cancel);
|
||||
msgBox.setText(tr("<br><b>Could not find the Data Files location</b><br><br> \
|
||||
The directory containing the data files was not found.<br><br> \
|
||||
Press \"Browse...\" to specify the location manually.<br>"));
|
||||
|
||||
QAbstractButton *dirSelectButton =
|
||||
msgBox.addButton(tr("B&rowse..."), QMessageBox::ActionRole);
|
||||
|
||||
msgBox.exec();
|
||||
|
||||
if (msgBox.clickedButton() == dirSelectButton) {
|
||||
|
||||
// Show a custom dir selection dialog which only accepts valid dirs
|
||||
QString selectedDir = FileDialog::getExistingDirectory(
|
||||
this, tr("Select Data Files Directory"),
|
||||
QDir::currentPath(),
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
|
||||
// Add the user selected data directory
|
||||
if (!selectedDir.isEmpty()) {
|
||||
mDataDirs.push_back(Files::PathContainer::value_type(selectedDir.toStdString()));
|
||||
mCfgMgr.processPaths(mDataDirs);
|
||||
} else {
|
||||
// Cancel from within the dir selection dialog
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Cancel
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DataFilesPage::setupDataFiles()
|
||||
{
|
||||
// We use the Configuration Manager to retrieve the configuration values
|
||||
boost::program_options::variables_map variables;
|
||||
boost::program_options::options_description desc;
|
||||
|
||||
desc.add_options()
|
||||
("data", boost::program_options::value<Files::PathContainer>()->default_value(Files::PathContainer(), "data")->multitoken())
|
||||
("data-local", boost::program_options::value<std::string>()->default_value(""))
|
||||
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false))
|
||||
("encoding", boost::program_options::value<std::string>()->default_value("win1252"));
|
||||
|
||||
boost::program_options::notify(variables);
|
||||
|
||||
mCfgMgr.readConfiguration(variables, desc);
|
||||
|
||||
if (variables["data"].empty()) {
|
||||
if (!showDataFilesWarning())
|
||||
return false;
|
||||
} else {
|
||||
mDataDirs = Files::PathContainer(variables["data"].as<Files::PathContainer>());
|
||||
}
|
||||
|
||||
std::string local = variables["data-local"].as<std::string>();
|
||||
if (!local.empty()) {
|
||||
mDataLocal.push_back(Files::PathContainer::value_type(local));
|
||||
}
|
||||
|
||||
mCfgMgr.processPaths(mDataDirs);
|
||||
mCfgMgr.processPaths(mDataLocal);
|
||||
|
||||
// Second chance to display the warning, the data= entries are invalid
|
||||
while (mDataDirs.empty()) {
|
||||
if (!showDataFilesWarning())
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the charset for reading the esm/esp files
|
||||
QString encoding = QString::fromStdString(variables["encoding"].as<std::string>());
|
||||
|
||||
Files::PathContainer paths;
|
||||
paths.insert(paths.end(), mDataDirs.begin(), mDataDirs.end());
|
||||
paths.insert(paths.end(), mDataLocal.begin(), mDataLocal.end());
|
||||
mDataFilesList->setupDataFiles(paths, encoding);
|
||||
readConfig();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DataFilesPage::writeConfig(QString profile)
|
||||
{
|
||||
QString pathStr = QString::fromStdString(mCfgMgr.getUserPath().string());
|
||||
QDir userPath(pathStr);
|
||||
|
||||
if (!userPath.exists()) {
|
||||
if (!userPath.mkpath(pathStr)) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error creating OpenMW configuration directory");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not create %0</b><br><br> \
|
||||
Please make sure you have the right permissions and try again.<br>").arg(pathStr));
|
||||
msgBox.exec();
|
||||
|
||||
qApp->quit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Open the OpenMW config as a QFile
|
||||
QFile file(pathStr.append("openmw.cfg"));
|
||||
|
||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||
// File cannot be opened or created
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error writing OpenMW configuration file");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not open or create %0</b><br><br> \
|
||||
Please make sure you have the right permissions and try again.<br>").arg(file.fileName()));
|
||||
msgBox.exec();
|
||||
|
||||
qApp->quit();
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream in(&file);
|
||||
QByteArray buffer;
|
||||
|
||||
// Remove all previous entries from config
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine();
|
||||
if (!line.startsWith("master") &&
|
||||
!line.startsWith("plugin") &&
|
||||
!line.startsWith("data") &&
|
||||
!line.startsWith("data-local"))
|
||||
{
|
||||
buffer += line += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
// Now we write back the other config entries
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error writing OpenMW configuration file");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not write to %0</b><br><br> \
|
||||
Please make sure you have the right permissions and try again.<br>").arg(file.fileName()));
|
||||
msgBox.exec();
|
||||
|
||||
qApp->quit();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!buffer.isEmpty()) {
|
||||
file.write(buffer);
|
||||
}
|
||||
|
||||
QTextStream gameConfig(&file);
|
||||
|
||||
// First write the list of data dirs
|
||||
mCfgMgr.processPaths(mDataDirs);
|
||||
mCfgMgr.processPaths(mDataLocal);
|
||||
|
||||
QString path;
|
||||
|
||||
// data= directories
|
||||
for (Files::PathContainer::iterator it = mDataDirs.begin(); it != mDataDirs.end(); ++it) {
|
||||
path = QString::fromStdString(it->string());
|
||||
path.remove(QChar('\"'));
|
||||
|
||||
// Make sure the string is quoted when it contains spaces
|
||||
if (path.contains(" ")) {
|
||||
gameConfig << "data=\"" << path << "\"" << endl;
|
||||
} else {
|
||||
gameConfig << "data=" << path << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// data-local directory
|
||||
if (!mDataLocal.empty()) {
|
||||
path = QString::fromStdString(mDataLocal.front().string());
|
||||
path.remove(QChar('\"'));
|
||||
|
||||
if (path.contains(" ")) {
|
||||
gameConfig << "data-local=\"" << path << "\"" << endl;
|
||||
} else {
|
||||
gameConfig << "data-local=" << path << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (profile.isEmpty())
|
||||
profile = mProfilesComboBox->currentText();
|
||||
|
||||
if (profile.isEmpty())
|
||||
return;
|
||||
|
||||
// Make sure we have no groups open
|
||||
while (!mLauncherConfig->group().isEmpty()) {
|
||||
mLauncherConfig->endGroup();
|
||||
}
|
||||
|
||||
mLauncherConfig->beginGroup("Profiles");
|
||||
mLauncherConfig->setValue("CurrentProfile", profile);
|
||||
|
||||
// Open the profile-name subgroup
|
||||
mLauncherConfig->beginGroup(profile);
|
||||
mLauncherConfig->remove(""); // Clear the subgroup
|
||||
|
||||
// Now write the masters to the configs
|
||||
const QStringList checkedFiles = mDataFilesList->checkedFiles();
|
||||
for(int i=0; i < checkedFiles.size(); i++)
|
||||
{
|
||||
if (checkedFiles.at(i).lastIndexOf("esm") != -1)
|
||||
{
|
||||
mLauncherConfig->setValue(QString("Master%0").arg(i), checkedFiles.at(i));
|
||||
gameConfig << "master=" << checkedFiles.at(i) << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
mLauncherConfig->setValue(QString("Plugin%1").arg(i), checkedFiles.at(i));
|
||||
gameConfig << "plugin=" << checkedFiles.at(i) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
mLauncherConfig->endGroup();
|
||||
mLauncherConfig->endGroup();
|
||||
mLauncherConfig->sync();
|
||||
}
|
||||
|
||||
|
||||
void DataFilesPage::newProfile()
|
||||
{
|
||||
if (mNewProfileDialog->exec() == QDialog::Accepted) {
|
||||
|
||||
const QString text = mNewProfileDialog->lineEdit()->text();
|
||||
mProfilesComboBox->addItem(text);
|
||||
|
||||
// Copy the currently checked items to cfg
|
||||
writeConfig(text);
|
||||
mLauncherConfig->sync();
|
||||
|
||||
mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text));
|
||||
}
|
||||
}
|
||||
|
||||
void DataFilesPage::updateOkButton(const QString &text)
|
||||
{
|
||||
if (text.isEmpty()) {
|
||||
mNewProfileDialog->setOkButtonEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
(mProfilesComboBox->findText(text) == -1)
|
||||
? mNewProfileDialog->setOkButtonEnabled(true)
|
||||
: mNewProfileDialog->setOkButtonEnabled(false);
|
||||
}
|
||||
|
||||
void DataFilesPage::deleteProfile()
|
||||
{
|
||||
QString profile = mProfilesComboBox->currentText();
|
||||
|
||||
if (profile.isEmpty())
|
||||
return;
|
||||
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setWindowTitle(tr("Delete Profile"));
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setStandardButtons(QMessageBox::Cancel);
|
||||
msgBox.setText(tr("Are you sure you want to delete <b>%0</b>?").arg(profile));
|
||||
|
||||
QAbstractButton *deleteButton =
|
||||
msgBox.addButton(tr("Delete"), QMessageBox::ActionRole);
|
||||
|
||||
msgBox.exec();
|
||||
|
||||
if (msgBox.clickedButton() == deleteButton) {
|
||||
// Make sure we have no groups open
|
||||
while (!mLauncherConfig->group().isEmpty()) {
|
||||
mLauncherConfig->endGroup();
|
||||
}
|
||||
|
||||
mLauncherConfig->beginGroup("Profiles");
|
||||
|
||||
// Open the profile-name subgroup
|
||||
mLauncherConfig->beginGroup(profile);
|
||||
mLauncherConfig->remove(""); // Clear the subgroup
|
||||
mLauncherConfig->endGroup();
|
||||
mLauncherConfig->endGroup();
|
||||
|
||||
// Remove the profile from the combobox
|
||||
mProfilesComboBox->removeItem(mProfilesComboBox->findText(profile));
|
||||
}
|
||||
}
|
||||
|
||||
void DataFilesPage::profileChanged(const QString &previous, const QString ¤t)
|
||||
{
|
||||
qDebug() << "Profile is changed from: " << previous << " to " << current;
|
||||
// Prevent the deletion of the default profile
|
||||
if (current == QLatin1String("Default")) {
|
||||
mDeleteProfileAction->setEnabled(false);
|
||||
mProfilesComboBox->setEditEnabled(false);
|
||||
} else {
|
||||
mDeleteProfileAction->setEnabled(true);
|
||||
mProfilesComboBox->setEditEnabled(true);
|
||||
}
|
||||
|
||||
if (!previous.isEmpty()) {
|
||||
writeConfig(previous);
|
||||
mLauncherConfig->sync();
|
||||
|
||||
if (mProfilesComboBox->currentIndex() == -1)
|
||||
return;
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
mDataFilesList->uncheckAll();
|
||||
readConfig();
|
||||
}
|
||||
|
||||
void DataFilesPage::profileRenamed(const QString &previous, const QString ¤t)
|
||||
{
|
||||
if (previous.isEmpty())
|
||||
return;
|
||||
|
||||
// Save the new profile name
|
||||
writeConfig(current);
|
||||
|
||||
// Make sure we have no groups open
|
||||
while (!mLauncherConfig->group().isEmpty()) {
|
||||
mLauncherConfig->endGroup();
|
||||
}
|
||||
|
||||
mLauncherConfig->beginGroup("Profiles");
|
||||
|
||||
// Open the profile-name subgroup
|
||||
mLauncherConfig->beginGroup(previous);
|
||||
mLauncherConfig->remove(""); // Clear the subgroup
|
||||
mLauncherConfig->endGroup();
|
||||
mLauncherConfig->endGroup();
|
||||
mLauncherConfig->sync();
|
||||
|
||||
// Remove the profile from the combobox
|
||||
mProfilesComboBox->removeItem(mProfilesComboBox->findText(previous));
|
||||
|
||||
mDataFilesList->uncheckAll();
|
||||
////mMastersModel->uncheckAll();
|
||||
////mPluginsModel->uncheckAll();
|
||||
readConfig();
|
||||
}
|
80
apps/launcher/datafilespage.hpp
Normal file
80
apps/launcher/datafilespage.hpp
Normal file
@ -0,0 +1,80 @@
|
||||
#ifndef DATAFILESPAGE_H
|
||||
#define DATAFILESPAGE_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QModelIndex>
|
||||
#include "utils/profilescombobox.hpp"
|
||||
#include <components/files/collections.hpp>
|
||||
|
||||
|
||||
class QTableView;
|
||||
class QSortFilterProxyModel;
|
||||
class QSettings;
|
||||
class QAction;
|
||||
class QToolBar;
|
||||
class QMenu;
|
||||
class ProfilesComboBox;
|
||||
class DataFilesModel;
|
||||
|
||||
class TextInputDialog;
|
||||
class DataFilesList;
|
||||
|
||||
namespace Files { struct ConfigurationManager; }
|
||||
|
||||
class DataFilesPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DataFilesPage(Files::ConfigurationManager& cfg, QWidget *parent = 0);
|
||||
|
||||
ProfilesComboBox *mProfilesComboBox;
|
||||
|
||||
void writeConfig(QString profile = QString());
|
||||
bool showDataFilesWarning();
|
||||
bool setupDataFiles();
|
||||
|
||||
public slots:
|
||||
void profileChanged(const QString &previous, const QString ¤t);
|
||||
void profileRenamed(const QString &previous, const QString ¤t);
|
||||
void updateOkButton(const QString &text);
|
||||
|
||||
// Action slots
|
||||
void newProfile();
|
||||
void deleteProfile();
|
||||
// void moveUp();
|
||||
// void moveDown();
|
||||
// void moveTop();
|
||||
// void moveBottom();
|
||||
|
||||
private:
|
||||
DataFilesList *mDataFilesList;
|
||||
|
||||
QToolBar *mProfileToolBar;
|
||||
|
||||
QAction *mNewProfileAction;
|
||||
QAction *mDeleteProfileAction;
|
||||
|
||||
// QAction *mMoveUpAction;
|
||||
// QAction *mMoveDownAction;
|
||||
// QAction *mMoveTopAction;
|
||||
// QAction *mMoveBottomAction;
|
||||
|
||||
Files::ConfigurationManager &mCfgMgr;
|
||||
Files::PathContainer mDataDirs;
|
||||
Files::PathContainer mDataLocal;
|
||||
|
||||
QSettings *mLauncherConfig;
|
||||
|
||||
TextInputDialog *mNewProfileDialog;
|
||||
|
||||
// const QStringList checkedPlugins();
|
||||
// const QStringList selectedMasters();
|
||||
|
||||
void createActions();
|
||||
void setupConfig();
|
||||
void readConfig();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@ -1,10 +1,9 @@
|
||||
#include <QtGui>
|
||||
|
||||
#include <components/fileorderlist/datafileslist.hpp>
|
||||
|
||||
#include "maindialog.hpp"
|
||||
#include "playpage.hpp"
|
||||
#include "graphicspage.hpp"
|
||||
#include "datafilespage.hpp"
|
||||
|
||||
MainDialog::MainDialog()
|
||||
{
|
||||
@ -124,16 +123,16 @@ void MainDialog::createPages()
|
||||
{
|
||||
mPlayPage = new PlayPage(this);
|
||||
mGraphicsPage = new GraphicsPage(mCfgMgr, this);
|
||||
mDataFilesList = new DataFilesList(mCfgMgr, this);
|
||||
mDataFilesPage = new DataFilesPage(mCfgMgr, this);
|
||||
|
||||
// Set the combobox of the play page to imitate the combobox on the datafilespage
|
||||
mPlayPage->mProfilesComboBox->setModel(mDataFilesList->mProfilesComboBox->model());
|
||||
mPlayPage->mProfilesComboBox->setCurrentIndex(mDataFilesList->mProfilesComboBox->currentIndex());
|
||||
mPlayPage->mProfilesComboBox->setModel(mDataFilesPage->mProfilesComboBox->model());
|
||||
mPlayPage->mProfilesComboBox->setCurrentIndex(mDataFilesPage->mProfilesComboBox->currentIndex());
|
||||
|
||||
// Add the pages to the stacked widget
|
||||
mPagesWidget->addWidget(mPlayPage);
|
||||
mPagesWidget->addWidget(mGraphicsPage);
|
||||
mPagesWidget->addWidget(mDataFilesList);
|
||||
mPagesWidget->addWidget(mDataFilesPage);
|
||||
|
||||
// Select the first page
|
||||
mIconWidget->setCurrentItem(mIconWidget->item(0), QItemSelectionModel::Select);
|
||||
@ -142,9 +141,9 @@ void MainDialog::createPages()
|
||||
|
||||
connect(mPlayPage->mProfilesComboBox,
|
||||
SIGNAL(currentIndexChanged(int)),
|
||||
mDataFilesList->mProfilesComboBox, SLOT(setCurrentIndex(int)));
|
||||
mDataFilesPage->mProfilesComboBox, SLOT(setCurrentIndex(int)));
|
||||
|
||||
connect(mDataFilesList->mProfilesComboBox,
|
||||
connect(mDataFilesPage->mProfilesComboBox,
|
||||
SIGNAL(currentIndexChanged(int)),
|
||||
mPlayPage->mProfilesComboBox, SLOT(setCurrentIndex(int)));
|
||||
|
||||
@ -190,7 +189,7 @@ bool MainDialog::setup()
|
||||
}
|
||||
|
||||
// Setup the Data Files page
|
||||
if (!mDataFilesList->setupDataFiles()) {
|
||||
if (!mDataFilesPage->setupDataFiles()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -208,7 +207,7 @@ void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous)
|
||||
void MainDialog::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
// Now write all config files
|
||||
mDataFilesList->writeConfig();
|
||||
mDataFilesPage->writeConfig();
|
||||
mGraphicsPage->writeConfig();
|
||||
|
||||
// Save user settings
|
||||
@ -221,7 +220,7 @@ void MainDialog::closeEvent(QCloseEvent *event)
|
||||
void MainDialog::play()
|
||||
{
|
||||
// First do a write of all the configs, just to be sure
|
||||
mDataFilesList->writeConfig();
|
||||
mDataFilesPage->writeConfig();
|
||||
mGraphicsPage->writeConfig();
|
||||
|
||||
// Save user settings
|
||||
|
@ -15,7 +15,7 @@ class QString;
|
||||
|
||||
class PlayPage;
|
||||
class GraphicsPage;
|
||||
class DataFilesList;
|
||||
class DataFilesPage;
|
||||
|
||||
class MainDialog : public QMainWindow
|
||||
{
|
||||
@ -39,7 +39,7 @@ private:
|
||||
|
||||
PlayPage *mPlayPage;
|
||||
GraphicsPage *mGraphicsPage;
|
||||
DataFilesList *mDataFilesList;
|
||||
DataFilesPage *mDataFilesPage;
|
||||
|
||||
Files::ConfigurationManager mCfgMgr;
|
||||
Settings::Manager mSettings;
|
||||
|
@ -10,7 +10,42 @@ OpenDialog::OpenDialog(QWidget * parent) : QDialog(parent)
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
mFileSelector = new DataFilesList(mCfgMgr, this);
|
||||
layout->addWidget(mFileSelector);
|
||||
mFileSelector->setupDataFiles();
|
||||
|
||||
//FIXME - same as DataFilesPage::setupDataFiles
|
||||
// We use the Configuration Manager to retrieve the configuration values
|
||||
boost::program_options::variables_map variables;
|
||||
boost::program_options::options_description desc;
|
||||
|
||||
desc.add_options()
|
||||
("data", boost::program_options::value<Files::PathContainer>()->default_value(Files::PathContainer(), "data")->multitoken())
|
||||
("data-local", boost::program_options::value<std::string>()->default_value(""))
|
||||
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false))
|
||||
("encoding", boost::program_options::value<std::string>()->default_value("win1252"));
|
||||
|
||||
boost::program_options::notify(variables);
|
||||
|
||||
mCfgMgr.readConfiguration(variables, desc);
|
||||
|
||||
Files::PathContainer mDataDirs, mDataLocal;
|
||||
if (!variables["data"].empty()) {
|
||||
mDataDirs = Files::PathContainer(variables["data"].as<Files::PathContainer>());
|
||||
}
|
||||
|
||||
std::string local = variables["data-local"].as<std::string>();
|
||||
if (!local.empty()) {
|
||||
mDataLocal.push_back(Files::PathContainer::value_type(local));
|
||||
}
|
||||
|
||||
mCfgMgr.processPaths(mDataDirs);
|
||||
mCfgMgr.processPaths(mDataLocal);
|
||||
|
||||
// Set the charset for reading the esm/esp files
|
||||
QString encoding = QString::fromStdString(variables["encoding"].as<std::string>());
|
||||
|
||||
Files::PathContainer dataDirs;
|
||||
dataDirs.insert(dataDirs.end(), mDataDirs.begin(), mDataDirs.end());
|
||||
dataDirs.insert(dataDirs.end(), mDataLocal.begin(), mDataLocal.end());
|
||||
mFileSelector->setupDataFiles(dataDirs, encoding);
|
||||
|
||||
buttonBox = new QDialogButtonBox(QDialogButtonBox::Open | QDialogButtonBox::Cancel, Qt::Horizontal, this);
|
||||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
@ -23,5 +58,5 @@ OpenDialog::OpenDialog(QWidget * parent) : QDialog(parent)
|
||||
|
||||
void OpenDialog::getFileList(std::vector<boost::filesystem::path>& paths)
|
||||
{
|
||||
mFileSelector->getSelectedFiles(paths);
|
||||
mFileSelector->selectedFiles(paths);
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ find_package(Qt4 COMPONENTS QtCore QtGui)
|
||||
if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY)
|
||||
add_component_qt_dir (fileorderlist
|
||||
datafileslist model/modelitem model/datafilesmodel model/esm/esmfile
|
||||
utils/filedialog utils/lineedit utils/profilescombobox utils/textinputdialog utils/naturalsort
|
||||
utils/filedialog utils/lineedit utils/naturalsort
|
||||
)
|
||||
|
||||
include(${QT_USE_FILE})
|
||||
|
@ -6,11 +6,9 @@
|
||||
#include "model/datafilesmodel.hpp"
|
||||
#include "model/esm/esmfile.hpp"
|
||||
|
||||
#include "utils/profilescombobox.hpp"
|
||||
#include "utils/filedialog.hpp"
|
||||
#include "utils/lineedit.hpp"
|
||||
#include "utils/naturalsort.hpp"
|
||||
#include "utils/textinputdialog.hpp"
|
||||
|
||||
#include "datafileslist.hpp"
|
||||
|
||||
@ -137,32 +135,10 @@ DataFilesList::DataFilesList(Files::ConfigurationManager &cfg, QWidget *parent)
|
||||
sizeList << 175 << 200;
|
||||
splitter->setSizes(sizeList);
|
||||
|
||||
// Bottom part with profile options
|
||||
QLabel *profileLabel = new QLabel(tr("Current Profile: "), this);
|
||||
|
||||
mProfilesComboBox = new ProfilesComboBox(this);
|
||||
mProfilesComboBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));
|
||||
mProfilesComboBox->setInsertPolicy(QComboBox::NoInsert);
|
||||
mProfilesComboBox->setDuplicatesEnabled(false);
|
||||
mProfilesComboBox->setEditEnabled(false);
|
||||
|
||||
mProfileToolBar = new QToolBar(this);
|
||||
mProfileToolBar->setMovable(false);
|
||||
mProfileToolBar->setIconSize(QSize(16, 16));
|
||||
|
||||
mProfileToolBar->addWidget(profileLabel);
|
||||
mProfileToolBar->addWidget(mProfilesComboBox);
|
||||
|
||||
QVBoxLayout *pageLayout = new QVBoxLayout(this);
|
||||
|
||||
pageLayout->addWidget(filterToolBar);
|
||||
pageLayout->addWidget(splitter);
|
||||
pageLayout->addWidget(mProfileToolBar);
|
||||
|
||||
// Create a dialog for the new profile name input
|
||||
mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this);
|
||||
|
||||
connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString)));
|
||||
|
||||
connect(mPluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
|
||||
connect(mMastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
|
||||
@ -173,11 +149,7 @@ DataFilesList::DataFilesList(Files::ConfigurationManager &cfg, QWidget *parent)
|
||||
|
||||
connect(mPluginsTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
|
||||
|
||||
connect(mProfilesComboBox, SIGNAL(profileRenamed(QString,QString)), this, SLOT(profileRenamed(QString,QString)));
|
||||
connect(mProfilesComboBox, SIGNAL(profileChanged(QString,QString)), this, SLOT(profileChanged(QString,QString)));
|
||||
|
||||
createActions();
|
||||
setupConfig();
|
||||
}
|
||||
|
||||
void DataFilesList::createActions()
|
||||
@ -187,22 +159,6 @@ void DataFilesList::createActions()
|
||||
refreshAction->setShortcut(QKeySequence(tr("F5")));
|
||||
connect(refreshAction, SIGNAL(triggered()), this, SLOT(refresh()));
|
||||
|
||||
// Profile actions
|
||||
mNewProfileAction = new QAction(QIcon::fromTheme("document-new"), tr("&New Profile"), this);
|
||||
mNewProfileAction->setToolTip(tr("New Profile"));
|
||||
mNewProfileAction->setShortcut(QKeySequence(tr("Ctrl+N")));
|
||||
connect(mNewProfileAction, SIGNAL(triggered()), this, SLOT(newProfile()));
|
||||
|
||||
mDeleteProfileAction = new QAction(QIcon::fromTheme("edit-delete"), tr("Delete Profile"), this);
|
||||
mDeleteProfileAction->setToolTip(tr("Delete Profile"));
|
||||
mDeleteProfileAction->setShortcut(QKeySequence(tr("Delete")));
|
||||
connect(mDeleteProfileAction, SIGNAL(triggered()), this, SLOT(deleteProfile()));
|
||||
|
||||
// Add the newly created actions to the toolbar
|
||||
mProfileToolBar->addSeparator();
|
||||
mProfileToolBar->addAction(mNewProfileAction);
|
||||
mProfileToolBar->addAction(mDeleteProfileAction);
|
||||
|
||||
// Context menu actions
|
||||
mCheckAction = new QAction(tr("Check selected"), this);
|
||||
connect(mCheckAction, SIGNAL(triggered()), this, SLOT(check()));
|
||||
@ -218,223 +174,16 @@ void DataFilesList::createActions()
|
||||
|
||||
}
|
||||
|
||||
void DataFilesList::setupConfig()
|
||||
bool DataFilesList::setupDataFiles(Files::PathContainer dataDirs, const QString encoding)
|
||||
{
|
||||
// Open our config file
|
||||
QString config = QString::fromStdString((mCfgMgr.getUserPath() / "launcher.cfg").string());
|
||||
mLauncherConfig = new QSettings(config, QSettings::IniFormat);
|
||||
|
||||
// Make sure we have no groups open
|
||||
while (!mLauncherConfig->group().isEmpty()) {
|
||||
mLauncherConfig->endGroup();
|
||||
}
|
||||
|
||||
mLauncherConfig->beginGroup("Profiles");
|
||||
QStringList profiles = mLauncherConfig->childGroups();
|
||||
|
||||
// Add the profiles to the combobox
|
||||
foreach (const QString &profile, profiles) {
|
||||
|
||||
if (profile.contains(QRegExp("[^a-zA-Z0-9_]")))
|
||||
continue; // Profile name contains garbage
|
||||
|
||||
|
||||
qDebug() << "adding " << profile;
|
||||
mProfilesComboBox->addItem(profile);
|
||||
}
|
||||
|
||||
// Add a default profile
|
||||
if (mProfilesComboBox->findText(QString("Default")) == -1) {
|
||||
mProfilesComboBox->addItem(QString("Default"));
|
||||
}
|
||||
|
||||
QString currentProfile = mLauncherConfig->value("CurrentProfile").toString();
|
||||
|
||||
if (currentProfile.isEmpty()) {
|
||||
// No current profile selected
|
||||
currentProfile = "Default";
|
||||
}
|
||||
|
||||
const int currentIndex = mProfilesComboBox->findText(currentProfile);
|
||||
if (currentIndex != -1) {
|
||||
// Profile is found
|
||||
mProfilesComboBox->setCurrentIndex(currentIndex);
|
||||
}
|
||||
|
||||
mLauncherConfig->endGroup();
|
||||
}
|
||||
|
||||
|
||||
void DataFilesList::readConfig()
|
||||
{
|
||||
// Don't read the config if no masters are found
|
||||
if (mMastersModel->rowCount() < 1)
|
||||
return;
|
||||
|
||||
QString profile = mProfilesComboBox->currentText();
|
||||
|
||||
// Make sure we have no groups open
|
||||
while (!mLauncherConfig->group().isEmpty()) {
|
||||
mLauncherConfig->endGroup();
|
||||
}
|
||||
|
||||
mLauncherConfig->beginGroup("Profiles");
|
||||
mLauncherConfig->beginGroup(profile);
|
||||
|
||||
QStringList childKeys = mLauncherConfig->childKeys();
|
||||
QStringList plugins;
|
||||
|
||||
// Sort the child keys numerical instead of alphabetically
|
||||
// i.e. Plugin1, Plugin2 instead of Plugin1, Plugin10
|
||||
qSort(childKeys.begin(), childKeys.end(), naturalSortLessThanCI);
|
||||
|
||||
foreach (const QString &key, childKeys) {
|
||||
const QString keyValue = mLauncherConfig->value(key).toString();
|
||||
|
||||
if (key.startsWith("Plugin")) {
|
||||
//QStringList checked = mPluginsModel->checkedItems();
|
||||
EsmFile *file = mPluginsModel->findItem(keyValue);
|
||||
QModelIndex index = mPluginsModel->indexFromItem(file);
|
||||
|
||||
mPluginsModel->setCheckState(index, Qt::Checked);
|
||||
// Move the row to the top of te view
|
||||
//mPluginsModel->moveRow(index.row(), checked.count());
|
||||
plugins << keyValue;
|
||||
}
|
||||
|
||||
if (key.startsWith("Master")) {
|
||||
EsmFile *file = mMastersModel->findItem(keyValue);
|
||||
mMastersModel->setCheckState(mMastersModel->indexFromItem(file), Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << plugins;
|
||||
|
||||
|
||||
// // Set the checked item positions
|
||||
// const QStringList checked = mPluginsModel->checkedItems();
|
||||
// for (int i = 0; i < plugins.size(); ++i) {
|
||||
// EsmFile *file = mPluginsModel->findItem(plugins.at(i));
|
||||
// QModelIndex index = mPluginsModel->indexFromItem(file);
|
||||
// mPluginsModel->moveRow(index.row(), i);
|
||||
// qDebug() << "Moving: " << plugins.at(i) << " from: " << index.row() << " to: " << i << " count: " << checked.count();
|
||||
|
||||
// }
|
||||
|
||||
// Iterate over the plugins to set their checkstate and position
|
||||
// for (int i = 0; i < plugins.size(); ++i) {
|
||||
// const QString plugin = plugins.at(i);
|
||||
|
||||
// const QList<QStandardItem *> pluginList = mPluginsModel->findItems(plugin);
|
||||
|
||||
// if (!pluginList.isEmpty())
|
||||
// {
|
||||
// foreach (const QStandardItem *currentPlugin, pluginList) {
|
||||
// mPluginsModel->setData(currentPlugin->index(), Qt::Checked, Qt::CheckStateRole);
|
||||
|
||||
// // Move the plugin to the position specified in the config file
|
||||
// mPluginsModel->insertRow(i, mPluginsModel->takeRow(currentPlugin->row()));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
bool DataFilesList::showDataFilesWarning()
|
||||
{
|
||||
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error detecting Morrowind installation");
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setStandardButtons(QMessageBox::Cancel);
|
||||
msgBox.setText(tr("<br><b>Could not find the Data Files location</b><br><br> \
|
||||
The directory containing the data files was not found.<br><br> \
|
||||
Press \"Browse...\" to specify the location manually.<br>"));
|
||||
|
||||
QAbstractButton *dirSelectButton =
|
||||
msgBox.addButton(tr("B&rowse..."), QMessageBox::ActionRole);
|
||||
|
||||
msgBox.exec();
|
||||
|
||||
if (msgBox.clickedButton() == dirSelectButton) {
|
||||
|
||||
// Show a custom dir selection dialog which only accepts valid dirs
|
||||
QString selectedDir = FileDialog::getExistingDirectory(
|
||||
this, tr("Select Data Files Directory"),
|
||||
QDir::currentPath(),
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
|
||||
// Add the user selected data directory
|
||||
if (!selectedDir.isEmpty()) {
|
||||
mDataDirs.push_back(Files::PathContainer::value_type(selectedDir.toStdString()));
|
||||
mCfgMgr.processPaths(mDataDirs);
|
||||
} else {
|
||||
// Cancel from within the dir selection dialog
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Cancel
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DataFilesList::setupDataFiles()
|
||||
{
|
||||
// We use the Configuration Manager to retrieve the configuration values
|
||||
boost::program_options::variables_map variables;
|
||||
boost::program_options::options_description desc;
|
||||
|
||||
desc.add_options()
|
||||
("data", boost::program_options::value<Files::PathContainer>()->default_value(Files::PathContainer(), "data")->multitoken())
|
||||
("data-local", boost::program_options::value<std::string>()->default_value(""))
|
||||
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false))
|
||||
("encoding", boost::program_options::value<std::string>()->default_value("win1252"));
|
||||
|
||||
boost::program_options::notify(variables);
|
||||
|
||||
mCfgMgr.readConfiguration(variables, desc);
|
||||
|
||||
if (variables["data"].empty()) {
|
||||
if (!showDataFilesWarning())
|
||||
return false;
|
||||
} else {
|
||||
mDataDirs = Files::PathContainer(variables["data"].as<Files::PathContainer>());
|
||||
}
|
||||
|
||||
std::string local = variables["data-local"].as<std::string>();
|
||||
if (!local.empty()) {
|
||||
mDataLocal.push_back(Files::PathContainer::value_type(local));
|
||||
}
|
||||
|
||||
mCfgMgr.processPaths(mDataDirs);
|
||||
mCfgMgr.processPaths(mDataLocal);
|
||||
|
||||
// Second chance to display the warning, the data= entries are invalid
|
||||
while (mDataDirs.empty()) {
|
||||
if (!showDataFilesWarning())
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the charset for reading the esm/esp files
|
||||
QString encoding = QString::fromStdString(variables["encoding"].as<std::string>());
|
||||
if (!encoding.isEmpty() && encoding != QLatin1String("win1252")) {
|
||||
mMastersModel->setEncoding(encoding);
|
||||
mPluginsModel->setEncoding(encoding);
|
||||
}
|
||||
|
||||
// Add the paths to the respective models
|
||||
for (Files::PathContainer::iterator it = mDataDirs.begin(); it != mDataDirs.end(); ++it) {
|
||||
QString path = QString::fromStdString(it->string());
|
||||
path.remove(QChar('\"'));
|
||||
mMastersModel->addMasters(path);
|
||||
mPluginsModel->addPlugins(path);
|
||||
}
|
||||
|
||||
// Same for the data-local paths
|
||||
for (Files::PathContainer::iterator it = mDataLocal.begin(); it != mDataLocal.end(); ++it) {
|
||||
for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) {
|
||||
QString path = QString::fromStdString(it->string());
|
||||
path.remove(QChar('\"'));
|
||||
mMastersModel->addMasters(path);
|
||||
@ -446,12 +195,10 @@ bool DataFilesList::setupDataFiles()
|
||||
// mMastersTable->sortByColumn(3, Qt::AscendingOrder);
|
||||
// mPluginsTable->sortByColumn(3, Qt::AscendingOrder);
|
||||
|
||||
|
||||
readConfig();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DataFilesList::getSelectedFiles(std::vector<boost::filesystem::path>& paths)
|
||||
void DataFilesList::selectedFiles(std::vector<boost::filesystem::path>& paths)
|
||||
{
|
||||
QStringList masterPaths = mMastersModel->checkedItemsPaths();
|
||||
foreach (const QString &path, masterPaths)
|
||||
@ -467,225 +214,6 @@ void DataFilesList::getSelectedFiles(std::vector<boost::filesystem::path>& paths
|
||||
}
|
||||
}
|
||||
|
||||
void DataFilesList::writeConfig(QString profile)
|
||||
{
|
||||
// Don't overwrite the config if no masters are found
|
||||
if (mMastersModel->rowCount() < 1)
|
||||
return;
|
||||
|
||||
QString pathStr = QString::fromStdString(mCfgMgr.getUserPath().string());
|
||||
QDir userPath(pathStr);
|
||||
|
||||
if (!userPath.exists()) {
|
||||
if (!userPath.mkpath(pathStr)) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error creating OpenMW configuration directory");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not create %0</b><br><br> \
|
||||
Please make sure you have the right permissions and try again.<br>").arg(pathStr));
|
||||
msgBox.exec();
|
||||
|
||||
qApp->quit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Open the OpenMW config as a QFile
|
||||
QFile file(pathStr.append("openmw.cfg"));
|
||||
|
||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||
// File cannot be opened or created
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error writing OpenMW configuration file");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not open or create %0</b><br><br> \
|
||||
Please make sure you have the right permissions and try again.<br>").arg(file.fileName()));
|
||||
msgBox.exec();
|
||||
|
||||
qApp->quit();
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream in(&file);
|
||||
QByteArray buffer;
|
||||
|
||||
// Remove all previous entries from config
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine();
|
||||
if (!line.startsWith("master") &&
|
||||
!line.startsWith("plugin") &&
|
||||
!line.startsWith("data") &&
|
||||
!line.startsWith("data-local"))
|
||||
{
|
||||
buffer += line += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
// Now we write back the other config entries
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error writing OpenMW configuration file");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not write to %0</b><br><br> \
|
||||
Please make sure you have the right permissions and try again.<br>").arg(file.fileName()));
|
||||
msgBox.exec();
|
||||
|
||||
qApp->quit();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!buffer.isEmpty()) {
|
||||
file.write(buffer);
|
||||
}
|
||||
|
||||
QTextStream gameConfig(&file);
|
||||
|
||||
// First write the list of data dirs
|
||||
mCfgMgr.processPaths(mDataDirs);
|
||||
mCfgMgr.processPaths(mDataLocal);
|
||||
|
||||
QString path;
|
||||
|
||||
// data= directories
|
||||
for (Files::PathContainer::iterator it = mDataDirs.begin(); it != mDataDirs.end(); ++it) {
|
||||
path = QString::fromStdString(it->string());
|
||||
path.remove(QChar('\"'));
|
||||
|
||||
// Make sure the string is quoted when it contains spaces
|
||||
if (path.contains(" ")) {
|
||||
gameConfig << "data=\"" << path << "\"" << endl;
|
||||
} else {
|
||||
gameConfig << "data=" << path << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// data-local directory
|
||||
if (!mDataLocal.empty()) {
|
||||
path = QString::fromStdString(mDataLocal.front().string());
|
||||
path.remove(QChar('\"'));
|
||||
|
||||
if (path.contains(" ")) {
|
||||
gameConfig << "data-local=\"" << path << "\"" << endl;
|
||||
} else {
|
||||
gameConfig << "data-local=" << path << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (profile.isEmpty())
|
||||
profile = mProfilesComboBox->currentText();
|
||||
|
||||
if (profile.isEmpty())
|
||||
return;
|
||||
|
||||
// Make sure we have no groups open
|
||||
while (!mLauncherConfig->group().isEmpty()) {
|
||||
mLauncherConfig->endGroup();
|
||||
}
|
||||
|
||||
mLauncherConfig->beginGroup("Profiles");
|
||||
mLauncherConfig->setValue("CurrentProfile", profile);
|
||||
|
||||
// Open the profile-name subgroup
|
||||
mLauncherConfig->beginGroup(profile);
|
||||
mLauncherConfig->remove(""); // Clear the subgroup
|
||||
|
||||
// Now write the masters to the configs
|
||||
const QStringList masters = mMastersModel->checkedItems();
|
||||
|
||||
// We don't use foreach because we need i
|
||||
for (int i = 0; i < masters.size(); ++i) {
|
||||
const QString currentMaster = masters.at(i);
|
||||
|
||||
mLauncherConfig->setValue(QString("Master%0").arg(i), currentMaster);
|
||||
gameConfig << "master=" << currentMaster << endl;
|
||||
|
||||
}
|
||||
|
||||
// And finally write all checked plugins
|
||||
const QStringList plugins = mPluginsModel->checkedItems();
|
||||
|
||||
for (int i = 0; i < plugins.size(); ++i) {
|
||||
const QString currentPlugin = plugins.at(i);
|
||||
mLauncherConfig->setValue(QString("Plugin%1").arg(i), currentPlugin);
|
||||
gameConfig << "plugin=" << currentPlugin << endl;
|
||||
}
|
||||
|
||||
file.close();
|
||||
mLauncherConfig->endGroup();
|
||||
mLauncherConfig->endGroup();
|
||||
mLauncherConfig->sync();
|
||||
}
|
||||
|
||||
|
||||
void DataFilesList::newProfile()
|
||||
{
|
||||
if (mNewProfileDialog->exec() == QDialog::Accepted) {
|
||||
|
||||
const QString text = mNewProfileDialog->lineEdit()->text();
|
||||
mProfilesComboBox->addItem(text);
|
||||
|
||||
// Copy the currently checked items to cfg
|
||||
writeConfig(text);
|
||||
mLauncherConfig->sync();
|
||||
|
||||
mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text));
|
||||
}
|
||||
}
|
||||
|
||||
void DataFilesList::updateOkButton(const QString &text)
|
||||
{
|
||||
if (text.isEmpty()) {
|
||||
mNewProfileDialog->setOkButtonEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
(mProfilesComboBox->findText(text) == -1)
|
||||
? mNewProfileDialog->setOkButtonEnabled(true)
|
||||
: mNewProfileDialog->setOkButtonEnabled(false);
|
||||
}
|
||||
|
||||
void DataFilesList::deleteProfile()
|
||||
{
|
||||
QString profile = mProfilesComboBox->currentText();
|
||||
|
||||
if (profile.isEmpty())
|
||||
return;
|
||||
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setWindowTitle(tr("Delete Profile"));
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setStandardButtons(QMessageBox::Cancel);
|
||||
msgBox.setText(tr("Are you sure you want to delete <b>%0</b>?").arg(profile));
|
||||
|
||||
QAbstractButton *deleteButton =
|
||||
msgBox.addButton(tr("Delete"), QMessageBox::ActionRole);
|
||||
|
||||
msgBox.exec();
|
||||
|
||||
if (msgBox.clickedButton() == deleteButton) {
|
||||
// Make sure we have no groups open
|
||||
while (!mLauncherConfig->group().isEmpty()) {
|
||||
mLauncherConfig->endGroup();
|
||||
}
|
||||
|
||||
mLauncherConfig->beginGroup("Profiles");
|
||||
|
||||
// Open the profile-name subgroup
|
||||
mLauncherConfig->beginGroup(profile);
|
||||
mLauncherConfig->remove(""); // Clear the subgroup
|
||||
mLauncherConfig->endGroup();
|
||||
mLauncherConfig->endGroup();
|
||||
|
||||
// Remove the profile from the combobox
|
||||
mProfilesComboBox->removeItem(mProfilesComboBox->findText(profile));
|
||||
}
|
||||
}
|
||||
|
||||
void DataFilesList::check()
|
||||
{
|
||||
// Check the current selection
|
||||
@ -733,8 +261,6 @@ void DataFilesList::refresh()
|
||||
|
||||
// Refresh the plugins table
|
||||
mPluginsTable->scrollToTop();
|
||||
writeConfig();
|
||||
readConfig();
|
||||
}
|
||||
|
||||
|
||||
@ -767,70 +293,18 @@ void DataFilesList::setCheckState(QModelIndex index)
|
||||
|
||||
}
|
||||
|
||||
void DataFilesList::uncheckAll()
|
||||
{
|
||||
mMastersModel->uncheckAll();
|
||||
mPluginsModel->uncheckAll();
|
||||
}
|
||||
|
||||
void DataFilesList::filterChanged(const QString filter)
|
||||
{
|
||||
QRegExp regExp(filter, Qt::CaseInsensitive, QRegExp::FixedString);
|
||||
mPluginsProxyModel->setFilterRegExp(regExp);
|
||||
}
|
||||
|
||||
void DataFilesList::profileChanged(const QString &previous, const QString ¤t)
|
||||
{
|
||||
qDebug() << "Profile is changed from: " << previous << " to " << current;
|
||||
// Prevent the deletion of the default profile
|
||||
if (current == QLatin1String("Default")) {
|
||||
mDeleteProfileAction->setEnabled(false);
|
||||
mProfilesComboBox->setEditEnabled(false);
|
||||
} else {
|
||||
mDeleteProfileAction->setEnabled(true);
|
||||
mProfilesComboBox->setEditEnabled(true);
|
||||
}
|
||||
|
||||
if (!previous.isEmpty()) {
|
||||
writeConfig(previous);
|
||||
mLauncherConfig->sync();
|
||||
|
||||
if (mProfilesComboBox->currentIndex() == -1)
|
||||
return;
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
mMastersModel->uncheckAll();
|
||||
mPluginsModel->uncheckAll();
|
||||
readConfig();
|
||||
}
|
||||
|
||||
void DataFilesList::profileRenamed(const QString &previous, const QString ¤t)
|
||||
{
|
||||
if (previous.isEmpty())
|
||||
return;
|
||||
|
||||
// Save the new profile name
|
||||
writeConfig(current);
|
||||
|
||||
// Make sure we have no groups open
|
||||
while (!mLauncherConfig->group().isEmpty()) {
|
||||
mLauncherConfig->endGroup();
|
||||
}
|
||||
|
||||
mLauncherConfig->beginGroup("Profiles");
|
||||
|
||||
// Open the profile-name subgroup
|
||||
mLauncherConfig->beginGroup(previous);
|
||||
mLauncherConfig->remove(""); // Clear the subgroup
|
||||
mLauncherConfig->endGroup();
|
||||
mLauncherConfig->endGroup();
|
||||
mLauncherConfig->sync();
|
||||
|
||||
// Remove the profile from the combobox
|
||||
mProfilesComboBox->removeItem(mProfilesComboBox->findText(previous));
|
||||
|
||||
mMastersModel->uncheckAll();
|
||||
mPluginsModel->uncheckAll();
|
||||
readConfig();
|
||||
}
|
||||
|
||||
void DataFilesList::showContextMenu(const QPoint &point)
|
||||
{
|
||||
// Make sure there are plugins in the view
|
||||
@ -858,3 +332,22 @@ void DataFilesList::showContextMenu(const QPoint &point)
|
||||
// Show menu
|
||||
mContextMenu->exec(globalPos);
|
||||
}
|
||||
|
||||
void DataFilesList::setCheckState(const QString& element, Qt::CheckState state)
|
||||
{
|
||||
EsmFile *file = mPluginsModel->findItem(element);
|
||||
if (file)
|
||||
{
|
||||
mPluginsModel->setCheckState(mPluginsModel->indexFromItem(file), Qt::Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
file = mMastersModel->findItem(element);
|
||||
mMastersModel->setCheckState(mMastersModel->indexFromItem(file), Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList DataFilesList::checkedFiles()
|
||||
{
|
||||
return mMastersModel->checkedItems() + mPluginsModel->checkedItems();
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include <QWidget>
|
||||
#include <QModelIndex>
|
||||
#include "utils/profilescombobox.hpp"
|
||||
#include <components/files/collections.hpp>
|
||||
|
||||
|
||||
@ -27,25 +26,20 @@ class DataFilesList : public QWidget
|
||||
public:
|
||||
DataFilesList(Files::ConfigurationManager& cfg, QWidget *parent = 0);
|
||||
|
||||
ProfilesComboBox *mProfilesComboBox;
|
||||
bool setupDataFiles(Files::PathContainer dataDirs, const QString encoding);
|
||||
void selectedFiles(std::vector<boost::filesystem::path>& paths);
|
||||
void uncheckAll();
|
||||
QStringList checkedFiles();
|
||||
void setCheckState(const QString& element, Qt::CheckState);
|
||||
|
||||
void writeConfig(QString profile = QString());
|
||||
bool showDataFilesWarning();
|
||||
bool setupDataFiles();
|
||||
void getSelectedFiles(std::vector<boost::filesystem::path>& paths);
|
||||
|
||||
public slots:
|
||||
void setCheckState(QModelIndex index);
|
||||
|
||||
void filterChanged(const QString filter);
|
||||
void showContextMenu(const QPoint &point);
|
||||
void profileChanged(const QString &previous, const QString ¤t);
|
||||
void profileRenamed(const QString &previous, const QString ¤t);
|
||||
void updateOkButton(const QString &text);
|
||||
|
||||
// Action slots
|
||||
void newProfile();
|
||||
void deleteProfile();
|
||||
// void moveUp();
|
||||
// void moveDown();
|
||||
// void moveTop();
|
||||
@ -63,12 +57,8 @@ private:
|
||||
QTableView *mMastersTable;
|
||||
QTableView *mPluginsTable;
|
||||
|
||||
QToolBar *mProfileToolBar;
|
||||
QMenu *mContextMenu;
|
||||
|
||||
QAction *mNewProfileAction;
|
||||
QAction *mDeleteProfileAction;
|
||||
|
||||
// QAction *mMoveUpAction;
|
||||
// QAction *mMoveDownAction;
|
||||
// QAction *mMoveTopAction;
|
||||
@ -77,20 +67,11 @@ private:
|
||||
QAction *mUncheckAction;
|
||||
|
||||
Files::ConfigurationManager &mCfgMgr;
|
||||
Files::PathContainer mDataDirs;
|
||||
Files::PathContainer mDataLocal;
|
||||
|
||||
QSettings *mLauncherConfig;
|
||||
|
||||
TextInputDialog *mNewProfileDialog;
|
||||
|
||||
// const QStringList checkedPlugins();
|
||||
// const QStringList selectedMasters();
|
||||
|
||||
void createActions();
|
||||
void setupConfig();
|
||||
void readConfig();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user