forked from teamnwah/openmw-tes3coop
Initial commit of the launcher
This commit is contained in:
parent
91fa147146
commit
7a03266729
19 changed files with 1237 additions and 0 deletions
53
apps/launcher/CMakeLists.txt
Normal file
53
apps/launcher/CMakeLists.txt
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
set(LAUNCHER
|
||||||
|
datafilesdialog.cpp
|
||||||
|
datafilesmodel.cpp
|
||||||
|
lineedit.cpp
|
||||||
|
main.cpp
|
||||||
|
maindialog.cpp
|
||||||
|
settingsdialog.cpp
|
||||||
|
datafilesdialog.h
|
||||||
|
datafilesmodel.h
|
||||||
|
lineedit.h
|
||||||
|
maindialog.h
|
||||||
|
settingsdialog.h
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(MOC_HDRS
|
||||||
|
datafilesdialog.h
|
||||||
|
lineedit.h
|
||||||
|
maindialog.h
|
||||||
|
settingsdialog.h
|
||||||
|
)
|
||||||
|
|
||||||
|
source_group(apps\\launcher FILES ${ESMTOOL})
|
||||||
|
|
||||||
|
find_package(Qt4 REQUIRED)
|
||||||
|
set(QT_USE_QTGUI 1)
|
||||||
|
|
||||||
|
QT4_ADD_RESOURCES(RCC_SRCS resources.qrc)
|
||||||
|
QT4_WRAP_CPP(MOC_SRCS ${MOC_HDRS})
|
||||||
|
|
||||||
|
include(${QT_USE_FILE})
|
||||||
|
|
||||||
|
# Main executable
|
||||||
|
add_executable(launcher
|
||||||
|
${LAUNCHER}
|
||||||
|
${MISC} ${MISC_HEADER}
|
||||||
|
${TO_UTF8}
|
||||||
|
${ESM}
|
||||||
|
${RCC_SRCS}
|
||||||
|
${MOC_SRCS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(launcher
|
||||||
|
${Boost_LIBRARIES}
|
||||||
|
${OGRE_LIBRARIES}
|
||||||
|
${QT_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if (APPLE)
|
||||||
|
# find_library(CARBON_FRAMEWORK Carbon)
|
||||||
|
# target_link_libraries(openmw ${CARBON_FRAMEWORK})
|
||||||
|
#endif (APPLE)
|
371
apps/launcher/datafilesdialog.cpp
Normal file
371
apps/launcher/datafilesdialog.cpp
Normal file
|
@ -0,0 +1,371 @@
|
||||||
|
#include <QtGui>
|
||||||
|
#include <components/esm/esm_reader.hpp>
|
||||||
|
|
||||||
|
#include "datafilesdialog.h"
|
||||||
|
#include "datafilesmodel.h"
|
||||||
|
|
||||||
|
using namespace ESM;
|
||||||
|
|
||||||
|
//DataFilesDialog::DataFilesDialog(QWidget *parent)
|
||||||
|
// : QDialog(parent)
|
||||||
|
|
||||||
|
DataFilesDialog::DataFilesDialog()
|
||||||
|
{
|
||||||
|
//QWidget *centralWidget = new QWidget;
|
||||||
|
|
||||||
|
dataFilesModel = new DataFilesModel();
|
||||||
|
dataFilesModel->setReadOnly(true); // Prevent changes to files
|
||||||
|
dataFilesModel->setRootPath("/opt/openmw/data");
|
||||||
|
|
||||||
|
// sortModel = new QSortFilterProxyModel();
|
||||||
|
// sortModel->setSourceModel(dataFilesModel);
|
||||||
|
|
||||||
|
selectionModel = new QItemSelectionModel(dataFilesModel);
|
||||||
|
// selectionModel = new QItemSelectionModel(sortModel);
|
||||||
|
|
||||||
|
// First, show only plugin files and sort them
|
||||||
|
QStringList acceptedfiles = (QStringList() << "*.esp");
|
||||||
|
dataFilesModel->setNameFilters(acceptedfiles);
|
||||||
|
dataFilesModel->setNameFilterDisables(false); // Hide all other files
|
||||||
|
|
||||||
|
dataFilesModel->sort(3, Qt::AscendingOrder); // Sort the plugins by date
|
||||||
|
dataFilesModel->submit(); // Force refresh of the data
|
||||||
|
|
||||||
|
// Now show master files too, to make them appear at the top of the list
|
||||||
|
acceptedfiles = (QStringList() << "*.esm" << "*.esp");
|
||||||
|
dataFilesModel->setNameFilters(acceptedfiles);
|
||||||
|
dataFilesModel->setFilter(QDir::Files);
|
||||||
|
|
||||||
|
// Column 1
|
||||||
|
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
|
||||||
|
QHBoxLayout *groupsLayout = new QHBoxLayout();
|
||||||
|
|
||||||
|
QGroupBox *groupFiles = new QGroupBox(tr("Morrowind Files"), this);
|
||||||
|
groupFiles->setMinimumWidth(450);
|
||||||
|
QVBoxLayout *groupFilesLayout = new QVBoxLayout(groupFiles);
|
||||||
|
|
||||||
|
QSpacerItem *vSpacer1 = new QSpacerItem(20, 2, QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
QHBoxLayout *filterLayout = new QHBoxLayout();
|
||||||
|
QLabel *labelFilter = new QLabel(tr("Filter:"), groupFiles);
|
||||||
|
lineFilter = new LineEdit(groupFiles);
|
||||||
|
|
||||||
|
filterLayout->addWidget(labelFilter);
|
||||||
|
filterLayout->addWidget(lineFilter);
|
||||||
|
|
||||||
|
// View for the game files
|
||||||
|
dataFilesView = new QTableView(groupFiles);
|
||||||
|
|
||||||
|
// Put everything in the correct layouts
|
||||||
|
groupFilesLayout->addLayout(filterLayout);
|
||||||
|
groupFilesLayout->addItem(vSpacer1);
|
||||||
|
groupFilesLayout->addWidget(dataFilesView);
|
||||||
|
groupsLayout->addWidget(groupFiles);
|
||||||
|
|
||||||
|
// Column 2
|
||||||
|
QGroupBox *groupInfo = new QGroupBox(tr("File Information"), this);
|
||||||
|
groupInfo->setFixedWidth(250);
|
||||||
|
QVBoxLayout *groupInfoLayout = new QVBoxLayout(groupInfo);
|
||||||
|
|
||||||
|
QSpacerItem *vSpacer2 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
QLabel *labelAuthor = new QLabel(tr("Author:"), groupInfo);
|
||||||
|
lineAuthor = new QLineEdit(groupInfo);
|
||||||
|
lineAuthor->setReadOnly(true);
|
||||||
|
|
||||||
|
QSpacerItem *vSpacer3 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
QLabel *labelDesc = new QLabel(tr("Description:"), groupInfo);
|
||||||
|
textDesc = new QPlainTextEdit(groupInfo);
|
||||||
|
textDesc->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
textDesc->setMinimumHeight(180);
|
||||||
|
textDesc->setReadOnly(true);
|
||||||
|
|
||||||
|
QSpacerItem *vSpacer4 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
QLabel *labelDepends = new QLabel(tr("Dependencies:"), groupInfo);
|
||||||
|
textDepends = new QPlainTextEdit(groupInfo);
|
||||||
|
textDepends->setFixedHeight(80);
|
||||||
|
textDepends->setReadOnly(true);
|
||||||
|
|
||||||
|
QHBoxLayout *buttonsLayout = new QHBoxLayout();
|
||||||
|
QSpacerItem *horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||||
|
|
||||||
|
QDialogButtonBox *buttonBox = new QDialogButtonBox();
|
||||||
|
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults);
|
||||||
|
buttonBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
buttonsLayout->addItem(horizontalSpacer);
|
||||||
|
buttonsLayout->addWidget(buttonBox);
|
||||||
|
|
||||||
|
// Put everything in the correct layouts
|
||||||
|
groupInfoLayout->addItem(vSpacer2);
|
||||||
|
groupInfoLayout->addWidget(labelAuthor);
|
||||||
|
groupInfoLayout->addWidget(lineAuthor);
|
||||||
|
groupInfoLayout->addItem(vSpacer3);
|
||||||
|
groupInfoLayout->addWidget(labelDesc);
|
||||||
|
groupInfoLayout->addWidget(textDesc);
|
||||||
|
groupInfoLayout->addItem(vSpacer4);
|
||||||
|
groupInfoLayout->addWidget(labelDepends);
|
||||||
|
groupInfoLayout->addWidget(textDepends);
|
||||||
|
|
||||||
|
groupsLayout->addWidget(groupInfo);
|
||||||
|
|
||||||
|
dialogLayout->addLayout(groupsLayout);
|
||||||
|
dialogLayout->addLayout(buttonsLayout);
|
||||||
|
|
||||||
|
setWindowTitle(tr("Data Files"));
|
||||||
|
|
||||||
|
|
||||||
|
// Signals and slots
|
||||||
|
connect(dataFilesModel, SIGNAL(directoryLoaded(const QString &)), this, SLOT(setupView()));
|
||||||
|
// connect(dataFilesModel, SIGNAL(dataChanged(const QModelIndex, const QModelIndex)), this, SLOT(readConfig()));
|
||||||
|
|
||||||
|
connect(dataFilesView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckstate(QModelIndex)));
|
||||||
|
connect(selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(changeData(QModelIndex, QModelIndex)));
|
||||||
|
|
||||||
|
connect(lineFilter, SIGNAL(textChanged(const QString &)), this, SLOT(setFilter()));
|
||||||
|
|
||||||
|
connect(buttonBox->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked()), this, SLOT(restoreDefaults()));
|
||||||
|
connect(buttonBox, SIGNAL(accepted()), this, SLOT(writeConfig()));
|
||||||
|
connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
|
||||||
|
|
||||||
|
readConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesDialog::changeData(QModelIndex index, QModelIndex bottom)
|
||||||
|
{
|
||||||
|
if (!index.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Added for testing
|
||||||
|
|
||||||
|
textDepends->clear(); // Clear the dependencies of previous file
|
||||||
|
|
||||||
|
ESMReader datafile;
|
||||||
|
QString path(dataFilesModel->filePath(index));
|
||||||
|
// QString path(dataFilesModel->filePath(sortModel->mapToSource(index)));
|
||||||
|
|
||||||
|
datafile.open(path.toStdString()); // Open the selected file
|
||||||
|
|
||||||
|
// Get the author of the selected file and display it
|
||||||
|
QString author(QString::fromStdString(datafile.getAuthor()));
|
||||||
|
lineAuthor->setText(author);
|
||||||
|
|
||||||
|
// Get the file desciption
|
||||||
|
QString desc(QString::fromStdString(datafile.getDesc()));
|
||||||
|
textDesc->setPlainText(desc);
|
||||||
|
|
||||||
|
// Get a list of master files on which the file depends
|
||||||
|
ESMReader::MasterList mlist = datafile.getMasters();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < mlist.size(); ++i) // Add each master file
|
||||||
|
textDepends->appendPlainText(QString::fromStdString(mlist[i].name));
|
||||||
|
|
||||||
|
/* Get the date of creation
|
||||||
|
QDateTime dateCreated = dataFilesModel->fileInfo(index).created();
|
||||||
|
QString created = dateCreated.toString(QString("dd.MM.yyyy"));
|
||||||
|
labelDateCreated->setText(created);
|
||||||
|
|
||||||
|
// Get the date last modified
|
||||||
|
QDateTime dateModified = dataFilesModel->fileInfo(index).lastModified();
|
||||||
|
QString modified = dateModified.toString(QString("dd.MM.yyyy"));
|
||||||
|
labelDateModified->setText(modified);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesDialog::setupView()
|
||||||
|
{
|
||||||
|
// The signal directoryLoaded is emitted after all files are in the model
|
||||||
|
dataFilesView->setModel(dataFilesModel);
|
||||||
|
// dataFilesView->setModel(sortModel);
|
||||||
|
|
||||||
|
// Set the view to the data directory
|
||||||
|
dataFilesView->setRootIndex(QModelIndex(dataFilesModel->index("/opt/openmw/data")));
|
||||||
|
// dataFilesView->setRootIndex(sortModel->mapFromSource(QModelIndex(dataFilesModel->index("/opt/openmw/data"))));
|
||||||
|
|
||||||
|
dataFilesView->verticalHeader()->hide();
|
||||||
|
|
||||||
|
//dataFilesView->hideColumn(1);
|
||||||
|
dataFilesView->hideColumn(3); // Hide Date Modified column
|
||||||
|
dataFilesView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
dataFilesView->verticalHeader()->setDefaultSectionSize(25); //setHeight
|
||||||
|
|
||||||
|
dataFilesView->setSortingEnabled(true);
|
||||||
|
|
||||||
|
dataFilesView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
dataFilesView->setSelectionModel(selectionModel);
|
||||||
|
|
||||||
|
|
||||||
|
dataFilesView->setAlternatingRowColors(true); // Fancy colors!
|
||||||
|
|
||||||
|
dataFilesView->resizeColumnsToContents();
|
||||||
|
dataFilesView->horizontalHeader()->setStretchLastSection(true);
|
||||||
|
|
||||||
|
|
||||||
|
//sortModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesDialog::readConfig()
|
||||||
|
{
|
||||||
|
qDebug() << "datachanged";
|
||||||
|
|
||||||
|
// Morrowind.ini settings
|
||||||
|
QSettings settings("Morrowind.ini",
|
||||||
|
QSettings::IniFormat);
|
||||||
|
settings.beginGroup("Game Files");
|
||||||
|
|
||||||
|
const QStringList childKeys = settings.childKeys();
|
||||||
|
|
||||||
|
// See if the files from the config file actually exist
|
||||||
|
foreach (const QString &childKey, childKeys) {
|
||||||
|
// Create full path to current file found in config
|
||||||
|
QString path = "/opt/openmw/data/"; // Note: get path from config
|
||||||
|
path.append(settings.value(childKey).toString());
|
||||||
|
|
||||||
|
QModelIndex index = dataFilesModel->index(path, 0);
|
||||||
|
// QModelIndex index = sortModel->mapFromSource(dataFilesModel->index(path, 0));
|
||||||
|
// QModelIndex index = sortModel->mapFromSource(dataFilesModel->index(path));
|
||||||
|
|
||||||
|
if (index.isValid()) {
|
||||||
|
// File is found in model, set it to checked
|
||||||
|
qDebug() << "File is found in model, set it to checked";
|
||||||
|
// dataFilesModel->setData(sortModel->mapToSource(index), Qt::Checked, Qt::CheckStateRole);
|
||||||
|
dataFilesModel->setData(index, Qt::Checked, Qt::CheckStateRole);
|
||||||
|
// dataFilesModel->checkedItems.insert(QPersistentModelIndex(sortModel->mapToSource(index)));
|
||||||
|
// dataFilesModel->checkedItems.insert(index);
|
||||||
|
|
||||||
|
//qDebug() << index;
|
||||||
|
} else {
|
||||||
|
// File is not found in the model
|
||||||
|
qDebug() << "file not found!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settings.endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesDialog::writeConfig()
|
||||||
|
{
|
||||||
|
/* // Custom write method: We cannot use QSettings because it does not accept spaces
|
||||||
|
|
||||||
|
// QList<QPersistentModelIndex> checkedItems = dataFilesModel->getCheckedItems().toList();
|
||||||
|
QList<QPersistentModelIndex> checkedItems = dataFilesModel->getCheckedItems();
|
||||||
|
|
||||||
|
qSort(checkedItems); // Sort the indexes so that master files end up on top
|
||||||
|
|
||||||
|
QString keyName;
|
||||||
|
QString fileName;
|
||||||
|
|
||||||
|
QFile file("Morrowind.ini"); // Specify filepath later
|
||||||
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
|
close(); // File cannot be opened or created
|
||||||
|
|
||||||
|
//QTextStream in(&file);
|
||||||
|
QTextStream in(&file);
|
||||||
|
|
||||||
|
//QString buffer;
|
||||||
|
QByteArray buffer;
|
||||||
|
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
QString line = in.readLine();
|
||||||
|
if (!line.contains("GameFile") && line != "[Game Files]") {
|
||||||
|
buffer += line + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
|
||||||
|
close();
|
||||||
|
|
||||||
|
QTextStream out(&file);
|
||||||
|
file.write(buffer);
|
||||||
|
|
||||||
|
out << "[Game Files]\n";
|
||||||
|
|
||||||
|
// Write the list of game files to the config
|
||||||
|
for (int i = 0; i < checkedItems.size(); ++i) {
|
||||||
|
fileName = dataFilesModel->fileName(checkedItems.at(i));
|
||||||
|
|
||||||
|
keyName.setNum(i);
|
||||||
|
keyName.prepend("GameFile");
|
||||||
|
|
||||||
|
out << keyName << "=" << fileName << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();*/
|
||||||
|
close(); // Exit dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesDialog::restoreDefaults()
|
||||||
|
{
|
||||||
|
// Uncheck all checked items
|
||||||
|
dataFilesModel->checkedItems.clear();
|
||||||
|
|
||||||
|
QModelIndexList indexlist; // Make a list of default master files
|
||||||
|
indexlist.append(dataFilesModel->index("/opt/openmw/data/Morrowind.esm", 0));
|
||||||
|
indexlist.append(dataFilesModel->index("/opt/openmw/data/Tribunal.esm", 0));
|
||||||
|
indexlist.append(dataFilesModel->index("/opt/openmw/data/Bloodmoon.esm", 0));
|
||||||
|
|
||||||
|
foreach (const QModelIndex &index, indexlist) {
|
||||||
|
if (index.isValid()) {
|
||||||
|
// Master file found, check it
|
||||||
|
dataFilesModel->setData(index, Qt::Checked, Qt::CheckStateRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataFilesModel->submit(); // Force refresh of view
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesDialog::setCheckstate(QModelIndex index)
|
||||||
|
{
|
||||||
|
// No check if index is valid: doubleclicked() always returns
|
||||||
|
// a valid index when emitted
|
||||||
|
|
||||||
|
//index = QModelIndex(sortModel->mapToSource(index)); // Get a valid index
|
||||||
|
index = index.sibling(index.row(), 0); // reset index to first column
|
||||||
|
// because that's where te checkbox is; makes it possible to doubleclick whole row
|
||||||
|
|
||||||
|
if (!index.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (dataFilesModel->data(index, Qt::CheckStateRole) == Qt::Checked) {
|
||||||
|
// Selected row is checked, uncheck it
|
||||||
|
dataFilesModel->setData(index, Qt::Unchecked, Qt::CheckStateRole);
|
||||||
|
} else {
|
||||||
|
dataFilesModel->setData(index, Qt::Checked, Qt::CheckStateRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesDialog::setFilter()
|
||||||
|
{
|
||||||
|
QStringList filefilter = (QStringList() << "*.esm" << "*.esp");
|
||||||
|
QStringList currentfilefilter;
|
||||||
|
|
||||||
|
QString esmfilter = lineFilter->text();
|
||||||
|
QString espfilter = lineFilter->text();
|
||||||
|
|
||||||
|
if (lineFilter->text().isEmpty()) {
|
||||||
|
dataFilesModel->setNameFilters(filefilter);
|
||||||
|
// sortModel->setFilterRegExp(QRegExp("*.esp", Qt::CaseInsensitive,
|
||||||
|
// QRegExp::FixedString));
|
||||||
|
// sortModel->setFilterKeyColumn(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
esmfilter.prepend("*");
|
||||||
|
esmfilter.append("*.esm");
|
||||||
|
espfilter.prepend("*");
|
||||||
|
espfilter.append("*.esp");
|
||||||
|
|
||||||
|
currentfilefilter << esmfilter << espfilter;
|
||||||
|
// sortModel->setFilterRegExp(QRegExp(espfilter, Qt::CaseInsensitive,
|
||||||
|
// QRegExp::FixedString));
|
||||||
|
// sortModel->setFilterKeyColumn(0);
|
||||||
|
dataFilesModel->setNameFilters(currentfilefilter);
|
||||||
|
|
||||||
|
// readConfig();
|
||||||
|
// dataFilesModel->submit();
|
||||||
|
// dataFilesModel->setData();
|
||||||
|
|
||||||
|
}
|
54
apps/launcher/datafilesdialog.h
Normal file
54
apps/launcher/datafilesdialog.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef DATAFILESDIALOG_H
|
||||||
|
#define DATAFILESDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
|
||||||
|
#include "lineedit.h"
|
||||||
|
|
||||||
|
class DataFilesModel;
|
||||||
|
class QStringList;
|
||||||
|
class QTableView;
|
||||||
|
class QLineEdit;
|
||||||
|
class QPlainTextEdit;
|
||||||
|
class QItemSelectionModel;
|
||||||
|
class QSortFilterProxyModel;
|
||||||
|
|
||||||
|
class DataFilesDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
DataFilesDialog();
|
||||||
|
// ~DataFilesDialog() { };
|
||||||
|
|
||||||
|
private:
|
||||||
|
DataFilesModel *dataFilesModel;
|
||||||
|
|
||||||
|
QTableView *dataFilesView;
|
||||||
|
QItemSelectionModel *selectionModel;
|
||||||
|
QSortFilterProxyModel *sortModel;
|
||||||
|
|
||||||
|
QLineEdit *lineAuthor;
|
||||||
|
LineEdit *lineFilter;
|
||||||
|
QPlainTextEdit *textDesc;
|
||||||
|
QPlainTextEdit *textDepends;
|
||||||
|
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void changeData(QModelIndex top, QModelIndex bottom); // edit
|
||||||
|
void restoreDefaults();
|
||||||
|
void readConfig();
|
||||||
|
void writeConfig();
|
||||||
|
void setupView();
|
||||||
|
|
||||||
|
void setFilter();
|
||||||
|
void setCheckstate(QModelIndex index);
|
||||||
|
// void doubleClicked(QModelIndex index);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
145
apps/launcher/datafilesmodel.cpp
Normal file
145
apps/launcher/datafilesmodel.cpp
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
#include "datafilesmodel.h"
|
||||||
|
|
||||||
|
DataFilesModel::DataFilesModel(QObject *parent)
|
||||||
|
: QFileSystemModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DataFilesModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (index.isValid() && role == Qt::DecorationRole) {
|
||||||
|
if (index.column() == 2) {
|
||||||
|
QFileIconProvider fip;
|
||||||
|
QIcon fileIcon = fip.icon(fileInfo(index));
|
||||||
|
return fileIcon;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return QIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index.isValid() && role == Qt::DisplayRole) {
|
||||||
|
if (index.column() == 2) {
|
||||||
|
//qDebug() << index.data(Qt::DisplayRole);
|
||||||
|
if (fileInfo(index).suffix().toLower() == "esp") {
|
||||||
|
return QString("Plugin File");
|
||||||
|
}
|
||||||
|
else if (fileInfo(index).suffix().toLower() == "esm") {
|
||||||
|
return QString("Master File");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index.isValid() && role == Qt::CheckStateRole && index.column() == 0) {
|
||||||
|
// Put a checkbox in the first column
|
||||||
|
if (index.isValid())
|
||||||
|
|
||||||
|
if (checkedItems.contains(filePath(index))) {
|
||||||
|
// if (checkedItems.contains(index)) {
|
||||||
|
return Qt::Checked;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Qt::Unchecked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QFileSystemModel::data(index, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataFilesModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (index.isValid() && role == Qt::CheckStateRole && index.column() == 0) {
|
||||||
|
// QPersistentModelIndex pindex(index);
|
||||||
|
|
||||||
|
// qDebug() << pindex;
|
||||||
|
|
||||||
|
if (value == Qt::Checked) {
|
||||||
|
//checkedItems.insert(pindex);
|
||||||
|
checkedItems.append(filePath(index));
|
||||||
|
} else {
|
||||||
|
// checkedItems.remove(pindex);
|
||||||
|
checkedItems.removeAll(filePath(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
emit dataChanged(index, index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QFileSystemModel::setData(index, value, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Qt::ItemFlags DataFilesModel::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
return QFileSystemModel::flags(index) | Qt::ItemIsUserCheckable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*QVariant DataFilesModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
if (section == 0) {
|
||||||
|
// ### TODO oh man this is ugly and doesn't even work all the way!
|
||||||
|
// it is still 2 pixels off
|
||||||
|
QImage pixmap(16, 1, QImage::Format_Mono);
|
||||||
|
pixmap.fill(0);
|
||||||
|
pixmap.setAlphaChannel(pixmap.createAlphaMask());
|
||||||
|
return pixmap;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::TextAlignmentRole:
|
||||||
|
return Qt::AlignLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
|
||||||
|
return QAbstractItemModel::headerData(section, orientation, role);
|
||||||
|
|
||||||
|
QString returnValue;
|
||||||
|
switch (section) {
|
||||||
|
case 0: returnValue = tr("TES3 File");
|
||||||
|
break;
|
||||||
|
case 1: returnValue = tr("Size");
|
||||||
|
break;
|
||||||
|
case 2: returnValue = tr("Status");
|
||||||
|
break;
|
||||||
|
case 3: returnValue = tr("Date Modified");
|
||||||
|
break;
|
||||||
|
default: return QVariant();
|
||||||
|
}
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*test
|
||||||
|
void DataFilesModel::setCheckedItems(const QStringList &gameFiles)
|
||||||
|
{
|
||||||
|
qDebug() << "test";
|
||||||
|
qDebug() << gameFiles.join("lol");
|
||||||
|
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*void DataFilesModel::unCheckAll()
|
||||||
|
{
|
||||||
|
checkedItems.clear();
|
||||||
|
// data();
|
||||||
|
emit dataChanged(QModelIndex(), QModelIndex());
|
||||||
|
submit();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
const QStringList DataFilesModel::getCheckedItems()
|
||||||
|
//const QList<QPersistentModelIndex> DataFilesModel::getCheckedItems()
|
||||||
|
//const QSet<QPersistentModelIndex> DataFilesModel::getCheckedItems()
|
||||||
|
{
|
||||||
|
return checkedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*void DataFilesModel::sort(int column, Qt::SortOrder order)
|
||||||
|
{
|
||||||
|
qDebug() << "Sort!";
|
||||||
|
}*/
|
38
apps/launcher/datafilesmodel.h
Normal file
38
apps/launcher/datafilesmodel.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef DATAFILESMODEL_H
|
||||||
|
#define DATAFILESMODEL_H
|
||||||
|
|
||||||
|
#include <QFileSystemModel>
|
||||||
|
#include <QFileIconProvider>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
class DataFilesModel : public QFileSystemModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DataFilesModel(QObject *parent = 0);
|
||||||
|
~DataFilesModel() {};
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||||
|
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||||
|
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
|
||||||
|
|
||||||
|
// void sort(int column, Qt::SortOrder order);
|
||||||
|
//test
|
||||||
|
// void setCheckedItems(const QStringList& files);
|
||||||
|
// void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
|
||||||
|
// void unCheckAll();
|
||||||
|
|
||||||
|
// const QSet<QPersistentModelIndex> getCheckedItems();
|
||||||
|
// const QList<QPersistentModelIndex> getCheckedItems();
|
||||||
|
const QStringList getCheckedItems();
|
||||||
|
|
||||||
|
// QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||||
|
|
||||||
|
// QSet<QPersistentModelIndex> checkedItems;
|
||||||
|
// QList<QPersistentModelIndex> checkedItems;
|
||||||
|
QStringList checkedItems;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
23
apps/launcher/launcher.pro
Normal file
23
apps/launcher/launcher.pro
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
######################################################################
|
||||||
|
# Automatically generated by qmake (2.01a) Sun Mar 27 19:33:07 2011
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
TEMPLATE = app
|
||||||
|
TARGET =
|
||||||
|
DEPENDPATH += .
|
||||||
|
INCLUDEPATH += .
|
||||||
|
|
||||||
|
# Input
|
||||||
|
HEADERS += datafilesdialog.h \
|
||||||
|
datafilesmodel.h \
|
||||||
|
lineedit.h \
|
||||||
|
maindialog.h \
|
||||||
|
settingsdialog.h
|
||||||
|
SOURCES += datafilesdialog.cpp \
|
||||||
|
datafilesmodel.cpp \
|
||||||
|
lineedit.cpp \
|
||||||
|
main.cpp \
|
||||||
|
maindialog.cpp \
|
||||||
|
settingsdialog.cpp
|
||||||
|
RESOURCES += resources.qrc
|
||||||
|
RC_FILE = launcher.rc
|
1
apps/launcher/launcher.rc
Normal file
1
apps/launcher/launcher.rc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
IDI_ICON1 ICON DISCARDABLE "resources/openmw_icon.ico"
|
46
apps/launcher/lineedit.cpp
Normal file
46
apps/launcher/lineedit.cpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (c) 2007 Trolltech ASA <info@trolltech.com>
|
||||||
|
**
|
||||||
|
** Use, modification and distribution is allowed without limitation,
|
||||||
|
** warranty, liability or support of any kind.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "lineedit.h"
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QStyle>
|
||||||
|
|
||||||
|
LineEdit::LineEdit(QWidget *parent)
|
||||||
|
: QLineEdit(parent)
|
||||||
|
{
|
||||||
|
clearButton = new QToolButton(this);
|
||||||
|
QPixmap pixmap(":resources/clear.png");
|
||||||
|
clearButton->setIcon(QIcon(pixmap));
|
||||||
|
clearButton->setIconSize(pixmap.size());
|
||||||
|
clearButton->setCursor(Qt::ArrowCursor);
|
||||||
|
clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
|
||||||
|
clearButton->hide();
|
||||||
|
connect(clearButton, SIGNAL(clicked()), this, SLOT(clear()));
|
||||||
|
connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&)));
|
||||||
|
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||||
|
setStyleSheet(QString("QLineEdit { padding-right: %1px; } ").arg(clearButton->sizeHint().width() + frameWidth + 1));
|
||||||
|
QSize msz = minimumSizeHint();
|
||||||
|
setMinimumSize(qMax(msz.width(), clearButton->sizeHint().height() + frameWidth * 2 + 2),
|
||||||
|
qMax(msz.height(), clearButton->sizeHint().height() + frameWidth * 2 + 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineEdit::resizeEvent(QResizeEvent *)
|
||||||
|
{
|
||||||
|
QSize sz = clearButton->sizeHint();
|
||||||
|
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||||
|
clearButton->move(rect().right() - frameWidth - sz.width(),
|
||||||
|
(rect().bottom() + 1 - sz.height())/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineEdit::updateCloseButton(const QString& text)
|
||||||
|
{
|
||||||
|
clearButton->setVisible(!text.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
35
apps/launcher/lineedit.h
Normal file
35
apps/launcher/lineedit.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (c) 2007 Trolltech ASA <info@trolltech.com>
|
||||||
|
**
|
||||||
|
** Use, modification and distribution is allowed without limitation,
|
||||||
|
** warranty, liability or support of any kind.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef LINEEDIT_H
|
||||||
|
#define LINEEDIT_H
|
||||||
|
|
||||||
|
#include <QLineEdit>
|
||||||
|
|
||||||
|
class QToolButton;
|
||||||
|
|
||||||
|
class LineEdit : public QLineEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
LineEdit(QWidget *parent = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent *);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateCloseButton(const QString &text);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QToolButton *clearButton;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LIENEDIT_H
|
||||||
|
|
13
apps/launcher/main.cpp
Normal file
13
apps/launcher/main.cpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
#include "maindialog.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
MainDialog dialog;
|
||||||
|
return dialog.exec();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
121
apps/launcher/maindialog.cpp
Normal file
121
apps/launcher/maindialog.cpp
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
#include <QtGui>
|
||||||
|
|
||||||
|
#include "maindialog.h"
|
||||||
|
#include "datafilesdialog.h"
|
||||||
|
#include "settingsdialog.h"
|
||||||
|
|
||||||
|
MainDialog::MainDialog()
|
||||||
|
{
|
||||||
|
|
||||||
|
QLabel *header = new QLabel(this);
|
||||||
|
header->setMinimumSize(QSize(400, 150));
|
||||||
|
header->setPixmap(QPixmap(":resources/openmw_header.png"));
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
QPushButton *buttonStart = new QPushButton(this);
|
||||||
|
buttonStart->setMinimumSize(QSize(200, 40));
|
||||||
|
buttonStart->setText(tr("Start OpenMW"));
|
||||||
|
|
||||||
|
QPushButton *buttonDataFiles = new QPushButton(this);
|
||||||
|
buttonDataFiles->setMinimumSize(QSize(200, 40));
|
||||||
|
buttonDataFiles->setText(tr("Data Files"));
|
||||||
|
|
||||||
|
QPushButton *buttonSettings = new QPushButton(this);
|
||||||
|
buttonSettings->setText(tr("Settings"));
|
||||||
|
buttonSettings->setIcon(QIcon::fromTheme("preferences-other"));
|
||||||
|
|
||||||
|
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
|
||||||
|
buttonBox->setStandardButtons(QDialogButtonBox::Close);
|
||||||
|
buttonBox->addButton(buttonSettings, QDialogButtonBox::ActionRole);
|
||||||
|
|
||||||
|
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
|
||||||
|
QVBoxLayout *buttonsLayout = new QVBoxLayout();
|
||||||
|
QHBoxLayout *bodyLayout = new QHBoxLayout();
|
||||||
|
QHBoxLayout *dialogButtonsLayout = new QHBoxLayout();
|
||||||
|
|
||||||
|
QSpacerItem *hSpacer1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||||
|
QSpacerItem *hSpacer2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||||
|
QSpacerItem *hSpacer3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||||
|
|
||||||
|
QSpacerItem *vSpacer1 = new QSpacerItem(40, 150, QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||||
|
QSpacerItem *vSpacer2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||||
|
|
||||||
|
buttonsLayout->addItem(vSpacer1);
|
||||||
|
buttonsLayout->addWidget(buttonStart);
|
||||||
|
buttonsLayout->addWidget(buttonDataFiles);
|
||||||
|
buttonsLayout->addItem(vSpacer2);
|
||||||
|
|
||||||
|
bodyLayout->addItem(hSpacer1);
|
||||||
|
bodyLayout->addLayout(buttonsLayout);
|
||||||
|
bodyLayout->addItem(hSpacer2);
|
||||||
|
|
||||||
|
dialogButtonsLayout->addItem(hSpacer3);
|
||||||
|
dialogButtonsLayout->addWidget(buttonBox);
|
||||||
|
|
||||||
|
dialogLayout->addLayout(bodyLayout);
|
||||||
|
dialogLayout->addLayout(dialogButtonsLayout);
|
||||||
|
|
||||||
|
setMinimumSize(QSize(400, 310));
|
||||||
|
setMaximumSize(QSize(400, 310));
|
||||||
|
|
||||||
|
setWindowTitle(tr("OpenMW Launcher"));
|
||||||
|
QPixmap pixmap(":resources/openmw_icon.png");
|
||||||
|
setWindowIcon(QIcon(pixmap));
|
||||||
|
|
||||||
|
// Signals and slots
|
||||||
|
connect(buttonStart, SIGNAL(clicked()), this, SLOT(start()));
|
||||||
|
connect(buttonDataFiles, SIGNAL(clicked()), this, SLOT(showDataFiles()));
|
||||||
|
connect(buttonSettings, SIGNAL(clicked()), this, SLOT(showSettings()));
|
||||||
|
connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
|
||||||
|
|
||||||
|
openmw = new QProcess(NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainDialog::start()
|
||||||
|
{
|
||||||
|
// Start the game!
|
||||||
|
openmw->start("./openmw");
|
||||||
|
connect(openmw, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainDialog::finished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||||
|
{
|
||||||
|
QString debuginfo = openmw->readAllStandardOutput();
|
||||||
|
|
||||||
|
if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
|
||||||
|
// Close the launcher if the game is quitted
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exitCode != 0) {
|
||||||
|
// An error occured whilst starting OpenMW
|
||||||
|
|
||||||
|
// First check if readAllStandardOutput is empty
|
||||||
|
// Finished gets signaled twice sometimes
|
||||||
|
|
||||||
|
if (!debuginfo.isEmpty())
|
||||||
|
{
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setWindowTitle("Error");
|
||||||
|
msgBox.setIcon(QMessageBox::Warning);
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
msgBox.setText(tr("\nAn error occured while starting OpenMW."));
|
||||||
|
msgBox.setDetailedText(debuginfo);
|
||||||
|
msgBox.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainDialog::showDataFiles()
|
||||||
|
{
|
||||||
|
DataFilesDialog dialog;
|
||||||
|
dialog.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainDialog::showSettings()
|
||||||
|
{
|
||||||
|
SettingsDialog dialog;
|
||||||
|
dialog.exec();
|
||||||
|
}
|
25
apps/launcher/maindialog.h
Normal file
25
apps/launcher/maindialog.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef MAINDIALOG_H
|
||||||
|
#define MAINDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
class MainDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MainDialog();
|
||||||
|
|
||||||
|
QProcess *openmw;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void showDataFiles();
|
||||||
|
void showSettings();
|
||||||
|
void finished(int, QProcess::ExitStatus exitStatus);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
7
apps/launcher/resources.qrc
Normal file
7
apps/launcher/resources.qrc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<!DOCTYPE RCC><RCC version="1.0">
|
||||||
|
<qresource>
|
||||||
|
<file>resources/clear.png</file>
|
||||||
|
<file>resources/openmw_header.png</file>
|
||||||
|
<file>resources/openmw_icon.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
BIN
apps/launcher/resources/clear.png
Normal file
BIN
apps/launcher/resources/clear.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 644 B |
BIN
apps/launcher/resources/openmw_header.png
Normal file
BIN
apps/launcher/resources/openmw_header.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 106 KiB |
BIN
apps/launcher/resources/openmw_icon.ico
Normal file
BIN
apps/launcher/resources/openmw_icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
BIN
apps/launcher/resources/openmw_icon.png
Normal file
BIN
apps/launcher/resources/openmw_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 59 KiB |
259
apps/launcher/settingsdialog.cpp
Normal file
259
apps/launcher/settingsdialog.cpp
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
#include <QtGui>
|
||||||
|
|
||||||
|
#include "settingsdialog.h"
|
||||||
|
|
||||||
|
SettingsDialog::SettingsDialog()
|
||||||
|
{
|
||||||
|
QTabWidget *tabWidget = new QTabWidget(this);
|
||||||
|
QWidget *graphicsTab = new QWidget();
|
||||||
|
|
||||||
|
// Render group
|
||||||
|
QGroupBox *groupRender = new QGroupBox(tr("Renderer"), graphicsTab);
|
||||||
|
groupRender->setMinimumWidth(450);
|
||||||
|
|
||||||
|
QVBoxLayout *groupRenderLayout = new QVBoxLayout(groupRender);
|
||||||
|
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
|
||||||
|
QVBoxLayout *pageLayout = new QVBoxLayout(graphicsTab);
|
||||||
|
|
||||||
|
QGridLayout *renderLayout = new QGridLayout();
|
||||||
|
|
||||||
|
QLabel *labelRender = new QLabel(tr("Rendering Subsystem:"), groupRender);
|
||||||
|
comboRender = new QComboBox(groupRender);
|
||||||
|
|
||||||
|
QLabel *labelRTT = new QLabel(tr("Preferred RTT Mode:"), groupRender);
|
||||||
|
comboRTT = new QComboBox(groupRender);
|
||||||
|
|
||||||
|
QLabel *labelAA = new QLabel(tr("Antialiasing:"), groupRender);
|
||||||
|
comboAA = new QComboBox(groupRender);
|
||||||
|
|
||||||
|
renderLayout->addWidget(labelRender, 0, 0, 1, 1);
|
||||||
|
renderLayout->addWidget(comboRender, 0, 1, 1, 1);
|
||||||
|
|
||||||
|
QSpacerItem *vSpacer1 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
|
renderLayout->addItem(vSpacer1, 1, 1, 1, 1);
|
||||||
|
|
||||||
|
renderLayout->addWidget(labelRTT, 2, 0, 1, 1);
|
||||||
|
renderLayout->addWidget(comboRTT, 2, 1, 1, 1);
|
||||||
|
renderLayout->addWidget(labelAA, 3, 0, 1, 1);
|
||||||
|
renderLayout->addWidget(comboAA, 3, 1, 1, 1);
|
||||||
|
|
||||||
|
QSpacerItem *vSpacer2 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||||
|
|
||||||
|
groupRenderLayout->addLayout(renderLayout);
|
||||||
|
groupRenderLayout->addItem(vSpacer2);
|
||||||
|
|
||||||
|
pageLayout->addWidget(groupRender);
|
||||||
|
|
||||||
|
// Display group
|
||||||
|
QGroupBox *groupDisplay = new QGroupBox(tr("Display"), graphicsTab);
|
||||||
|
QVBoxLayout *groupDisplayLayout = new QVBoxLayout(groupDisplay);
|
||||||
|
|
||||||
|
QGridLayout *displayLayout = new QGridLayout();
|
||||||
|
|
||||||
|
QLabel *labelResolution = new QLabel(tr("Resolution:"), groupDisplay);
|
||||||
|
comboResolution = new QComboBox(groupDisplay);
|
||||||
|
|
||||||
|
QLabel *labelFrequency = new QLabel(tr("Display Frequency:"), groupDisplay);
|
||||||
|
comboFrequency = new QComboBox(groupDisplay);
|
||||||
|
|
||||||
|
checkVSync = new QCheckBox(tr("Vertical Sync"), groupDisplay);
|
||||||
|
checkGamma = new QCheckBox(tr("sRGB Gamma Conversion"), groupDisplay);
|
||||||
|
checkFullScreen = new QCheckBox(tr("Full Screen"), groupDisplay);
|
||||||
|
|
||||||
|
displayLayout->addWidget(labelResolution, 0, 0, 1, 1);
|
||||||
|
displayLayout->addWidget(comboResolution, 0, 1, 1, 1);
|
||||||
|
displayLayout->addWidget(labelFrequency, 1, 0, 1, 1);
|
||||||
|
displayLayout->addWidget(comboFrequency, 1, 1, 1, 1);
|
||||||
|
|
||||||
|
QSpacerItem *vSpacer3 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
|
displayLayout->addItem(vSpacer3, 2, 1, 1, 1);
|
||||||
|
|
||||||
|
displayLayout->addWidget(checkVSync, 3, 0, 1, 1);
|
||||||
|
displayLayout->addWidget(checkGamma, 3, 1, 1, 1);
|
||||||
|
displayLayout->addWidget(checkFullScreen, 6, 0, 1, 1);
|
||||||
|
|
||||||
|
QSpacerItem *vSpacer4 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||||
|
|
||||||
|
groupDisplayLayout->addLayout(displayLayout);
|
||||||
|
groupDisplayLayout->addItem(vSpacer4);
|
||||||
|
|
||||||
|
pageLayout->addWidget(groupDisplay);
|
||||||
|
|
||||||
|
|
||||||
|
tabWidget->addTab(graphicsTab, QString(tr("Graphics")));
|
||||||
|
tabWidget->setCurrentIndex(0);
|
||||||
|
|
||||||
|
dialogLayout->addWidget(tabWidget);
|
||||||
|
|
||||||
|
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
|
||||||
|
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
|
||||||
|
|
||||||
|
dialogLayout->addWidget(buttonBox);
|
||||||
|
|
||||||
|
setWindowTitle(tr("Settings"));
|
||||||
|
setWindowIcon(QIcon::fromTheme("preferences-other"));
|
||||||
|
|
||||||
|
// Ogre Settings
|
||||||
|
// TODO: Find out a way to do this nice and platform-independent
|
||||||
|
QString filepath = QDir::homePath();
|
||||||
|
filepath.append("/.config/openmw/ogre.cfg");
|
||||||
|
|
||||||
|
ogreConfig = new QSettings(filepath, QSettings::IniFormat);
|
||||||
|
|
||||||
|
// Signals and slots
|
||||||
|
connect(comboRender, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(rendererChanged(const QString&)));
|
||||||
|
connect(buttonBox, SIGNAL(accepted()), this, SLOT(writeConfig()));
|
||||||
|
connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
|
||||||
|
|
||||||
|
// Ogre stuff
|
||||||
|
root = new Ogre::Root("plugins.cfg");
|
||||||
|
|
||||||
|
// Get the available renderers and put them in the combobox
|
||||||
|
const Ogre::RenderSystemList &renderers = root->getAvailableRenderers();
|
||||||
|
|
||||||
|
for (Ogre::RenderSystemList::const_iterator r = renderers.begin(); r != renderers.end(); ++r) {
|
||||||
|
comboRender->addItem((*r)->getName().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = comboRender->findText(getConfigValue("Render System"));
|
||||||
|
|
||||||
|
if ( index != -1) {
|
||||||
|
comboRender->setCurrentIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList SettingsDialog::getAvailableOptions(const QString& key)
|
||||||
|
{
|
||||||
|
QStringList result;
|
||||||
|
|
||||||
|
uint row = 0;
|
||||||
|
Ogre::ConfigOptionMap options = mSelectedRenderSystem->getConfigOptions();
|
||||||
|
|
||||||
|
for (Ogre::ConfigOptionMap::iterator i = options.begin (); i != options.end (); i++, row++)
|
||||||
|
{
|
||||||
|
Ogre::StringVector::iterator opt_it;
|
||||||
|
uint idx = 0;
|
||||||
|
for (opt_it = i->second.possibleValues.begin ();
|
||||||
|
opt_it != i->second.possibleValues.end (); opt_it++, idx++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (strcmp (key.toStdString().c_str(), i->first.c_str()) == 0)
|
||||||
|
result << (*opt_it).c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsDialog::rendererChanged(const QString& renderer)
|
||||||
|
{
|
||||||
|
// Set the render system to the selected one
|
||||||
|
mSelectedRenderSystem = root->getRenderSystemByName(renderer.toStdString().c_str());
|
||||||
|
|
||||||
|
comboRTT->addItems(getAvailableOptions("RTT Preferred Mode"));
|
||||||
|
comboAA->addItems(getAvailableOptions("FSAA"));
|
||||||
|
comboResolution->addItems(getAvailableOptions("Video Mode"));
|
||||||
|
comboFrequency->addItems(getAvailableOptions("Display Frequency"));
|
||||||
|
|
||||||
|
// Get the value for the option the config file, find if it's in the combobox.
|
||||||
|
// If it's found, set the current index to that value, otherwise: ignore.
|
||||||
|
|
||||||
|
int index = comboRTT->findText(getConfigValue("RTT Preferred Mode"));
|
||||||
|
if ( index != -1)
|
||||||
|
comboRTT->setCurrentIndex(index);
|
||||||
|
|
||||||
|
index = comboAA->findText(getConfigValue("FSAA"));
|
||||||
|
if ( index != -1)
|
||||||
|
comboAA->setCurrentIndex(index);
|
||||||
|
|
||||||
|
index = comboResolution->findText(getConfigValue("Video Mode"));
|
||||||
|
if ( index != -1)
|
||||||
|
comboResolution->setCurrentIndex(index);
|
||||||
|
|
||||||
|
index = comboFrequency->findText(getConfigValue("Display Frequency"));
|
||||||
|
if ( index != -1)
|
||||||
|
comboFrequency->setCurrentIndex(index);
|
||||||
|
|
||||||
|
// Now we do the same for the checkboxes
|
||||||
|
if (QString::compare(getConfigValue("VSync"), QString("Yes")) == 0) {
|
||||||
|
checkVSync->setCheckState(Qt::Checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QString::compare(getConfigValue("sRGB Gamma Conversion"), QString("Yes")) == 0) {
|
||||||
|
checkGamma->setCheckState(Qt::Checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QString::compare(getConfigValue("Full Screen"), QString("Yes")) == 0) {
|
||||||
|
checkFullScreen->setCheckState(Qt::Checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SettingsDialog::getConfigValue(const QString& key)
|
||||||
|
{
|
||||||
|
QString result;
|
||||||
|
|
||||||
|
ogreConfig->beginGroup(mSelectedRenderSystem->getName().c_str());
|
||||||
|
result = ogreConfig->value(key).toString();
|
||||||
|
ogreConfig->endGroup();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsDialog::writeConfig()
|
||||||
|
{
|
||||||
|
// Get the values from the GUI elements and write them to the config file
|
||||||
|
|
||||||
|
// Custom write method: We cannot use QSettings because it does not accept spaces
|
||||||
|
|
||||||
|
QString keyName;
|
||||||
|
QString fileName;
|
||||||
|
|
||||||
|
QFile file(ogreConfig->fileName());
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
|
||||||
|
// File could not be opened, TODO error
|
||||||
|
close();
|
||||||
|
|
||||||
|
QTextStream out(&file);
|
||||||
|
|
||||||
|
out << "Render System=" << mSelectedRenderSystem->getName().c_str() << endl << endl;
|
||||||
|
|
||||||
|
// add brackets to the renderer's name
|
||||||
|
QString renderer = mSelectedRenderSystem->getName().c_str();
|
||||||
|
renderer.prepend("[");
|
||||||
|
renderer.append("]");
|
||||||
|
out << renderer << endl;
|
||||||
|
|
||||||
|
out << "Display Frequency=" << comboFrequency->currentText() << endl;
|
||||||
|
out << "FSAA=" << comboAA->currentText() << endl;
|
||||||
|
|
||||||
|
if (checkFullScreen->checkState() == Qt::Checked) {
|
||||||
|
out << "Full Screen=Yes" << endl;
|
||||||
|
} else {
|
||||||
|
out << "Full Screen=No" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
out << "RTT Preferred Mode=" << comboRTT->currentText() << endl;
|
||||||
|
|
||||||
|
if (checkVSync->checkState() == Qt::Checked) {
|
||||||
|
out << "VSync=Yes" << endl;
|
||||||
|
} else {
|
||||||
|
out << "VSync=No" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
out << "Video Mode=" << comboResolution->currentText() << endl;
|
||||||
|
|
||||||
|
if (checkGamma->checkState() == Qt::Checked) {
|
||||||
|
out << "sRGB Gamma Conversion=Yes" << endl;
|
||||||
|
} else {
|
||||||
|
out << "sRGB Gamma Conversion=No" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
close(); // Exit dialog
|
||||||
|
}
|
||||||
|
|
46
apps/launcher/settingsdialog.h
Normal file
46
apps/launcher/settingsdialog.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef SETTINGSDIALOG_H
|
||||||
|
#define SETTINGSDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
#include <OgreRoot.h>
|
||||||
|
#include <OgreRenderSystem.h>
|
||||||
|
#include <OgreConfigFile.h>
|
||||||
|
#include <OgreConfigDialog.h>
|
||||||
|
#include <OgreException.h>
|
||||||
|
#include <OgreLogManager.h>
|
||||||
|
|
||||||
|
class SettingsDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SettingsDialog();
|
||||||
|
QStringList getAvailableOptions(const QString& key);
|
||||||
|
|
||||||
|
Ogre::Root *root;
|
||||||
|
Ogre::RenderSystem *mSelectedRenderSystem;
|
||||||
|
|
||||||
|
QComboBox *comboRender;
|
||||||
|
QComboBox *comboRTT;
|
||||||
|
QComboBox *comboAA;
|
||||||
|
QComboBox *comboResolution;
|
||||||
|
QComboBox *comboFrequency;
|
||||||
|
|
||||||
|
QCheckBox *checkVSync;
|
||||||
|
QCheckBox *checkGamma;
|
||||||
|
QCheckBox *checkFullScreen;
|
||||||
|
|
||||||
|
QSettings *ogreConfig;
|
||||||
|
|
||||||
|
QString getConfigValue(const QString& key);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void rendererChanged(const QString& renderer);
|
||||||
|
void writeConfig();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue