Launcher improvements: ask for data dir and write it to cfg if none is found

and prevent removal of the default profile
pull/21/head
Pieter van der Kloet 12 years ago
parent 1512481c07
commit 5b54a658d8

@ -428,7 +428,7 @@ if (APPLE)
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
set(CPACK_GENERATOR "DragNDrop")
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
set(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})

@ -72,13 +72,13 @@ endif()
if (APPLE)
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
"${APP_BUNDLE_DIR}/../launcher.qss")
"${APP_BUNDLE_DIR}/resources/../launcher.qss")
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
"${APP_BUNDLE_DIR}/../launcher.cfg")
else()
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launcher.qss")
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/resources/launcher.qss")
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.cfg
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launcher.cfg")
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}launcher.cfg")
endif()

@ -1,8 +1,6 @@
#include <QtGui>
#include <components/esm/esm_reader.hpp>
#include <components/files/collections.hpp>
#include <components/files/multidircollection.hpp>
#include <components/files/configurationmanager.hpp>
#include "datafilespage.hpp"
@ -120,11 +118,12 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent)
connect(mPluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex)));
connect(mPluginsTable, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&)));
connect(mProfilesComboBox, SIGNAL(textChanged(const QString&, const QString&)), this, SLOT(profileChanged(const QString&, const QString&)));
createActions();
setupConfig();
setupDataFiles();
createActions();
}
void DataFilesPage::setupConfig()
@ -138,8 +137,7 @@ void DataFilesPage::setupConfig()
// Open our config file
mLauncherConfig = new QSettings(config, QSettings::IniFormat);
mLauncherConfig->sync();
file.close();
// Make sure we have no groups open
while (!mLauncherConfig->group().isEmpty()) {
@ -162,13 +160,14 @@ void DataFilesPage::setupConfig()
// No current profile selected
currentProfile = "Default";
}
mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(currentProfile));
mLauncherConfig->endGroup();
const int currentIndex = mProfilesComboBox->findText(currentProfile);
if (currentIndex != -1) {
// Profile is found
mProfilesComboBox->setCurrentIndex(currentIndex);
}
// Now we connect the combobox to do something if the profile changes
// This prevents strange behaviour while reading and appending the profiles
connect(mProfilesComboBox, SIGNAL(textChanged(const QString&, const QString&)), this, SLOT(profileChanged(const QString&, const QString&)));
mLauncherConfig->endGroup();
}
@ -188,19 +187,51 @@ void DataFilesPage::setupDataFiles()
// Put the paths in a boost::filesystem vector to use with Files::Collections
Files::PathContainer dataDirs(variables["data"].as<Files::PathContainer>());
std::string local(variables["data-local"].as<std::string>());
if (!local.empty())
{
mDataDirs = dataDirs;
std::string local = variables["data-local"].as<std::string>();
if (!local.empty()) {
mDataLocal.push_back(Files::PathContainer::value_type(local));
dataDirs.push_back(Files::PathContainer::value_type(local));
}
if (dataDirs.empty())
{
dataDirs.push_back(mCfgMgr.getLocalPath());
mCfgMgr.processPaths(dataDirs);
while (dataDirs.empty()) {
// No valid data files directory found
QMessageBox msgBox;
msgBox.setWindowTitle("Error detecting Morrowind installation");
msgBox.setIcon(QMessageBox::Critical);
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) {
QString dataDir = QFileDialog::getExistingDirectory(
this, tr("Select Data Files Directory"),
"/home",
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
dataDirs.push_back(Files::PathContainer::value_type(dataDir.toStdString()));
mDataDirs.push_back(Files::PathContainer::value_type(dataDir.toStdString()));
} else {
// Cancel
break;
}
}
mCfgMgr.processPaths(dataDirs);
// Check if cancel was clicked because we can't exit from while loop
if (dataDirs.empty()) {
QApplication::exit(1);
}
// Create a file collection for the dataDirs
Files::Collections fileCollections(dataDirs, !variables["fs-strict"].as<bool>());
@ -209,15 +240,13 @@ void DataFilesPage::setupDataFiles()
const Files::MultiDirCollection &esm = fileCollections.getCollection(".esm");
unsigned int i = 0; // Row number
for (Files::MultiDirCollection::TIter iter(esm.begin()); iter!=esm.end(); ++iter)
{
for (Files::MultiDirCollection::TIter iter(esm.begin()); iter!=esm.end(); ++iter) {
QString currentMaster = QString::fromStdString(
boost::filesystem::path (iter->second.filename()).string());
const QList<QTableWidgetItem*> itemList = mMastersWidget->findItems(currentMaster, Qt::MatchExactly);
if (itemList.isEmpty()) // Master is not yet in the widget
{
if (itemList.isEmpty()) { // Master is not yet in the widget
mMastersWidget->insertRow(i);
QTableWidgetItem *item = new QTableWidgetItem(currentMaster);
mMastersWidget->setItem(i, 0, item);
@ -228,8 +257,7 @@ void DataFilesPage::setupDataFiles()
// Now on to the plugins
const Files::MultiDirCollection &esp = fileCollections.getCollection(".esp");
for (Files::MultiDirCollection::TIter iter(esp.begin()); iter!=esp.end(); ++iter)
{
for (Files::MultiDirCollection::TIter iter(esp.begin()); iter!=esp.end(); ++iter) {
ESMReader fileReader;
QStringList availableMasters; // Will contain all found masters
@ -245,8 +273,7 @@ void DataFilesPage::setupDataFiles()
const QList<QTableWidgetItem*> itemList = mMastersWidget->findItems(currentMaster, Qt::MatchExactly);
if (itemList.isEmpty()) // Master is not yet in the widget
{
if (itemList.isEmpty()) { // Master is not yet in the widget
mMastersWidget->insertRow(i);
QTableWidgetItem *item = new QTableWidgetItem(currentMaster);
@ -435,18 +462,18 @@ void DataFilesPage::deleteProfile()
return;
}
QMessageBox deleteMessageBox(this);
deleteMessageBox.setWindowTitle(tr("Delete Profile"));
deleteMessageBox.setText(tr("Are you sure you want to delete <b>%0</b>?").arg(profile));
deleteMessageBox.setIcon(QMessageBox::Warning);
QAbstractButton *deleteButton =
deleteMessageBox.addButton(tr("Delete"), QMessageBox::ActionRole);
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));
deleteMessageBox.addButton(QMessageBox::Cancel);
QAbstractButton *deleteButton =
msgBox.addButton(tr("Delete"), QMessageBox::ActionRole);
deleteMessageBox.exec();
msgBox.exec();
if (deleteMessageBox.clickedButton() == deleteButton) {
if (msgBox.clickedButton() == deleteButton) {
// Make sure we have no groups open
while (!mLauncherConfig->group().isEmpty()) {
mLauncherConfig->endGroup();
@ -503,7 +530,6 @@ void DataFilesPage::moveUp()
void DataFilesPage::moveDown()
{
// Shift the selected plugins down one row
if (!mPluginsTable->selectionModel()->hasSelection()) {
return;
}
@ -919,9 +945,18 @@ void DataFilesPage::filterChanged(const QString filter)
void DataFilesPage::profileChanged(const QString &previous, const QString &current)
{
// Prevent the deletion of the default profile
if (current == "Default") {
mDeleteProfileAction->setEnabled(false);
} else {
mDeleteProfileAction->setEnabled(true);
}
if (!previous.isEmpty()) {
writeConfig(previous);
mLauncherConfig->sync();
} else {
return;
}
uncheckPlugins();
@ -989,22 +1024,12 @@ void DataFilesPage::readConfig()
void DataFilesPage::writeConfig(QString profile)
{
// Don't overwrite the config if no plugins are found
if (mPluginsModel->rowCount() < 1) {
return;
}
if (profile.isEmpty()) {
profile = mProfilesComboBox->currentText();
}
if (profile.isEmpty()) {
// Don't overwrite the config if no masters are found
if (mMastersWidget->rowCount() < 1) {
return;
}
// Prepare the OpenMW config
// Open the config as a QFile
// Open the OpenMW config as a QFile
QFile file(QString::fromStdString((mCfgMgr.getUserPath()/"openmw.cfg").string()));
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
@ -1023,10 +1048,14 @@ void DataFilesPage::writeConfig(QString profile)
QTextStream in(&file);
QByteArray buffer;
// Remove all previous master/plugin entries from config
// Remove all previous entries from config
while (!in.atEnd()) {
QString line = in.readLine();
if (!line.contains("master") && !line.contains("plugin")) {
if (!line.startsWith("master") &&
!line.startsWith("plugin") &&
!line.startsWith("data") &&
!line.startsWith("data-local"))
{
buffer += line += "\n";
}
}
@ -1046,9 +1075,52 @@ void DataFilesPage::writeConfig(QString profile)
QApplication::exit(1);
}
file.write(buffer);
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();
@ -1061,7 +1133,7 @@ void DataFilesPage::writeConfig(QString profile)
mLauncherConfig->beginGroup(profile);
mLauncherConfig->remove(""); // Clear the subgroup
// First write the masters to the configs
// Now write the masters to the configs
const QStringList masters = selectedMasters();
// We don't use foreach because we need i
@ -1073,11 +1145,10 @@ void DataFilesPage::writeConfig(QString profile)
}
// Now write all checked plugins
// And finally write all checked plugins
const QStringList plugins = checkedPlugins();
for (int i = 0; i < plugins.size(); ++i)
{
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;
@ -1086,5 +1157,6 @@ void DataFilesPage::writeConfig(QString profile)
file.close();
mLauncherConfig->endGroup();
mLauncherConfig->endGroup();
mLauncherConfig->sync();
}

@ -3,6 +3,9 @@
#include <QWidget>
#include <QModelIndex>
#include <components/files/collections.hpp>
#include "combobox.hpp"
class QTableWidget;
@ -77,6 +80,8 @@ private:
QAction *mUncheckAction;
Files::ConfigurationManager &mCfgMgr;
Files::PathContainer mDataDirs;
Files::PathContainer mDataLocal;
QSettings *mLauncherConfig;

Loading…
Cancel
Save