mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 03:56:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			387 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			387 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include <QtGui>
 | 
						|
 | 
						|
#include "maindialog.hpp"
 | 
						|
#include "playpage.hpp"
 | 
						|
#include "graphicspage.hpp"
 | 
						|
#include "datafilespage.hpp"
 | 
						|
 | 
						|
MainDialog::MainDialog()
 | 
						|
{
 | 
						|
    mIconWidget = new QListWidget;
 | 
						|
    mIconWidget->setObjectName("IconWidget");
 | 
						|
    mIconWidget->setViewMode(QListView::IconMode);
 | 
						|
    mIconWidget->setWrapping(false);
 | 
						|
    mIconWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // Just to be sure
 | 
						|
    mIconWidget->setIconSize(QSize(48, 48));
 | 
						|
    mIconWidget->setMovement(QListView::Static);
 | 
						|
 | 
						|
    mIconWidget->setMinimumWidth(400);
 | 
						|
    mIconWidget->setFixedHeight(80);
 | 
						|
    mIconWidget->setSpacing(4);
 | 
						|
    mIconWidget->setCurrentRow(0);
 | 
						|
    mIconWidget->setFlow(QListView::LeftToRight);
 | 
						|
 | 
						|
    QGroupBox *groupBox = new QGroupBox(this);
 | 
						|
    QVBoxLayout *groupLayout = new QVBoxLayout(groupBox);
 | 
						|
 | 
						|
    mPagesWidget = new QStackedWidget(groupBox);
 | 
						|
    groupLayout->addWidget(mPagesWidget);
 | 
						|
 | 
						|
    QPushButton *playButton = new QPushButton(tr("Play"));
 | 
						|
 | 
						|
    QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
 | 
						|
    buttonBox->setStandardButtons(QDialogButtonBox::Close);
 | 
						|
    buttonBox->addButton(playButton, QDialogButtonBox::AcceptRole);
 | 
						|
 | 
						|
    QVBoxLayout *dialogLayout = new QVBoxLayout(this);
 | 
						|
    dialogLayout->addWidget(mIconWidget);
 | 
						|
    dialogLayout->addWidget(groupBox);
 | 
						|
    dialogLayout->addWidget(buttonBox);
 | 
						|
 | 
						|
 | 
						|
    setWindowTitle(tr("OpenMW Launcher"));
 | 
						|
    setWindowIcon(QIcon(":/images/openmw.png"));
 | 
						|
    // Remove what's this? button
 | 
						|
    setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
 | 
						|
    setMinimumSize(QSize(575, 575));
 | 
						|
 | 
						|
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
 | 
						|
    connect(buttonBox, SIGNAL(accepted()), this, SLOT(play()));
 | 
						|
 | 
						|
    createIcons();
 | 
						|
    createPages();
 | 
						|
}
 | 
						|
 | 
						|
void MainDialog::createIcons()
 | 
						|
{
 | 
						|
    if (!QIcon::hasThemeIcon("document-new")) {
 | 
						|
        QIcon::setThemeName("tango");
 | 
						|
    }
 | 
						|
 | 
						|
    // We create a fallback icon because the default fallback doesn't work
 | 
						|
    QIcon graphicsIcon = QIcon(":/icons/tango/video-display.png");
 | 
						|
 | 
						|
    QListWidgetItem *playButton = new QListWidgetItem(mIconWidget);
 | 
						|
    playButton->setIcon(QIcon(":/images/openmw.png"));
 | 
						|
    playButton->setText(tr("Play"));
 | 
						|
    playButton->setTextAlignment(Qt::AlignCenter);
 | 
						|
    playButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
 | 
						|
 | 
						|
    QListWidgetItem *graphicsButton = new QListWidgetItem(mIconWidget);
 | 
						|
    graphicsButton->setIcon(QIcon::fromTheme("video-display", graphicsIcon));
 | 
						|
    graphicsButton->setText(tr("Graphics"));
 | 
						|
    graphicsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom | Qt::AlignAbsolute);
 | 
						|
    graphicsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
 | 
						|
 | 
						|
    QListWidgetItem *dataFilesButton = new QListWidgetItem(mIconWidget);
 | 
						|
    dataFilesButton->setIcon(QIcon(":/images/openmw-plugin.png"));
 | 
						|
    dataFilesButton->setText(tr("Data Files"));
 | 
						|
    dataFilesButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
 | 
						|
    dataFilesButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
 | 
						|
 | 
						|
    connect(mIconWidget,
 | 
						|
            SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
 | 
						|
            this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*)));
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
QStringList MainDialog::readConfig(const QString &fileName)
 | 
						|
{
 | 
						|
    // We can't use QSettings directly because it
 | 
						|
    // does not support multiple keys with the same name
 | 
						|
    QFile file(fileName);
 | 
						|
 | 
						|
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
 | 
						|
        QMessageBox msgBox;
 | 
						|
        msgBox.setWindowTitle("Error opening OpenMW configuration file");
 | 
						|
        msgBox.setIcon(QMessageBox::Critical);
 | 
						|
        msgBox.setStandardButtons(QMessageBox::Ok);
 | 
						|
        msgBox.setText(tr("<br><b>Could not open %0</b><br><br> \
 | 
						|
        Please make sure you have the right permissions and try again.<br>").arg(file.fileName()));
 | 
						|
        msgBox.exec();
 | 
						|
 | 
						|
        QApplication::exit(); // File cannot be opened or created
 | 
						|
    }
 | 
						|
 | 
						|
    QTextStream in(&file);
 | 
						|
    QStringList dataDirs;
 | 
						|
    QString dataLocal;
 | 
						|
 | 
						|
    // Read the config line by line
 | 
						|
    while (!in.atEnd()) {
 | 
						|
        QString line = in.readLine();
 | 
						|
 | 
						|
        if (line.startsWith("data=")) {
 | 
						|
            dataDirs.append(line.remove("data="));
 | 
						|
        }
 | 
						|
 | 
						|
        // Read the data-local key, if more than one are found only the last is used
 | 
						|
        if (line.startsWith("data-local=")) {
 | 
						|
            dataLocal = line.remove("data-local=");
 | 
						|
        }
 | 
						|
 | 
						|
        // Read fs-strict key
 | 
						|
        if (line.startsWith("fs-strict=")) {
 | 
						|
            QString value = line.remove("fs-strict=");
 | 
						|
 | 
						|
            (value.toLower() == QLatin1String("true"))
 | 
						|
            ? mStrict = true
 | 
						|
            : mStrict = false;
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    // Add the data-local= key to the end of the dataDirs for priority reasons
 | 
						|
    if (!dataLocal.isEmpty()) {
 | 
						|
        dataDirs.append(dataLocal);
 | 
						|
    }
 | 
						|
 | 
						|
    if (!dataDirs.isEmpty())
 | 
						|
    {
 | 
						|
        // Reset the global datadirs to the newly read entries
 | 
						|
        // Else return the previous dataDirs because nothing was found in this file;
 | 
						|
        mDataDirs = dataDirs;
 | 
						|
    }
 | 
						|
 | 
						|
    file.close();
 | 
						|
 | 
						|
    return mDataDirs;
 | 
						|
}
 | 
						|
 | 
						|
void MainDialog::createPages()
 | 
						|
{
 | 
						|
    mPlayPage = new PlayPage(this);
 | 
						|
    mGraphicsPage = new GraphicsPage(this);
 | 
						|
    mDataFilesPage = new DataFilesPage(this);
 | 
						|
 | 
						|
    // Retrieve all data entries from the configs
 | 
						|
    QStringList dataDirs;
 | 
						|
 | 
						|
    // Global location
 | 
						|
    QFile file(QString::fromStdString((mCfg.getGlobalConfigPath()/"openmw.cfg").string()));
 | 
						|
    if (file.exists()) {
 | 
						|
        dataDirs = readConfig(file.fileName());
 | 
						|
    }
 | 
						|
 | 
						|
    // User location
 | 
						|
    file.setFileName(QString::fromStdString((mCfg.getLocalConfigPath()/"openmw.cfg").string()));
 | 
						|
    if (file.exists()) {
 | 
						|
        dataDirs = readConfig(file.fileName());
 | 
						|
    }
 | 
						|
 | 
						|
    // Local location
 | 
						|
    file.setFileName("./openmw.cfg");
 | 
						|
 | 
						|
    if (file.exists()) {
 | 
						|
        dataDirs = readConfig(file.fileName());
 | 
						|
    }
 | 
						|
 | 
						|
    file.close();
 | 
						|
 | 
						|
    if (!dataDirs.isEmpty()) {
 | 
						|
        // Now pass the datadirs on to the DataFilesPage
 | 
						|
        mDataFilesPage->setupDataFiles(dataDirs, mStrict);
 | 
						|
    } else {
 | 
						|
        QMessageBox msgBox;
 | 
						|
        msgBox.setWindowTitle("Error reading OpenMW configuration file");
 | 
						|
        msgBox.setIcon(QMessageBox::Critical);
 | 
						|
        msgBox.setStandardButtons(QMessageBox::Ok);
 | 
						|
        msgBox.setText(tr("<br><b>Could not read the location of the data files</b><br><br> \
 | 
						|
                        Please make sure OpenMW is correctly configured and try again.<br>"));
 | 
						|
        msgBox.exec();
 | 
						|
 | 
						|
        QApplication::exit(); // No data or data-local entries in openmw.cfg
 | 
						|
    }
 | 
						|
 | 
						|
    // Set the combobox of the play page to imitate the comobox on the datafilespage
 | 
						|
    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(mDataFilesPage);
 | 
						|
 | 
						|
    // Select the first page
 | 
						|
    mIconWidget->setCurrentItem(mIconWidget->item(0), QItemSelectionModel::Select);
 | 
						|
 | 
						|
    connect(mPlayPage->mPlayButton, SIGNAL(clicked()), this, SLOT(play()));
 | 
						|
 | 
						|
    connect(mPlayPage->mProfilesComboBox,
 | 
						|
            SIGNAL(currentIndexChanged(int)),
 | 
						|
            this, SLOT(profileChanged(int)));
 | 
						|
 | 
						|
    connect(mDataFilesPage->mProfilesComboBox,
 | 
						|
            SIGNAL(currentIndexChanged(int)),
 | 
						|
            this, SLOT(profileChanged(int)));
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void MainDialog::profileChanged(int index)
 | 
						|
{
 | 
						|
    // Just to be sure, should always have a selection
 | 
						|
    if (!mIconWidget->selectionModel()->hasSelection()) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    QString currentPage = mIconWidget->currentItem()->data(Qt::DisplayRole).toString();
 | 
						|
    if (currentPage == QLatin1String("Play")) {
 | 
						|
        mDataFilesPage->mProfilesComboBox->setCurrentIndex(index);
 | 
						|
    }
 | 
						|
 | 
						|
    if (currentPage == QLatin1String("Data Files")) {
 | 
						|
        mPlayPage->mProfilesComboBox->setCurrentIndex(index);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous)
 | 
						|
{
 | 
						|
    if (!current)
 | 
						|
        current = previous;
 | 
						|
 | 
						|
    mPagesWidget->setCurrentIndex(mIconWidget->row(current));
 | 
						|
}
 | 
						|
 | 
						|
void MainDialog::closeEvent(QCloseEvent *event)
 | 
						|
{
 | 
						|
    // Now write all config files
 | 
						|
    writeConfig();
 | 
						|
    event->accept();
 | 
						|
}
 | 
						|
 | 
						|
void MainDialog::play()
 | 
						|
{
 | 
						|
    // First do a write of all the configs, just to be sure
 | 
						|
    writeConfig();
 | 
						|
 | 
						|
#ifdef Q_WS_WIN
 | 
						|
    QString game = "./openmw.exe";
 | 
						|
    QFile file(game);
 | 
						|
#elif defined(Q_WS_MAC)
 | 
						|
    QDir dir(QCoreApplication::applicationDirPath());
 | 
						|
    QString game = dir.absoluteFilePath("openmw");
 | 
						|
    QFile file(game);
 | 
						|
#else
 | 
						|
    QString game = "./openmw";
 | 
						|
    QFile file(game);
 | 
						|
#endif
 | 
						|
 | 
						|
    QProcess process;
 | 
						|
    QFileInfo info(file);
 | 
						|
 | 
						|
    if (!file.exists()) {
 | 
						|
        QMessageBox msgBox;
 | 
						|
        msgBox.setWindowTitle("Error starting OpenMW");
 | 
						|
        msgBox.setIcon(QMessageBox::Warning);
 | 
						|
        msgBox.setStandardButtons(QMessageBox::Ok);
 | 
						|
        msgBox.setText(tr("<br><b>Could not find OpenMW</b><br><br> \
 | 
						|
                        The OpenMW application is not found.<br> \
 | 
						|
                        Please make sure OpenMW is installed correctly and try again.<br>"));
 | 
						|
        msgBox.exec();
 | 
						|
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!info.isExecutable()) {
 | 
						|
        QMessageBox msgBox;
 | 
						|
        msgBox.setWindowTitle("Error starting OpenMW");
 | 
						|
        msgBox.setIcon(QMessageBox::Critical);
 | 
						|
        msgBox.setStandardButtons(QMessageBox::Ok);
 | 
						|
        msgBox.setText(tr("<br><b>Could not start OpenMW</b><br><br> \
 | 
						|
                        The OpenMW application is not executable.<br> \
 | 
						|
                        Please make sure you have the right permissions and try again.<br>"));
 | 
						|
        msgBox.exec();
 | 
						|
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    // Start the game
 | 
						|
    if (!process.startDetached(game)) {
 | 
						|
        QMessageBox msgBox;
 | 
						|
        msgBox.setWindowTitle("Error starting OpenMW");
 | 
						|
        msgBox.setIcon(QMessageBox::Critical);
 | 
						|
        msgBox.setStandardButtons(QMessageBox::Ok);
 | 
						|
        msgBox.setText(tr("<br><b>Could not start OpenMW</b><br><br> \
 | 
						|
                        An error occurred while starting OpenMW.<br><br> \
 | 
						|
                        Press \"Show Details...\" for more information.<br>"));
 | 
						|
        msgBox.setDetailedText(process.errorString());
 | 
						|
        msgBox.exec();
 | 
						|
 | 
						|
        return;
 | 
						|
    } else {
 | 
						|
        close();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void MainDialog::writeConfig()
 | 
						|
{
 | 
						|
    // Write the profiles
 | 
						|
    mDataFilesPage->writeConfig();
 | 
						|
    mDataFilesPage->mLauncherConfig->sync();
 | 
						|
 | 
						|
    // Write the graphics settings
 | 
						|
    mGraphicsPage->writeConfig();
 | 
						|
    mGraphicsPage->mOgreConfig->sync();
 | 
						|
 | 
						|
    QStringList dataFiles = mDataFilesPage->selectedMasters();
 | 
						|
    dataFiles.append(mDataFilesPage->checkedPlugins());
 | 
						|
 | 
						|
    // Open the config as a QFile
 | 
						|
    QFile file(QString::fromStdString((mCfg.getLocalConfigPath()/"openmw.cfg").string()));
 | 
						|
 | 
						|
    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();
 | 
						|
 | 
						|
        QApplication::exit(1);
 | 
						|
    }
 | 
						|
 | 
						|
    QTextStream in(&file);
 | 
						|
    QByteArray buffer;
 | 
						|
 | 
						|
    // Remove all previous master/plugin entries from config
 | 
						|
    while (!in.atEnd()) {
 | 
						|
        QString line = in.readLine();
 | 
						|
        if (!line.contains("master") && !line.contains("plugin")) {
 | 
						|
            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();
 | 
						|
 | 
						|
        QApplication::exit(1);
 | 
						|
    }
 | 
						|
 | 
						|
    file.write(buffer);
 | 
						|
 | 
						|
    QTextStream out(&file);
 | 
						|
 | 
						|
    // Write the list of game files to the config
 | 
						|
    foreach (const QString ¤tFile, dataFiles) {
 | 
						|
 | 
						|
        if (currentFile.endsWith(QString(".esm"), Qt::CaseInsensitive)) {
 | 
						|
            out << "master=" << currentFile << endl;
 | 
						|
        } else if (currentFile.endsWith(QString(".esp"), Qt::CaseInsensitive)) {
 | 
						|
            out << "plugin=" << currentFile << endl;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    file.close();
 | 
						|
}
 |