Fixed a lot of MSVC problems
This commit is contained in:
		@@ -20,8 +20,6 @@
 | 
			
		||||
#include <QPoint>
 | 
			
		||||
#include <QColor>
 | 
			
		||||
 | 
			
		||||
AppSettings *settings;
 | 
			
		||||
 | 
			
		||||
AppSettings::AppSettings(QObject *parent) :
 | 
			
		||||
	BasicSettingsObject(parent)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,4 @@ public:
 | 
			
		||||
	explicit AppSettings(QObject *parent = 0);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern AppSettings *settings;
 | 
			
		||||
 | 
			
		||||
#endif // APPSETTINGS_H
 | 
			
		||||
 
 | 
			
		||||
@@ -34,213 +34,215 @@
 | 
			
		||||
// commandline splitter
 | 
			
		||||
QStringList MinecraftProcess::splitArgs(QString args)
 | 
			
		||||
{
 | 
			
		||||
    QStringList argv;
 | 
			
		||||
    QString current;
 | 
			
		||||
    bool escape = false;
 | 
			
		||||
    QChar inquotes;
 | 
			
		||||
    for (int i=0; i<args.length(); i++)
 | 
			
		||||
    {
 | 
			
		||||
        QChar cchar = args.at(i);
 | 
			
		||||
 | 
			
		||||
        // \ escaped
 | 
			
		||||
        if (escape) {
 | 
			
		||||
            current += cchar;
 | 
			
		||||
            escape = false;
 | 
			
		||||
        // in "quotes"
 | 
			
		||||
        } else if (!inquotes.isNull()) {
 | 
			
		||||
            if (cchar == 0x5C)
 | 
			
		||||
                escape = true;
 | 
			
		||||
            else if (cchar == inquotes)
 | 
			
		||||
                inquotes = 0;
 | 
			
		||||
            else
 | 
			
		||||
                current += cchar;
 | 
			
		||||
        // otherwise
 | 
			
		||||
        } else {
 | 
			
		||||
            if (cchar == 0x20) {
 | 
			
		||||
                if (!current.isEmpty()) {
 | 
			
		||||
                    argv << current;
 | 
			
		||||
                    current.clear();
 | 
			
		||||
                }
 | 
			
		||||
            } else if (cchar == 0x22 || cchar == 0x27)
 | 
			
		||||
                inquotes = cchar;
 | 
			
		||||
            else
 | 
			
		||||
                current += cchar;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (!current.isEmpty())
 | 
			
		||||
        argv << current;
 | 
			
		||||
    return argv;
 | 
			
		||||
	QStringList argv;
 | 
			
		||||
	QString current;
 | 
			
		||||
	bool escape = false;
 | 
			
		||||
	QChar inquotes;
 | 
			
		||||
	for (int i=0; i<args.length(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		QChar cchar = args.at(i);
 | 
			
		||||
		
 | 
			
		||||
		// \ escaped
 | 
			
		||||
		if (escape) {
 | 
			
		||||
			current += cchar;
 | 
			
		||||
			escape = false;
 | 
			
		||||
			// in "quotes"
 | 
			
		||||
		} else if (!inquotes.isNull()) {
 | 
			
		||||
			if (cchar == 0x5C)
 | 
			
		||||
				escape = true;
 | 
			
		||||
			else if (cchar == inquotes)
 | 
			
		||||
				inquotes = 0;
 | 
			
		||||
			else
 | 
			
		||||
				current += cchar;
 | 
			
		||||
			// otherwise
 | 
			
		||||
		} else {
 | 
			
		||||
			if (cchar == 0x20) {
 | 
			
		||||
				if (!current.isEmpty()) {
 | 
			
		||||
					argv << current;
 | 
			
		||||
					current.clear();
 | 
			
		||||
				}
 | 
			
		||||
			} else if (cchar == 0x22 || cchar == 0x27)
 | 
			
		||||
				inquotes = cchar;
 | 
			
		||||
			else
 | 
			
		||||
				current += cchar;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (!current.isEmpty())
 | 
			
		||||
		argv << current;
 | 
			
		||||
	return argv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// prepare tools
 | 
			
		||||
inline void MinecraftProcess::extractIcon(InstancePtr inst, QString destination)
 | 
			
		||||
{
 | 
			
		||||
    QImage(":/icons/instances/" + inst->iconKey()).save(destination);
 | 
			
		||||
	QImage(":/icons/instances/" + inst->iconKey()).save(destination);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void MinecraftProcess::extractLauncher(QString destination)
 | 
			
		||||
{
 | 
			
		||||
    QFile(":/launcher/launcher.jar").copy(destination);
 | 
			
		||||
	QFile(":/launcher/launcher.jar").copy(destination);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MinecraftProcess::prepare(InstancePtr inst)
 | 
			
		||||
{
 | 
			
		||||
    extractLauncher(PathCombine(inst->minecraftDir(), LAUNCHER_FILE));
 | 
			
		||||
    extractIcon(inst, PathCombine(inst->minecraftDir(), "icon.png"));
 | 
			
		||||
	extractLauncher(PathCombine(inst->minecraftDir(), LAUNCHER_FILE));
 | 
			
		||||
	extractIcon(inst, PathCombine(inst->minecraftDir(), "icon.png"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// constructor
 | 
			
		||||
MinecraftProcess::MinecraftProcess(InstancePtr inst, QString user, QString session, ConsoleWindow *console) :
 | 
			
		||||
    m_instance(inst), m_user(user), m_session(session), m_console(console)
 | 
			
		||||
	m_instance(inst), m_user(user), m_session(session), m_console(console)
 | 
			
		||||
{
 | 
			
		||||
    connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(finish(int, QProcess::ExitStatus)));
 | 
			
		||||
 | 
			
		||||
    // prepare the process environment
 | 
			
		||||
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
 | 
			
		||||
 | 
			
		||||
	connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(finish(int, QProcess::ExitStatus)));
 | 
			
		||||
	
 | 
			
		||||
	// prepare the process environment
 | 
			
		||||
	QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
 | 
			
		||||
	
 | 
			
		||||
#ifdef LINUX
 | 
			
		||||
    // Strip IBus
 | 
			
		||||
    if (env.value("XMODIFIERS").contains(IBUS))
 | 
			
		||||
        env.insert("XMODIFIERS", env.value("XMODIFIERS").replace(IBUS, ""));
 | 
			
		||||
	// Strip IBus
 | 
			
		||||
	if (env.value("XMODIFIERS").contains(IBUS))
 | 
			
		||||
		env.insert("XMODIFIERS", env.value("XMODIFIERS").replace(IBUS, ""));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // export some infos
 | 
			
		||||
    env.insert("INST_NAME", inst->name());
 | 
			
		||||
    env.insert("INST_ID", inst->id());
 | 
			
		||||
    env.insert("INST_DIR", QDir(inst->rootDir()).absolutePath());
 | 
			
		||||
 | 
			
		||||
    this->setProcessEnvironment(env);
 | 
			
		||||
    m_prepostlaunchprocess.setProcessEnvironment(env);
 | 
			
		||||
 | 
			
		||||
    // set the cwd
 | 
			
		||||
    QDir mcDir(inst->minecraftDir());
 | 
			
		||||
    this->setWorkingDirectory(mcDir.absolutePath());
 | 
			
		||||
    m_prepostlaunchprocess.setWorkingDirectory(mcDir.absolutePath());
 | 
			
		||||
 | 
			
		||||
    // std channels
 | 
			
		||||
    connect(this, SIGNAL(readyReadStandardError()), SLOT(on_stdErr()));
 | 
			
		||||
    connect(this, SIGNAL(readyReadStandardOutput()), SLOT(on_stdOut()));
 | 
			
		||||
	
 | 
			
		||||
	// export some infos
 | 
			
		||||
	env.insert("INST_NAME", inst->name());
 | 
			
		||||
	env.insert("INST_ID", inst->id());
 | 
			
		||||
	env.insert("INST_DIR", QDir(inst->rootDir()).absolutePath());
 | 
			
		||||
	
 | 
			
		||||
	this->setProcessEnvironment(env);
 | 
			
		||||
	m_prepostlaunchprocess.setProcessEnvironment(env);
 | 
			
		||||
	
 | 
			
		||||
	// set the cwd
 | 
			
		||||
	QDir mcDir(inst->minecraftDir());
 | 
			
		||||
	this->setWorkingDirectory(mcDir.absolutePath());
 | 
			
		||||
	m_prepostlaunchprocess.setWorkingDirectory(mcDir.absolutePath());
 | 
			
		||||
	
 | 
			
		||||
	// std channels
 | 
			
		||||
	connect(this, SIGNAL(readyReadStandardError()), SLOT(on_stdErr()));
 | 
			
		||||
	connect(this, SIGNAL(readyReadStandardOutput()), SLOT(on_stdOut()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// console window
 | 
			
		||||
void MinecraftProcess::on_stdErr()
 | 
			
		||||
{
 | 
			
		||||
    if (m_console != nullptr)
 | 
			
		||||
        m_console->write(readAllStandardError(), ConsoleWindow::ERROR);
 | 
			
		||||
	if (m_console != nullptr)
 | 
			
		||||
		m_console->write(readAllStandardError(), ConsoleWindow::ERROR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MinecraftProcess::on_stdOut()
 | 
			
		||||
{
 | 
			
		||||
    if (m_console != nullptr)
 | 
			
		||||
        m_console->write(readAllStandardOutput(), ConsoleWindow::DEFAULT);
 | 
			
		||||
	if (m_console != nullptr)
 | 
			
		||||
		m_console->write(readAllStandardOutput(), ConsoleWindow::DEFAULT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MinecraftProcess::log(QString text)
 | 
			
		||||
{
 | 
			
		||||
    if (m_console != nullptr)
 | 
			
		||||
        m_console->write(text);
 | 
			
		||||
    else
 | 
			
		||||
        qDebug(qPrintable(text));
 | 
			
		||||
	if (m_console != nullptr)
 | 
			
		||||
		m_console->write(text);
 | 
			
		||||
	else
 | 
			
		||||
		qDebug(qPrintable(text));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// exit handler
 | 
			
		||||
void MinecraftProcess::finish(int code, ExitStatus status)
 | 
			
		||||
{
 | 
			
		||||
    if (status != NormalExit)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO: error handling
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    log("Minecraft exited.");
 | 
			
		||||
 | 
			
		||||
    m_prepostlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(code));
 | 
			
		||||
 | 
			
		||||
    // run post-exit
 | 
			
		||||
    if (!m_instance->getPostExitCommand().isEmpty())
 | 
			
		||||
    {
 | 
			
		||||
        m_prepostlaunchprocess.start(m_instance->getPostExitCommand());
 | 
			
		||||
        m_prepostlaunchprocess.waitForFinished();
 | 
			
		||||
        if (m_prepostlaunchprocess.exitStatus() != NormalExit)
 | 
			
		||||
        {
 | 
			
		||||
            //TODO: error handling
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m_console != nullptr)
 | 
			
		||||
        m_console->setMayClose(true);
 | 
			
		||||
 | 
			
		||||
    emit ended();
 | 
			
		||||
	if (status != NormalExit)
 | 
			
		||||
	{
 | 
			
		||||
		//TODO: error handling
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	log("Minecraft exited.");
 | 
			
		||||
	
 | 
			
		||||
	m_prepostlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(code));
 | 
			
		||||
	
 | 
			
		||||
	// run post-exit
 | 
			
		||||
	if (!m_instance->settings().get("PostExitCommand").toString().isEmpty())
 | 
			
		||||
	{
 | 
			
		||||
		m_prepostlaunchprocess.start(m_instance->settings().get("PostExitCommand").toString());
 | 
			
		||||
		m_prepostlaunchprocess.waitForFinished();
 | 
			
		||||
		if (m_prepostlaunchprocess.exitStatus() != NormalExit)
 | 
			
		||||
		{
 | 
			
		||||
			//TODO: error handling
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (m_console != nullptr)
 | 
			
		||||
		m_console->setMayClose(true);
 | 
			
		||||
	
 | 
			
		||||
	emit ended();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MinecraftProcess::launch()
 | 
			
		||||
{
 | 
			
		||||
    if (!m_instance->getPreLaunchCommand().isEmpty())
 | 
			
		||||
    {
 | 
			
		||||
        m_prepostlaunchprocess.start(m_instance->getPreLaunchCommand());
 | 
			
		||||
        m_prepostlaunchprocess.waitForFinished();
 | 
			
		||||
        if (m_prepostlaunchprocess.exitStatus() != NormalExit)
 | 
			
		||||
        {
 | 
			
		||||
            //TODO: error handling
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_instance->setLastLaunch();
 | 
			
		||||
 | 
			
		||||
    prepare(m_instance);
 | 
			
		||||
 | 
			
		||||
    genArgs();
 | 
			
		||||
 | 
			
		||||
    log(QString("Minecraft folder is: '%1'").arg(workingDirectory()));
 | 
			
		||||
    log(QString("Instance launched with arguments: '%1'").arg(m_arguments.join("' '")));
 | 
			
		||||
 | 
			
		||||
    start(m_instance->getJavaPath(), m_arguments);
 | 
			
		||||
    if (!waitForStarted())
 | 
			
		||||
    {
 | 
			
		||||
        //TODO: error handling
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(m_console != nullptr)
 | 
			
		||||
        m_console->setMayClose(false);
 | 
			
		||||
	if (!m_instance->settings().get("PreLaunchCommand").toString().isEmpty())
 | 
			
		||||
	{
 | 
			
		||||
		m_prepostlaunchprocess.start(m_instance->settings().get("PreLaunchCommand").toString());
 | 
			
		||||
		m_prepostlaunchprocess.waitForFinished();
 | 
			
		||||
		if (m_prepostlaunchprocess.exitStatus() != NormalExit)
 | 
			
		||||
		{
 | 
			
		||||
			//TODO: error handling
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	m_instance->setLastLaunch();
 | 
			
		||||
	
 | 
			
		||||
	prepare(m_instance);
 | 
			
		||||
	
 | 
			
		||||
	genArgs();
 | 
			
		||||
	
 | 
			
		||||
	log(QString("Minecraft folder is: '%1'").arg(workingDirectory()));
 | 
			
		||||
	log(QString("Instance launched with arguments: '%1'").arg(m_arguments.join("' '")));
 | 
			
		||||
	
 | 
			
		||||
	start(m_instance->settings().get("JavaPath").toString(), m_arguments);
 | 
			
		||||
	if (!waitForStarted())
 | 
			
		||||
	{
 | 
			
		||||
		//TODO: error handling
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if(m_console != nullptr)
 | 
			
		||||
		m_console->setMayClose(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MinecraftProcess::genArgs()
 | 
			
		||||
{
 | 
			
		||||
    // start fresh
 | 
			
		||||
    m_arguments.clear();
 | 
			
		||||
 | 
			
		||||
    // window size
 | 
			
		||||
    QString windowSize;
 | 
			
		||||
    if (m_instance->getLaunchMaximized())
 | 
			
		||||
        windowSize = "max";
 | 
			
		||||
    else
 | 
			
		||||
        windowSize = QString("%1x%2").arg(m_instance->getMinecraftWinWidth()).arg(m_instance->getMinecraftWinHeight());
 | 
			
		||||
 | 
			
		||||
    // window title
 | 
			
		||||
    QString windowTitle;
 | 
			
		||||
    windowTitle.append("MultiMC: ").append(m_instance->name());
 | 
			
		||||
 | 
			
		||||
    // Java arguments
 | 
			
		||||
    m_arguments.append(splitArgs(m_instance->getJvmArgs()));
 | 
			
		||||
 | 
			
		||||
	// start fresh
 | 
			
		||||
	m_arguments.clear();
 | 
			
		||||
	
 | 
			
		||||
	// window size
 | 
			
		||||
	QString windowSize;
 | 
			
		||||
	if (m_instance->settings().get("LaunchMaximized").toBool())
 | 
			
		||||
		windowSize = "max";
 | 
			
		||||
	else
 | 
			
		||||
		windowSize = QString("%1x%2").
 | 
			
		||||
				arg(m_instance->settings().get("MinecraftWinWidth").toInt()).
 | 
			
		||||
				arg(m_instance->settings().get("MinecraftWinHeight").toInt());
 | 
			
		||||
	
 | 
			
		||||
	// window title
 | 
			
		||||
	QString windowTitle;
 | 
			
		||||
	windowTitle.append("MultiMC: ").append(m_instance->name());
 | 
			
		||||
	
 | 
			
		||||
	// Java arguments
 | 
			
		||||
	m_arguments.append(splitArgs(m_instance->settings().get("JvmArgs").toString()));
 | 
			
		||||
	
 | 
			
		||||
#ifdef OSX
 | 
			
		||||
    // OSX dock icon and name
 | 
			
		||||
    m_arguments << "-Xdock:icon=icon.png";
 | 
			
		||||
    m_arguments << QString("-Xdock:name=\"%1\"").arg(windowTitle);
 | 
			
		||||
	// OSX dock icon and name
 | 
			
		||||
	m_arguments << "-Xdock:icon=icon.png";
 | 
			
		||||
	m_arguments << QString("-Xdock:name=\"%1\"").arg(windowTitle);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // lwjgl
 | 
			
		||||
    QString lwjgl = m_instance->lwjglVersion();
 | 
			
		||||
    if (lwjgl != "Mojang")
 | 
			
		||||
        lwjgl = QDir(settings->getLWJGLDir() + "/" + lwjgl).absolutePath();
 | 
			
		||||
 | 
			
		||||
    // launcher arguments
 | 
			
		||||
    m_arguments << QString("-Xms%1m").arg(m_instance->getMinMemAlloc());
 | 
			
		||||
    m_arguments << QString("-Xmx%1m").arg(m_instance->getMaxMemAlloc());
 | 
			
		||||
    m_arguments << "-jar" << LAUNCHER_FILE;
 | 
			
		||||
    m_arguments << m_user;
 | 
			
		||||
    m_arguments << m_session;
 | 
			
		||||
    m_arguments << windowTitle;
 | 
			
		||||
    m_arguments << windowSize;
 | 
			
		||||
    m_arguments << lwjgl;
 | 
			
		||||
	
 | 
			
		||||
	// lwjgl
 | 
			
		||||
	QString lwjgl = m_instance->lwjglVersion();
 | 
			
		||||
	if (lwjgl != "Mojang")
 | 
			
		||||
		lwjgl = QDir(globalSettings->get("LWJGLDir").toString() + "/" + lwjgl).absolutePath();
 | 
			
		||||
	
 | 
			
		||||
	// launcher arguments
 | 
			
		||||
	m_arguments << QString("-Xms%1m").arg(m_instance->settings().get("MinMemAlloc").toInt());
 | 
			
		||||
	m_arguments << QString("-Xmx%1m").arg(m_instance->settings().get("MaxMemAlloc").toInt());
 | 
			
		||||
	m_arguments << "-jar" << LAUNCHER_FILE;
 | 
			
		||||
	m_arguments << m_user;
 | 
			
		||||
	m_arguments << m_session;
 | 
			
		||||
	m_arguments << windowTitle;
 | 
			
		||||
	m_arguments << windowSize;
 | 
			
		||||
	m_arguments << lwjgl;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ void openInDefaultProgram(QString filename);
 | 
			
		||||
MainWindow::MainWindow(QWidget *parent) :
 | 
			
		||||
	QMainWindow(parent),
 | 
			
		||||
	ui(new Ui::MainWindow),
 | 
			
		||||
	instList(settings->get("InstanceDir").toString())
 | 
			
		||||
	instList(globalSettings->get("InstanceDir").toString())
 | 
			
		||||
{
 | 
			
		||||
	ui->setupUi(this);
 | 
			
		||||
	
 | 
			
		||||
@@ -78,7 +78,7 @@ void MainWindow::on_actionAddInstance_triggered()
 | 
			
		||||
 | 
			
		||||
void MainWindow::on_actionViewInstanceFolder_triggered()
 | 
			
		||||
{
 | 
			
		||||
	openInDefaultProgram(settings->get("InstanceDir").toString());
 | 
			
		||||
	openInDefaultProgram(globalSettings->get("InstanceDir").toString());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::on_actionRefresh_triggered()
 | 
			
		||||
@@ -88,7 +88,7 @@ void MainWindow::on_actionRefresh_triggered()
 | 
			
		||||
 | 
			
		||||
void MainWindow::on_actionViewCentralModsFolder_triggered()
 | 
			
		||||
{
 | 
			
		||||
	openInDefaultProgram(settings->get("CentralModsDir").toString());
 | 
			
		||||
	openInDefaultProgram(globalSettings->get("CentralModsDir").toString());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::on_actionCheckUpdate_triggered()
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) :
 | 
			
		||||
{
 | 
			
		||||
	ui->setupUi(this);
 | 
			
		||||
	
 | 
			
		||||
	loadSettings(settings);
 | 
			
		||||
	loadSettings(globalSettings);
 | 
			
		||||
	updateCheckboxStuff();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -84,7 +84,7 @@ void SettingsDialog::on_maximizedCheckBox_clicked(bool checked)
 | 
			
		||||
 | 
			
		||||
void SettingsDialog::on_buttonBox_accepted()
 | 
			
		||||
{
 | 
			
		||||
	applySettings(settings);
 | 
			
		||||
	applySettings(globalSettings);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SettingsDialog::applySettings(SettingsObject *s)
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,8 @@
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
 | 
			
		||||
#include <settingsobject.h>
 | 
			
		||||
 | 
			
		||||
#include "inifile.h"
 | 
			
		||||
 | 
			
		||||
#include "libinstance_config.h"
 | 
			
		||||
@@ -280,6 +282,16 @@ public:
 | 
			
		||||
	 */
 | 
			
		||||
	virtual void updateCurrentVersion(bool keepCurrent = false) = 0; 
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	//// Settings System ////
 | 
			
		||||
	
 | 
			
		||||
	/*!
 | 
			
		||||
	 * \brief Gets this instance's settings object.
 | 
			
		||||
	 * This settings object stores instance-specific settings.
 | 
			
		||||
	 * \return A pointer to this instance's settings object.
 | 
			
		||||
	 */
 | 
			
		||||
	virtual SettingsObject &settings();
 | 
			
		||||
	
 | 
			
		||||
protected:
 | 
			
		||||
	/*!
 | 
			
		||||
	 * \brief Gets the value of the given field in the instance's config file.
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,8 @@
 | 
			
		||||
 | 
			
		||||
#include <QFileInfo>
 | 
			
		||||
 | 
			
		||||
#include "settingsobject.h"
 | 
			
		||||
 | 
			
		||||
#include "pathutils.h"
 | 
			
		||||
 | 
			
		||||
Instance::Instance(const QString &rootDir, QObject *parent) :
 | 
			
		||||
@@ -104,3 +106,8 @@ void Instance::setField(const QString &name, QVariant val)
 | 
			
		||||
{
 | 
			
		||||
	config.set(name, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SettingsObject &Instance::settings()
 | 
			
		||||
{
 | 
			
		||||
	return *globalSettings;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -162,4 +162,9 @@ private:
 | 
			
		||||
	QMap<QString, Setting *> m_settings;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 * \brief A global settings object.
 | 
			
		||||
 */
 | 
			
		||||
LIBMMCSETTINGS_EXPORT extern SettingsObject *globalSettings;
 | 
			
		||||
 | 
			
		||||
#endif // SETTINGSOBJECT_H
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,8 @@
 | 
			
		||||
 | 
			
		||||
#include <QVariant>
 | 
			
		||||
 | 
			
		||||
SettingsObject *globalSettings;
 | 
			
		||||
 | 
			
		||||
SettingsObject::SettingsObject(QObject *parent) :
 | 
			
		||||
	QObject(parent)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,8 @@
 | 
			
		||||
#include <QHash>
 | 
			
		||||
#include <QStringList>
 | 
			
		||||
 | 
			
		||||
#include "libutil_config.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file libutil/include/cmdutils.h
 | 
			
		||||
 * @brief commandline parsing utilities
 | 
			
		||||
@@ -37,7 +39,11 @@ namespace Commandline {
 | 
			
		||||
 * @brief The FlagStyle enum
 | 
			
		||||
 * Specifies how flags are decorated
 | 
			
		||||
 */
 | 
			
		||||
enum class FlagStyle {
 | 
			
		||||
 | 
			
		||||
namespace FlagStyle
 | 
			
		||||
{
 | 
			
		||||
enum LIBMMCUTIL_EXPORT Enum
 | 
			
		||||
{
 | 
			
		||||
	GNU,     /**< --option and -o (GNU Style) */
 | 
			
		||||
	Unix,    /**< -option and -o  (Unix Style) */
 | 
			
		||||
	Windows, /**< /option and /o  (Windows Style) */
 | 
			
		||||
@@ -47,11 +53,15 @@ enum class FlagStyle {
 | 
			
		||||
	Default = GNU
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The ArgumentStyle enum
 | 
			
		||||
 */
 | 
			
		||||
enum class ArgumentStyle {
 | 
			
		||||
namespace ArgumentStyle 
 | 
			
		||||
{
 | 
			
		||||
enum LIBMMCUTIL_EXPORT Enum
 | 
			
		||||
{
 | 
			
		||||
	Space,          /**< --option=value */
 | 
			
		||||
	Equals,         /**< --option value */
 | 
			
		||||
	SpaceAndEquals, /**< --option[= ]value */
 | 
			
		||||
@@ -61,11 +71,21 @@ enum class ArgumentStyle {
 | 
			
		||||
	Default = SpaceAndEquals
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace OptionType
 | 
			
		||||
{
 | 
			
		||||
enum LIBMMCUTIL_EXPORT Enum
 | 
			
		||||
{
 | 
			
		||||
	Switch,
 | 
			
		||||
	Option
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The ParsingError class
 | 
			
		||||
 */
 | 
			
		||||
class ParsingError : public std::exception
 | 
			
		||||
class LIBMMCUTIL_EXPORT ParsingError : public std::exception
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	ParsingError(const QString &what);
 | 
			
		||||
@@ -80,7 +100,7 @@ private:
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The Parser class
 | 
			
		||||
 */
 | 
			
		||||
class Parser
 | 
			
		||||
class LIBMMCUTIL_EXPORT Parser
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	/**
 | 
			
		||||
@@ -88,45 +108,46 @@ public:
 | 
			
		||||
	 * @param flagStyle the FlagStyle to use in this Parser
 | 
			
		||||
	 * @param argStyle the ArgumentStyle to use in this Parser
 | 
			
		||||
	 */
 | 
			
		||||
	Parser(FlagStyle flagStyle=FlagStyle::Default, ArgumentStyle argStyle=ArgumentStyle::Default);
 | 
			
		||||
	Parser(FlagStyle::Enum flagStyle = FlagStyle::Default, 
 | 
			
		||||
		   ArgumentStyle::Enum argStyle = ArgumentStyle::Default);
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief set the flag style
 | 
			
		||||
	 * @param style
 | 
			
		||||
	 */
 | 
			
		||||
	void setFlagStyle(FlagStyle style);
 | 
			
		||||
	void setFlagStyle(FlagStyle::Enum style);
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief get the flag style
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
	FlagStyle flagStyle();
 | 
			
		||||
	FlagStyle::Enum flagStyle();
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief set the argument style
 | 
			
		||||
	 * @param style
 | 
			
		||||
	 */
 | 
			
		||||
	void setArgumentStyle(ArgumentStyle style);
 | 
			
		||||
	void setArgumentStyle(ArgumentStyle::Enum style);
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief get the argument style
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
	ArgumentStyle argumentStyle();
 | 
			
		||||
	ArgumentStyle::Enum argumentStyle();
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief define a boolean switch
 | 
			
		||||
	 * @param name the parameter name
 | 
			
		||||
	 * @param def the default value
 | 
			
		||||
	 */
 | 
			
		||||
	void addSwitch(QString name, bool def=false);
 | 
			
		||||
	void addSwitch(QString name, bool def = false);
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief define an option that takes an additional argument
 | 
			
		||||
	 * @param name the parameter name
 | 
			
		||||
	 * @param def the default value
 | 
			
		||||
	 */
 | 
			
		||||
	void addOption(QString name, QVariant def=QVariant());
 | 
			
		||||
	void addOption(QString name, QVariant def = QVariant());
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief define a positional argument
 | 
			
		||||
@@ -134,7 +155,7 @@ public:
 | 
			
		||||
	 * @param required wether this argument is required
 | 
			
		||||
	 * @param def the default value
 | 
			
		||||
	 */
 | 
			
		||||
	void addArgument(QString name, bool required=true, QVariant def=QVariant());
 | 
			
		||||
	void addArgument(QString name, bool required = true, QVariant def = QVariant());
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief adds a flag to an existing parameter
 | 
			
		||||
@@ -153,7 +174,7 @@ public:
 | 
			
		||||
	 * Note: on positional arguments, metavar replaces the name as displayed.
 | 
			
		||||
	 *       on options , metavar replaces the value placeholder
 | 
			
		||||
	 */
 | 
			
		||||
	void addDocumentation(QString name, QString doc, QString metavar=QString());
 | 
			
		||||
	void addDocumentation(QString name, QString doc, QString metavar = QString());
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief generate a help message
 | 
			
		||||
@@ -162,7 +183,7 @@ public:
 | 
			
		||||
	 * @param flagsInUsage whether we should use flags instead of options in the usage
 | 
			
		||||
	 * @return a help message
 | 
			
		||||
	 */
 | 
			
		||||
	QString compileHelp(QString progName, int helpIndent=22, bool flagsInUsage=true);
 | 
			
		||||
	QString compileHelp(QString progName, int helpIndent = 22, bool flagsInUsage = true);
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief generate a short usage message
 | 
			
		||||
@@ -170,7 +191,7 @@ public:
 | 
			
		||||
	 * @param useFlags whether we should use flags instead of options
 | 
			
		||||
	 * @return a usage message
 | 
			
		||||
	 */
 | 
			
		||||
	QString compileUsage(QString progName, bool useFlags=true);
 | 
			
		||||
	QString compileUsage(QString progName, bool useFlags = true);
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief parse
 | 
			
		||||
@@ -187,13 +208,8 @@ public:
 | 
			
		||||
	~Parser();
 | 
			
		||||
	
 | 
			
		||||
private:
 | 
			
		||||
	FlagStyle m_flagStyle;
 | 
			
		||||
	ArgumentStyle m_argStyle;
 | 
			
		||||
	
 | 
			
		||||
	enum class OptionType {
 | 
			
		||||
		Switch,
 | 
			
		||||
		Option
 | 
			
		||||
	};
 | 
			
		||||
	FlagStyle::Enum m_flagStyle;
 | 
			
		||||
	ArgumentStyle::Enum m_argStyle;
 | 
			
		||||
	
 | 
			
		||||
	// Important: the common part MUST BE COMMON ON ALL THREE structs
 | 
			
		||||
	struct CommonDef {
 | 
			
		||||
@@ -210,7 +226,7 @@ private:
 | 
			
		||||
		QString metavar;
 | 
			
		||||
		QVariant def;
 | 
			
		||||
		// option
 | 
			
		||||
		OptionType type;
 | 
			
		||||
		OptionType::Enum type;
 | 
			
		||||
		QChar flag;
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
 
 | 
			
		||||
@@ -3,15 +3,17 @@
 | 
			
		||||
 | 
			
		||||
#include <QString>
 | 
			
		||||
 | 
			
		||||
#include "libutil_config.h"
 | 
			
		||||
 | 
			
		||||
namespace Util
 | 
			
		||||
{
 | 
			
		||||
// Get the Directory representing the User's Desktop
 | 
			
		||||
QString getDesktopDir();
 | 
			
		||||
LIBMMCUTIL_EXPORT QString getDesktopDir();
 | 
			
		||||
 | 
			
		||||
// Create a shortcut at *location*, pointing to *dest* called with the arguments *args*
 | 
			
		||||
// call it *name* and assign it the icon *icon*
 | 
			
		||||
// return true if operation succeeded
 | 
			
		||||
bool createShortCut(QString location, QString dest, QStringList args, QString name, QString iconLocation);
 | 
			
		||||
LIBMMCUTIL_EXPORT bool createShortCut(QString location, QString dest, QStringList args, QString name, QString iconLocation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // USERUTILS_H
 | 
			
		||||
 
 | 
			
		||||
@@ -24,410 +24,410 @@
 | 
			
		||||
namespace Util {
 | 
			
		||||
namespace Commandline {
 | 
			
		||||
 | 
			
		||||
Parser::Parser(FlagStyle flagStyle, ArgumentStyle argStyle)
 | 
			
		||||
Parser::Parser(FlagStyle::Enum flagStyle, ArgumentStyle::Enum argStyle)
 | 
			
		||||
{
 | 
			
		||||
    m_flagStyle = flagStyle;
 | 
			
		||||
    m_argStyle = argStyle;
 | 
			
		||||
	m_flagStyle = flagStyle;
 | 
			
		||||
	m_argStyle = argStyle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// styles setter/getter
 | 
			
		||||
void Parser::setArgumentStyle(ArgumentStyle style)
 | 
			
		||||
void Parser::setArgumentStyle(ArgumentStyle::Enum style)
 | 
			
		||||
{
 | 
			
		||||
    m_argStyle = style;
 | 
			
		||||
	m_argStyle = style;
 | 
			
		||||
}
 | 
			
		||||
ArgumentStyle Parser::argumentStyle()
 | 
			
		||||
ArgumentStyle::Enum Parser::argumentStyle()
 | 
			
		||||
{
 | 
			
		||||
    return m_argStyle;
 | 
			
		||||
	return m_argStyle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Parser::setFlagStyle(FlagStyle style)
 | 
			
		||||
void Parser::setFlagStyle(FlagStyle::Enum style)
 | 
			
		||||
{
 | 
			
		||||
    m_flagStyle = style;
 | 
			
		||||
	m_flagStyle = style;
 | 
			
		||||
}
 | 
			
		||||
FlagStyle Parser::flagStyle()
 | 
			
		||||
FlagStyle::Enum Parser::flagStyle()
 | 
			
		||||
{
 | 
			
		||||
    return m_flagStyle;
 | 
			
		||||
	return m_flagStyle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup methods
 | 
			
		||||
void Parser::addSwitch(QString name, bool def)
 | 
			
		||||
{
 | 
			
		||||
    if (m_params.contains(name))
 | 
			
		||||
        throw "Name not unique";
 | 
			
		||||
 | 
			
		||||
    OptionDef *param = new OptionDef;
 | 
			
		||||
    param->type = OptionType::Switch;
 | 
			
		||||
    param->name = name;
 | 
			
		||||
    param->metavar = QString("<%1>").arg(name);
 | 
			
		||||
    param->def = def;
 | 
			
		||||
 | 
			
		||||
    m_options[name] = param;
 | 
			
		||||
    m_params[name] = (CommonDef *)param;
 | 
			
		||||
    m_optionList.append(param);
 | 
			
		||||
	if (m_params.contains(name))
 | 
			
		||||
		throw "Name not unique";
 | 
			
		||||
	
 | 
			
		||||
	OptionDef *param = new OptionDef;
 | 
			
		||||
	param->type = OptionType::Switch;
 | 
			
		||||
	param->name = name;
 | 
			
		||||
	param->metavar = QString("<%1>").arg(name);
 | 
			
		||||
	param->def = def;
 | 
			
		||||
	
 | 
			
		||||
	m_options[name] = param;
 | 
			
		||||
	m_params[name] = (CommonDef *)param;
 | 
			
		||||
	m_optionList.append(param);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Parser::addOption(QString name, QVariant def)
 | 
			
		||||
{
 | 
			
		||||
    if (m_params.contains(name))
 | 
			
		||||
        throw "Name not unique";
 | 
			
		||||
 | 
			
		||||
    OptionDef *param = new OptionDef;
 | 
			
		||||
    param->type = OptionType::Option;
 | 
			
		||||
    param->name = name;
 | 
			
		||||
    param->metavar = QString("<%1>").arg(name);
 | 
			
		||||
    param->def = def;
 | 
			
		||||
 | 
			
		||||
    m_options[name] = param;
 | 
			
		||||
    m_params[name] = (CommonDef *)param;
 | 
			
		||||
    m_optionList.append(param);
 | 
			
		||||
	if (m_params.contains(name))
 | 
			
		||||
		throw "Name not unique";
 | 
			
		||||
	
 | 
			
		||||
	OptionDef *param = new OptionDef;
 | 
			
		||||
	param->type = OptionType::Option;
 | 
			
		||||
	param->name = name;
 | 
			
		||||
	param->metavar = QString("<%1>").arg(name);
 | 
			
		||||
	param->def = def;
 | 
			
		||||
	
 | 
			
		||||
	m_options[name] = param;
 | 
			
		||||
	m_params[name] = (CommonDef *)param;
 | 
			
		||||
	m_optionList.append(param);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Parser::addArgument(QString name, bool required, QVariant def)
 | 
			
		||||
{
 | 
			
		||||
    if (m_params.contains(name))
 | 
			
		||||
        throw "Name not unique";
 | 
			
		||||
 | 
			
		||||
    PositionalDef *param = new PositionalDef;
 | 
			
		||||
    param->name = name;
 | 
			
		||||
    param->def = def;
 | 
			
		||||
    param->required = required;
 | 
			
		||||
    param->metavar = name;
 | 
			
		||||
 | 
			
		||||
    m_positionals.append(param);
 | 
			
		||||
    m_params[name] = (CommonDef *)param;
 | 
			
		||||
	if (m_params.contains(name))
 | 
			
		||||
		throw "Name not unique";
 | 
			
		||||
	
 | 
			
		||||
	PositionalDef *param = new PositionalDef;
 | 
			
		||||
	param->name = name;
 | 
			
		||||
	param->def = def;
 | 
			
		||||
	param->required = required;
 | 
			
		||||
	param->metavar = name;
 | 
			
		||||
	
 | 
			
		||||
	m_positionals.append(param);
 | 
			
		||||
	m_params[name] = (CommonDef *)param;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Parser::addDocumentation(QString name, QString doc, QString metavar)
 | 
			
		||||
{
 | 
			
		||||
    if (!m_params.contains(name))
 | 
			
		||||
        throw "Name does not exist";
 | 
			
		||||
 | 
			
		||||
    CommonDef *param = m_params[name];
 | 
			
		||||
    param->doc = doc;
 | 
			
		||||
    if (!metavar.isNull())
 | 
			
		||||
        param->metavar = metavar;
 | 
			
		||||
	if (!m_params.contains(name))
 | 
			
		||||
		throw "Name does not exist";
 | 
			
		||||
	
 | 
			
		||||
	CommonDef *param = m_params[name];
 | 
			
		||||
	param->doc = doc;
 | 
			
		||||
	if (!metavar.isNull())
 | 
			
		||||
		param->metavar = metavar;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Parser::addShortOpt(QString name, QChar flag)
 | 
			
		||||
{
 | 
			
		||||
    if (!m_params.contains(name))
 | 
			
		||||
        throw "Name does not exist";
 | 
			
		||||
    if (!m_options.contains(name))
 | 
			
		||||
        throw "Name is not an Option or Swtich";
 | 
			
		||||
 | 
			
		||||
    OptionDef *param = m_options[name];
 | 
			
		||||
    m_flags[flag] = param;
 | 
			
		||||
    param->flag = flag;
 | 
			
		||||
	if (!m_params.contains(name))
 | 
			
		||||
		throw "Name does not exist";
 | 
			
		||||
	if (!m_options.contains(name))
 | 
			
		||||
		throw "Name is not an Option or Swtich";
 | 
			
		||||
	
 | 
			
		||||
	OptionDef *param = m_options[name];
 | 
			
		||||
	m_flags[flag] = param;
 | 
			
		||||
	param->flag = flag;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// help methods
 | 
			
		||||
QString Parser::compileHelp(QString progName, int helpIndent, bool useFlags)
 | 
			
		||||
{
 | 
			
		||||
    QStringList help;
 | 
			
		||||
    help << compileUsage(progName, useFlags) << "\r\n";
 | 
			
		||||
 | 
			
		||||
    // positionals
 | 
			
		||||
    if (!m_positionals.isEmpty())
 | 
			
		||||
    {
 | 
			
		||||
        help << "\r\n";
 | 
			
		||||
        help << "Positional arguments:\r\n";
 | 
			
		||||
        QListIterator<PositionalDef *> it2(m_positionals);
 | 
			
		||||
        while(it2.hasNext())
 | 
			
		||||
        {
 | 
			
		||||
            PositionalDef *param = it2.next();
 | 
			
		||||
            help << "  " << param->metavar;
 | 
			
		||||
            help << " " << QString(helpIndent - param->metavar.length() - 1, ' ');
 | 
			
		||||
            help << param->doc << "\r\n";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Options
 | 
			
		||||
    if (!m_optionList.isEmpty())
 | 
			
		||||
    {
 | 
			
		||||
        help << "\r\n";
 | 
			
		||||
        QString optPrefix, flagPrefix;
 | 
			
		||||
        getPrefix(optPrefix, flagPrefix);
 | 
			
		||||
 | 
			
		||||
        help << "Options & Switches:\r\n";
 | 
			
		||||
        QListIterator<OptionDef *> it(m_optionList);
 | 
			
		||||
        while(it.hasNext())
 | 
			
		||||
        {
 | 
			
		||||
            OptionDef *option = it.next();
 | 
			
		||||
            help << "  ";
 | 
			
		||||
            int nameLength = optPrefix.length() + option->name.length();
 | 
			
		||||
            if (!option->flag.isNull())
 | 
			
		||||
            {
 | 
			
		||||
                nameLength += 3 + flagPrefix.length();
 | 
			
		||||
                help << flagPrefix << option->flag << ", ";
 | 
			
		||||
            }
 | 
			
		||||
            help << optPrefix << option->name;
 | 
			
		||||
            if (option->type == OptionType::Option)
 | 
			
		||||
            {
 | 
			
		||||
                QString arg = QString("%1%2").arg(((m_argStyle == ArgumentStyle::Equals) ? "=" : " "), option->metavar);
 | 
			
		||||
                nameLength += arg.length();
 | 
			
		||||
                help << arg;
 | 
			
		||||
            }
 | 
			
		||||
            help << " " << QString(helpIndent - nameLength - 1, ' ');
 | 
			
		||||
            help << option->doc << "\r\n";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return help.join("");
 | 
			
		||||
	QStringList help;
 | 
			
		||||
	help << compileUsage(progName, useFlags) << "\r\n";
 | 
			
		||||
	
 | 
			
		||||
	// positionals
 | 
			
		||||
	if (!m_positionals.isEmpty())
 | 
			
		||||
	{
 | 
			
		||||
		help << "\r\n";
 | 
			
		||||
		help << "Positional arguments:\r\n";
 | 
			
		||||
		QListIterator<PositionalDef *> it2(m_positionals);
 | 
			
		||||
		while(it2.hasNext())
 | 
			
		||||
		{
 | 
			
		||||
			PositionalDef *param = it2.next();
 | 
			
		||||
			help << "  " << param->metavar;
 | 
			
		||||
			help << " " << QString(helpIndent - param->metavar.length() - 1, ' ');
 | 
			
		||||
			help << param->doc << "\r\n";
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// Options
 | 
			
		||||
	if (!m_optionList.isEmpty())
 | 
			
		||||
	{
 | 
			
		||||
		help << "\r\n";
 | 
			
		||||
		QString optPrefix, flagPrefix;
 | 
			
		||||
		getPrefix(optPrefix, flagPrefix);
 | 
			
		||||
		
 | 
			
		||||
		help << "Options & Switches:\r\n";
 | 
			
		||||
		QListIterator<OptionDef *> it(m_optionList);
 | 
			
		||||
		while(it.hasNext())
 | 
			
		||||
		{
 | 
			
		||||
			OptionDef *option = it.next();
 | 
			
		||||
			help << "  ";
 | 
			
		||||
			int nameLength = optPrefix.length() + option->name.length();
 | 
			
		||||
			if (!option->flag.isNull())
 | 
			
		||||
			{
 | 
			
		||||
				nameLength += 3 + flagPrefix.length();
 | 
			
		||||
				help << flagPrefix << option->flag << ", ";
 | 
			
		||||
			}
 | 
			
		||||
			help << optPrefix << option->name;
 | 
			
		||||
			if (option->type == OptionType::Option)
 | 
			
		||||
			{
 | 
			
		||||
				QString arg = QString("%1%2").arg(((m_argStyle == ArgumentStyle::Equals) ? "=" : " "), option->metavar);
 | 
			
		||||
				nameLength += arg.length();
 | 
			
		||||
				help << arg;
 | 
			
		||||
			}
 | 
			
		||||
			help << " " << QString(helpIndent - nameLength - 1, ' ');
 | 
			
		||||
			help << option->doc << "\r\n";
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return help.join("");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString Parser::compileUsage(QString progName, bool useFlags)
 | 
			
		||||
{
 | 
			
		||||
    QStringList usage;
 | 
			
		||||
    usage << "Usage: " << progName;
 | 
			
		||||
 | 
			
		||||
    QString optPrefix, flagPrefix;
 | 
			
		||||
    getPrefix(optPrefix, flagPrefix);
 | 
			
		||||
 | 
			
		||||
    // options
 | 
			
		||||
    QListIterator<OptionDef *> it(m_optionList);
 | 
			
		||||
    while(it.hasNext())
 | 
			
		||||
    {
 | 
			
		||||
        OptionDef *option = it.next();
 | 
			
		||||
        usage << " [";
 | 
			
		||||
        if (!option->flag.isNull() && useFlags)
 | 
			
		||||
            usage << flagPrefix << option->flag;
 | 
			
		||||
        else
 | 
			
		||||
            usage << optPrefix << option->name;
 | 
			
		||||
        if (option->type == OptionType::Option)
 | 
			
		||||
            usage << ((m_argStyle == ArgumentStyle::Equals) ? "=" : " ") <<  option->metavar;
 | 
			
		||||
        usage << "]";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // arguments
 | 
			
		||||
    QListIterator<PositionalDef *> it2(m_positionals);
 | 
			
		||||
    while(it2.hasNext())
 | 
			
		||||
    {
 | 
			
		||||
        PositionalDef *param = it2.next();
 | 
			
		||||
        usage << " " << (param->required ? "<" : "[");
 | 
			
		||||
        usage << param->metavar;
 | 
			
		||||
        usage << (param->required ? ">" : "]");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return usage.join("");
 | 
			
		||||
	QStringList usage;
 | 
			
		||||
	usage << "Usage: " << progName;
 | 
			
		||||
	
 | 
			
		||||
	QString optPrefix, flagPrefix;
 | 
			
		||||
	getPrefix(optPrefix, flagPrefix);
 | 
			
		||||
	
 | 
			
		||||
	// options
 | 
			
		||||
	QListIterator<OptionDef *> it(m_optionList);
 | 
			
		||||
	while(it.hasNext())
 | 
			
		||||
	{
 | 
			
		||||
		OptionDef *option = it.next();
 | 
			
		||||
		usage << " [";
 | 
			
		||||
		if (!option->flag.isNull() && useFlags)
 | 
			
		||||
			usage << flagPrefix << option->flag;
 | 
			
		||||
		else
 | 
			
		||||
			usage << optPrefix << option->name;
 | 
			
		||||
		if (option->type == OptionType::Option)
 | 
			
		||||
			usage << ((m_argStyle == ArgumentStyle::Equals) ? "=" : " ") <<  option->metavar;
 | 
			
		||||
		usage << "]";
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// arguments
 | 
			
		||||
	QListIterator<PositionalDef *> it2(m_positionals);
 | 
			
		||||
	while(it2.hasNext())
 | 
			
		||||
	{
 | 
			
		||||
		PositionalDef *param = it2.next();
 | 
			
		||||
		usage << " " << (param->required ? "<" : "[");
 | 
			
		||||
		usage << param->metavar;
 | 
			
		||||
		usage << (param->required ? ">" : "]");
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return usage.join("");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parsing
 | 
			
		||||
QHash<QString, QVariant> Parser::parse(QStringList argv)
 | 
			
		||||
{
 | 
			
		||||
    QHash<QString, QVariant> map;
 | 
			
		||||
 | 
			
		||||
    QStringListIterator it(argv);
 | 
			
		||||
    QString programName = it.next();
 | 
			
		||||
 | 
			
		||||
    QString optionPrefix;
 | 
			
		||||
    QString flagPrefix;
 | 
			
		||||
    QListIterator<PositionalDef *> positionals(m_positionals);
 | 
			
		||||
    QStringList expecting;
 | 
			
		||||
 | 
			
		||||
    getPrefix(optionPrefix, flagPrefix);
 | 
			
		||||
 | 
			
		||||
    while (it.hasNext())
 | 
			
		||||
    {
 | 
			
		||||
        QString arg = it.next();
 | 
			
		||||
 | 
			
		||||
        if (!expecting.isEmpty())
 | 
			
		||||
            // we were expecting an argument
 | 
			
		||||
        {
 | 
			
		||||
            QString name = expecting.first();
 | 
			
		||||
 | 
			
		||||
            if (map.contains(name))
 | 
			
		||||
                throw ParsingError(QString("Option %2%1 was given multiple times").arg(name, optionPrefix));
 | 
			
		||||
 | 
			
		||||
            map[name] = QVariant(arg);
 | 
			
		||||
 | 
			
		||||
            expecting.removeFirst();
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (arg.startsWith(optionPrefix))
 | 
			
		||||
            // we have an option
 | 
			
		||||
        {
 | 
			
		||||
            //qDebug("Found option %s", qPrintable(arg));
 | 
			
		||||
 | 
			
		||||
            QString name = arg.mid(optionPrefix.length());
 | 
			
		||||
            QString equals;
 | 
			
		||||
 | 
			
		||||
            if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && name.contains("="))
 | 
			
		||||
            {
 | 
			
		||||
                int i = name.indexOf("=");
 | 
			
		||||
                equals = name.mid(i+1);
 | 
			
		||||
                name = name.left(i);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (m_options.contains(name))
 | 
			
		||||
            {
 | 
			
		||||
                if (map.contains(name))
 | 
			
		||||
                    throw ParsingError(QString("Option %2%1 was given multiple times").arg(name, optionPrefix));
 | 
			
		||||
 | 
			
		||||
                OptionDef *option = m_options[name];
 | 
			
		||||
                if (option->type == OptionType::Switch)
 | 
			
		||||
                    map[name] = true;
 | 
			
		||||
                else //if (option->type == OptionType::Option)
 | 
			
		||||
                {
 | 
			
		||||
                    if (m_argStyle == ArgumentStyle::Space)
 | 
			
		||||
                        expecting.append(name);
 | 
			
		||||
                    else if (!equals.isNull())
 | 
			
		||||
                        map[name] = equals;
 | 
			
		||||
                    else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
 | 
			
		||||
                        expecting.append(name);
 | 
			
		||||
                    else
 | 
			
		||||
                        throw ParsingError(QString("Option %2%1 reqires an argument.").arg(name, optionPrefix));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (arg.startsWith(flagPrefix))
 | 
			
		||||
            // we have (a) flag(s)
 | 
			
		||||
        {
 | 
			
		||||
            //qDebug("Found flags %s", qPrintable(arg));
 | 
			
		||||
 | 
			
		||||
            QString flags = arg.mid(flagPrefix.length());
 | 
			
		||||
            QString equals;
 | 
			
		||||
 | 
			
		||||
            if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && flags.contains("="))
 | 
			
		||||
            {
 | 
			
		||||
                int i = flags.indexOf("=");
 | 
			
		||||
                equals = flags.mid(i+1);
 | 
			
		||||
                flags = flags.left(i);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < flags.length(); i++)
 | 
			
		||||
            {
 | 
			
		||||
                QChar flag = flags.at(i);
 | 
			
		||||
 | 
			
		||||
                if (!m_flags.contains(flag))
 | 
			
		||||
                    throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix));
 | 
			
		||||
 | 
			
		||||
                OptionDef *option = m_flags[flag];
 | 
			
		||||
 | 
			
		||||
                if (map.contains(option->name))
 | 
			
		||||
                    throw ParsingError(QString("Option %2%1 was given multiple times").arg(option->name, optionPrefix));
 | 
			
		||||
 | 
			
		||||
                if (option->type == OptionType::Switch)
 | 
			
		||||
                    map[option->name] = true;
 | 
			
		||||
                else //if (option->type == OptionType::Option)
 | 
			
		||||
                {
 | 
			
		||||
                    if (m_argStyle == ArgumentStyle::Space)
 | 
			
		||||
                        expecting.append(option->name);
 | 
			
		||||
                    else if (!equals.isNull())
 | 
			
		||||
                        if (i == flags.length()-1)
 | 
			
		||||
                            map[option->name] = equals;
 | 
			
		||||
                        else
 | 
			
		||||
                            throw ParsingError(QString("Flag %4%2 of Argument-requiring Option %1 not last flag in %4%3").arg(option->name, flag, flags, flagPrefix));
 | 
			
		||||
                    else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
 | 
			
		||||
                        expecting.append(option->name);
 | 
			
		||||
                    else
 | 
			
		||||
                        throw ParsingError(QString("Option %1 reqires an argument. (flag %3%2)").arg(option->name, flag, flagPrefix));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // must be a positional argument
 | 
			
		||||
        if (!positionals.hasNext())
 | 
			
		||||
            throw ParsingError(QString("Don't know what to do with '%1'").arg(arg));
 | 
			
		||||
 | 
			
		||||
        PositionalDef *param = positionals.next();
 | 
			
		||||
 | 
			
		||||
        map[param->name] = arg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // check if we're missing something
 | 
			
		||||
    if (!expecting.isEmpty())
 | 
			
		||||
        throw ParsingError(QString("Was still expecting arguments for %2%1").arg(expecting.join(QString(", ")+optionPrefix), optionPrefix));
 | 
			
		||||
 | 
			
		||||
    while (positionals.hasNext())
 | 
			
		||||
    {
 | 
			
		||||
        PositionalDef *param = positionals.next();
 | 
			
		||||
        if (param->required)
 | 
			
		||||
            throw ParsingError(QString("Missing required positional argument '%1'").arg(param->name));
 | 
			
		||||
        else
 | 
			
		||||
            map[param->name] = param->def;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // fill out gaps
 | 
			
		||||
    QListIterator<OptionDef *> iter(m_optionList);
 | 
			
		||||
    while (iter.hasNext())
 | 
			
		||||
    {
 | 
			
		||||
        OptionDef *option = iter.next();
 | 
			
		||||
        if (!map.contains(option->name))
 | 
			
		||||
            map[option->name] = option->def;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return map;
 | 
			
		||||
	QHash<QString, QVariant> map;
 | 
			
		||||
	
 | 
			
		||||
	QStringListIterator it(argv);
 | 
			
		||||
	QString programName = it.next();
 | 
			
		||||
	
 | 
			
		||||
	QString optionPrefix;
 | 
			
		||||
	QString flagPrefix;
 | 
			
		||||
	QListIterator<PositionalDef *> positionals(m_positionals);
 | 
			
		||||
	QStringList expecting;
 | 
			
		||||
	
 | 
			
		||||
	getPrefix(optionPrefix, flagPrefix);
 | 
			
		||||
	
 | 
			
		||||
	while (it.hasNext())
 | 
			
		||||
	{
 | 
			
		||||
		QString arg = it.next();
 | 
			
		||||
		
 | 
			
		||||
		if (!expecting.isEmpty())
 | 
			
		||||
			// we were expecting an argument
 | 
			
		||||
		{
 | 
			
		||||
			QString name = expecting.first();
 | 
			
		||||
			
 | 
			
		||||
			if (map.contains(name))
 | 
			
		||||
				throw ParsingError(QString("Option %2%1 was given multiple times").arg(name, optionPrefix));
 | 
			
		||||
			
 | 
			
		||||
			map[name] = QVariant(arg);
 | 
			
		||||
			
 | 
			
		||||
			expecting.removeFirst();
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (arg.startsWith(optionPrefix))
 | 
			
		||||
			// we have an option
 | 
			
		||||
		{
 | 
			
		||||
			//qDebug("Found option %s", qPrintable(arg));
 | 
			
		||||
			
 | 
			
		||||
			QString name = arg.mid(optionPrefix.length());
 | 
			
		||||
			QString equals;
 | 
			
		||||
			
 | 
			
		||||
			if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && name.contains("="))
 | 
			
		||||
			{
 | 
			
		||||
				int i = name.indexOf("=");
 | 
			
		||||
				equals = name.mid(i+1);
 | 
			
		||||
				name = name.left(i);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			if (m_options.contains(name))
 | 
			
		||||
			{
 | 
			
		||||
				if (map.contains(name))
 | 
			
		||||
					throw ParsingError(QString("Option %2%1 was given multiple times").arg(name, optionPrefix));
 | 
			
		||||
				
 | 
			
		||||
				OptionDef *option = m_options[name];
 | 
			
		||||
				if (option->type == OptionType::Switch)
 | 
			
		||||
					map[name] = true;
 | 
			
		||||
				else //if (option->type == OptionType::Option)
 | 
			
		||||
				{
 | 
			
		||||
					if (m_argStyle == ArgumentStyle::Space)
 | 
			
		||||
						expecting.append(name);
 | 
			
		||||
					else if (!equals.isNull())
 | 
			
		||||
						map[name] = equals;
 | 
			
		||||
					else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
 | 
			
		||||
						expecting.append(name);
 | 
			
		||||
					else
 | 
			
		||||
						throw ParsingError(QString("Option %2%1 reqires an argument.").arg(name, optionPrefix));
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix));
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (arg.startsWith(flagPrefix))
 | 
			
		||||
			// we have (a) flag(s)
 | 
			
		||||
		{
 | 
			
		||||
			//qDebug("Found flags %s", qPrintable(arg));
 | 
			
		||||
			
 | 
			
		||||
			QString flags = arg.mid(flagPrefix.length());
 | 
			
		||||
			QString equals;
 | 
			
		||||
			
 | 
			
		||||
			if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && flags.contains("="))
 | 
			
		||||
			{
 | 
			
		||||
				int i = flags.indexOf("=");
 | 
			
		||||
				equals = flags.mid(i+1);
 | 
			
		||||
				flags = flags.left(i);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			for (int i = 0; i < flags.length(); i++)
 | 
			
		||||
			{
 | 
			
		||||
				QChar flag = flags.at(i);
 | 
			
		||||
				
 | 
			
		||||
				if (!m_flags.contains(flag))
 | 
			
		||||
					throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix));
 | 
			
		||||
				
 | 
			
		||||
				OptionDef *option = m_flags[flag];
 | 
			
		||||
				
 | 
			
		||||
				if (map.contains(option->name))
 | 
			
		||||
					throw ParsingError(QString("Option %2%1 was given multiple times").arg(option->name, optionPrefix));
 | 
			
		||||
				
 | 
			
		||||
				if (option->type == OptionType::Switch)
 | 
			
		||||
					map[option->name] = true;
 | 
			
		||||
				else //if (option->type == OptionType::Option)
 | 
			
		||||
				{
 | 
			
		||||
					if (m_argStyle == ArgumentStyle::Space)
 | 
			
		||||
						expecting.append(option->name);
 | 
			
		||||
					else if (!equals.isNull())
 | 
			
		||||
						if (i == flags.length()-1)
 | 
			
		||||
							map[option->name] = equals;
 | 
			
		||||
						else
 | 
			
		||||
							throw ParsingError(QString("Flag %4%2 of Argument-requiring Option %1 not last flag in %4%3").arg(option->name, flag, flags, flagPrefix));
 | 
			
		||||
					else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
 | 
			
		||||
						expecting.append(option->name);
 | 
			
		||||
					else
 | 
			
		||||
						throw ParsingError(QString("Option %1 reqires an argument. (flag %3%2)").arg(option->name, flag, flagPrefix));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// must be a positional argument
 | 
			
		||||
		if (!positionals.hasNext())
 | 
			
		||||
			throw ParsingError(QString("Don't know what to do with '%1'").arg(arg));
 | 
			
		||||
		
 | 
			
		||||
		PositionalDef *param = positionals.next();
 | 
			
		||||
		
 | 
			
		||||
		map[param->name] = arg;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// check if we're missing something
 | 
			
		||||
	if (!expecting.isEmpty())
 | 
			
		||||
		throw ParsingError(QString("Was still expecting arguments for %2%1").arg(expecting.join(QString(", ")+optionPrefix), optionPrefix));
 | 
			
		||||
	
 | 
			
		||||
	while (positionals.hasNext())
 | 
			
		||||
	{
 | 
			
		||||
		PositionalDef *param = positionals.next();
 | 
			
		||||
		if (param->required)
 | 
			
		||||
			throw ParsingError(QString("Missing required positional argument '%1'").arg(param->name));
 | 
			
		||||
		else
 | 
			
		||||
			map[param->name] = param->def;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// fill out gaps
 | 
			
		||||
	QListIterator<OptionDef *> iter(m_optionList);
 | 
			
		||||
	while (iter.hasNext())
 | 
			
		||||
	{
 | 
			
		||||
		OptionDef *option = iter.next();
 | 
			
		||||
		if (!map.contains(option->name))
 | 
			
		||||
			map[option->name] = option->def;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return map;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//clear defs
 | 
			
		||||
void Parser::clear()
 | 
			
		||||
{
 | 
			
		||||
    m_flags.clear();
 | 
			
		||||
    m_params.clear();
 | 
			
		||||
    m_options.clear();
 | 
			
		||||
 | 
			
		||||
    QMutableListIterator<OptionDef *> it(m_optionList);
 | 
			
		||||
    while(it.hasNext())
 | 
			
		||||
    {
 | 
			
		||||
        OptionDef *option = it.next();
 | 
			
		||||
        it.remove();
 | 
			
		||||
        delete option;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QMutableListIterator<PositionalDef *> it2(m_positionals);
 | 
			
		||||
    while(it2.hasNext())
 | 
			
		||||
    {
 | 
			
		||||
        PositionalDef *arg = it2.next();
 | 
			
		||||
        it2.remove();
 | 
			
		||||
        delete arg;
 | 
			
		||||
    }
 | 
			
		||||
	m_flags.clear();
 | 
			
		||||
	m_params.clear();
 | 
			
		||||
	m_options.clear();
 | 
			
		||||
	
 | 
			
		||||
	QMutableListIterator<OptionDef *> it(m_optionList);
 | 
			
		||||
	while(it.hasNext())
 | 
			
		||||
	{
 | 
			
		||||
		OptionDef *option = it.next();
 | 
			
		||||
		it.remove();
 | 
			
		||||
		delete option;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	QMutableListIterator<PositionalDef *> it2(m_positionals);
 | 
			
		||||
	while(it2.hasNext())
 | 
			
		||||
	{
 | 
			
		||||
		PositionalDef *arg = it2.next();
 | 
			
		||||
		it2.remove();
 | 
			
		||||
		delete arg;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//Destructor
 | 
			
		||||
Parser::~Parser()
 | 
			
		||||
{
 | 
			
		||||
    clear();
 | 
			
		||||
	clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//getPrefix
 | 
			
		||||
void Parser::getPrefix(QString &opt, QString &flag)
 | 
			
		||||
{
 | 
			
		||||
    if (m_flagStyle == FlagStyle::Windows)
 | 
			
		||||
        opt = flag = "/";
 | 
			
		||||
    else if (m_flagStyle == FlagStyle::Unix)
 | 
			
		||||
        opt = flag = "-";
 | 
			
		||||
    //else if (m_flagStyle == FlagStyle::GNU)
 | 
			
		||||
    else {
 | 
			
		||||
        opt = "--";
 | 
			
		||||
        flag = "-";
 | 
			
		||||
    }
 | 
			
		||||
	if (m_flagStyle == FlagStyle::Windows)
 | 
			
		||||
		opt = flag = "/";
 | 
			
		||||
	else if (m_flagStyle == FlagStyle::Unix)
 | 
			
		||||
		opt = flag = "-";
 | 
			
		||||
	//else if (m_flagStyle == FlagStyle::GNU)
 | 
			
		||||
	else {
 | 
			
		||||
		opt = "--";
 | 
			
		||||
		flag = "-";
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParsingError
 | 
			
		||||
ParsingError::ParsingError(const QString &what)
 | 
			
		||||
{
 | 
			
		||||
    m_what = what;
 | 
			
		||||
	m_what = what;
 | 
			
		||||
}
 | 
			
		||||
ParsingError::ParsingError(const ParsingError &e)
 | 
			
		||||
{
 | 
			
		||||
    m_what = e.m_what;
 | 
			
		||||
	m_what = e.m_what;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *ParsingError::what() const throw()
 | 
			
		||||
{
 | 
			
		||||
    return m_what.toLocal8Bit().constData();
 | 
			
		||||
	return m_what.toLocal8Bit().constData();
 | 
			
		||||
}
 | 
			
		||||
QString ParsingError::qwhat() const
 | 
			
		||||
{
 | 
			
		||||
    return m_what;
 | 
			
		||||
	return m_what;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,94 +20,104 @@
 | 
			
		||||
 | 
			
		||||
bool called_coinit = false;
 | 
			
		||||
 | 
			
		||||
HRESULT CreateLink(LPCSTR linkPath, LPCWSTR targetPath, LPCWSTR args)
 | 
			
		||||
HRESULT CreateLink(LPCSTR linkPath, LPCSTR targetPath, LPCSTR args)
 | 
			
		||||
{
 | 
			
		||||
    HRESULT hres;
 | 
			
		||||
 | 
			
		||||
    if (!called_coinit)
 | 
			
		||||
    {
 | 
			
		||||
        hres = CoInitialize(NULL);
 | 
			
		||||
        called_coinit = true;
 | 
			
		||||
 | 
			
		||||
        if (!SUCCEEDED(hres))
 | 
			
		||||
        {
 | 
			
		||||
            qWarning("Failed to initialize COM. Error 0x%08X", hres);
 | 
			
		||||
            return hres;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    IShellLink* link;
 | 
			
		||||
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&link);
 | 
			
		||||
 | 
			
		||||
    if (SUCCEEDED(hres))
 | 
			
		||||
    {
 | 
			
		||||
        IPersistFile* persistFile;
 | 
			
		||||
 | 
			
		||||
        link->SetPath(targetPath);
 | 
			
		||||
        link->SetArguments(args);
 | 
			
		||||
 | 
			
		||||
        hres = link->QueryInterface(IID_IPersistFile, (LPVOID*)&persistFile);
 | 
			
		||||
        if (SUCCEEDED(hres))
 | 
			
		||||
        {
 | 
			
		||||
            WCHAR wstr[MAX_PATH];
 | 
			
		||||
 | 
			
		||||
            MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wstr, MAX_PATH);
 | 
			
		||||
 | 
			
		||||
            hres = persistFile->Save(wstr, TRUE);
 | 
			
		||||
            persistFile->Release();
 | 
			
		||||
        }
 | 
			
		||||
        link->Release();
 | 
			
		||||
    }
 | 
			
		||||
    return hres;
 | 
			
		||||
	HRESULT hres;
 | 
			
		||||
	
 | 
			
		||||
	if (!called_coinit)
 | 
			
		||||
	{
 | 
			
		||||
		hres = CoInitialize(NULL);
 | 
			
		||||
		called_coinit = true;
 | 
			
		||||
		
 | 
			
		||||
		if (!SUCCEEDED(hres))
 | 
			
		||||
		{
 | 
			
		||||
			qWarning("Failed to initialize COM. Error 0x%08X", hres);
 | 
			
		||||
			return hres;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	IShellLink* link;
 | 
			
		||||
	hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&link);
 | 
			
		||||
	
 | 
			
		||||
	if (SUCCEEDED(hres))
 | 
			
		||||
	{
 | 
			
		||||
		IPersistFile* persistFile;
 | 
			
		||||
		
 | 
			
		||||
		link->SetPath(targetPath);
 | 
			
		||||
		link->SetArguments(args);
 | 
			
		||||
		
 | 
			
		||||
		hres = link->QueryInterface(IID_IPersistFile, (LPVOID*)&persistFile);
 | 
			
		||||
		if (SUCCEEDED(hres))
 | 
			
		||||
		{
 | 
			
		||||
			WCHAR wstr[MAX_PATH];
 | 
			
		||||
			
 | 
			
		||||
			MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wstr, MAX_PATH);
 | 
			
		||||
			
 | 
			
		||||
			hres = persistFile->Save(wstr, TRUE);
 | 
			
		||||
			persistFile->Release();
 | 
			
		||||
		}
 | 
			
		||||
		link->Release();
 | 
			
		||||
	}
 | 
			
		||||
	return hres;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
QString Util::getDesktopDir()
 | 
			
		||||
{
 | 
			
		||||
    return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
 | 
			
		||||
	return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Cross-platform Shortcut creation
 | 
			
		||||
bool Util::createShortCut(QString location, QString dest, QStringList args, QString name, QString icon)
 | 
			
		||||
{
 | 
			
		||||
#if LINUX
 | 
			
		||||
    location = PathCombine(location, name + ".desktop");
 | 
			
		||||
    qDebug("location: %s", qPrintable(location));
 | 
			
		||||
 | 
			
		||||
    QFile f(location);
 | 
			
		||||
    f.open(QIODevice::WriteOnly | QIODevice::Text);
 | 
			
		||||
    QTextStream stream(&f);
 | 
			
		||||
 | 
			
		||||
    QString argstring;
 | 
			
		||||
    if (!args.empty())
 | 
			
		||||
        argstring = " '" + args.join("' '") + "'";
 | 
			
		||||
 | 
			
		||||
    stream << "[Desktop Entry]" << "\n";
 | 
			
		||||
    stream << "Type=Application" << "\n";
 | 
			
		||||
    stream << "TryExec=" << dest.toLocal8Bit() << "\n";
 | 
			
		||||
    stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n";
 | 
			
		||||
    stream << "Name=" << name.toLocal8Bit() << "\n";
 | 
			
		||||
    stream << "Icon=" << icon.toLocal8Bit() << "\n";
 | 
			
		||||
 | 
			
		||||
    stream.flush();
 | 
			
		||||
    f.close();
 | 
			
		||||
 | 
			
		||||
    f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
	location = PathCombine(location, name + ".desktop");
 | 
			
		||||
	qDebug("location: %s", qPrintable(location));
 | 
			
		||||
	
 | 
			
		||||
	QFile f(location);
 | 
			
		||||
	f.open(QIODevice::WriteOnly | QIODevice::Text);
 | 
			
		||||
	QTextStream stream(&f);
 | 
			
		||||
	
 | 
			
		||||
	QString argstring;
 | 
			
		||||
	if (!args.empty())
 | 
			
		||||
		argstring = " '" + args.join("' '") + "'";
 | 
			
		||||
	
 | 
			
		||||
	stream << "[Desktop Entry]" << "\n";
 | 
			
		||||
	stream << "Type=Application" << "\n";
 | 
			
		||||
	stream << "TryExec=" << dest.toLocal8Bit() << "\n";
 | 
			
		||||
	stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n";
 | 
			
		||||
	stream << "Name=" << name.toLocal8Bit() << "\n";
 | 
			
		||||
	stream << "Icon=" << icon.toLocal8Bit() << "\n";
 | 
			
		||||
	
 | 
			
		||||
	stream.flush();
 | 
			
		||||
	f.close();
 | 
			
		||||
	
 | 
			
		||||
	f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther);
 | 
			
		||||
	
 | 
			
		||||
	return true;
 | 
			
		||||
#elif WINDOWS
 | 
			
		||||
    QFile file(path, name + ".lnk");
 | 
			
		||||
    WCHAR *file_w;
 | 
			
		||||
    WCHAR *dest_w;
 | 
			
		||||
    WCHAR *args_w;
 | 
			
		||||
    file.fileName().toWCharArray(file_w);
 | 
			
		||||
    dest.toWCharArray(dest_w);
 | 
			
		||||
    args.toWCharArray(args_w);
 | 
			
		||||
    return SUCCEEDED(CreateLink(file_w, dest_w, args_w));
 | 
			
		||||
	// TODO: Fix
 | 
			
		||||
//	QFile file(PathCombine(location, name + ".lnk"));
 | 
			
		||||
//	WCHAR *file_w;
 | 
			
		||||
//	WCHAR *dest_w;
 | 
			
		||||
//	WCHAR *args_w;
 | 
			
		||||
//	file.fileName().toWCharArray(file_w);
 | 
			
		||||
//	dest.toWCharArray(dest_w);
 | 
			
		||||
	
 | 
			
		||||
//	QString argStr;
 | 
			
		||||
//	for (int i = 0; i < args.count(); i++)
 | 
			
		||||
//	{
 | 
			
		||||
//		argStr.append(args[i]);
 | 
			
		||||
//		argStr.append(" ");
 | 
			
		||||
//	}
 | 
			
		||||
//	argStr.toWCharArray(args_w);
 | 
			
		||||
	
 | 
			
		||||
//	return SUCCEEDED(CreateLink(file_w, dest_w, args_w));
 | 
			
		||||
	return false;
 | 
			
		||||
#else
 | 
			
		||||
    qWarning("Desktop Shortcuts not supported on your platform!");
 | 
			
		||||
    return false;
 | 
			
		||||
	qWarning("Desktop Shortcuts not supported on your platform!");
 | 
			
		||||
	return false;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								main.cpp
									
									
									
									
									
								
							@@ -52,7 +52,7 @@ private:
 | 
			
		||||
	MinecraftProcess *proc;
 | 
			
		||||
	ConsoleWindow *console;
 | 
			
		||||
public:
 | 
			
		||||
	InstanceLauncher(QString instId) : QObject(), instances(settings->get("InstanceDir").toString())
 | 
			
		||||
	InstanceLauncher(QString instId) : QObject(), instances(globalSettings->get("InstanceDir").toString())
 | 
			
		||||
	{
 | 
			
		||||
		this->instId = instId;
 | 
			
		||||
	}
 | 
			
		||||
@@ -85,7 +85,7 @@ private slots:
 | 
			
		||||
	{
 | 
			
		||||
		// TODO: console
 | 
			
		||||
		console = new ConsoleWindow();
 | 
			
		||||
		proc = new MinecraftProcess(instance, response.getUsername(), response.getSessionID(), console);
 | 
			
		||||
		proc = new MinecraftProcess(instance, response.username(), response.sessionID(), console);
 | 
			
		||||
		//if (instance->getShowConsole())
 | 
			
		||||
		console->show();
 | 
			
		||||
		connect(proc, SIGNAL(ended()), SLOT(onTerminated()));
 | 
			
		||||
@@ -217,7 +217,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
	QDir::setCurrent(args["dir"].toString());
 | 
			
		||||
	
 | 
			
		||||
	// load settings
 | 
			
		||||
	settings = new AppSettings(&app);
 | 
			
		||||
	globalSettings = new AppSettings(&app);
 | 
			
		||||
	
 | 
			
		||||
	// Register meta types.
 | 
			
		||||
	qRegisterMetaType<LoginResponse>("LoginResponse");
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user