summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2019-05-30 01:14:31 +0200
committerSimon Rettberg2019-05-30 01:14:31 +0200
commitdf168536ca1aaf0b147e67ef214bf35dfd34e441 (patch)
tree7ffcd8e12318c57440e733728de71cf556705c12
parentAdd 'disable screensaver' checkbox (diff)
downloadvmchooser2-df168536ca1aaf0b147e67ef214bf35dfd34e441.tar.gz
vmchooser2-df168536ca1aaf0b147e67ef214bf35dfd34e441.tar.xz
vmchooser2-df168536ca1aaf0b147e67ef214bf35dfd34e441.zip
Cleanup, and rewrite cmdline + settings handling
Command line parsing now uses QCommandLineXXX classes Old unused options have been removed, like the "pools" feature Closes #3599
-rw-r--r--src/command_line_options.cpp140
-rw-r--r--src/command_line_options.h23
-rw-r--r--src/config.cpp103
-rw-r--r--src/config.h46
-rw-r--r--src/dialog.cpp59
-rw-r--r--src/dialog.h4
-rw-r--r--src/globals.cpp23
-rw-r--r--src/globals.h25
-rw-r--r--src/main.cpp284
-rw-r--r--src/vsession.cpp16
10 files changed, 235 insertions, 488 deletions
diff --git a/src/command_line_options.cpp b/src/command_line_options.cpp
deleted file mode 100644
index fc4e0e1..0000000
--- a/src/command_line_options.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-#include "command_line_options.h"
-#include <getopt.h>
-#include <QDebug>
-
-
-CommandLineOptions::CommandLineOptions(int argc, char * const argv[]) {
- // parse command line arguments (please sort by short option for easier handling)
- static const struct option longOptions[] = {
- {"allow-vm-edit", no_argument, nullptr, 'vmed'},
- {"autoquit", required_argument, nullptr, 'aqit'},
- {"base", required_argument, nullptr, 'b'},
- {"path", required_argument, nullptr, 'b'}, // Compatibility to v1.0
- {"config", required_argument, nullptr, 'c'},
- {"debug", no_argument, nullptr, 'D'},
- {"default", required_argument, nullptr, 'd'},
- {"exam-mode", no_argument, nullptr, 'exms'},
- {"fullscreen", no_argument, nullptr, 'F'},
- {"file", required_argument, nullptr, 'f'},
- {"help", no_argument, nullptr, 'h'},
- {"insecure", no_argument, nullptr, 'i'},
- {"locations", required_argument, nullptr, 'l'},
- {"pool", required_argument, nullptr, 'P'},
- {"pvs", no_argument, nullptr, 'p'},
- {"pvs-checked", no_argument, nullptr, 'pvck'},
- {"runscript", no_argument, nullptr, 'S'},
- {"size", required_argument, nullptr, 's'},
- {"tab", required_argument, nullptr, 'T'},
- {"theme", required_argument, nullptr, 't'},
- {"url", required_argument, nullptr, 'u'},
- {"url-list", required_argument, nullptr, 'ulst'},
- {"url-news", required_argument, nullptr, 'unws'},
- {"url-help", required_argument, nullptr, 'uhlp'},
- {"version", no_argument, nullptr, 'v'},
- {"xpath", required_argument, nullptr, 'x'},
- {"location-mode", required_argument, nullptr, 'locm'},
- {"template-mode", required_argument, nullptr, 'tmpm'},
- {"start-uuid", required_argument, nullptr, 'uuid'},
- {"no-vtx", no_argument, nullptr, 'nvtx'},
- {nullptr, 0, nullptr, 0}
- };
-
- int c;
-
- // Again, please sort alphabetically in getopt_long call and switch statement
- while ((c = getopt_long(argc, argv, "b:c:Dd:Ff:hil:P:pSs:t:T:u:vx:?", longOptions, nullptr)) != -1) {
- switch (c) {
- case 'aqit':
- options.insert("autoquit", optarg);
- break;
- case 'b':
- options.insert("base", optarg);
- break;
- case 'c':
- options.insert("config", optarg);
- break;
- case 'D':
- options.insert("debugMode", "debugMode");
- break;
- case 'd':
- options.insert("default", optarg);
- break;
- case 'F':
- options.insert("fullscreen", "fullscreen");
- break;
- case 'exms':
- options.insert("exam-mode", "yo");
- break;
- case 'f':
- options.insert("file", optarg);
- break;
- case 'h':
- case '?':
- options.insert("usage", "usage");
- break;
- case 'i':
- options.insert("insecure", "nossl");
- break;
- case 'l':
- options.insert("locations", optarg);
- break;
- case 'p':
- options.insert("pvs", "pvs");
- break;
- case 'pvck':
- options.insert("pvs-checked", "pvs-checked");
- break;
- case 'P':
- options.insert("pool", optarg);
- break;
- case 'S':
- options.insert("runscript", optarg);
- break;
- case 's':
- options.insert("size", optarg);
- break;
- case 't':
- options.insert("theme", optarg);
- break;
- case 'T':
- options.insert("tab", optarg);
- break;
- case 'u':
- options.insert("url", optarg);
- break;
- case 'v':
- options.insert("version", "version");
- break;
- case 'x':
- options.insert("xpath", optarg);
- break;
- case 'locm':
- options.insert("location-mode", optarg);
- break;
- case 'tmpm':
- options.insert("template-mode", optarg);
- break;
- case 'nvtx':
- options.insert("no-vtx", "no-vtx");
- break;
- case 'ulst':
- options.insert("url-list", optarg);
- break;
- case 'unws':
- options.insert("url-news", optarg);
- break;
- case 'uhlp':
- options.insert("url-help", optarg);
- break;
- case 'uuid':
- options.insert("uuid", optarg);
- break;
- case 'vmed':
- options.insert("allow-vm-edit", "");
- break;
- default:
- options.insert("error", "error");
- break;
- }
- }
-}
diff --git a/src/command_line_options.h b/src/command_line_options.h
deleted file mode 100644
index 8798ff2..0000000
--- a/src/command_line_options.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef VMCHOOSER_COMMAND_LINE_OPTIONS_H
-#define VMCHOOSER_COMMAND_LINE_OPTIONS_H
-
-#include <QMap>
-#include <QString>
-
-class CommandLineOptions {
- public:
- CommandLineOptions(int argc, char * const argv[]);
-
- bool contains(const QString& key) const {
- return options.contains(key);
- }
-
- QString value(const QString& key) const {
- return options.value(key);
- }
-
- private:
- QMap<QString, QString> options;
-};
-
-#endif // VMCHOOSER_COMMAND_LINE_OPTIONS_H
diff --git a/src/config.cpp b/src/config.cpp
new file mode 100644
index 0000000..63630d0
--- /dev/null
+++ b/src/config.cpp
@@ -0,0 +1,103 @@
+#include "config.h"
+#include "globals.h"
+
+#include <QFileInfo>
+#include <QCommandLineOption>
+#include <QCommandLineParser>
+#include <QSettings>
+
+static QCommandLineParser parser;
+static QSettings* configFile = nullptr;
+
+static inline QStringList combine(const QString &a, const QString &b)
+{
+ QStringList ret;
+ if (!a.isEmpty()) {
+ ret << a;
+ }
+ if (!b.isEmpty()) {
+ ret << b;
+ }
+ return ret;
+}
+
+struct ConfigOption
+{
+ const QCommandLineOption cmdLine;
+ const QString iniKey;
+ const QString defaultValue;
+ const bool withArgument;
+ ConfigOption(const QString optShort, const QString optLong, const QString iniKey, const QString valueName, const QString defaultValue, const QString description)
+ : cmdLine(combine(optLong, optShort), description, valueName, defaultValue), iniKey(iniKey), defaultValue(defaultValue), withArgument(!valueName.isEmpty())
+ {
+ if (!cmdLine.names().isEmpty()) {
+ parser.addOption(cmdLine);
+ }
+ }
+};
+
+const ConfigOption* const Config::ALLOW_VM_EDIT = new ConfigOption("", "allow-vm-edit", "allow-vm-edit", "", "", "Show edit checkbox for VMs/lectures where meta data allows editing");
+const ConfigOption* const Config::AUTOQUIT = new ConfigOption("", "autoquit", "autoquit", "seconds", "120", "Time after which vmchooser will quit if no user interaction is detected");
+const ConfigOption* const Config::BASEDIR = new ConfigOption("b", "base", "base", "path", "/mnt/vmstore", "Base directory where vm meta data is relative to");
+const ConfigOption* const Config::CONFIG = new ConfigOption("c", "config", "", "path", CONFIG_FILE_GLOBAL, "Path to global config file");
+const ConfigOption* const Config::DEBUG = new ConfigOption("D", "debug", "debug", "", "", "Enable debug mode");
+const ConfigOption* const Config::DEFAULT_SESSION = new ConfigOption("d", "default", "", "uuid", "", "Preselect session with given uuid or name");
+const ConfigOption* const Config::EXAM_MODE = new ConfigOption("", "exam-mode", "exam-mode", "", "", "Turn on exam mode: Limits options, forces PVS");
+const ConfigOption* const Config::FULLSCREEN = new ConfigOption("F", "fullscreen", "fullscreen", "", "", "Show vmchooser in fullscreen mode");
+const ConfigOption* const Config::INSECURE = new ConfigOption("k", "insecure", "insecure", "", "", "When using HTTPS, don't check server's certificate");
+const ConfigOption* const Config::LOCATIONS = new ConfigOption("l", "locations", "locations", "ids..", "", "Space separated list of location ids, for list request and location-mode");
+const ConfigOption* const Config::PVS = new ConfigOption("p", "pvs", "pvs", "", "", "Show 'join PVS' checkbox");
+const ConfigOption* const Config::PVS_CHECKED = new ConfigOption("", "pvs-checked", "pvs-checked", "", "", "PVS checkbox is selected by default");
+const ConfigOption* const Config::RUNSCRIPT = new ConfigOption("S", "runscript", "runscript", "path", RUN_VIRT_PATH, "Path to run-virt script");
+const ConfigOption* const Config::WINDOW_SIZE = new ConfigOption("s", "size", "size", "WxH", "640x480", "Size of window if not using fullscreen");
+const ConfigOption* const Config::DEFAULT_TAB = new ConfigOption("T", "tab", "tab", "tabno", "2", "Default tab to show, first tab being 0");
+const ConfigOption* const Config::THEME = new ConfigOption("t", "theme", "theme", "name", "", "Name of theme to load");
+const ConfigOption* const Config::URL_BASE = new ConfigOption("u", "url", "url", "url", "", "Base URL path to fetch resources from");
+const ConfigOption* const Config::URL_LIST = new ConfigOption("", "url-list", "url-list", "url", "", "Use this URL for the VM list instead of <urlbase>/list");
+const ConfigOption* const Config::URL_NEWS = new ConfigOption("", "url-news", "url-news", "url", "", "Use this URL for the news panel instead of <urlbase>/news");
+const ConfigOption* const Config::URL_HELP = new ConfigOption("", "url-help", "url-help", "url", "", "Use this URL for the help panel instead of <urlbase>/help");
+const ConfigOption* const Config::XSESSION_PATH = new ConfigOption("x", "xpath", "xpath", "path", VMCHOOSER_X_SESSIONS_PATH, "Path to xsession files");
+const ConfigOption* const Config::LOCATION_MODE = new ConfigOption("", "location-mode", "location-mode", "mode", "BUMP", "Whether to IGNORE locations, BUMP matching entries, or EXCLUSIVE-ly show only those matching the currently configured location");
+const ConfigOption* const Config::TEMPLATE_MODE = new ConfigOption("", "template-mode", "template-mode", "mode", "BUMP", "Whether to BUMP entries marked as template, or IGNORE the flag");
+const ConfigOption* const Config::AUTOSTART_UUID = new ConfigOption("", "start-uuid", "start-uuid", "uuid", "", "Immediately launch session with given uuid/name");
+const ConfigOption* const Config::NO_VTX = new ConfigOption("", "no-vtx", "no-vtx", "", "0", "Fade all VM sessions that would require VTX/SVM CPU capabilities");
+
+
+QString Config::get(const ConfigOption* const option)
+{
+ if (option == nullptr)
+ return QString();
+ if (parser.isSet(option->cmdLine))
+ return parser.value(option->cmdLine);
+ if (configFile != nullptr && !option->iniKey.isEmpty())
+ return configFile->value(option->iniKey, option->defaultValue).toString();
+ // TODO: CONFIG_FILE_USER is currently not supported, but unused anyways
+ return option->defaultValue;
+}
+
+bool Config::isSet(const ConfigOption* const option)
+{
+ if (option == nullptr)
+ return false;
+ if (parser.isSet(option->cmdLine))
+ return true;
+ if (configFile != nullptr && !option->iniKey.isEmpty())
+ return !configFile->value(option->iniKey, option->defaultValue).isNull();
+ return false;
+}
+
+bool Config::init(const QCoreApplication& app, const ConfigOption* const configFileName)
+{
+ parser.addHelpOption();
+ parser.addVersionOption();
+ parser.process(app);
+ if (configFileName != nullptr && parser.isSet(configFileName->cmdLine)) {
+ QString file(parser.value(configFileName->cmdLine));
+ if (!QFileInfo(file).exists())
+ return false;
+ configFile = new QSettings(file, QSettings::IniFormat);
+ configFile->setIniCodec("UTF-8");
+ }
+ return true;
+}
+
diff --git a/src/config.h b/src/config.h
new file mode 100644
index 0000000..872836d
--- /dev/null
+++ b/src/config.h
@@ -0,0 +1,46 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include <QCoreApplication>
+#include <QList>
+
+struct ConfigOption;
+
+class Config
+{
+public:
+ static const ConfigOption* const ALLOW_VM_EDIT;
+ static const ConfigOption* const AUTOQUIT;
+ static const ConfigOption* const BASEDIR;
+ static const ConfigOption* const CONFIG;
+ static const ConfigOption* const DEBUG;
+ static const ConfigOption* const DEFAULT_SESSION;
+ static const ConfigOption* const EXAM_MODE;
+ static const ConfigOption* const FULLSCREEN;
+ static const ConfigOption* const INSECURE;
+ static const ConfigOption* const LOCATIONS;
+ static const ConfigOption* const PVS;
+ static const ConfigOption* const PVS_CHECKED;
+ static const ConfigOption* const RUNSCRIPT;
+ static const ConfigOption* const WINDOW_SIZE;
+ static const ConfigOption* const DEFAULT_TAB;
+ static const ConfigOption* const THEME;
+ static const ConfigOption* const URL_BASE;
+ static const ConfigOption* const URL_LIST;
+ static const ConfigOption* const URL_NEWS;
+ static const ConfigOption* const URL_HELP;
+ static const ConfigOption* const XSESSION_PATH;
+ static const ConfigOption* const LOCATION_MODE;
+ static const ConfigOption* const TEMPLATE_MODE;
+ static const ConfigOption* const AUTOSTART_UUID;
+ static const ConfigOption* const NO_VTX;
+
+ static bool init(const QCoreApplication& app, const ConfigOption* const configFile);
+ static QString get(const ConfigOption* const option);
+ static bool isSet(const ConfigOption* const option);
+
+private:
+ Config() {}
+};
+
+#endif // CONFIG_H
diff --git a/src/dialog.cpp b/src/dialog.cpp
index 10ebe22..8c02c9a 100644
--- a/src/dialog.cpp
+++ b/src/dialog.cpp
@@ -1,4 +1,5 @@
#include "dialog.h"
+#include "config.h"
#include <QMessageBox>
#include <QDebug>
@@ -24,17 +25,13 @@
static bool isProcessRunning(const QString &binary);
-Dialog::Dialog(int defaultTab, bool examMode, QWidget *parent)
+Dialog::Dialog(QWidget *parent)
: QDialog(parent), ui(new Ui::Dialog) {
model_[0] = new SessionTreeModel(parent);
model_[1] = new SessionTreeModel(parent);
model_[2] = new SessionTreeModel(parent);
- if (defaultTab < 0 || defaultTab > TAB_COUNT) defaultTab = TAB_ALL_VMS;
- defaultTab_ = defaultTab;
- qDebug() << "Default tab: " << defaultTab;
userInteracted_ = false;
genericExpandedOnce_ = false;
- examMode_ = examMode;
autoQuit_ = g_autoQuitSeconds;
ui->setupUi(this);
@@ -71,11 +68,11 @@ Dialog::Dialog(int defaultTab, bool examMode, QWidget *parent)
this, SLOT(treeView_selectionChanged(const QModelIndex&, const QModelIndex&)));
*/
- ui->PVS_checkbox->setVisible(g_pvsEnabled);
- ui->PVS_checkbox->setChecked(g_pvsChecked);
+ ui->PVS_checkbox->setVisible(Config::isSet(Config::PVS));
+ ui->PVS_checkbox->setChecked(Config::isSet(Config::PVS_CHECKED));
activeTab_ = -1;
- if (examMode_) {
+ if (Config::isSet(Config::EXAM_MODE)) {
ui->tabButtonLocal->setEnabled(false);
this->onTabButtonChanged(TAB_ALL_VMS);
/* modify the pvs checkbox */
@@ -88,7 +85,7 @@ Dialog::Dialog(int defaultTab, bool examMode, QWidget *parent)
this->selectPreviousSession();
}
- ui->chkAdminMode->setVisible(g_allowVmEdit);
+ ui->chkAdminMode->setVisible(Config::isSet(Config::ALLOW_VM_EDIT));
ui->chkAdminMode->setEnabled(false);
ui->btnScreenSetup->setVisible(isProcessRunning("beamergui"));
@@ -132,7 +129,7 @@ void Dialog::on_treeView_doubleClicked(const QModelIndex& index)
return;
// These two are up here in case run-virt cares...
- if (g_pvsEnabled) {
+ if (Config::isSet(Config::PVS)) {
if (ui->PVS_checkbox->isChecked()) {
setenv("PVS_AUTO_CONNECT", "TRUE", 1);
} else {
@@ -217,7 +214,7 @@ void Dialog::addItems(const QList<Session*>& entries, int tab) {
if (tab < 0 || tab > 2) {
return;
}
- if (examMode_ && tab == TAB_NATIVE)
+ if (Config::isSet(Config::EXAM_MODE) && tab == TAB_NATIVE)
return;
this->model_[tab]->addItems(entries);
tabs_[tab]->setEnabled(this->model_[tab]->rowCount() != 0);
@@ -346,7 +343,10 @@ void Dialog::selectPreviousSession() {
qDebug() << "Not selecting previous session as user interacted or session was already selected";
return;
}
- QString lastSession = ChooserSettings::getSetting("last-session");
+ QString lastSession = Config::get(Config::DEFAULT_SESSION);
+ if (lastSession.isEmpty()) {
+ lastSession = ChooserSettings::getSetting("last-session");
+ }
if (!lastSession.isEmpty()) {
qDebug() << "Trying to select last session: " << lastSession;
ui->treeView->clearSelection();
@@ -362,9 +362,10 @@ void Dialog::selectPreviousSession() {
qDebug() << "Trying to select last tab " << lastTab;
this->onTabButtonChanged(lastTab.toInt());
} else {
- qDebug() << "Selected default tab " << defaultTab_;
+ int defaultTab = Config::get(Config::DEFAULT_TAB).toInt();
+ qDebug() << "Selected default tab " << defaultTab;
// Select default tab
- this->onTabButtonChanged(defaultTab_);
+ this->onTabButtonChanged(defaultTab);
}
}
@@ -377,12 +378,15 @@ void Dialog::setTheme() {
QString backgroundColor, imageLeft, imageRight;
QString themePathBase, themePathIni, themePathImgLeft, themePathImgRight;
- if (g_themeName.isEmpty()) return;
+ if (Config::isSet(Config::THEME))
+ return;
- themePathBase = QString("%1/%2/").arg(VMCHOOSER_THEME_BASE).arg(g_themeName);
- themePathIni = QString("%1%2.ini").arg(themePathBase).arg(g_themeName);
+ QString theme(Config::get(Config::THEME));
+ themePathBase = QString("%1/%2/").arg(VMCHOOSER_THEME_BASE).arg(theme);
+ themePathIni = QString("%1%2.ini").arg(themePathBase).arg(theme);
- if (!QFile::exists(themePathIni)) return;
+ if (!QFile::exists(themePathIni))
+ return;
QSettings themeSettings(themePathIni, QSettings::IniFormat);
@@ -437,13 +441,15 @@ void Dialog::onCenterTimer() {
* Download lecture list, news and help
*/
void Dialog::downloadData(const QString& locationIds) {
- QUrl listUrl(g_urlList);
+ QUrl listUrl(Config::isSet(Config::URL_LIST)
+ ? Config::get(Config::URL_LIST)
+ : Config::get(Config::URL_BASE).append("/list"));
QUrlQuery listQuery(listUrl);
if (!locationIds.isEmpty()) {
listQuery.addQueryItem("locations", locationIds);
}
- if (examMode_) {
+ if (Config::isSet(Config::EXAM_MODE)) {
listQuery.addQueryItem("exams", "exam-mode");
}
listUrl.setQuery(listQuery);
@@ -509,7 +515,9 @@ void Dialog::downloadData(const QString& locationIds) {
});
//
// News
- FileDownloader::download(QUrl(g_urlNews), [this](QNetworkReply::NetworkError err, const QByteArray& data) {
+ FileDownloader::download(QUrl(Config::isSet(Config::URL_NEWS)
+ ? Config::get(Config::URL_NEWS)
+ : Config::get(Config::URL_BASE).append("/news")), [this](QNetworkReply::NetworkError err, const QByteArray& data) {
if (err != QNetworkReply::NoError) {
if (g_debugMode) {
qDebug() << "Could not get news. Try to get cached news.";
@@ -580,7 +588,9 @@ void Dialog::downloadData(const QString& locationIds) {
});
//
// Download help
- FileDownloader::download(QUrl(g_urlHelp), [this](QNetworkReply::NetworkError err, const QByteArray& data) {
+ FileDownloader::download(QUrl(Config::isSet(Config::URL_HELP)
+ ? Config::get(Config::URL_HELP)
+ : Config::get(Config::URL_BASE).append("/help")), [this](QNetworkReply::NetworkError err, const QByteArray& data) {
if (err != QNetworkReply::NoError) {
if (g_debugMode) {
qDebug() << "Could not get help xml. Try to get cached help...";
@@ -673,7 +683,8 @@ void Dialog::treeView_selectionChanged(const QModelIndex& current, const QModelI
ui->label_platform->setText(vs->getAttribute("virtualizer_name", "param"));
ui->label_platform->setToolTip(vs->getAttribute("virtualizer_name", "param"));
- ui->chkAdminMode->setEnabled(vs->canEdit() || g_allowVmEdit);
+ // TODO: This is a bug? vs->canEdit() seems completely pointless right now...
+ ui->chkAdminMode->setEnabled(vs->canEdit() || Config::isSet(Config::ALLOW_VM_EDIT));
if (vs->keywords().length() > 0) {
description = "\n\nKeywords: ";
@@ -709,7 +720,7 @@ void Dialog::on_tabButtonAllClasses_clicked() {
}
void Dialog::onTabButtonChanged(int tab) {
- if (tab < 0 || tab > 2) {
+ if (tab < 0 || tab >= TAB_COUNT) {
// no valid button
return;
}
diff --git a/src/dialog.h b/src/dialog.h
index c2d3959..0d74111 100644
--- a/src/dialog.h
+++ b/src/dialog.h
@@ -31,7 +31,7 @@ class Dialog : public QDialog {
static const int TAB_COUNT = 3;
public: // Public methods
- explicit Dialog(int defaultTab = -1, bool examMode = false, QWidget *parent = nullptr);
+ explicit Dialog(QWidget *parent = nullptr);
~Dialog();
void addItems(const QList<Session*>&, int tab);
void addStatusString(const int status);
@@ -57,11 +57,9 @@ class Dialog : public QDialog {
QTimer *centerTimer_;
QString autoStartEntry_;
int activeTab_;
- int defaultTab_;
int autoQuit_;
bool userInteracted_;
bool genericExpandedOnce_;
- bool examMode_;
QString strings_[STR__MAX];
void onTabButtonChanged(int tab);
void configClearButton();
diff --git a/src/globals.cpp b/src/globals.cpp
index 427b4bb..c21598a 100644
--- a/src/globals.cpp
+++ b/src/globals.cpp
@@ -3,45 +3,24 @@
#include "globals.h"
#include "session.h"
-#define VMCHOOSER_SCRIPTS_PATH "/opt/openslx/scripts"
-#define VMCHOOSER_X_SESSIONS_PATH "/usr/share/xsessions"
-
static const QString userPath(QDir::homePath() + "/.config/openslx");
-//QString binPath(QApplication::applicationDirPath());
-QString g_xSessionPath(VMCHOOSER_X_SESSIONS_PATH);
-QString g_runVmScript(VMCHOOSER_SCRIPTS_PATH "/vmchooser-run_virt");
-
const QString SESSION_START_SCRIPT(VMCHOOSER_SESSION_START_SCRIPT);
-const QString CONFIG_FILE_GLOBAL("/opt/openslx/vmchooser/config/vmchooser.conf");
const QString CONFIG_FILE_USER(userPath + "/vmchooser.conf");
const QString CONFIG_FILE_XSESSIONS("/opt/openslx/vmchooser/config/xsessions.conf");
const QString PREVIOUS_SESSION_USER(userPath + "/vmchooser2.ini");
bool g_debugMode = false;
-bool g_pvsEnabled = false;
-bool g_pvsChecked = false;
+bool g_fullscreen = false;
int g_autoQuitSeconds = 0;
-bool g_allowVmEdit = false;
-
-QString g_currentPoolName;
-QString g_themeName;
-QString g_vmBasePath;
const QString TEMP_PATH_ICONS("/tmp/vmchooser2/icons/");
const QString TEMP_PATH_XML_LIST("/tmp/vmchooser2/vmchooser2.xml");
const QString TEMP_PATH_HELP("/tmp/vmchooser2/vmchooser2_help.xml");
const QString TEMP_PATH_NEWS("/tmp/vmchooser2/vmchooser2_news.xml");
-QString g_urlBase;
-QString g_urlList;
-QString g_urlNews;
-QString g_urlHelp;
-
-bool g_fullscreen = false;
-
int g_templateHandling = TEMPLATES_IGNORE;
int g_forLocationHandling = LOCATION_BUMP;
diff --git a/src/globals.h b/src/globals.h
index 860048e..81bf2f5 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -5,6 +5,10 @@
#define VMCHOOSER_SESSION_START_SCRIPT "/opt/openslx/vmchooser/sessionstart"
#define VMCHOOSER_THEME_BASE "/opt/openslx/vmchooser/themes"
+#define VMCHOOSER_X_SESSIONS_PATH "/usr/share/xsessions"
+#define RUN_VIRT_PATH "/opt/openslx/scripts/vmchooser-run_virt"
+
+#define CONFIG_FILE_GLOBAL "/opt/openslx/vmchooser/config/vmchooser.conf"
#define VMCHOOSER_DEFAULT_WIDTH 800
#define VMCHOOSER_DEFAULT_HEIGHT 600
@@ -14,40 +18,21 @@
class Session;
extern bool g_debugMode;
-extern bool g_pvsEnabled;
-extern bool g_pvsChecked;
+extern bool g_fullscreen;
extern int g_autoQuitSeconds;
-extern bool g_allowVmEdit;
-extern QString g_xSessionPath;
-
-extern QString g_runVmScript;
-extern QString printerScript;
-extern QString scannerScript;
// Script that is run before the xsession/vsession is started
extern const QString SESSION_START_SCRIPT;
-extern const QString CONFIG_FILE_GLOBAL;
extern const QString CONFIG_FILE_USER;
extern const QString CONFIG_FILE_XSESSIONS;
extern const QString PREVIOUS_SESSION_USER;
-extern QString g_currentPoolName;
-extern QString g_themeName;
-extern QString g_vmBasePath;
-
extern const QString TEMP_PATH_ICONS;
extern const QString TEMP_PATH_XML_LIST;
extern const QString TEMP_PATH_HELP;
extern const QString TEMP_PATH_NEWS;
-extern QString g_urlBase;
-extern QString g_urlList;
-extern QString g_urlNews;
-extern QString g_urlHelp;
-
-extern bool g_fullscreen;
-
#define TEMPLATES_IGNORE (0)
#define TEMPLATES_BUMP (1)
extern int g_templateHandling;
diff --git a/src/main.cpp b/src/main.cpp
index 1da6f68..0e3229b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -13,7 +13,7 @@
#include <iostream>
#include <string>
-#include "command_line_options.h"
+#include "config.h"
#include "dialog.h"
#include "globals.h"
#include "xsession.h"
@@ -25,221 +25,23 @@ int main(int argc, char *argv[]) {
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"
- " --url-list url of vms' list as .xml file\n"
- " --url-news url of the news to display\n"
- " --url-help url of the help to display\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"
- " --pvs-checked check pvs box by default\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 (!Config::init(a, Config::CONFIG)) {
+ qDebug() << "Error initializing config. Invalid --config passed?";
+ return 1;
}
- 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;
- }
- }
- if (cmdOptions.contains("insecure")) {
+ if (Config::isSet(Config::INSECURE)) {
QSslConfiguration sslConf = QSslConfiguration::defaultConfiguration();
sslConf.setPeerVerifyMode(QSslSocket::VerifyNone);
QSslConfiguration::setDefaultConfiguration(sslConf);
}
- // 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(CONFIG_FILE_USER).exists()) {
- confFile = CONFIG_FILE_USER;
- std::cerr << a.translate("Console", "Using user specific config: ").toUtf8().constData() << CONFIG_FILE_USER.toUtf8().constData() << std::endl;
- }
- if (confFile.isEmpty() && QFileInfo(CONFIG_FILE_GLOBAL).exists()) {
- confFile = CONFIG_FILE_GLOBAL;
- std::cerr << a.translate("Console", "Using global config: ").toUtf8().constData() << CONFIG_FILE_GLOBAL.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")) {
- g_xSessionPath = cmdOptions.value("xpath");
- } else if (settings.contains("xpath")) {
- g_xSessionPath = settings.value("xpath").toString();
- } // else keep default path
-
- // Change the runVmScript path
- if (cmdOptions.contains("runscript")) {
- g_runVmScript = cmdOptions.value("runscript");
- } else if (settings.contains("runscript")) {
- g_runVmScript = settings.value("runscript").toString();
- }
-
-
- if (cmdOptions.contains("url")) {
- g_urlBase = cmdOptions.value("url");
- } else if (settings.contains("url")) {
- g_urlBase = settings.value("url").toString();
- }
-
- if (!g_urlBase.isNull() && !g_urlBase.isEmpty()) {
- if (!g_urlBase.endsWith("/")) {
- g_urlBase += "/";
- }
- }
- // parse urls for resources: list, news, help
- QMap<QString, QString*> resources;
- resources["list"] = &g_urlList;
- resources["news"] = &g_urlNews;
- resources["help"] = &g_urlHelp;
- QMap<QString, QString*>::const_iterator r = resources.constBegin();
- QString cur;
- while (r != resources.constEnd()) {
- cur = "url-" + r.key();
- if (cmdOptions.contains(cur)) {
- *r.value() = cmdOptions.value(cur);
- } else {
- if (!g_urlBase.isNull()) {
- // if not explictly specified, use the old scheme
- *r.value() = g_urlBase + r.key();
- }
- }
- r++;
- }
-
- QString size;
- int width = VMCHOOSER_DEFAULT_WIDTH, height = VMCHOOSER_DEFAULT_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;
- }
- }
-
- if (cmdOptions.contains("pool")) {
- g_currentPoolName = cmdOptions.value("pool");
- } else if (settings.contains("pool")) {
- g_currentPoolName = settings.value("pool").toString();
- }
-
- if (cmdOptions.contains("theme")) {
- g_themeName = cmdOptions.value("theme");
- } else if (settings.contains("theme")) {
- g_themeName = settings.value("theme").toString();
- }
-
- if (cmdOptions.contains("debugMode")) {
+ if (Config::isSet(Config::DEBUG)) {
g_debugMode = true;
}
- if (cmdOptions.contains("base")) {
- g_vmBasePath = cmdOptions.value("base");
- } else if (settings.contains("base")) {
- g_vmBasePath = settings.value("base").toString();
- } else if (settings.contains("path")) { // Compatibility to v1.0
- g_vmBasePath = settings.value("path").toString();
- }
-
- if (cmdOptions.contains("location-mode")) {
- QString mode = cmdOptions.value("location-mode");
+ if (Config::isSet(Config::LOCATION_MODE)) {
+ QString mode = Config::get(Config::LOCATION_MODE);
if (mode == "IGNORE") {
g_forLocationHandling = LOCATION_IGNORE;
} else if (mode == "BUMP") {
@@ -253,12 +55,12 @@ int main(int argc, char *argv[]) {
}
}
- if (cmdOptions.contains("template-mode")) {
- QString mode = cmdOptions.value("template-mode");
+ if (Config::isSet(Config::TEMPLATE_MODE)) {
+ QString mode = Config::get(Config::TEMPLATE_MODE);
if (mode == "IGNORE") {
- g_templateHandling = LOCATION_IGNORE;
+ g_templateHandling = TEMPLATES_IGNORE;
} else if (mode == "BUMP") {
- g_templateHandling = LOCATION_BUMP;
+ g_templateHandling = TEMPLATES_BUMP;
} else {
qDebug() << "Invalid template mode: " << mode;
QMessageBox::critical(nullptr, "Error", "Invalid template mode: " + mode);
@@ -266,55 +68,47 @@ int main(int argc, char *argv[]) {
}
}
- 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;
- }
+ g_noVtx = Config::isSet(Config::NO_VTX);
- if (cmdOptions.contains("pvs")) {
- g_pvsEnabled = true;
- }
- if (cmdOptions.contains("pvs-checked")) {
- g_pvsChecked = true;
- }
-
- if (cmdOptions.contains("autoquit")) {
+ if (Config::isSet(Config::AUTOQUIT)) {
bool ok = false;
- g_autoQuitSeconds = cmdOptions.value("autoquit").toInt(&ok, 10);
+ g_autoQuitSeconds = Config::get(Config::AUTOQUIT).toInt(&ok, 10);
if (!ok) {
g_autoQuitSeconds = 0;
}
}
- g_allowVmEdit = cmdOptions.contains("allow-vm-edit");
-
/* read session files */
- QList<Session*> xsessions(XSession::readSessions(g_xSessionPath));
+ QList<Session*> xsessions(XSession::readSessions(Config::get(Config::XSESSION_PATH)));
- Dialog w(defaultTab, cmdOptions.contains("exam-mode"));
-
- w.downloadData(locationIds);
-
- w.setTheme();
-
- w.setWindowFlags(Qt::FramelessWindowHint);
+ Dialog w;
QRect desktopRect = QApplication::desktop()->availableGeometry(&w);
- if (size == "fullscreen") {
+ int width = VMCHOOSER_DEFAULT_WIDTH, height = VMCHOOSER_DEFAULT_HEIGHT;
+ if (Config::isSet(Config::FULLSCREEN) || Config::get(Config::WINDOW_SIZE) == QLatin1String("fullscreen")) {
width = desktopRect.width();
height = desktopRect.height();
g_fullscreen = true;
+ } else {
+ QString size(Config::get(Config::WINDOW_SIZE));
+ if (!size.isEmpty()) {
+ 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 {
+ std::cerr
+ << a.translate("Console", "vmchooser: invalid size argument").toUtf8().data()
+ << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
}
+ w.downloadData(Config::get(Config::LOCATIONS));
+ w.setTheme();
+ w.setWindowFlags(Qt::FramelessWindowHint);
w.resize(width, height);
if (xsessions.size()) {
@@ -324,9 +118,9 @@ int main(int argc, char *argv[]) {
w.show();
- if (autostart_uuid != "") {
+ if (Config::isSet(Config::AUTOSTART_UUID)) {
qDebug() << "using startSession() from main.cpp";
- w.startSession(autostart_uuid);
+ w.startSession(Config::get(Config::AUTOSTART_UUID));
}
diff --git a/src/vsession.cpp b/src/vsession.cpp
index e35c1af..a4e5a7b 100644
--- a/src/vsession.cpp
+++ b/src/vsession.cpp
@@ -1,3 +1,5 @@
+#include "config.h"
+
#include <QtXml>
#include <QDir>
#include <QApplication>
@@ -107,7 +109,7 @@ QString VSession::toXml() const {
.toElement();
if (QFileInfo(image).isRelative()) {
// make path to image absolute
- path.setAttribute("param", g_vmBasePath + "/" + image);
+ path.setAttribute("param", Config::get(Config::BASEDIR) + "/" + image);
} else {
path.setAttribute("param", image);
}
@@ -205,15 +207,7 @@ bool VSession::isActive() const {
return false;
}
}
- // Filtering by pool name
- if (!g_currentPoolName.isEmpty()) {
- QStringList pools = getAttribute("pools").split("\\s*,\\s*");
- if (!pools.isEmpty() && !pools.contains(g_currentPoolName)) {
- // pools does not contain pool
- if (g_debugMode) qDebug() << "'" << shortDescription() << "' not active. Reason: '" << g_currentPoolName << "' is not part of active pool list (" << pools << ")";
- return false;
- }
- }
+
// Filter by LDAP data
if (!UserLdapData::isEmpty()) {
QDomElement el(eintrag_.namedItem("filters").firstChildElement("filter"));
@@ -286,7 +280,7 @@ bool VSession::run() const {
tmpfile.close();
QObject::connect(&_process, SIGNAL(finished(int, QProcess::ExitStatus)), QApplication::instance(), SLOT(quit()));
- _process.start(g_runVmScript, QStringList(tmpFileName));
+ _process.start(Config::get(Config::RUNSCRIPT), QStringList(tmpFileName));
_process.waitForStarted(10);
if (_process.state() == QProcess::Starting || _process.state() == QProcess::Running)
return true;