summaryrefslogblamecommitdiffstats
path: root/src/main.cpp
blob: 044f4775621a866277193301589cf54dcd8c23b9 (plain) (tree)
1
2
3
4
5
6
7
8
9




                       
                                 


                         
                      







                                 
                     
                            
 
                                  

























































































                                                                                                                                                                       


                                                                                                                                                       
     


                                                                                                                                                  



















                                                                                                               
                                                   
                                            
                                                            


                                     
                                            
                                          
                                                     








                                                                                    
                                                      
                                                
                                                               


                   
                                           




                                                                                   

                                       





























                                                                                                 
                                                     
                                           
                                                              


                                       
                                                
                                            
                                                         


                                           
                           


                                      
                                                
                                           
                                                         
                                                                    
                                                         











                                                          
                                                                                      











                                                          
                                                                                      



































                                                                        
                                                                      


                                                           
                                








                                                                       
                            



















                                                              
                                                                    


                          
 
#include <QMap>
#include <QString>
#include <QSettings>
#include <QTranslator>
#include <QtAlgorithms>
#include <QtWidgets/QApplication>
#include <QDesktopWidget>
#include <QLocale>
#include <QtDebug>
#include <QMessageBox>

#include <cstdlib>
#include <iostream>
#include <string>

#include "command_line_options.h"
#include "dialog.h"
#include "globals.h"
#include "xsession.h"
#include "choosersettings.h"

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    QTranslator translator;
    translator.load(":" + QLocale::system().name());
    a.installTranslator(&translator);

    CommandLineOptions cmdOptions(argc, argv);

    QString autostart_uuid("");

    std::string usage(
            a.translate("Console", "Usage: vmchooser [ OPTIONS ]\n\n"
                    "  --allow-vm-edit   show the 'edit this vm' checkbox\n"
                    "  --autoquit [secs] automatically exit if no selection is made after secs seconds\n"
                    "  -b  --base        base directory where VM images are accessible\n"
                    "  -d, --default     name of default session\n"
                    "  -c, --config      alternative config file\n"
                    "  -l, --locations   location id(s), space separated\n"
                    "  --location-mode   how to treat entries for this location (IGNORE, BUMP or EXCLUSIVE)\n"
                    "  --exam-mode       enable exam mode\n"
                    "  -P, --pool        one or more pool names to display (comma separated)\n"
                    "  -f, --file        direct boot .desktop file\n"
                    "  -x, --xpath       path of X Session .desktop files\n"
                    "  -u, --url         url of vmware .xml file\n"
                    "  -s, --size        window size <width>x<height>\n"
                    "  -t, --theme       theme\n"
                    "  --template-mode   how to treat template entries (IGNORE or BUMP)\n"
                    "  -p, --pvs         show pvs options\n"
                    "  --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 (cmdOptions.contains("file")) {
        QString file(cmdOptions.value("file"));

        if (file.endsWith(".desktop")) {
            XSession s;
            if (s.init(file) && s.run()) {
                return EXIT_SUCCESS;
            }
            std::cerr
                    << a.translate("Console",
                            "vmchooser: failed to run session").toUtf8().constData()
                    << std::endl;
            return EXIT_FAILURE;
        } else {
            std::cerr
                    << a.translate("Console", "vmchooser: invalid session file").toUtf8().constData()
                    << std::endl;
            return EXIT_FAILURE;
        }
    }

    // read configuration file:
    //   file supplied as command line option or
    //   user vmchooser.conf or
    //   global vmchooser.conf
    QString confFile;
    if (cmdOptions.contains("config")) {
        if (QFileInfo(cmdOptions.value("config")).exists()) {
            confFile = cmdOptions.value("config");
        } else {
            std::cerr << a.translate("Console", "Requested --config not found: ").toUtf8().constData() << cmdOptions.value("config").toUtf8().constData() << std::endl;
        }
    }
    if (confFile.isEmpty() && QFileInfo(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

    if (cmdOptions.contains("url")) {
        g_urlBase = cmdOptions.value("url");
    } else if (settings.contains("url")) {
        g_urlBase = settings.value("url").toString();
    } else {
        std::cerr
                << a.translate("Console", "vmchooser: no URL given").toUtf8().data()
                << std::endl;
        return EXIT_FAILURE;
    }

    // Change the runVmScript path
    if (cmdOptions.contains("runscript")) {
        g_runVmScript = cmdOptions.value("runscript");
    } else if (settings.contains("runscript")) {
        g_runVmScript = settings.value("runscript").toString();
    }

    /* PARSE URL */
    if (!g_urlBase.startsWith("http://")) {
        std::cerr
                << a.translate("Console", "vmchooser: invalid URL").toUtf8().data()
                << std::endl;
        return EXIT_FAILURE;
    } else {
        if (!g_urlBase.endsWith("/")) {
            g_urlBase += "/";
        }
    }

    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")) {
        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 (mode == "IGNORE") {
            g_forLocationHandling = LOCATION_IGNORE;
        } else if (mode == "BUMP") {
            g_forLocationHandling = LOCATION_BUMP;
        } else if (mode == "EXCLUSIVE") {
            g_forLocationHandling = LOCATION_EXCLUSIVE;
        } else {
            qDebug() << "Invalid location mode: " << mode;
            QMessageBox::critical(nullptr, "Error", "Invalid location mode: " + mode);
            return 1;
        }
    }

    if (cmdOptions.contains("template-mode")) {
        QString mode = cmdOptions.value("template-mode");
        if (mode == "IGNORE") {
            g_templateHandling = LOCATION_IGNORE;
        } else if (mode == "BUMP") {
            g_templateHandling = LOCATION_BUMP;
        } else {
            qDebug() << "Invalid template mode: " << mode;
            QMessageBox::critical(nullptr, "Error", "Invalid template mode: " + mode);
            return 1;
        }
    }

    int defaultTab = -1;
    if (cmdOptions.contains("tab")) {
        defaultTab = cmdOptions.value("tab").toInt();
    }

    QString locationIds;
    if (cmdOptions.contains("locations")) {
        locationIds = cmdOptions.value("locations");
    }

    if (cmdOptions.contains("no-vtx")) {
        g_noVtx = true;
    }

    if (cmdOptions.contains("pvs")) {
        g_pvsEnabled = true;
    }
    if (cmdOptions.contains("pvs-checked")) {
        g_pvsChecked = true;
    }

    if (cmdOptions.contains("autoquit")) {
        bool ok = false;
        g_autoQuitSeconds = cmdOptions.value("autoquit").toInt(&ok, 10);
        if (!ok) {
            g_autoQuitSeconds = 0;
        }
    }

    g_allowVmEdit = cmdOptions.contains("allow-vm-edit");

    /* read session files */
    QList<Session*> xsessions(XSession::readSessions(g_xSessionPath));

    Dialog w(defaultTab, cmdOptions.contains("exam-mode"));

    w.downloadData(locationIds);

    w.setTheme();

    w.setWindowFlags(Qt::FramelessWindowHint);

    QRect desktopRect = QApplication::desktop()->availableGeometry(&w);
    if (size == "fullscreen") {
        width = desktopRect.width();
        height = desktopRect.height();
        g_fullscreen = true;
    }

    w.resize(width, height);

    if (xsessions.size()) {
        qSort(xsessions.begin(), xsessions.end(), myLessThan);
        w.addItems(xsessions, 0);
    }

    w.show();

    if (autostart_uuid != "") {
        qDebug() << "using startSession() from main.cpp";
        w.startSession(autostart_uuid);
    }



    // center dialog on primary screen
    QPoint center = desktopRect.center();
    w.move(center.x() - w.width() / 2, center.y() - w.height() / 2);
    a.setActiveWindow(&w);

    return a.exec();
}