#include <QMap>
#include <QString>
#include <QSettings>
#include <QTranslator>
#include <QtAlgorithms>
#include <QtGui/QApplication>
#include <QDesktopWidget>
#include <QLocale>
#include <QtDebug>
#include <QMessageBox>
#include <cstdlib>
#include <iostream>
#include <string>
#include "command_line_options.h"
#include "dialog.h"
#include "globals.h"
#include "vsession.h"
#include "xsession.h"
#include "httpxmldownloader.h"
#include "choosersettings.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QTranslator translator;
translator.load(":" + QLocale::system().name());
a.installTranslator(&translator);
CommandLineOptions cmdOptions(argc, argv);
QString autostart_uuid("");
std::string usage(
a.translate("Console", "Usage: vmchooser [ OPTIONS ]\n\n"
" --allow-vm-edit show the 'edit this vm' checkbox\n"
" --autoquit [secs] automatically exit if no selection is made after secs seconds\n"
" -b --base base directory where VM images are accessible\n"
" -d, --default name of default session\n"
" -c, --config alternative config file\n"
" -l, --locations location id(s), space separated\n"
" --location-mode how to treat entries for this location (IGNORE, BUMP or EXCLUSIVE)\n"
" --exam-mode enable exam mode\n"
" -P, --pool one or more pool names to display (comma separated)\n"
" -f, --file direct boot .desktop file\n"
" -x, --xpath path of X Session .desktop files\n"
" -u, --url url of vmware .xml file\n"
" -s, --size window size <width>x<height>\n"
" -t, --theme theme\n"
" --template-mode how to treat template entries (IGNORE or BUMP)\n"
" -p, --pvs show pvs options\n"
" -D, --debug print debug information\n"
" -v, --version print version and exit\n"
" -h, --help print usage information and exit\n"
" -S, --runscript change path to run-virt.sh\n"
" -T --tab default tab (0=xsession, 1=my vms, 2=all vms)\n"
" --no-vtx Host doesn't support VT-x/AMD-V (mark 64bit guests)\n"
" --start-uuid start lecture with the given uuid\n"
"\nFILE can be a vmware .xml or an X .desktop file\n").toUtf8().data());
if (cmdOptions.contains("error")) {
std::cerr << usage;
return EXIT_FAILURE;
}
if (cmdOptions.contains("usage")) {
std::cout << usage;
return EXIT_SUCCESS;
}
if (cmdOptions.contains("version")) {
std::cout << "vmchooser " << VMCHOOSER_VERSION << std::endl;
return EXIT_SUCCESS;
}
if (cmdOptions.contains("uuid")) {
autostart_uuid = cmdOptions.value("uuid");
}
if (cmdOptions.contains("file")) {
QString file(cmdOptions.value("file"));
if (file.endsWith(".desktop")) {
XSession s;
if (s.init(file) && s.run()) {
return EXIT_SUCCESS;
}
std::cerr
<< a.translate("Console",
"vmchooser: failed to run session").toUtf8().constData()
<< std::endl;
return EXIT_FAILURE;
} else {
std::cerr
<< a.translate("Console", "vmchooser: invalid session file").toUtf8().constData()
<< std::endl;
return EXIT_FAILURE;
}
}
// read configuration file:
// file supplied as command line option or
// user vmchooser.conf or
// global vmchooser.conf
QString confFile;
if (cmdOptions.contains("config")) {
if (QFileInfo(cmdOptions.value("config")).exists()) {
confFile = cmdOptions.value("config");
} else {
std::cerr << a.translate("Console", "Requested --config not found: ").toUtf8().constData() << cmdOptions.value("config").toUtf8().constData() << std::endl;
}
}
if (confFile.isEmpty() && QFileInfo(userConfFile).exists()) {
confFile = userConfFile;
std::cerr << a.translate("Console", "Using user specific config: ").toUtf8().constData() << userConfFile.toUtf8().constData() << std::endl;
}
if (confFile.isEmpty() && QFileInfo(globalConfFile).exists()) {
confFile = globalConfFile;
std::cerr << a.translate("Console", "Using global config: ").toUtf8().constData() << globalConfFile.toUtf8().constData() << std::endl;
}
if (confFile.isEmpty()) {
std::cerr << a.translate("Console", "No config file found or given").toUtf8().constData() << std::endl;
}
// TODO: This is the system wide settings, give proper name
QSettings settings(confFile, QSettings::IniFormat);
settings.setIniCodec("UTF-8");
if (ChooserSettings::getSetting("last-session").isEmpty()) {
QString defaultSession;
if (cmdOptions.contains("default")) {
defaultSession = cmdOptions.value("default");
} else if (settings.contains("default")) {
defaultSession = settings.value("default").toString();
}
ChooserSettings::setSetting("last-session", defaultSession);
}
if (cmdOptions.contains("xpath")) {
xSessionPath = cmdOptions.value("xpath");
} else if (settings.contains("xpath")) {
xSessionPath = settings.value("xpath").toString();
} // else keep default path
if (cmdOptions.contains("url")) {
urlBase = cmdOptions.value("url");
} else if (settings.contains("url")) {
urlBase = settings.value("url").toString();
} else {
std::cerr
<< a.translate("Console", "vmchooser: no URL given").toUtf8().data()
<< std::endl;
return EXIT_FAILURE;
}
// Change the runVmScript path
if (cmdOptions.contains("runscript")) {
runVmScript = cmdOptions.value("runscript");
} else if (settings.contains("runscript")) {
runVmScript = settings.value("runscript").toString();
}
/* PARSE URL */
if (!urlBase.startsWith("http://")) {
std::cerr
<< a.translate("Console", "vmchooser: invalid URL").toUtf8().data()
<< std::endl;
return EXIT_FAILURE;
} else {
if (!urlBase.endsWith("/")) {
urlBase += "/";
}
}
QString size;
int width, height;
if (cmdOptions.contains("fullscreen")) {
size = "fullscreen";
} else if (settings.contains("fullscreen")) {
size = "fullscreen";
} else if (cmdOptions.contains("size")) {
size = cmdOptions.value("size");
} else if (settings.contains("size")) {
size = settings.value("size").toString();
}
if (size != "fullscreen") {
QRegExp rx("^(\\d+)x(\\d+)$");
if (rx.indexIn(size) != -1) {
QStringList list = rx.capturedTexts();
width = list.value(1).toInt();
height = list.value(2).toInt();
} else if (!size.isEmpty()) {
std::cerr
<< a.translate("Console", "vmchooser: invalid size argument").toUtf8().data()
<< std::endl;
return EXIT_FAILURE;
} else {
width = VMCHOOSER_DEFAULT_WIDTH;
height = VMCHOOSER_DEFAULT_HEIGHT;
}
}
if (cmdOptions.contains("pool")) {
pool = cmdOptions.value("pool");
} else if (settings.contains("pool")) {
pool = settings.value("pool").toString();
}
if (cmdOptions.contains("theme")) {
theme = cmdOptions.value("theme");
} else if (settings.contains("theme")) {
theme = settings.value("theme").toString();
}
if (cmdOptions.contains("debugMode")) {
debugMode = true;
}
if (cmdOptions.contains("base")) {
basePath = cmdOptions.value("base");
} else if (settings.contains("base")) {
basePath = settings.value("base").toString();
} else if (settings.contains("path")) { // Compatibility to v1.0
basePath = settings.value("path").toString();
}
if (cmdOptions.contains("location-mode")) {
QString mode = cmdOptions.value("location-mode");
if (mode == "IGNORE") {
g_forLocationHandling = LOCATION_IGNORE;
} else if (mode == "BUMP") {
g_forLocationHandling = LOCATION_BUMP;
} else if (mode == "EXCLUSIVE") {
g_forLocationHandling = LOCATION_EXCLUSIVE;
} else {
qDebug() << "Invalid location mode: " << mode;
QMessageBox::critical(NULL, "Error", "Invalid location mode: " + mode);
return 1;
}
}
if (cmdOptions.contains("template-mode")) {
QString mode = cmdOptions.value("template-mode");
if (mode == "IGNORE") {
g_templateHandling = LOCATION_IGNORE;
} else if (mode == "BUMP") {
g_templateHandling = LOCATION_BUMP;
} else {
qDebug() << "Invalid template mode: " << mode;
QMessageBox::critical(NULL, "Error", "Invalid template mode: " + mode);
return 1;
}
}
int defaultTab = -1;
if (cmdOptions.contains("tab")) {
defaultTab = cmdOptions.value("tab").toInt();
}
QString locationIds;
if (cmdOptions.contains("locations")) {
locationIds = cmdOptions.value("locations");
}
if (cmdOptions.contains("no-vtx")) {
g_noVtx = true;
}
if (cmdOptions.contains("pvs")) {
pvsEnabled = true;
}
if (cmdOptions.contains("autoquit")) {
bool ok = false;
g_autoQuitSeconds = cmdOptions.value("autoquit").toInt(&ok, 10);
if (!ok) {
g_autoQuitSeconds = 0;
}
}
g_allowVmEdit = cmdOptions.contains("allow-vm-edit");
/* read session files */
QList<Session*> xsessions(XSession::readSessions(xSessionPath));
Dialog w(defaultTab, cmdOptions.contains("exam-mode"));
/* DOWNLOAD VSESSIONS */
HttpXmlDownloader httpxmldownloader;
httpxmldownloader.connectSlot(&w,
SLOT(addSessionsAfterDownload(QNetworkReply*)));
// read xml and add items later
if (cmdOptions.contains("exam-mode")) {
httpxmldownloader.makeRequest(urlBase + "list.php?exams=exam-mode", locationIds);
} else {
httpxmldownloader.makeRequest(urlBase + "list.php", locationIds);
}
/* DOWNLOAD NEWS */
HttpXmlDownloader news_downloader;
news_downloader.connectSlot(&w, SLOT(addNewsAfterDownload(QNetworkReply*)));
news_downloader.makeRequest(urlBase + "news.php");
/* DOWNLOAD HELP-SECTION */
HttpXmlDownloader help_downloader;
help_downloader.connectSlot(&w, SLOT(addHelpAfterDownload(QNetworkReply*)));
help_downloader.makeRequest(urlBase + "help.php");
w.setTheme();
w.setWindowFlags(Qt::FramelessWindowHint);
QRect desktopRect = QApplication::desktop()->availableGeometry(&w);
if (size == "fullscreen") {
width = desktopRect.width();
height = desktopRect.height();
_fullscreen = true;
}
w.resize(width, height);
if (xsessions.size()) {
qSort(xsessions.begin(), xsessions.end(), myLessThan);
w.addItems(xsessions, 0);
}
w.show();
if (autostart_uuid != "") {
qDebug() << "using startSession() from main.cpp";
w.startSession(autostart_uuid);
}
// center dialog on primary screen
QPoint center = desktopRect.center();
w.move(center.x() - w.width() * 0.5, center.y() - w.height() * 0.5);
a.setActiveWindow(&w);
return a.exec();
}