From 030d91e628a2ecd5634376c9c4d903a1fa0fb423 Mon Sep 17 00:00:00 2001 From: Nils Schwabe Date: Mon, 3 Mar 2014 15:14:20 +0100 Subject: added files from vmchooser1 --- .gitignore | 3 + CMakeLists.txt | 77 ++ README | 86 +++ build.sh | 46 ++ default.desktop | 7 + src/command_line_options.cpp | 68 ++ src/command_line_options.h | 23 + src/dialog.cpp | 248 +++++++ src/dialog.h | 50 ++ src/globals.cpp | 26 + src/globals.h | 46 ++ src/i18n/de.ts | 134 ++++ src/i18n/pt.ts | 135 ++++ src/images.qrc | 39 ++ src/img/Atari.svg | 58 ++ src/img/LICENSE | 56 ++ src/img/amiga.png | Bin 0 -> 2382 bytes src/img/amiga2.png | Bin 0 -> 4380 bytes src/img/atari.png | Bin 0 -> 1726 bytes src/img/beos.png | Bin 0 -> 2474 bytes src/img/bsd.png | Bin 0 -> 7697 bytes src/img/debian.png | Bin 0 -> 1823 bytes src/img/debian.svg | 18 + src/img/dosbox.png | Bin 0 -> 9743 bytes src/img/fedora.png | Bin 0 -> 2069 bytes src/img/fedora.svg | 31 + src/img/gentoo.png | Bin 0 -> 4315 bytes src/img/gentoo.svg | 268 +++++++ src/img/gnome.png | Bin 0 -> 1304 bytes src/img/gnome.svg | 42 ++ src/img/kde.png | Bin 0 -> 6568 bytes src/img/kde.svg | 323 +++++++++ src/img/linux.png | Bin 0 -> 4896 bytes src/img/linux.svg | 933 +++++++++++++++++++++++++ src/img/locked.png | Bin 0 -> 1901 bytes src/img/lxde.png | Bin 0 -> 8685 bytes src/img/macos.png | Bin 0 -> 1437 bytes src/img/macos.svg | 33 + src/img/mess.png | Bin 0 -> 2341 bytes src/img/none.png | Bin 0 -> 187 bytes src/img/openslx-logo.png | Bin 0 -> 17520 bytes src/img/opensolaris.png | Bin 0 -> 3725 bytes src/img/opensolaris.svg | 164 +++++ src/img/os2.png | Bin 0 -> 4715 bytes src/img/osx.png | Bin 0 -> 3061 bytes src/img/osx.svg | 143 ++++ src/img/qemu.png | Bin 0 -> 3653 bytes src/img/redhat.png | Bin 0 -> 1947 bytes src/img/redhat.svg | 101 +++ src/img/riscos.png | Bin 0 -> 2802 bytes src/img/riscos_orig.png | Bin 0 -> 6048 bytes src/img/solaris.png | Bin 0 -> 3683 bytes src/img/suse.png | Bin 0 -> 1559 bytes src/img/suse.svg | 23 + src/img/term.png | Bin 0 -> 18052 bytes src/img/title_l.png | Bin 0 -> 9187 bytes src/img/title_r.png | Bin 0 -> 3390 bytes src/img/ubuntu.png | Bin 0 -> 1232 bytes src/img/ubuntu.svg | 4 + src/img/unknown.png | Bin 0 -> 6276 bytes src/img/virtualbox.png | Bin 0 -> 8688 bytes src/img/vmware.png | Bin 0 -> 1140 bytes src/img/vmware.svg | 86 +++ src/img/win311.png | Bin 0 -> 2872 bytes src/img/win311.svg | 322 +++++++++ src/img/win7.png | Bin 0 -> 7619 bytes src/img/win7_orig.png | Bin 0 -> 83573 bytes src/img/windows.png | Bin 0 -> 5636 bytes src/img/xfce.png | Bin 0 -> 5326 bytes src/img/xfce.svg | 226 ++++++ src/main.cpp | 238 +++++++ src/save_restore_session.cpp | 31 + src/save_restore_session.h | 7 + src/session.h | 26 + src/sessiontreeitem.cpp | 50 ++ src/sessiontreeitem.h | 34 + src/sessiontreemodel.cpp | 162 +++++ src/sessiontreemodel.h | 35 + src/ui/dialog.ui | 281 ++++++++ src/vsession.cpp | 405 +++++++++++ src/vsession.h | 72 ++ src/xsession.cpp | 149 ++++ src/xsession.h | 49 ++ themes/openslx/openslx-left.png | Bin 0 -> 9187 bytes themes/openslx/openslx-right.png | Bin 0 -> 3390 bytes themes/openslx/openslx.ini | 4 + themes/planets/planets-left.png | Bin 0 -> 11337 bytes themes/planets/planets-right.png | Bin 0 -> 3082 bytes themes/planets/planets.ini | 4 + themes/unifr/title_l.png | Bin 0 -> 17458 bytes themes/unifr/title_r.png | Bin 0 -> 4113 bytes themes/unifr/unifr.ini | 4 + vmChooser/.classpath | 6 - vmChooser/.project | 17 - vmChooser/.settings/org.eclipse.jdt.core.prefs | 11 - vmChooser/bin/HelloWorld.class | Bin 533 -> 0 bytes vmChooser/src/HelloWorld.java | 13 - 97 files changed, 5370 insertions(+), 47 deletions(-) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 README create mode 100755 build.sh create mode 100644 default.desktop create mode 100644 src/command_line_options.cpp create mode 100644 src/command_line_options.h create mode 100644 src/dialog.cpp create mode 100644 src/dialog.h create mode 100644 src/globals.cpp create mode 100644 src/globals.h create mode 100644 src/i18n/de.ts create mode 100755 src/i18n/pt.ts create mode 100644 src/images.qrc create mode 100644 src/img/Atari.svg create mode 100644 src/img/LICENSE create mode 100644 src/img/amiga.png create mode 100644 src/img/amiga2.png create mode 100644 src/img/atari.png create mode 100644 src/img/beos.png create mode 100644 src/img/bsd.png create mode 100644 src/img/debian.png create mode 100644 src/img/debian.svg create mode 100644 src/img/dosbox.png create mode 100644 src/img/fedora.png create mode 100644 src/img/fedora.svg create mode 100644 src/img/gentoo.png create mode 100644 src/img/gentoo.svg create mode 100644 src/img/gnome.png create mode 100644 src/img/gnome.svg create mode 100644 src/img/kde.png create mode 100644 src/img/kde.svg create mode 100644 src/img/linux.png create mode 100644 src/img/linux.svg create mode 100644 src/img/locked.png create mode 100644 src/img/lxde.png create mode 100644 src/img/macos.png create mode 100644 src/img/macos.svg create mode 100644 src/img/mess.png create mode 100644 src/img/none.png create mode 100644 src/img/openslx-logo.png create mode 100644 src/img/opensolaris.png create mode 100644 src/img/opensolaris.svg create mode 100644 src/img/os2.png create mode 100644 src/img/osx.png create mode 100644 src/img/osx.svg create mode 100644 src/img/qemu.png create mode 100644 src/img/redhat.png create mode 100644 src/img/redhat.svg create mode 100644 src/img/riscos.png create mode 100644 src/img/riscos_orig.png create mode 100644 src/img/solaris.png create mode 100644 src/img/suse.png create mode 100644 src/img/suse.svg create mode 100644 src/img/term.png create mode 100644 src/img/title_l.png create mode 100644 src/img/title_r.png create mode 100644 src/img/ubuntu.png create mode 100644 src/img/ubuntu.svg create mode 100644 src/img/unknown.png create mode 100644 src/img/virtualbox.png create mode 100644 src/img/vmware.png create mode 100644 src/img/vmware.svg create mode 100644 src/img/win311.png create mode 100644 src/img/win311.svg create mode 100644 src/img/win7.png create mode 100644 src/img/win7_orig.png create mode 100644 src/img/windows.png create mode 100644 src/img/xfce.png create mode 100644 src/img/xfce.svg create mode 100644 src/main.cpp create mode 100644 src/save_restore_session.cpp create mode 100644 src/save_restore_session.h create mode 100644 src/session.h create mode 100644 src/sessiontreeitem.cpp create mode 100644 src/sessiontreeitem.h create mode 100644 src/sessiontreemodel.cpp create mode 100644 src/sessiontreemodel.h create mode 100644 src/ui/dialog.ui create mode 100644 src/vsession.cpp create mode 100644 src/vsession.h create mode 100644 src/xsession.cpp create mode 100644 src/xsession.h create mode 100644 themes/openslx/openslx-left.png create mode 100644 themes/openslx/openslx-right.png create mode 100644 themes/openslx/openslx.ini create mode 100644 themes/planets/planets-left.png create mode 100644 themes/planets/planets-right.png create mode 100644 themes/planets/planets.ini create mode 100644 themes/unifr/title_l.png create mode 100644 themes/unifr/title_r.png create mode 100644 themes/unifr/unifr.ini delete mode 100644 vmChooser/.classpath delete mode 100644 vmChooser/.project delete mode 100644 vmChooser/.settings/org.eclipse.jdt.core.prefs delete mode 100644 vmChooser/bin/HelloWorld.class delete mode 100644 vmChooser/src/HelloWorld.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3245ec2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.cproject +.project +build/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4f6ca9c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required(VERSION 2.6) + +# project name +project(vmchooser) + +set(CMAKE_BUILD_TYPE Debug) +set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -Wall -Wextra -Werror") +set(CMAKE_CXX_FLAGS_RELEASE "-O2") + +file(GLOB_RECURSE VMCHOOSER_SOURCES src/*.cpp) +file(GLOB_RECURSE VMCHOOSER_MOC_HEADERS src/*.h) +file(GLOB_RECURSE VMCHOOSER_UIS src/ui/*.ui) +file(GLOB_RECURSE VMCHOOSER_RESOURCES src/*.qrc) +file(GLOB_RECURSE VMCHOOSER_TSS src/i18n/*.ts) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +# +# Qt4 +# +find_package(Qt4 4.5.0 REQUIRED) +if(QT4_FOUND) + message(STATUS "Qt4 found") +else(QT4_FOUND) + message(FATAL_ERROR "Qt4 not found") +endif(QT4_FOUND) + +set(QT_USE_QTXML TRUE) +set(QT_USE_QTSVG TRUE) + +include(${QT_USE_FILE}) + +option(UPDATE_TRANSLATIONS "Update .ts files (WARNING: make clean will delete the .ts files!)") +if(VMCHOOSER_TSS) + if (UPDATE_TRANSLATIONS) + set (FILES_TO_TRANSLATE ${FILES_TO_TRANSLATE} ${VMCHOOSER_SOURCES} ${VMCHOOSER_UIS}) + QT4_CREATE_TRANSLATION(VMCHOOSER_QMS ${FILES_TO_TRANSLATE} ${VMCHOOSER_TSS} OPTIONS -noobsolete) + message(STATUS ".tr files have been updated") + else (UPDATE_TRANSLATIONS) + QT4_ADD_TRANSLATION(VMCHOOSER_QMS ${VMCHOOSER_TSS}) + endif (UPDATE_TRANSLATIONS) + + # write a resource file for qm files + set(resource_file_content "\n \n") + foreach(file ${VMCHOOSER_QMS}) + get_filename_component(filename ${file} NAME) + set(resource_file_content "${resource_file_content} ${filename}\n") + endforeach(file) + set(resource_file_content "${resource_file_content} \n\n") + file(WRITE "${CMAKE_BINARY_DIR}/translation.qrc" "${resource_file_content}") + set(VMCHOOSER_RESOURCES ${VMCHOOSER_RESOURCES} "${CMAKE_BINARY_DIR}/translation.qrc") + + #add_custom_target(translations_target DEPENDS ${VMCHOOSER_QMS}) +endif(VMCHOOSER_TSS) + +QT4_ADD_RESOURCES(VMCHOOSER_RC_SOURCES ${VMCHOOSER_RESOURCES}) +QT4_WRAP_UI(VMCHOOSER_UI_HEADERS ${VMCHOOSER_UIS}) +QT4_WRAP_CPP(VMCHOOSER_MOC_SOURCES ${VMCHOOSER_MOC_HEADERS}) + +# +# build vmchooser +# +add_executable(vmchooser + ${VMCHOOSER_SOURCES} + ${VMCHOOSER_MOC_SOURCES} + ${VMCHOOSER_UI_HEADERS} + ${VMCHOOSER_RC_SOURCES} + ${VMCHOOSER_QMS} +) + +target_link_libraries(vmchooser + ${QT_LIBRARIES} +) + +install(TARGETS vmchooser RUNTIME DESTINATION bin) +install(FILES default.desktop DESTINATION /usr/share/xsessions) +install(DIRECTORY themes DESTINATION /usr/local/share/vmchooser) diff --git a/README b/README new file mode 100644 index 0000000..9e727c1 --- /dev/null +++ b/README @@ -0,0 +1,86 @@ + +VM Chooser Helper Program +================================== + +This is the program used by the vmchooser-plugin, which +is part of the openslx-system. + + + +================================== +FAQ +================================== + +What does it do? + It handles xml-files for the virtual-machines plugins + or linux sessions after the login-screen. + If chosen, it starts the proper virtualizer script or the linux session + as a background process and terminates itself. + +How can I build it? + This project has been converted to cmake and can be built by running: + $ mkdir -p build + $ cd build + $ cmake .. && make + Alternatively you can just run: + $ ./build.sh + +How can I install it? + See below + +What command-line parameters are available? + "-p|--path=" In this (abolute) path are your xml-files for the virtualizer-plugin + "-l|--lpath=" In this (absolute) path are your linux sessions + "-g|--group=" Show only entries valid for this group + "-h|--help" Show help + +================================== + + +You just need to compile this, if you have local changes. +The most recent svn version is also included in binary format +in the main folder of this openslx-distribution. + +Enter "cmake && make" to compile everything. + +UPDATE: There is a script in the build-directory to simplify building. + +Enter "cp vmchooser ../../../../openslx/trunk/os-plugins/plugins/vmchooser/files/" +to install it to the proper path of the svn distribution of openslx +(only if the build-path is [SVN ROOT]/openslx-src-tools/vmchooser/trunk/somefolder/). + +Do not forget to enter "make install" in [SVN ROOT]/openslx/trunk . + +Needed libraries to compile: + - All sorts of X libs and development files + - fltk-2 (included - see note *) + - libxml2 (included - libxml2-dev on Ubuntu) + + * Boost Libraries (static - dynamic versions can + be enabled by changing the CMakelists.txt - + specifically commenting out the + Boost_USE_STATIC_LIBS variable definition) + (libboost-dev/libboost-[regex|filesystem|system]-dev on Ubuntu) + - libboost-regex_s + - libboost_filesystem_s + - libboost_system_s + +Most probably (for fltk2-includes): + - libpng-dev (libpng12-dev on Ubuntu) + - libjpeg-dev (libjpeg-dev on Ubuntu) + - libxi-dev (libxi-dev on Ubuntu) + - libxinerama-dev (libxinerama-dev on Ubuntu) + - libxrender-dev (libxrender-dev on Ubuntu) + - libxconfig1-dev (libxconfig1-dev on Ubuntu) + - libxft-dev (libxft-dev on Ubuntu) + +Needed libraries to run: + - All sorts of X libs + - libxml2 + +=================================== +* Some static libraries of fltk - svn version - and libxml2 are located +in fltk/ and libxml2/ and are used to link against this program. +- as images are enabled, you should have libjpeg and libpng too. +=================================== + diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..fdd8b44 --- /dev/null +++ b/build.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# relative path to the cmake source tree directory (contains "CMakeLists.txt") +SRCDIR="." + +# relative path to the cmake build tree directory +BUILDDIR="build" + +DIR=$(pwd) + +SCRIPTNAME=$(basename "$0" 2>/dev/null || echo "$0") + +if [[ ! -f "$DIR"/"$SRCDIR"/CMakeLists.txt ]] +then + echo "$SRCDIR/CMakeLists.txt not found" >&2 + echo "please run '$SCRIPTNAME' from its containing directory" >&2 + exit 1 +fi + +for OPTION in "$@" +do + if [[ "$OPTION" == "--clean" ]] + then + rm -r "$BUILDDIR" + elif [[ "$OPTION" == "--update-translations" ]] + then + CMAKE_ARGS="$CMAKE_ARGS -DUPDATE_TRANSLATIONS:BOOL=ON" + else + echo "usage: $SCRIPTNAME [--clean] [--update-translations]" >&2 + exit 1 + fi +done + +# note: NCORES may be too large on systems with hyperthreading +NCORES=$(grep -c "^processor" /proc/cpuinfo 2>/dev/null) +if [[ ! $NCORES -ge 1 ]] +then + NCORES=1 +fi + +mkdir -p "$BUILDDIR" +cd "$BUILDDIR" + +cmake $CMAKE_ARGS "$DIR"/"$SRCDIR"/ && make -j $NCORES + +cd "$DIR" diff --git a/default.desktop b/default.desktop new file mode 100644 index 0000000..944b771 --- /dev/null +++ b/default.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Name=RZ VMChooser +Comment=This session logs you into VMChooser +Exec=vmchooser --pvs +TryExec=vmchooser +Icon= +Type=Applicatio \ No newline at end of file diff --git a/src/command_line_options.cpp b/src/command_line_options.cpp new file mode 100644 index 0000000..1cf1194 --- /dev/null +++ b/src/command_line_options.cpp @@ -0,0 +1,68 @@ +#include "command_line_options.h" +#include +#include + +CommandLineOptions::CommandLineOptions(int argc, char * const argv[]) { + // parse command line arguments + static const struct option longOptions[] = { + {"config", required_argument, NULL, 'c'}, + {"default", required_argument, NULL, 'd'}, + {"env", required_argument, NULL, 'e'}, + {"file", required_argument, NULL, 'f'}, + {"path", required_argument, NULL, 'p'}, + {"xpath", required_argument, NULL, 'x'}, + {"size", required_argument, NULL, 's'}, + {"theme", required_argument, NULL, 't'}, + {"pvs", no_argument, NULL, 'b'}, + {"debug", no_argument, NULL, 'D'}, + {"version", no_argument, NULL, 'v'}, + {"help", no_argument, NULL, 'h'}, + {0, 0, 0, 0} + }; + + int c; + + while ((c = getopt_long(argc, argv, "c:d:e:f:p:x:s:t:w:vhbD", longOptions, NULL)) != -1) { + switch (c) { + case 'c': + options.insert("config", optarg); + break; + case 'd': + options.insert("default", optarg); + break; + case 'f': + options.insert("file", optarg); + break; + case 'D': + options.insert("debugMode", "debugMode"); + break; + case 'e': + options.insert("env", optarg); + break; + case 'p': + options.insert("path", optarg); + break; + case 'x': + options.insert("xpath", optarg); + break; + case 's': + options.insert("size", optarg); + break; + case 't': + options.insert("theme", optarg); + break; + case 'b': + options.insert("pvs", "pvs"); + break; + case 'v': + options.insert("version", "version"); + break; + case 'h': + options.insert("usage", "usage"); + break; + case '?': + default: + options.insert("error", "error"); + } + } +} diff --git a/src/command_line_options.h b/src/command_line_options.h new file mode 100644 index 0000000..8798ff2 --- /dev/null +++ b/src/command_line_options.h @@ -0,0 +1,23 @@ +#ifndef VMCHOOSER_COMMAND_LINE_OPTIONS_H +#define VMCHOOSER_COMMAND_LINE_OPTIONS_H + +#include +#include + +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 options; +}; + +#endif // VMCHOOSER_COMMAND_LINE_OPTIONS_H diff --git a/src/dialog.cpp b/src/dialog.cpp new file mode 100644 index 0000000..d758b0a --- /dev/null +++ b/src/dialog.cpp @@ -0,0 +1,248 @@ +#include "dialog.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "ui_dialog.h" +#include "save_restore_session.h" +#include "sessiontreeitem.h" +#include "globals.h" + +Dialog::Dialog(QWidget *parent) + : QDialog(parent), ui(new Ui::Dialog) { + model_ = new SessionTreeModel(parent); + ui->setupUi(this); + + pvsSettings_ = NULL; + ui->PVSOptionsGroupBox->hide(); + + // Re-center dialog every second to account for resolution changes + QRect desktopRect = QApplication::desktop()->availableGeometry(this); + oldCenter_ = desktopRect.center(); + centerTimer_ = new QTimer(this); + connect(centerTimer_, SIGNAL(timeout()), this, SLOT(on_centerTimer())); + centerTimer_->start(1000); +} + +Dialog::~Dialog() { + delete ui; + delete model_; +} + +void Dialog::changeEvent(QEvent *e) { + QDialog::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +void Dialog::on_treeView_activated(QModelIndex index) { + // this method gets called when a Session has been activated + + SessionTreeItem* item = + static_cast(index.internalPointer()); + + const Session* s(item->session()); + if (!s) { + // no valid session has been selected, do nothing + return; + } + + // Run session start script + if (QFile::exists(sessionStartScript)) { + QProcess scriptProcess; + scriptProcess.start(sessionStartScript, QIODevice::ReadOnly); + scriptProcess.waitForFinished(); + scriptProcess.close(); + } + + if (s->run()) { + writePVSSettings(); + writeSessionName(s->shortDescription()); + setVisible(false); + + } else { + QMessageBox::warning( + this, trUtf8("vmchooser"), + trUtf8("Vmchooser failed to run the selected session!")); + } +} + +void Dialog::addItems(const QList& entries, const QString& section) { + this->model_->addItems(entries, section); + ui->treeView->setModel(model_); + ui->treeView->expandAll(); +} + +void Dialog::on_pushButtonAbort_clicked() { + close(); +} + +void Dialog::on_pushButtonStart_clicked() { + this->on_treeView_activated(ui->treeView->selectionModel()->currentIndex()); +} + +void Dialog::readPVSSettings() { + if (!pvsSettings_) return; + QString value; + + value = pvsSettings_->value("Permissions/vnc_lecturer").toString(); + if (value == "rw") { + ui->comboBoxLecturer->setCurrentIndex(2); + } else if (value == "ro") { + ui->comboBoxLecturer->setCurrentIndex(1); + } else { + ui->comboBoxLecturer->setCurrentIndex(0); + } + + value = pvsSettings_->value("Permissions/vnc_other").toString(); + if (value == "rw") { + ui->comboBoxOthers->setCurrentIndex(2); + } else if (value == "ro") { + ui->comboBoxOthers->setCurrentIndex(1); + } else { + ui->comboBoxOthers->setCurrentIndex(0); + } +} + +void Dialog::writePVSSettings() { + if (!pvsSettings_) return; + int accessLecturer = ui->comboBoxLecturer->currentIndex(); + if (accessLecturer == 2) { + pvsSettings_->setValue("Permissions/vnc_lecturer", "rw"); + } else if (accessLecturer == 1) { + pvsSettings_->setValue("Permissions/vnc_lecturer", "ro"); + } else { + pvsSettings_->setValue("Permissions/vnc_lecturer", "no"); + } + + int accessOthers = ui->comboBoxOthers->currentIndex(); + if (accessOthers == 2) { + pvsSettings_->setValue("Permissions/vnc_other", "rw"); + } else if (accessOthers == 1) { + pvsSettings_->setValue("Permissions/vnc_other", "ro"); + } else { + pvsSettings_->setValue("Permissions/vnc_other", "no"); + } + pvsSettings_->sync(); +} + +void Dialog::on_comboBoxLecturer_currentIndexChanged(int index) { + // TODO (Jan): may others have more access than lecturer? + if (index < ui->comboBoxOthers->currentIndex()) { + ui->comboBoxOthers->setCurrentIndex(index); + } +} + +void Dialog::on_comboBoxOthers_currentIndexChanged(int index) { + // TODO (Jan): may others have more access than lecturer? + if (index > ui->comboBoxLecturer->currentIndex()) { + ui->comboBoxLecturer->setCurrentIndex(index); + } +} + +bool Dialog::selectSession(const QString& name) { + QModelIndex root(ui->treeView->rootIndex()); + + for (int i = 0; i < model_->rowCount(root); ++i) { + QModelIndex section = model_->index(i, 0, root); + if (!section.isValid()) break; + for (int row = 0; row < model_->rowCount(section); ++row) { + QModelIndex index = model_->index(row, 0, section); + if (!index.isValid()) break; + + SessionTreeItem* item = + static_cast(index.internalPointer()); + const Session* s(item->session()); + if (!s) continue; + if (s->shortDescription() == name) { + ui->treeView->selectionModel() + ->setCurrentIndex(index, QItemSelectionModel::Select); + return true; + } + } + } + return false; +} + +void Dialog::selectPreviousSession() { + selectSession(readSessionName()); +} + +void Dialog::startSession(const QString& name) { + autoStartEntry_ = name; +} + +void Dialog::showSettingsPVS() { + pvsSettings_ = new QSettings("openslx", "pvs", this); + QStringList accessOptions; + accessOptions <comboBoxLecturer->insertItems(0, accessOptions); + ui->comboBoxOthers->insertItems(0, accessOptions); + readPVSSettings(); + ui->PVSOptionsGroupBox->show(); +} + +void Dialog::setTheme() { + QString label_l_style, label_r_style; + QString backgroundColor, imageLeft, imageRight; + QString themePathBase, themePathIni, themePathImgLeft, themePathImgRight; + + if (theme.isEmpty()) return; + + themePathBase = QString("%1/%2/").arg(VMCHOOSER_THEME_BASE).arg(theme); + themePathIni = QString("%1%2.ini").arg(themePathBase).arg(theme); + + if (!QFile::exists(themePathIni)) return; + + + QSettings themeSettings(themePathIni, QSettings::IniFormat); + backgroundColor = themeSettings.value("background-color").toString(); + imageLeft = themeSettings.value("image-left").toString(); + imageRight = themeSettings.value("image-right").toString(); + + themePathImgLeft = QString("%1%2").arg(themePathBase).arg(imageLeft); + themePathImgRight = QString("%1%2").arg(themePathBase).arg(imageRight); + + QRegExp re; + + ui->label_l->setPixmap(QPixmap(themePathImgLeft)); + ui->label_r->setPixmap(QPixmap(themePathImgRight)); + label_l_style = ui->label_l->styleSheet(); + label_r_style = ui->label_r->styleSheet(); + backgroundColor.prepend("\\1").append("\\2"); + label_l_style.replace(QRegExp("(.*background-color:)#[^;]*(;.*)"), backgroundColor); + label_r_style.replace(QRegExp("(.*background-color:)#[^;]*(;.*)"), backgroundColor); + //qDebug() << label_r_style << label_l_style; + ui->label_l->setStyleSheet(label_l_style); + ui->label_r->setStyleSheet(label_r_style); +} + +void Dialog::on_centerTimer() { + if (!autoStartEntry_.isEmpty()) { + if (this->selectSession(autoStartEntry_)) { + this->on_treeView_activated(ui->treeView->selectionModel()->currentIndex()); + } else { + QMessageBox::critical(this, "Autostart", QString::fromUtf8("Konnte %1 nicht starten.").arg(autoStartEntry_)); + } + autoStartEntry_.clear(); + return; + } + // center dialog on primary screen + QRect desktopRect = QApplication::desktop()->availableGeometry(this); + QPoint center = desktopRect.center(); + if (center != oldCenter_) { + this->move(center.x() - this->width() / 2, center.y() - this->height() / 2); + oldCenter_ = center; + } +} + diff --git a/src/dialog.h b/src/dialog.h new file mode 100644 index 0000000..d1daa68 --- /dev/null +++ b/src/dialog.h @@ -0,0 +1,50 @@ +#ifndef DIALOG_H +#define DIALOG_H + +#include +#include +#include +#include +#include "session.h" +#include "sessiontreemodel.h" + +namespace Ui { + class Dialog; +} +class QTimer; + +class Dialog : public QDialog { + Q_OBJECT + public: + explicit Dialog(QWidget *parent = 0); + ~Dialog(); + void addItems(const QList&, const QString& section); + bool selectSession(const QString& name); + void selectPreviousSession(); + void showSettingsPVS(); + void setTheme(); + void startSession(const QString& name); + + protected: + void changeEvent(QEvent *e); + + private: + Ui::Dialog *ui; + SessionTreeModel *model_; + QSettings *pvsSettings_; + QPoint oldCenter_; + QTimer *centerTimer_; + QString autoStartEntry_; + void readPVSSettings(); + void writePVSSettings(); + + private slots: + void on_comboBoxOthers_currentIndexChanged(int index); + void on_comboBoxLecturer_currentIndexChanged(int index); + void on_pushButtonStart_clicked(); + void on_pushButtonAbort_clicked(); + void on_treeView_activated(QModelIndex index); + void on_centerTimer(); +}; + +#endif // DIALOG_H diff --git a/src/globals.cpp b/src/globals.cpp new file mode 100644 index 0000000..8026752 --- /dev/null +++ b/src/globals.cpp @@ -0,0 +1,26 @@ +#include +#include +#include "globals.h" + +//QString binPath(QApplication::applicationDirPath()); +QString binPath(VMCHOOSER_BIN_PATH); +QString etcPath(VMCHOOSER_ETC_BASE_PATH); +QString vSessionPath(VMCHOOSER_VMPATH); +QString xSessionPath(VMCHOOSER_X_SESSIONS_PATH); +QString userPath(QDir::homePath() + "/.openslx"); + +QString runVmScript(binPath + "/run-virt.sh"); +QString filterScript(binPath + "/xmlfilter.sh"); +QString printerScript(etcPath + "/printer.sh"); +QString scannerScript(etcPath + "/scanner.sh"); +QString sessionStartScript(VMCHOOSER_SESSION_START_SCRIPT); + +const QString globalConfFile(etcPath + "/vmchooser.conf"); +const QString userConfFile(userPath + "/vmchooser.conf"); +const QString previousSessionFile(userPath + "/vmchooser_prev_session"); + +bool debugMode = false; +bool pvsEnabled = false; + +QString pool; +QString theme; diff --git a/src/globals.h b/src/globals.h new file mode 100644 index 0000000..32ecedb --- /dev/null +++ b/src/globals.h @@ -0,0 +1,46 @@ +#ifndef VMCHOOSER_GLOBALS_H +#define VMCHOOSER_GLOBALS_H + +#define VMCHOOSER_VERSION "0.1.0" + +#define VMCHOOSER_PLUGIN_PATH "/opt/openslx/plugin-repo/vmchooser" +#define VMCHOOSER_BIN_PATH "/var/opt/openslx/bin" +#define VMCHOOSER_ETC_BASE_PATH "/etc/vmchooser" +#define VMCHOOSER_VMPATH "/var/lib/virt" +#define VMCHOOSER_THEME_BASE "/usr/local/share/vmchooser/themes" + +#define VMCHOOSER_X_SESSIONS_PATH "/usr/share/xsessions" + +#define VMCHOOSER_SESSION_START_SCRIPT "/opt/openslx/vmchooser/sessionstart" + +#define VMCHOOSER_DEFAULT_WIDTH 500 +#define VMCHOOSER_DEFAULT_HEIGHT 580 + +#define OPENSLXCONFIG "/opt/openslx/config" + +class QString; + +extern bool debugMode; +extern bool pvsEnabled; + +extern QString binPath; +extern QString etcPath; +extern QString vSessionPath; +extern QString xSessionPath; +extern QString userPath; + +extern QString runVmScript; +extern QString filterScript; +extern QString printerScript; +extern QString scannerScript; +// Script that is run before the xsession/vsession is started +extern QString sessionStartScript; + +extern const QString globalConfFile; +extern const QString userConfFile; +extern const QString previousSessionFile; + +extern QString pool; +extern QString theme; + +#endif diff --git a/src/i18n/de.ts b/src/i18n/de.ts new file mode 100644 index 0000000..b920b73 --- /dev/null +++ b/src/i18n/de.ts @@ -0,0 +1,134 @@ + + + + + Console + + + Usage: vmchooser [ OPTIONS | FILE ] + + -d, --default name of default session + -P, --pool name of the environment + -p, --path path to vmware .xml files + -x, --xpath path of X Session .desktop files + -s, --size window size <width>x<height> + -v, --version print version and exit + -h, --help print usage information and exit + +FILE can be a vmware .xml or an X .desktop file + + Aufruf: vmchooser [ OPTIONEN | DATEI ] + + -d, --default Name der Standardsitzung + -P, --pool Name der Umgebung + -p, --path Pfad zu .xml-Dateien für virtuelle Sitzungen + -x, --xpath Pfad zu .desktop-Dateien für X Sitzungen + -s, --size Fenstergröße <Breite>x<Höhe> + -v, --version Version anzeigen und beenden + -h, --help Hilfetext anzeigen und beenden + + DATEI kann eine .xml- oder .desktop-Datei sein + + + + + + vmchooser: failed to run session + vmchooser: Fehler beim Start der Sitzung + + + + vmchooser: invalid session file + vmchooser: ungültige Sitzungsdatei + + + + vmchooser: invlid size argument + vmchooser: ungültige Größenangabe + + + + vmchooser: no sessions found + vmchooser: keine Sitzungen gefunden + + + + vmchooser: external script %1 is not executable + vmchooser: externes Skript %1 ist nicht ausführbar + + + + Dialog + + + + vmchooser + vmchooser + + + + PVS Options + PVS Einstellungen + + + + VNC access by lecturer: + VNC-Zugriff für Dozenten: + + + + VNC access by others: + VNC-Zugriff für andere: + + + + Accept chat messages + Chat-Nachrichten akzeptieren + + + + Accept file transfers + Dateiübertragungen akzeptieren + + + + Abort + Abbrechen + + + + Start + Start + + + + None + kein Zugriff + + + + View Only + nur ansehen + + + + Full + Vollzugriff + + + + Vmchooser failed to run the selected session! + Vmchooser konnte die gewählte Sitzung nicht ausführen! + + + + X Sessions + X-Sitzungen + + + + Virtual Sessions + Virtuelle Sitzungen + + + diff --git a/src/i18n/pt.ts b/src/i18n/pt.ts new file mode 100755 index 0000000..d75f1f2 --- /dev/null +++ b/src/i18n/pt.ts @@ -0,0 +1,135 @@ + + + + + Console + + + Usage: vmchooser [ OPTIONS | FILE ] + + -d, --default name of default session + -P, --pool name of the environment + -p, --path path to vmware .xml files + -x, --xpath path of X Session .desktop files + -s, --size window size <width>x<height> + -v, --version print version and exit + -h, --help print usage information and exit + +FILE can be a vmware .xml or an X .desktop file + + Uso: vmchooser [ OPÇOES | ARQUIVO ] + + -d, --(default) nome da sessão padrão + -P, --(pool) nome do pool do ambiente + -p, --(path) caminho para os arquivos xml do vmware + -x, --(xpath) caminho dos arquivos da área de trabalho da sessão X + -s, --(size) tamanho da janela <largura>x<altura> + -v, --(version) mostrar versão e sair + -h, --(help) mostrar ajuda e sair + +ARQUIVO pode ser um arquivo xml do vmware ou do área de trabalho do X + + + + + + vmchooser: failed to run session + vmchooser: falhou ao executar a sessão + + + + vmchooser: invalid session file + vmchooser: arquivo de sessão inválido + + + + vmchooser: invlid size argument + vmchooser: argumento de tamanho inválido + + + + vmchooser: no sessions found + vmchooser: nenhuma sessão encontrada + + + + vmchooser: external script %1 is not executable + vmchooser: o script externo %1 não é executável + + + + Dialog + + + + vmchooser + seletor + + + + PVS Options + Opções do PVS + + + + VNC access by lecturer: + Acesso VNC para o Instrutor: + + + + VNC access by others: + Acesso VNC para os demais: + + + + Accept chat messages + Aceitar mensagens instantâneas + + + + Accept file transfers + Aceitar transferência de arquivos + + + + Abort + Interromper + + + + Start + Iniciar + + + + None + it's used for no access + Nada + + + + View Only + Apenar ver + + + + Full + Total + + + + Vmchooser failed to run the selected session! + O seletor da VM falhou ao executar a sessão selecionada! + + + + X Sessions + Sessões X + + + + Virtual Sessions + Sessões Virtuais + + + diff --git a/src/images.qrc b/src/images.qrc new file mode 100644 index 0000000..bf903f3 --- /dev/null +++ b/src/images.qrc @@ -0,0 +1,39 @@ + + + img/none.png + img/linux.png + img/ubuntu.png + img/debian.png + img/suse.png + img/gentoo.png + img/redhat.png + img/fedora.png + img/bsd.png + img/osx.png + img/macos.png + img/gnome.png + img/kde.png + img/xfce.png + img/windows.png + img/vmware.png + img/openslx-logo.png + img/title_r.png + img/title_l.png + img/lxde.png + img/virtualbox.png + img/unknown.png + img/dosbox.png + img/qemu.png + img/mess.png + img/beos.png + img/os2.png + img/amiga.png + img/amiga2.png + img/atari.png + img/riscos.png + img/opensolaris.png + img/solaris.png + img/win311.png + img/win7.png + + diff --git a/src/img/Atari.svg b/src/img/Atari.svg new file mode 100644 index 0000000..ab14ef7 --- /dev/null +++ b/src/img/Atari.svg @@ -0,0 +1,58 @@ + + + + + Atari Games Logo + + + + image/svg+xml + + Atari Games Logo + + + + + + + diff --git a/src/img/LICENSE b/src/img/LICENSE new file mode 100644 index 0000000..0c3439e --- /dev/null +++ b/src/img/LICENSE @@ -0,0 +1,56 @@ +linux.svg / linux.png +Source: https://secure.wikimedia.org/wikipedia/commons/wiki/File:Tux-G2.svg +License: public domain + +fedora.svg / fedora.png +Source: https://secure.wikimedia.org/wikipedia/de/w/index.php?title=Datei:Fedora_%28Linux-Distribution%29_logo.svg&filetimestamp=20080912041413 +License: registered trademark + +xfce.svg / xfce.png +Source: https://secure.wikimedia.org/wikipedia/en/wiki/File:Xfce_logo.svg +License: Creative Commons Attribution-Share Alike 3.0 Unported license + +ubuntu.svg / ubuntu.png +Source: https://secure.wikimedia.org/wikipedia/commons/wiki/File:UbuntuCoF.svg +License: registered trademark + +suse.svg / suse.png +Source: https://secure.wikimedia.org/wikipedia/en/wiki/File:Suse_logo.svg +License: GPL / registered trademark + +redhat.svg / redhat.png +Source: https://secure.wikimedia.org/wikipedia/en/wiki/File:RedHat.svg +License: registered trademark + +macos.svg / macos.png +Source: https://secure.wikimedia.org/wikipedia/en/wiki/File:Mac_OS_Logo_with_Text.svg +License: registered trademark + +osx.svg / osx.png +Source: https://secure.wikimedia.org/wikipedia/en/wiki/File:OSXLeopard.svg +License: registered trademark + +kde.svg / kde.png +Source: https://secure.wikimedia.org/wikipedia/en/wiki/File:KDE_logo.svg +License: registered trademark + +gnome.svg / gnome.png +Source: https://secure.wikimedia.org/wikipedia/en/wiki/File:Gnomelogo.svg +License: GPL / registered trademark + +gentoo.svg / gentoo.png +Source: https://secure.wikimedia.org/wikipedia/en/wiki/File:Gentoo_Linux_logo_matte.svg +License: Creative Commons Attribution-Share Alike 2.5 Generic / registered trademark + +bsd.png +Source: https://secure.wikimedia.org/wikipedia/en/wiki/File:Freebsd_logo.svg +License: registered trademark + +windows.png +Source: https://secure.wikimedia.org/wikipedia/en/wiki/File:Windows_logo.svg +License: registered trademark + +vmware.svg / vmware.png +Source: https://secure.wikimedia.org/wikipedia/en/wiki/File:Vmware.svg +License: registered trademark + diff --git a/src/img/amiga.png b/src/img/amiga.png new file mode 100644 index 0000000..0291875 Binary files /dev/null and b/src/img/amiga.png differ diff --git a/src/img/amiga2.png b/src/img/amiga2.png new file mode 100644 index 0000000..d90af56 Binary files /dev/null and b/src/img/amiga2.png differ diff --git a/src/img/atari.png b/src/img/atari.png new file mode 100644 index 0000000..419dd16 Binary files /dev/null and b/src/img/atari.png differ diff --git a/src/img/beos.png b/src/img/beos.png new file mode 100644 index 0000000..11834fa Binary files /dev/null and b/src/img/beos.png differ diff --git a/src/img/bsd.png b/src/img/bsd.png new file mode 100644 index 0000000..8b26986 Binary files /dev/null and b/src/img/bsd.png differ diff --git a/src/img/debian.png b/src/img/debian.png new file mode 100644 index 0000000..b1ebf06 Binary files /dev/null and b/src/img/debian.png differ diff --git a/src/img/debian.svg b/src/img/debian.svg new file mode 100644 index 0000000..0146264 --- /dev/null +++ b/src/img/debian.svg @@ -0,0 +1,18 @@ + + + \ No newline at end of file diff --git a/src/img/dosbox.png b/src/img/dosbox.png new file mode 100644 index 0000000..73a0f4c Binary files /dev/null and b/src/img/dosbox.png differ diff --git a/src/img/fedora.png b/src/img/fedora.png new file mode 100644 index 0000000..870716f Binary files /dev/null and b/src/img/fedora.png differ diff --git a/src/img/fedora.svg b/src/img/fedora.svg new file mode 100644 index 0000000..7589d1f --- /dev/null +++ b/src/img/fedora.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/src/img/gentoo.png b/src/img/gentoo.png new file mode 100644 index 0000000..9505c79 Binary files /dev/null and b/src/img/gentoo.png differ diff --git a/src/img/gentoo.svg b/src/img/gentoo.svg new file mode 100644 index 0000000..293ecda --- /dev/null +++ b/src/img/gentoo.svg @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/gnome.png b/src/img/gnome.png new file mode 100644 index 0000000..d2f09cd Binary files /dev/null and b/src/img/gnome.png differ diff --git a/src/img/gnome.svg b/src/img/gnome.svg new file mode 100644 index 0000000..27c9120 --- /dev/null +++ b/src/img/gnome.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + diff --git a/src/img/kde.png b/src/img/kde.png new file mode 100644 index 0000000..6e29013 Binary files /dev/null and b/src/img/kde.png differ diff --git a/src/img/kde.svg b/src/img/kde.svg new file mode 100644 index 0000000..2503826 --- /dev/null +++ b/src/img/kde.svg @@ -0,0 +1,323 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/img/linux.png b/src/img/linux.png new file mode 100644 index 0000000..fd76d28 Binary files /dev/null and b/src/img/linux.png differ diff --git a/src/img/linux.svg b/src/img/linux.svg new file mode 100644 index 0000000..57f4a1e --- /dev/null +++ b/src/img/linux.svg @@ -0,0 +1,933 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/locked.png b/src/img/locked.png new file mode 100644 index 0000000..414a9be Binary files /dev/null and b/src/img/locked.png differ diff --git a/src/img/lxde.png b/src/img/lxde.png new file mode 100644 index 0000000..69b0f9e Binary files /dev/null and b/src/img/lxde.png differ diff --git a/src/img/macos.png b/src/img/macos.png new file mode 100644 index 0000000..f4dd5f0 Binary files /dev/null and b/src/img/macos.png differ diff --git a/src/img/macos.svg b/src/img/macos.svg new file mode 100644 index 0000000..b6d11f6 --- /dev/null +++ b/src/img/macos.svg @@ -0,0 +1,33 @@ + + + Mac-OS Logo + + + + + + + + diff --git a/src/img/mess.png b/src/img/mess.png new file mode 100644 index 0000000..cb98f10 Binary files /dev/null and b/src/img/mess.png differ diff --git a/src/img/none.png b/src/img/none.png new file mode 100644 index 0000000..e6fc91a Binary files /dev/null and b/src/img/none.png differ diff --git a/src/img/openslx-logo.png b/src/img/openslx-logo.png new file mode 100644 index 0000000..7e40912 Binary files /dev/null and b/src/img/openslx-logo.png differ diff --git a/src/img/opensolaris.png b/src/img/opensolaris.png new file mode 100644 index 0000000..e70051b Binary files /dev/null and b/src/img/opensolaris.png differ diff --git a/src/img/opensolaris.svg b/src/img/opensolaris.svg new file mode 100644 index 0000000..f063aed --- /dev/null +++ b/src/img/opensolaris.svg @@ -0,0 +1,164 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/os2.png b/src/img/os2.png new file mode 100644 index 0000000..5a74de3 Binary files /dev/null and b/src/img/os2.png differ diff --git a/src/img/osx.png b/src/img/osx.png new file mode 100644 index 0000000..12a7ea3 Binary files /dev/null and b/src/img/osx.png differ diff --git a/src/img/osx.svg b/src/img/osx.svg new file mode 100644 index 0000000..ceb8e0a --- /dev/null +++ b/src/img/osx.svg @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/qemu.png b/src/img/qemu.png new file mode 100644 index 0000000..a154cec Binary files /dev/null and b/src/img/qemu.png differ diff --git a/src/img/redhat.png b/src/img/redhat.png new file mode 100644 index 0000000..437ca10 Binary files /dev/null and b/src/img/redhat.png differ diff --git a/src/img/redhat.svg b/src/img/redhat.svg new file mode 100644 index 0000000..d7a6788 --- /dev/null +++ b/src/img/redhat.svg @@ -0,0 +1,101 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/img/riscos.png b/src/img/riscos.png new file mode 100644 index 0000000..2c4573e Binary files /dev/null and b/src/img/riscos.png differ diff --git a/src/img/riscos_orig.png b/src/img/riscos_orig.png new file mode 100644 index 0000000..1b9752f Binary files /dev/null and b/src/img/riscos_orig.png differ diff --git a/src/img/solaris.png b/src/img/solaris.png new file mode 100644 index 0000000..8433849 Binary files /dev/null and b/src/img/solaris.png differ diff --git a/src/img/suse.png b/src/img/suse.png new file mode 100644 index 0000000..1472b93 Binary files /dev/null and b/src/img/suse.png differ diff --git a/src/img/suse.svg b/src/img/suse.svg new file mode 100644 index 0000000..3a2f285 --- /dev/null +++ b/src/img/suse.svg @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/src/img/term.png b/src/img/term.png new file mode 100644 index 0000000..f4c0200 Binary files /dev/null and b/src/img/term.png differ diff --git a/src/img/title_l.png b/src/img/title_l.png new file mode 100644 index 0000000..900dd86 Binary files /dev/null and b/src/img/title_l.png differ diff --git a/src/img/title_r.png b/src/img/title_r.png new file mode 100644 index 0000000..8ca9347 Binary files /dev/null and b/src/img/title_r.png differ diff --git a/src/img/ubuntu.png b/src/img/ubuntu.png new file mode 100644 index 0000000..b43c137 Binary files /dev/null and b/src/img/ubuntu.png differ diff --git a/src/img/ubuntu.svg b/src/img/ubuntu.svg new file mode 100644 index 0000000..d835062 --- /dev/null +++ b/src/img/ubuntu.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/img/unknown.png b/src/img/unknown.png new file mode 100644 index 0000000..21ccd9c Binary files /dev/null and b/src/img/unknown.png differ diff --git a/src/img/virtualbox.png b/src/img/virtualbox.png new file mode 100644 index 0000000..21bee21 Binary files /dev/null and b/src/img/virtualbox.png differ diff --git a/src/img/vmware.png b/src/img/vmware.png new file mode 100644 index 0000000..a704627 Binary files /dev/null and b/src/img/vmware.png differ diff --git a/src/img/vmware.svg b/src/img/vmware.svg new file mode 100644 index 0000000..a92e234 --- /dev/null +++ b/src/img/vmware.svg @@ -0,0 +1,86 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/src/img/win311.png b/src/img/win311.png new file mode 100644 index 0000000..b527bf4 Binary files /dev/null and b/src/img/win311.png differ diff --git a/src/img/win311.svg b/src/img/win311.svg new file mode 100644 index 0000000..6768fae --- /dev/null +++ b/src/img/win311.svg @@ -0,0 +1,322 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/win7.png b/src/img/win7.png new file mode 100644 index 0000000..3552207 Binary files /dev/null and b/src/img/win7.png differ diff --git a/src/img/win7_orig.png b/src/img/win7_orig.png new file mode 100644 index 0000000..a4adfe5 Binary files /dev/null and b/src/img/win7_orig.png differ diff --git a/src/img/windows.png b/src/img/windows.png new file mode 100644 index 0000000..50dc89f Binary files /dev/null and b/src/img/windows.png differ diff --git a/src/img/xfce.png b/src/img/xfce.png new file mode 100644 index 0000000..41c8d21 Binary files /dev/null and b/src/img/xfce.png differ diff --git a/src/img/xfce.svg b/src/img/xfce.svg new file mode 100644 index 0000000..6ff4acc --- /dev/null +++ b/src/img/xfce.svg @@ -0,0 +1,226 @@ + + + + + XFCE 4 Logo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..8ccbba2 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,238 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "command_line_options.h" +#include "dialog.h" +#include "globals.h" +#include "save_restore_session.h" +#include "vsession.h" +#include "xsession.h" + +bool myLessThan(Session* a, Session* b) { + return *a < *b; +} + +int main(int argc, char *argv[]) { + QApplication a(argc, argv); + + QTranslator translator; + translator.load(":" + QLocale::system().name()); + a.installTranslator(&translator); + + CommandLineOptions cmdOptions(argc, argv); + + std::string usage(a.translate( + "Console", + "Usage: vmchooser [ OPTIONS ]\n\n" + " -d, --default name of default session\n" + " -c, --config alternative config file\n" + " -e, --env name of the environment\n" + " -f, --file direct boot FILE\n" + " -p, --path path to vmware .xml files\n" + " -x, --xpath path of X Session .desktop files\n" + " -s, --size window size x\n" + " -t, --theme theme\n" + " -b, --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" + "\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("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().data() << + std::endl; + return EXIT_FAILURE; + } else if (file.endsWith(".xml")) { + // our XML-files can contain multiple sessions + // let's just take the first one + Session* s(VSession::readXmlFile(file).value(0)); + if (s && s->run()) { + return EXIT_SUCCESS; + } + std::cerr << a.translate( + "Console", + "vmchooser: failed to run session").toUtf8().data() << + std::endl; + } else { + std::cerr << a.translate( + "Console", + "vmchooser: invalid session file").toUtf8().data() << + std::endl; + return EXIT_FAILURE; + } + } + + // read configuration file: + // file supplied as command line option or + // user vmchooser.conf or + // globel vmchooser.conf + QString confFile; + if (cmdOptions.contains("config")) { + confFile = cmdOptions.value("config"); + } else if (QFileInfo(userConfFile).exists()) { + confFile = userConfFile; + } else { + confFile = globalConfFile; + } + QSettings settings(confFile, QSettings::IniFormat); + settings.setIniCodec("UTF-8"); + + QString defaultSession; + if (cmdOptions.contains("default")) { + defaultSession = cmdOptions.value("default"); + } else if (settings.contains("default")) { + defaultSession = settings.value("default").toString(); + } else { + defaultSession = readSessionName(); + } + + if (cmdOptions.contains("path")) { + vSessionPath = cmdOptions.value("path"); + } else if (settings.contains("path")) { + vSessionPath = settings.value("path").toString(); + } // else keep default path + + if (cmdOptions.contains("xpath")) { + xSessionPath = cmdOptions.value("xpath"); + } else if (settings.contains("xpath")) { + xSessionPath = settings.value("xpath").toString(); + } // else keep default path + + QString size; + if (cmdOptions.contains("size")) { + size = cmdOptions.value("size"); + } else if (settings.contains("size")) { + size = settings.value("size").toString(); + } + + int width, height; + 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: invlid size argument").toUtf8().data() + << std::endl; + return EXIT_FAILURE; + } else { + width = VMCHOOSER_DEFAULT_WIDTH; + height = VMCHOOSER_DEFAULT_HEIGHT; + } + + if (cmdOptions.contains("env")) { + pool = cmdOptions.value("env"); + } 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; + } + + /* read session files */ + QList xsessions(XSession::readSessions(xSessionPath)); + QList vsessions(VSession::readXmlDir(vSessionPath)); + + Dialog w; + + w.setTheme(); + + w.setWindowFlags(Qt::FramelessWindowHint); + if (cmdOptions.contains("pvs")) { + pvsEnabled = true; + } else if (settings.contains("pvs")) { + if (settings.value("pvs").toInt() == 1) + pvsEnabled = true; + } + + if ( pvsEnabled ) + w.showSettingsPVS(); + + w.resize(width, height); + if (xsessions.empty() && vsessions.empty()) { + std::cerr << a.translate( + "Console", + "vmchooser: no sessions found").toUtf8().data() + << std::endl; + return EXIT_FAILURE; + } + if (xsessions.size()) { + qSort(xsessions.begin(), xsessions.end(), myLessThan); + w.addItems(xsessions, a.translate("Dialog", "X Sessions")); + } + if (vsessions.size()) { + if (!(QFile::permissions(runVmScript) & QFile::ExeUser)) { + std::cerr << a.translate( + "Console", + "vmchooser: external script %1 is not executable") + .arg(runVmScript).toUtf8().data() + << std::endl; + return EXIT_FAILURE; + } + qSort(vsessions.begin(), vsessions.end(), myLessThan); + w.addItems(vsessions, a.translate("Dialog", "Virtual Sessions")); + } + + QSettings SLXsettings(OPENSLXCONFIG, QSettings::NativeFormat); + if ( SLXsettings.contains("SLX_BENCHMARK_VM") ) { + QString vm = SLXsettings.value("SLX_BENCHMARK_VM").toString(); + vm.remove('\''); + w.startSession(vm); + } else { + w.selectSession(defaultSession); + } + w.show(); + + // center dialog on primary screen + QRect desktopRect = QApplication::desktop()->availableGeometry(&w); + QPoint center = desktopRect.center(); + w.move(center.x()-w.width()*0.5, center.y()-w.height()*0.5); + a.setActiveWindow(&w); + + return a.exec(); +} diff --git a/src/save_restore_session.cpp b/src/save_restore_session.cpp new file mode 100644 index 0000000..8ca1f9d --- /dev/null +++ b/src/save_restore_session.cpp @@ -0,0 +1,31 @@ +#include "save_restore_session.h" +#include +#include +#include +#include "globals.h" + +void writeSessionName(QString name) { + QDir saveFileDir(QFileInfo(previousSessionFile).absoluteDir()); + if (!saveFileDir.exists()) { + if (!saveFileDir.mkpath(saveFileDir.path())) { + // TODO: error + return; + } + } + + QFile saveFile(previousSessionFile); + if (!saveFile.open(QIODevice::WriteOnly) || + saveFile.write(name.toUtf8().data()) == -1) { + // TODO: error + } +} + +QString readSessionName() { + QFile saveFile(previousSessionFile); + + if (saveFile.open(QIODevice::ReadOnly)) { + return QString(saveFile.readAll()); + } else { + return QString(); + } +} diff --git a/src/save_restore_session.h b/src/save_restore_session.h new file mode 100644 index 0000000..e04ee28 --- /dev/null +++ b/src/save_restore_session.h @@ -0,0 +1,7 @@ +#ifndef VMCHOOSER_SAVE_RESTORE_SESSION_H +#define VMCHOOSER_SAVE_RESTORE_SESSION_H +class QString; + +void writeSessionName(QString name); +QString readSessionName(); +#endif diff --git a/src/session.h b/src/session.h new file mode 100644 index 0000000..f3d4b4b --- /dev/null +++ b/src/session.h @@ -0,0 +1,26 @@ +#ifndef VMCHOOSER_SESSION_H_ +#define VMCHOOSER_SESSION_H_ + +class QString; + +class Session { + public: + virtual ~Session() {} + + virtual bool isActive() const = 0; + virtual bool isLocked() const = 0; + virtual bool isValid() const = 0; + virtual int priority() const = 0; + virtual QString shortDescription() const = 0; + virtual QString description() const = 0; + virtual QString icon() const = 0; + virtual bool run() const = 0; + virtual int type() const = 0; + + virtual bool operator<(const Session& s) const = 0; + + const static int XSESSION = 0; + const static int VSESSION = 1; + +}; +#endif /*VMCHOOSER_SESSION_H_*/ diff --git a/src/sessiontreeitem.cpp b/src/sessiontreeitem.cpp new file mode 100644 index 0000000..45a4774 --- /dev/null +++ b/src/sessiontreeitem.cpp @@ -0,0 +1,50 @@ +#include "sessiontreeitem.h" + +SessionTreeItem::SessionTreeItem(const Session* session, + SessionTreeItem *parent) + : parent_(parent), session_(session) { +} + +SessionTreeItem::SessionTreeItem(const QString& text, SessionTreeItem *parent) + : parent_(parent), session_(NULL), text_(text) { +} + +SessionTreeItem::~SessionTreeItem() { + qDeleteAll(children_); +} + +void SessionTreeItem::appendChild(SessionTreeItem *item) { + children_.append(item); +} + +SessionTreeItem *SessionTreeItem::child(int row) { + return children_.value(row); +} + +int SessionTreeItem::childCount() const { + return children_.count(); +} + +int SessionTreeItem::columnCount() const { + return 1; +} + +SessionTreeItem *SessionTreeItem::parent() { + return parent_; +} + +int SessionTreeItem::row() const { + if (parent_) { + return parent_->children_.indexOf(const_cast(this)); + } + + return 0; +} + +const Session* SessionTreeItem::session() const { + return session_; +} + +const QString SessionTreeItem::text() const { + return text_; +} diff --git a/src/sessiontreeitem.h b/src/sessiontreeitem.h new file mode 100644 index 0000000..77a1078 --- /dev/null +++ b/src/sessiontreeitem.h @@ -0,0 +1,34 @@ +#ifndef SESSIONTREEITEM_H +#define SESSIONTREEITEM_H + +#include +#include + +// class ... instead of include? +#include "session.h" +#include + +class SessionTreeItem { + public: + SessionTreeItem(const Session* session, SessionTreeItem *parent = 0); + SessionTreeItem(const QString& text, SessionTreeItem *parent = 0); + ~SessionTreeItem(); + + void appendChild(SessionTreeItem *child); + + SessionTreeItem *child(int row); + int childCount() const; + int columnCount() const; + int row() const; + SessionTreeItem *parent(); + const Session* session() const; + const QString text() const; + + private: + QList children_; + SessionTreeItem *parent_; + const Session *session_; + const QString text_; +}; + +#endif // SESSIONTREEITEM_H diff --git a/src/sessiontreemodel.cpp b/src/sessiontreemodel.cpp new file mode 100644 index 0000000..12eebf5 --- /dev/null +++ b/src/sessiontreemodel.cpp @@ -0,0 +1,162 @@ +#include "sessiontreemodel.h" + +#include +#include +#include +#include + +#include "sessiontreeitem.h" + +SessionTreeModel::SessionTreeModel(QObject *parent) + : QAbstractItemModel(parent) { + root_ = new SessionTreeItem("dummy"); +} + +SessionTreeModel::~SessionTreeModel() { + delete root_; +} + +int SessionTreeModel::columnCount(const QModelIndex& /*parent*/) const { + return 1; +} + +int SessionTreeModel::rowCount(const QModelIndex &parent) const { + SessionTreeItem* parentItem; + if (parent.column() > 0) { + return 0; + } + + if (!parent.isValid()) { + parentItem = root_; + } else { + parentItem = static_cast(parent.internalPointer()); + } + + return parentItem->childCount(); +} + +QVariant SessionTreeModel::data(const QModelIndex &index, int role) const { + if (!index.isValid()) { + return QVariant(); + } + + SessionTreeItem* item = + static_cast(index.internalPointer()); + + const Session* s = item->session(); + if (s) { + if (role == Qt::DisplayRole) + return s->shortDescription(); + if (role == Qt::ToolTipRole) + return s->description(); + if (role == Qt::DecorationRole) { + // TODO: use cache for icons + if (index.column() == 0) { // TODO: is this line needed? + QString icon(s->icon()); + + if (QFileInfo(icon).isAbsolute()) { + // try to load icon from file + return QIcon(icon); + } else { + // try to load icon from QResource + if (QResource(":" + icon.toLower() + ".svg").isValid()) { + return QIcon(":" + icon.toLower() + ".svg"); + } else if (QResource(":" + icon.toLower()).isValid()) { + return QIcon(":" + icon.toLower()); + } else { + return QIcon(":none"); + } + } + } + } + } else if (role == Qt::DisplayRole) { + // this is a section item (X Sessions / Virtual Sessions) + return item->text(); + } + + return QVariant(); +} + +Qt::ItemFlags SessionTreeModel::flags(const QModelIndex &index) const { + if (!index.isValid()) { + return 0; + } + + SessionTreeItem* item = + static_cast(index.internalPointer()); + + if (item->session()) { + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } else { + return Qt::ItemIsEnabled; + } +} + +QVariant SessionTreeModel::headerData(int /*section*/, + Qt::Orientation /*orientation*/, + int /*role*/) const { + return QVariant(); +} + +QModelIndex SessionTreeModel::index(int row, int column, + const QModelIndex &parent) const { + if (!hasIndex(row, column, parent)) { + return QModelIndex(); + } + + SessionTreeItem *parentItem; + + if (!parent.isValid()) { + parentItem = root_; + } else { + parentItem = static_cast(parent.internalPointer()); + } + + SessionTreeItem *childItem = parentItem->child(row); + if (childItem) { + return createIndex(row, column, childItem); + } else { + return QModelIndex(); + } +} + +QModelIndex SessionTreeModel::parent(const QModelIndex &index) const { + if (!index.isValid()) { + return QModelIndex(); + } + + SessionTreeItem *childItem = + static_cast(index.internalPointer()); + SessionTreeItem *parentItem = childItem->parent(); + + if (parentItem == root_) { + return QModelIndex(); + } + + return createIndex(parentItem->row(), 0, parentItem); +} + +void SessionTreeModel::addItems(const QList& sessions, + const QString& section) { + SessionTreeItem* parentItem; + + bool sectionExists = false; + + for (int i = 0; i < root_->childCount(); ++i) { + SessionTreeItem* item = root_->child(i); + if (item->text() == section) { + parentItem = item; + sectionExists = true; + break; + } + } + + if (!sectionExists) { + parentItem = new SessionTreeItem(section, root_); + root_->appendChild(parentItem); + } + + foreach (Session* s, sessions) { + parentItem->appendChild(new SessionTreeItem(s, parentItem)); + } +} diff --git a/src/sessiontreemodel.h b/src/sessiontreemodel.h new file mode 100644 index 0000000..b5d8ff8 --- /dev/null +++ b/src/sessiontreemodel.h @@ -0,0 +1,35 @@ +#ifndef VMCHOOSER_SESSIONTREEMODEL_H +#define VMCHOOSER_SESSIONTREEMODEL_H + +#include +#include +#include + +class SessionTreeItem; +class Session; + +class SessionTreeModel : public QAbstractItemModel { + Q_OBJECT + + public: + explicit SessionTreeModel(QObject *parent = 0); + ~SessionTreeModel(); + + QVariant data(const QModelIndex &index, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + void addItems(const QList& sessions, const QString& section); + + + private: + SessionTreeItem* root_; +}; + +#endif // VMCHOOSER_SESSIONTREEMODEL_H diff --git a/src/ui/dialog.ui b/src/ui/dialog.ui new file mode 100644 index 0000000..16990b3 --- /dev/null +++ b/src/ui/dialog.ui @@ -0,0 +1,281 @@ + + + Dialog + + + + 0 + 0 + 543 + 655 + + + + vmchooser + + + #Dialog { + border:1px solid #999; +} + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + 0 + + + + + + 0 + 110 + + + + #label_l {background-color:#fff; +margin-left:1px; +margin-top:1px; +margin-bottom:0px;} + + + QFrame::Plain + + + + + + :/title_l + + + + + + + + 120 + 110 + + + + + 120 + 16777215 + + + + #label_r {background-color:#fff; +margin-top:1px; +margin-right:1px; +margin-bottom:0px;} + + + QFrame::Plain + + + + + + :/title_r + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + 16777215 + 16777215 + + + + #treeView {border-top:1px solid #999; +border-bottom:1px solid #999;} + + + + QFrame::HLine + + + QFrame::Plain + + + 0 + + + + 32 + 32 + + + + true + + + 23 + + + + + + + true + + + PVS Options + + + + 9 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + VNC access by lecturer: + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + VNC access by others: + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 9 + + + 6 + + + 9 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Abort + + + + + + + Start + + + true + + + + + + + + + + + + + diff --git a/src/vsession.cpp b/src/vsession.cpp new file mode 100644 index 0000000..e9059f2 --- /dev/null +++ b/src/vsession.cpp @@ -0,0 +1,405 @@ +#include +#include +#include +#include +#include +#include +#if 0 +#include // available since Qt 4.7 +#endif +#include // for HOST_NAME_MAX +#include // for gethostname(), getuid() +#include // for getuid, getpwuid +#include // for getpwuid +#include "globals.h" +#include "vsession.h" + +bool VSession::init(const QString& xml, const QString& baseDirPath) { + this->baseDirPath_ = baseDirPath; + _process = new QProcess(); + return this->doc_.setContent(xml); +} + +void VSession::addNodeWithAttribute(const QString& nodeName, + const QString& value, + const QString& attribute, + bool replace) { + QDomElement node = + this->doc_.namedItem("eintrag").namedItem(nodeName).toElement(); + + if (replace == false || node.isNull()) { + // create a new node + node = this->doc_.createElement(nodeName); + this->doc_.namedItem("eintrag").appendChild(node); + } + + node.setAttribute(attribute, value); +} + +QString VSession::icon() const { + QString icon(getAttribute("icon")); + if (icon.isEmpty()) { + if (imgtype() == VMWARE) icon = "vmware"; + else if (imgtype() == VBOX) icon = "virtualbox"; + else icon = "unknown"; + } else if (icon.contains(".") && QDir::isRelativePath(icon)) { + // non-built-in icon with relative path + icon.prepend(baseDirPath_ + "/"); + } + return icon; + } + +QString VSession::toXml() const { + QDomDocument doc; + doc.appendChild(doc.createElement("settings")); + + doc.firstChild().appendChild(doc.importNode(doc_.documentElement(), true)); + + QDomNode xmlNode = doc.createProcessingInstruction( + "xml", "version=\"1.0\" encoding=\"UTF-8\""); + doc.insertBefore(xmlNode, doc.firstChild()); + + return doc.toString(); +} + +QString VSession::getAttribute(const QString &nodeName, + const QString &attribute) const { + QDomDocument doc = this->doc_; + QDomNode n = doc.namedItem("eintrag").namedItem(nodeName); + return this->doc_.namedItem("eintrag").namedItem(nodeName).toElement() + .attribute(attribute); +} + +QString VSession::getNodeText(const QString& nodeName) const { + return this->doc_.namedItem(nodeName).toText().data(); +} + +ImgType VSession::imgtype() const { + QString s(getAttribute("virtualmachine")); + + if (s.compare("vmware") == 0) { + return VMWARE; + } else if (s.compare("virtualbox") == 0 || s.compare("vbox") == 0) { + return VBOX; + } else { + return OTHER; + } +} + +bool VSession::isActive() const { + QString value(getAttribute("active")); + + if (value.compare("false") == 0) { + return false; + } else if (value.count("/") == 1) { + // try to interpret value as date range + // [YYYY-MM-DD]/[YYYY-MM-DD] + // eg. "1970-01-01/1971-01-01" from Jan 1st 1970 till Jan 1st 1971 + // "/1971-01-01" till Jan 1st 1971 + // "1970-01-01/" from Jan 1st 1970 + // "/" allways + // note: invalid dates are treated as empty dates + + QStringList list(value.split("/")); + QString from(list.value(0)); + QString till(list.value(1)); + QDate fromDate(QDate::fromString(from, Qt::ISODate)); + QDate tillDate(QDate::fromString(till, Qt::ISODate)); + + QDate today(QDate::currentDate()); + + if (fromDate.isValid() && fromDate > today) { + // fromDate is in the future + if (debugMode) qDebug() << "Not active. Reason: fromDate is in the future"; + return false; + } + + if (tillDate.isValid() && tillDate < today) { + // tillDate is in the past + if (debugMode) qDebug() << "Not active. Reason: tillDate is in the past"; + return false; + } + } + + if (!pool.isEmpty()) { + QStringList pools = getAttribute("pools").split("\\s*,\\s*"); + if (!pools.isEmpty() && !pools.contains(pool)) { + // pools does not contain pool + if (debugMode) qDebug() << "Not active. Reason: vsession is not part of active env"; + return false; + } + } + + return true; +} + +bool VSession::isLocked() const { + // default to false + return getAttribute("locked").compare("true") == 0; +} + +bool VSession::isValid() const { + // default to false + return QFile::exists(QString(this->baseDirPath_).append("/").append(getAttribute("image_name"))); +} + +int VSession::priority() const { + return getAttribute("priority").toInt(); +} + + +void VSession::addPrinters(const QString& script, const QString& type) { + QDomElement printersNode = + this->doc_.namedItem("eintrag").namedItem(type + "s").toElement(); + + if (printersNode.isNull()) { + // create new printers node + printersNode = this->doc_.createElement(type + "s"); + this->doc_.namedItem("eintrag").appendChild(printersNode); + } + + QProcess addPrintersScript; + addPrintersScript.start(script, QIODevice::ReadOnly); + while (!addPrintersScript.atEnd()) { + QString line(addPrintersScript.readLine()); + QStringList tokens(line.split("\t")); + + if (tokens.size() < 2 or tokens.size() > 3) { + // TODO error message + // invalid output of printerScript + // printserver\tprinter\tprinter description + continue; + } + + QDomElement printerNode(doc_.createElement(type)); + printerNode.setAttribute("name", tokens.at(1)); + printerNode.setAttribute("path", + "\\\\" + tokens.at(0) + "\\" + tokens.at(1)); + if (tokens.size() == 3) { + QDomText printerDescriptionNode(doc_.createTextNode(tokens.at(3))); + printerNode.appendChild(printerDescriptionNode); + } + printersNode.appendChild(printerNode); + } + + addPrintersScript.close(); + + return; +} + +void VSession::addScanners(const QString& script) { + addPrinters(script, "scanner"); +} + +void VSession::addUserAndHostname() { + QString username(getpwuid(geteuid())->pw_name); + this->addNodeWithAttribute("username", username); + + // Qt >= 4.7 has + // QString hostname(QHostInfo::localHostName()); + char hname[HOST_NAME_MAX + 1]; + gethostname(hname, HOST_NAME_MAX); + QString hostname(hname); + this->addNodeWithAttribute("hostname", hostname); + + QString image(this->getAttribute("image_name")); + if (QFileInfo(image).isRelative()) { + // make path to image absolute + this->addNodeWithAttribute("image_name", + this->baseDirPath_ + "/" + image); + } + + // insert computername as the first child of + // bootpgm needs computername within the first 500 bytes + QDomElement computername(doc_.createElement("computername")); + computername.setAttribute("param", hostname); + this->doc_.namedItem("eintrag").insertBefore(computername, QDomNode()); +} + +void VSession::mergePoolXml() { + QDomDocument doc; + + QString poolXmlFile = etcPath + "/vmchooser-" + pool + ".xml"; + + QFile file(poolXmlFile); + if (!file.open(QIODevice::ReadOnly)) { + return; + } + if (!doc.setContent(&file)) { + file.close(); + return; + } + file.close(); + + for (QDomElement envNode(doc.firstChildElement("environment")); + !envNode.isNull(); + envNode = envNode.nextSiblingElement()) { + if (envNode.attribute("param") != pool) continue; + + for (QDomElement typeNode(envNode.firstChildElement()); + !typeNode.isNull(); + typeNode = typeNode.nextSiblingElement()) { + QString type = typeNode.nodeName(); + if (type != "shared_folders" && + type != "printers" && + type != "scanners") continue; + + QDomElement destinationNode = + this->doc_.namedItem("eintrag").namedItem(type).toElement(); + + if (destinationNode.isNull()) { + // create new node + destinationNode = this->doc_.createElement(type); + this->doc_.namedItem("eintrag").appendChild(destinationNode); + } + + for (QDomElement el(typeNode.firstChildElement()); + !el.isNull(); + el = el.nextSiblingElement()) { + destinationNode.appendChild(this->doc_.importNode(el, true)); + } + } + } +} + +bool VSession::run() const { + QString command = getAttribute("command"); + if (!command.isEmpty()) { + return QProcess::startDetached(command); + } + + VSession session = *this; + + session.addPrinters(printerScript); + session.addScanners(scannerScript); + + session.addUserAndHostname(); + + session.mergePoolXml(); + + // write xml to temporary file + QTemporaryFile tmpfile(QDir::tempPath() + "/vmchooser-XXXXXX.xml"); + if (!tmpfile.open() || + tmpfile.write(session.toXml().toUtf8()) == -1) { + return false; + } + tmpfile.close(); + tmpfile.setAutoRemove(false); + + _process->start(runVmScript, QStringList(tmpfile.fileName())); + QObject::connect(_process, SIGNAL(finished(int, QProcess::ExitStatus)), QApplication::instance(), SLOT(quit())); + if (_process->state() == QProcess::Starting || QProcess::Running) + return true; + else + return false; +} + +int VSession::type() const { + return Session::VSESSION; +} + +QList VSession::readXmlFile(const QString& filepath) { + QList retval; + + QDomDocument doc; + QFile file(filepath); + if (!file.open(QIODevice::ReadOnly)) { + // TODO: error message + return retval; + } + if (!doc.setContent(&file)) { + // TODO: error message + file.close(); + return retval; + } + file.close(); + + QString dirName(QFileInfo(filepath).dir().absolutePath()); + QDomElement settingsNode = doc.firstChildElement("settings"); + for (QDomElement el(settingsNode.firstChildElement("eintrag")); + !el.isNull(); + el = el.nextSiblingElement("eintrag")) { + QDomDocument dummy; + dummy.appendChild(dummy.importNode(el, true)); + VSession* e = new VSession; + if (e->init(dummy.toString(), dirName)) { + retval.append(e); + } + } + return retval; +} + +/** + * - calls xmlfilter.sh to glob a folder for xmls + * -> if no xmlfilter.sh is available, it globs for available xmls + * - reads all xml files and creates for each its own VSession-struct + */ +QList VSession::readXmlDir(const QString& path) { + QList retval; + + if (QFile::exists(filterScript)) { + // run filterScript + // treat every output line as a filename and read it + QProcess myFilterScript; + myFilterScript.start(filterScript, QStringList(path), + QIODevice::ReadOnly); + myFilterScript.waitForFinished(); + while (!myFilterScript.atEnd()) { + QString filename(myFilterScript.readLine()); + filename = filename.trimmed(); + if (QDir::isRelativePath(filename)) { + filename.prepend(path + "/"); + } + retval.append(readXmlFile(filename)); + } + + myFilterScript.close(); + } else { + // iterate over all .xml files in directory (and sub-directories) + // and read them + QDirIterator di(path, + QDirIterator::Subdirectories | + QDirIterator::FollowSymlinks); + while (di.hasNext()) { + if (!di.next().endsWith(".xml")) continue; + + if (!di.fileInfo().isReadable()) { + if (debugMode) qDebug() << "skip" << di.fileInfo().absoluteFilePath() << ": xml not readable, incorrect file permissions"; + continue; + } + + QList vsessionTmp = readXmlFile(di.fileInfo().absoluteFilePath()); + + if (vsessionTmp.isEmpty()) { + if (debugMode) qDebug() << "skip" << di.fileInfo().absoluteFilePath() << ": reading xml failed for some reason"; + continue; + } + + if (!vsessionTmp.first()->isValid()) { + if (debugMode) qDebug() << "skip" << vsessionTmp.first()->shortDescription() << ": vdi/vmdk missing"; + continue; + } + + if (!vsessionTmp.first()->isActive()) { + if (debugMode) qDebug() << "skip" << vsessionTmp.first()->shortDescription() << ": not active"; + continue; + } + + retval.append(vsessionTmp); + } + } + return retval; +} + +bool VSession::operator<(const Session& other) const { + int p0 = this->priority(); + int p1 = other.priority(); + + if (p0 < p1) return true; + if (p0 == p1) { + QString d0 = this->shortDescription(); + QString d1 = other.shortDescription(); + return d0.localeAwareCompare(d1) < 0; + } + return false; +} diff --git a/src/vsession.h b/src/vsession.h new file mode 100644 index 0000000..8bbcc7e --- /dev/null +++ b/src/vsession.h @@ -0,0 +1,72 @@ +#ifndef VMCHOOSER_VSESSION_H_ +#define VMCHOOSER_VSESSION_H_ + +#include +#include +#include +#include +#include +#include "session.h" + +enum ImgType { + VMWARE, + VBOX, + OTHER +}; + +class VSession : public Session { + public: + bool init(const QString& xml, const QString& baseDirPath); + + ImgType imgtype() const; + bool isActive() const; + bool isLocked() const; + bool isValid() const; + int priority() const; + + QString shortDescription() const { + return getAttribute("short_description"); + } + + QString description() const { + return getAttribute("description"); + } + + QString icon() const; + + QString os() const { + return getAttribute("os"); + } + + QString getAttribute(const QString& nodeName, + const QString& attribute = "param") const; + QString getNodeText(const QString& nodeName) const; + + void addNodeWithAttribute(const QString& nodeName, + const QString& value, + const QString& attribute = "param", + bool replace = true); + void addPrinters(const QString& script, const QString& type = "printer"); + void addScanners(const QString& script); + void addUserAndHostname(); + void mergePoolXml(); + + QString toXml() const; + + bool run() const; + + int type() const; + + bool operator<(const Session& other) const; + + static QList readXmlDir(const QString& path); + static QList readXmlFile(const QString& filepath); + + private: + QDomDocument doc_; + QString baseDirPath_; + + QProcess *_process; +}; + +#endif /*VMCHOOSER_VSESSION_H_*/ diff --git a/src/xsession.cpp b/src/xsession.cpp new file mode 100644 index 0000000..f4cc3d9 --- /dev/null +++ b/src/xsession.cpp @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include + +#include "xsession.h" + +void XSession::init(const QString& name, const QString& exec, + const QString& comment, const QString& icon) { + this->name_ = name; + this->exec_ = exec; + this->comment_ = comment; + this->icon_ = icon; +} + +bool XSession::init(const QString& filename) { + QSettings settings(filename, QSettings::IniFormat); + settings.setIniCodec("UTF-8"); + + settings.beginGroup("Desktop Entry"); + + if (settings.value("NoDisplay").toString().compare("true") == 0 || + settings.value("Hidden").toString().compare("true") == 0) { + return false; + } + + if (!settings.contains("Exec")) { + return false; + } + QString exec(settings.value("Exec").toString()); + + QString locale(QLocale::system().name()); + QString language(locale.split("_").at(0)); + QString name; + if (settings.contains("Name[" + locale + "]")) { + name = settings.value("Name[" + locale + "]").toString(); + } else if (settings.contains("Name[" + language + "]")) { + name = settings.value("Name[" + language + "]").toString(); + } else if (settings.contains("Name")) { + name = settings.value("Name").toString(); + } else { + return false; + } + + QString comment; + if (settings.contains("Comment[" + locale + "]")) { + comment = settings.value("Comment[" + locale + "]").toString(); + } else if (settings.contains("Comment[" + language + "]")) { + comment = settings.value("Comment[" + language + "]").toString(); + } else { + comment = settings.value("Comment").toString(); + } + + QString icon(settings.value("Icon").toString()); + if (QDir::isRelativePath(icon)) { + // icons with relative paths are too complicated to find + // see http://freedesktop.org/wiki/Specifications/icon-theme-spec + // let's just ignore them + icon = QString(); + } + + this->name_ = name; + this->exec_ = exec; + this->comment_ = comment; + this->icon_ = icon; + + _process = new QProcess(); + + return true; +} + +bool XSession::isActive() const { + return true; +} + +bool XSession::isValid() const { + return true; +} + +bool XSession::isLocked() const { + return false; +} + +int XSession::priority() const { + return 0; +} + +QString XSession::icon() const { + QString icon(this->icon_); + + if (icon.isEmpty()) { + if (this->exec_.contains("kde", Qt::CaseInsensitive)) { + icon = "kde"; + } else if (this->exec_.contains("gnome", Qt::CaseInsensitive)) { + icon = "gnome"; + } else if (this->exec_.contains("term", Qt::CaseInsensitive)) { + icon = "term"; + } else if (this->exec_.contains("xfce", Qt::CaseInsensitive)) { + icon = "xfce"; + } else if (this->exec_.contains("lxde", Qt::CaseInsensitive)) { + icon = "lxde"; + } else { + icon = "linux"; + } + } + + return icon; +} + +bool XSession::run() const { + _process->start(this->exec_); + QObject::connect(_process, SIGNAL(finished(int, QProcess::ExitStatus)), QApplication::instance(), SLOT(quit())); + if (_process->state() == QProcess::Starting || QProcess::Running) + return true; + else + return false; +} + +int XSession::type() const { + return Session::XSESSION; +} + +QList XSession::readSessions(const QString& path) { + QList retval; + foreach (QFileInfo fi, QDir(path).entryInfoList(QStringList("*.desktop"))) { + if (fi.baseName().compare("default") == 0) { + continue; + } + XSession* session = new XSession; + if (session->init(fi.absoluteFilePath())) { + retval.append(session); + } + } + return retval; +} + +bool XSession::operator<(const Session& other) const { + int p0 = this->priority(); + int p1 = other.priority(); + + if (p0 < p1) return true; + if (p0 == p1) { + QString d0 = this->shortDescription(); + QString d1 = other.shortDescription(); + return d0.localeAwareCompare(d1) < 0; + } + return false; +} diff --git a/src/xsession.h b/src/xsession.h new file mode 100644 index 0000000..1d36d64 --- /dev/null +++ b/src/xsession.h @@ -0,0 +1,49 @@ +#ifndef VMCHOOSER_XSESSION_H_ +#define VMCHOOSER_XSESSION_H_ + +#include +#include +#include +#include +#include +#include "session.h" + +class XSession : public Session { + public: + void init(const QString& name, const QString& exec, + const QString& comment, const QString& icon); + bool init(const QString& filename); + + bool isActive() const; + bool isLocked() const; + bool isValid() const; + int priority() const; + + QString shortDescription() const { + return this->name_; + } + + QString description() const { + return this->comment_; + } + + QString icon() const; + + bool run() const; + + int type() const; + + bool operator<(const Session& other) const; + + static QList readSessions(const QString& path); + + private: + QString name_; + QString exec_; + QString comment_; + QString icon_; + + QProcess *_process; +}; + +#endif /*VMCHOOSER_XSESSION_H_*/ diff --git a/themes/openslx/openslx-left.png b/themes/openslx/openslx-left.png new file mode 100644 index 0000000..900dd86 Binary files /dev/null and b/themes/openslx/openslx-left.png differ diff --git a/themes/openslx/openslx-right.png b/themes/openslx/openslx-right.png new file mode 100644 index 0000000..8ca9347 Binary files /dev/null and b/themes/openslx/openslx-right.png differ diff --git a/themes/openslx/openslx.ini b/themes/openslx/openslx.ini new file mode 100644 index 0000000..57a2282 --- /dev/null +++ b/themes/openslx/openslx.ini @@ -0,0 +1,4 @@ +background-color=#ffffff +image-right=openslx-right.png +image-left=openslx-left.png + diff --git a/themes/planets/planets-left.png b/themes/planets/planets-left.png new file mode 100644 index 0000000..c8736b7 Binary files /dev/null and b/themes/planets/planets-left.png differ diff --git a/themes/planets/planets-right.png b/themes/planets/planets-right.png new file mode 100644 index 0000000..e21f0d8 Binary files /dev/null and b/themes/planets/planets-right.png differ diff --git a/themes/planets/planets.ini b/themes/planets/planets.ini new file mode 100644 index 0000000..d9aa17f --- /dev/null +++ b/themes/planets/planets.ini @@ -0,0 +1,4 @@ +background-color=#ffffff +image-right=planets-right.png +image-left=planets-left.png + diff --git a/themes/unifr/title_l.png b/themes/unifr/title_l.png new file mode 100644 index 0000000..e602ccd Binary files /dev/null and b/themes/unifr/title_l.png differ diff --git a/themes/unifr/title_r.png b/themes/unifr/title_r.png new file mode 100644 index 0000000..3edbcb0 Binary files /dev/null and b/themes/unifr/title_r.png differ diff --git a/themes/unifr/unifr.ini b/themes/unifr/unifr.ini new file mode 100644 index 0000000..dadcb4e --- /dev/null +++ b/themes/unifr/unifr.ini @@ -0,0 +1,4 @@ +background-color=#003592 +image-right=title_r.png +image-left=title_l.png + diff --git a/vmChooser/.classpath b/vmChooser/.classpath deleted file mode 100644 index 91ee9a5..0000000 --- a/vmChooser/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/vmChooser/.project b/vmChooser/.project deleted file mode 100644 index b0e6edb..0000000 --- a/vmChooser/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - vmChooser - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/vmChooser/.settings/org.eclipse.jdt.core.prefs b/vmChooser/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 838bd9d..0000000 --- a/vmChooser/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,11 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.7 diff --git a/vmChooser/bin/HelloWorld.class b/vmChooser/bin/HelloWorld.class deleted file mode 100644 index 8d43e61..0000000 Binary files a/vmChooser/bin/HelloWorld.class and /dev/null differ diff --git a/vmChooser/src/HelloWorld.java b/vmChooser/src/HelloWorld.java deleted file mode 100644 index a3d5427..0000000 --- a/vmChooser/src/HelloWorld.java +++ /dev/null @@ -1,13 +0,0 @@ - -public class HelloWorld { - - /** - * @param args - */ - public static void main(String[] args) { - // TODO Auto-generated method stub - System.out.println("Hello World"); - - } - -} -- cgit v1.2.3-55-g7522