diff options
author | Jan Darmochwal | 2010-10-02 18:50:09 +0200 |
---|---|---|
committer | Jan Darmochwal | 2010-10-02 18:50:09 +0200 |
commit | 6117049617df720fb744a90773a3580b3450b005 (patch) | |
tree | c3b605ab7a7c2e9fd9d14572e8c0e69432d6ac76 | |
parent | fixed bad copy & paste in CMakeLists.txt (diff) | |
download | vmchooser-6117049617df720fb744a90773a3580b3450b005.tar.gz vmchooser-6117049617df720fb744a90773a3580b3450b005.tar.xz vmchooser-6117049617df720fb744a90773a3580b3450b005.zip |
Qt port is almost complete (at least it compiles)
Major change:
* struct DataEntry has become class Session with sub-classes XSession and VSession
* functions from addInfo.cpp, addPrinters.cpp, addScanners.cpp, readLinSess.cpp, readXmlDir.cpp, runImage.cpp have been moved to XSession and VSession
Several minor changes:
* new files globals.h and globals.cpp for global variables (replaces constants.h and paths.h)
* replaced (all) libxml2, (much) std:: and (most) boost:: stuff by Qt stuff
Things left to do:
* remove tons of debug printfs
* show error messages on errors
* tidy up anyoption stuff in main()
* highlight session run previously
* readGroupXml stuff
* tree view (with "X Sessions" and "Virtual Sessions" sections) instead of list view for session selection
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/DataEntry.h | 42 | ||||
-rw-r--r-- | src/addInfo.cpp | 346 | ||||
-rw-r--r-- | src/addPrinters.cpp | 138 | ||||
-rw-r--r-- | src/addScanners.cpp | 135 | ||||
-rw-r--r-- | src/constants.h | 7 | ||||
-rw-r--r-- | src/dialog.cpp | 29 | ||||
-rw-r--r-- | src/dialog.h | 8 | ||||
-rw-r--r-- | src/functions.h | 46 | ||||
-rw-r--r-- | src/globals.cpp | 5 | ||||
-rw-r--r-- | src/globals.h | 17 | ||||
-rw-r--r-- | src/main.cpp | 54 | ||||
-rw-r--r-- | src/model.cpp | 66 | ||||
-rw-r--r-- | src/model.h | 16 | ||||
-rw-r--r-- | src/paths.h | 15 | ||||
-rw-r--r-- | src/readLinSess.cpp | 124 | ||||
-rw-r--r-- | src/readXmlDir.cpp | 411 | ||||
-rw-r--r-- | src/runImage.cpp | 183 | ||||
-rw-r--r-- | src/save_restore_session.cpp | 35 | ||||
-rw-r--r-- | src/save_restore_session.h | 7 | ||||
-rw-r--r-- | src/session.h | 20 | ||||
-rw-r--r-- | src/userSession.cpp | 90 | ||||
-rw-r--r-- | src/vsession.cpp | 295 | ||||
-rw-r--r-- | src/vsession.h | 81 | ||||
-rw-r--r-- | src/xsession.cpp | 135 | ||||
-rw-r--r-- | src/xsession.h | 45 |
26 files changed, 704 insertions, 1648 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index c71b024..2ac8297 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(vmchooser) set(CMAKE_BUILD_TYPE Debug) set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -Wall -Wextra") -set(CMAKE_CXX_FLAGS_RELEASE "-O3 -march=native -Wall") +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -march=native -Wall -Wextra -Werror") set(CMAKE_VERBOSE_MAKEFILE TRUE) set(OPENSLX_ROOT "../../../..") diff --git a/src/DataEntry.h b/src/DataEntry.h deleted file mode 100644 index 723e2a1..0000000 --- a/src/DataEntry.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef DATAENTRY_H_ -#define DATAENTRY_H_ - -#include <string> -#include <libxml/tree.h> -using namespace std; - -enum ImgType { - LINUX, - VMWARE, - VBOX, - OTHER -}; - -struct DataEntry { - - string short_description; - string description; - - string creator; - string email; - string phone; - - string imgname; - ImgType imgtype; - string os; - string icon; - string network; - - bool active; - bool locked; - string pools; - string xdm; - int priority; - - string command; - string xml_name; - xmlDoc* xml; - -}; - -#endif /*DATAENTRY_H_*/ diff --git a/src/addInfo.cpp b/src/addInfo.cpp deleted file mode 100644 index 1eb2213..0000000 --- a/src/addInfo.cpp +++ /dev/null @@ -1,346 +0,0 @@ -#include "functions.h" -#include "paths.h" - -#include <iostream> -#include <fstream> -#include <unistd.h> -#include <pwd.h> -#include <sys/types.h> - -#include "boost/filesystem.hpp" - -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xpath.h> - -namespace bfs = boost::filesystem; - -extern string env; - -/****************************************** - * Adds user info and hostname to xml - * - * usernode: <username param="user" /> - * hostnamenode: <hostname param="host" /> - * computername: needed for bootpgm <computername .../> - ******************************************/ -void addInfo(xmlNode* node, DataEntry* dat) { - - if (node == NULL) { - return; - } - - bool user = false; - bool host = false; - - const int MAX_LENGTH = 200; - char hostname[MAX_LENGTH]; - uid_t id; - passwd *pwd; - - string strline; - xmlNodePtr cur = node->children; - xmlNodePtr usernode = NULL; - xmlNodePtr hostnamenode = NULL; - xmlNodePtr compnamenode = NULL; - xmlNodePtr filenamenode = NULL; - xmlNodePtr firstchild = node->children; - - // just use some standard Linux functions here ... - id = geteuid(); // gets effective user id - pwd = getpwuid(id); // gets passwd struct (including username) - gethostname(hostname, MAX_LENGTH - 1); // gets hostname - - // Get <username> node and add "username#param" attribute - while (cur != NULL) { - if (!xmlStrcmp(cur->name, (const xmlChar *) "username")) { - user = true; - usernode = cur; - break; - } - cur = cur->next; - } - if (!user) { - usernode = xmlNewNode(NULL, (const xmlChar*) "username"); - if (usernode != NULL) { - xmlNewProp(usernode, (const xmlChar*) "param", - (const xmlChar*) pwd->pw_name); - xmlAddChild(node, usernode); - } else { - cerr << "<username> node could not be created!" << endl; - } - } else { - // set param attribute in <username> - xmlSetProp(usernode, (const xmlChar*) "param", - (const xmlChar*) pwd->pw_name); - } - - cur = node->children; - - // Get <hostname> node and add "hostname#param" attribute - while (cur != NULL) { - if (!xmlStrcmp(cur->name, (const xmlChar *) "hostname")) { - host = true; - hostnamenode = cur; - break; - } - cur = cur->next; - } - if (!host) { - hostnamenode = xmlNewNode(NULL, (const xmlChar*) "hostname"); - if (hostnamenode != NULL) { - xmlNewProp(hostnamenode, (const xmlChar*) "param", - (const xmlChar*) hostname); - xmlAddChild(node, hostnamenode); - } else { - cerr << "<hostname> node could not be created!" << endl; - } - } else { - // add param value to existant hostname-node - xmlSetProp(hostnamenode, (const xmlChar*) "param", (xmlChar*) hostname); - } - - // We need to add computername-node as the first node - compnamenode = xmlNewNode(NULL, (const xmlChar*) "computername"); - if (compnamenode != NULL) { - xmlNewProp(compnamenode, (const xmlChar*) "param", - (const xmlChar*) hostname); - // Add this node to the beginning of available children - // -> that is because bootpgm only looks in the first 500 chars - if (firstchild != NULL) { - xmlAddPrevSibling(firstchild, compnamenode); - } - //xmlFreeNode(compnamenode); - } else { - cerr << "<computername> node could not be created!" << endl; - } - - // We need to add the filename to the xml - if (dat->xml_name.empty()) - return; - bfs::path path(dat->xml_name); - std::string folder = path.branch_path().string(); - folder.append("/"); - - if (folder.empty()) - return; - cur = node->children; - - // Get <hostname> node and add "hostname#param" attribute - while (cur != NULL) { - if (!xmlStrcmp(cur->name, (const xmlChar *) "image_name")) { - filenamenode = cur; - break; - } - cur = cur->next; - } - if (!filenamenode) { - cerr << "There is no node called 'image_name'. " << endl; - } else { - // add param value to existant hostname-node - xmlChar* bla = xmlGetProp(filenamenode, (const xmlChar*) "param"); - if (!bla) { - cerr << "Could not read Attribute 'param' in 'image_name' node." - << endl; - return; - } else { - xmlSetProp(filenamenode, (const xmlChar*) "param", - (const xmlChar*) folder.append((char*) bla).c_str()); - } - } - - return; -} - - - - -/** - * read specific xml files for a group from - * - * /etc/opt/openslx/vmchooser-[groupname].xml - * - * and add group specific informations like shared_folders, - * printers and scanners - * - * @param dat - this is the DataEntry struct pointer - * @param group - this is the group name to get informations from - */ -void readGroupXml(DataEntry* dat, string group) { - - xmlNodePtr envnode = 0, - tnode = 0, tnode2=0, tnode3=0, // temporary nodes - shared=0, // Node for shared folders - printer=0, // Node for printers - scanner=0; // Node for scanners - - xmlChar* xmlenv = 0; - string t; - - // these variables are for xpath queries - xmlXPathObjectPtr xpp; - int size = 0; - - string grpXmlPath; - - grpXmlPath = string(VMCHOOSER_ETC_BASE_PATH) - .append("vmchooser-") - .append(group) - .append(".xml"); - - if (!bfs::is_regular(grpXmlPath)) { - return; - } - - xmlDocPtr doc = xmlReadFile( - grpXmlPath.c_str(), - NULL, - XML_PARSE_RECOVER|XML_PARSE_NOERROR - ); - - if(! doc ) return; - - - envnode = xmlFirstElementChild(doc->children); - if(envnode == 0) { - return; - } - - do { - xmlenv = xmlGetProp(envnode, (const xmlChar*)"param"); - if(xmlStrlen(xmlenv) == 0 - || string((const char*)envnode->name) != "environment") - { - continue; - } - if(group == (const char*)xmlenv) { - tnode = xmlFirstElementChild(envnode); - do { - if(tnode->type != XML_ELEMENT_NODE) continue; - t = (const char*)tnode->name; - - // Here we are looking for shared_folders,printers and scanners - // respectively - if(t == "shared_folders") { - // There could be many shared folders in there - shared = xmlFirstElementChild(tnode); - do { - if(shared->type != XML_ELEMENT_NODE) continue; - xpp = evalXPath(dat->xml, "/settings/eintrag/shared_folders"); - size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0; - - if(size == 0) { - // shared_folders node not found - add it - tnode2 = xmlNewNode(NULL, (const xmlChar*) "shared_folders"); - xmlAddChild(tnode2, shared); - xpp = evalXPath(dat->xml, "/settings/eintrag"); - size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0; - - for (int i= 0; i < size; i++) { - tnode3 = xpp->nodesetval->nodeTab[i]; - if (tnode3->type == XML_ELEMENT_NODE ) { - xmlAddChild(tnode3, tnode2); - } else { - continue; - } - } - } - else - { - // found shared_folders node - add children - for (int i= 0; i < size; i++) { - tnode2 = xpp->nodesetval->nodeTab[i]; - if (tnode2->type == XML_ELEMENT_NODE ) { - xmlAddChild(tnode2, shared); - } else { - continue; - } - } - } - } while ( (shared = shared->next) ); - } - else if(t == "printers") { - // There could be many printer nodes in there - printer = xmlFirstElementChild(tnode); - do { - if(printer->type != XML_ELEMENT_NODE) continue; - xpp = evalXPath(dat->xml, "/settings/eintrag/printers"); - size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0; - - if(size == 0) { - // shared_folders node not found - add it - tnode2 = xmlNewNode(NULL, (const xmlChar*) "printers"); - xmlAddChild(tnode2, printer); - xpp = evalXPath(dat->xml, "/settings/eintrag"); - size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0; - - for (int i= 0; i < size; i++) { - tnode3 = xpp->nodesetval->nodeTab[i]; - if (tnode3->type == XML_ELEMENT_NODE ) { - xmlAddChild(tnode3, tnode2); - } else { - continue; - } - } - } - else - { - // found shared_folders node - add children - for (int i= 0; i < size; i++) { - tnode2 = xpp->nodesetval->nodeTab[i]; - if (tnode2->type == XML_ELEMENT_NODE ) { - xmlAddChild(tnode2, printer); - } else { - continue; - } - } - } - } while ( (printer = printer->next) ); - } - else if(t == "scanners") { - // There could be many printer nodes in there - scanner = xmlFirstElementChild(tnode); - do { - if(scanner->type != XML_ELEMENT_NODE) continue; - xpp = evalXPath(dat->xml, "/settings/eintrag/scanners"); - size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0; - - if(size == 0) { - // scanners node not found - add it - tnode2 = xmlNewNode(NULL, (const xmlChar*) "scanners"); - xmlAddChild(tnode2, scanner); - xpp = evalXPath(dat->xml, "/settings/eintrag"); - size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0; - - for (int i= 0; i < size; i++) { - tnode3 = xpp->nodesetval->nodeTab[i]; - if (tnode3->type == XML_ELEMENT_NODE ) { - xmlAddChild(tnode3, tnode2); - } else { - continue; - } - } - } - else - { - // found scanners node - add children - for (int i= 0; i < size; i++) { - tnode2 = xpp->nodesetval->nodeTab[i]; - if (tnode2->type == XML_ELEMENT_NODE ) { - xmlAddChild(tnode2, scanner); - } else { - continue; - } - } - } - } while ( (scanner = scanner->next) ); - } - } - while ( (tnode = tnode->next) ); - } - } - while ( (envnode = envnode->next) ); - - -} - diff --git a/src/addPrinters.cpp b/src/addPrinters.cpp deleted file mode 100644 index 77541da..0000000 --- a/src/addPrinters.cpp +++ /dev/null @@ -1,138 +0,0 @@ - - -#include "functions.h" - -#include <iostream> -#include <string> -#include <vector> -#include <queue> - -#include <boost/filesystem.hpp> - -namespace bfs=boost::filesystem; - -/** - * function addPrinters(xmlNode* node, char* script) - * ---------------------------------------------------------- - * runs content of script (absolute path of a script-file) - * -> this expects the script to print out printer information - * in the following format - * - * printserver\tprinter\tprinter description - * - * all other output has to be directed to /dev/null - * - * then this function add some printer-nodes to the xml-file - * in "settings/eintrag/printers" - * (which will be created also if needed.) - * in the following form: <br/> - * - * <printer name="printer" path="//printserver/printer" > - * Printerdescription - * </printer> - */ -bool addPrinters(xmlNode* node, char* script) { - - if(node == NULL) { - return false; - } - - bool printer = false; - vector<string> info_printer; - - const int MAX_LENGTH = 300; - char line[MAX_LENGTH]; - char delims[] = "\t"; - string strline; - FILE* inp = 0; - - unsigned int tindex = 0; - xmlNodePtr cur = node->children; - xmlNodePtr printernode = NULL; - - // Get <printers> node - while(cur != NULL) { - if (!xmlStrcmp(cur->name, (const xmlChar *)"printers")){ - printer = true; - printernode = cur; - break; - } - cur = cur->next; - } - if(! printer) { - printernode = xmlNewNode(NULL, (const xmlChar*) "printers"); - if(printernode != NULL ) { - xmlAddChild(node, printernode); - } - else { - cerr << "No <printers> node created" << endl; - } - } - - // Parse input of printer-Skript (called by "char* script") - // and write into <printer> nodes - if( bfs::is_regular(bfs::path(script)) ) - if( (inp = popen(script, "r" )) ) { - while(fgets(line, MAX_LENGTH, inp ) != NULL) { - strline = string(line); - if(strline.length() > 3) { - - queue<unsigned int> temp; - temp.push( strline.find_first_of( delims , 0) ); - - while( temp.back() != string::npos ) { - temp.push( strline.find_first_of( delims, temp.back()+1 ) ); - } - - unsigned int t_front; - string tstr = string(""); - while( tindex != string::npos ) { - - // build printer-info element - t_front = temp.front(); - - if(tindex == 0) { - tstr = strline.substr(0, t_front); - } - else if(t_front != string::npos) { - tstr = strline.substr(tindex+1, t_front-tindex-1) ; - } - else { - tstr = strline.substr( tindex+1, strline.length() - tindex-2 ); - } - if(tstr.length() > 2) { - info_printer.push_back( tstr ); - // DEBUG - cout << info_printer.back() << endl; - } - tindex = t_front; - temp.pop(); - } - - // Construct <printer> nodes - xmlNodePtr pNode = xmlNewNode(NULL, (const xmlChar*) "printer"); - xmlNewProp(pNode, (const xmlChar*) "name", (const xmlChar*) info_printer.at(1).c_str()); - xmlNewProp ( pNode, (const xmlChar*) "path", (const xmlChar*) - string( string( "\\\\" ) + info_printer.at(0) + string( "\\" ) + info_printer.at(1) ).c_str() ); - - if(info_printer.size() > 2) { - xmlAddChild( pNode, xmlNewText( (const xmlChar*) info_printer.at(2).c_str() ) ); - } - - if(pNode != NULL) { - xmlAddChild( printernode, pNode); - } - - info_printer.clear(); - tindex = 0; - } - } - pclose(inp); - } - return true; -} - - - - - diff --git a/src/addScanners.cpp b/src/addScanners.cpp deleted file mode 100644 index 2b070a4..0000000 --- a/src/addScanners.cpp +++ /dev/null @@ -1,135 +0,0 @@ - - -#include "functions.h" - -#include <iostream> -#include <string> -#include <vector> -#include <queue> - -#include <boost/filesystem.hpp> - -namespace bfs=boost::filesystem; - -/** - * function addScanners(xmlNode* node, char* script) - * ---------------------------------------------------------- - * runs content of script (absolute path of a script-file) - * -> this expects the script to print out scanner information - * in the following format - * - * scanserver\tscanner\tscanner description - * - * all other output has to be directed to /dev/null - * - * then this function add some scanner-nodes to the xml-file - * in "settings/eintrag/scanners" - * (which will be created also if needed.) - * in the following form: <br/> - * - * <scanner name="scanner" path="//scanserver/scanner" > - * Scannerdescription - * </scanner> - */ -bool addScanners(xmlNode* node, char* script) { - - if(node == NULL) { - return false; - } - - bool scanner = false; - vector<string> info_scanner; - - const int MAX_LENGTH = 300; - char line[MAX_LENGTH]; - char delims[] = "\t"; - string strline; - FILE* inp = 0; - - unsigned int tindex = 0; - xmlNodePtr cur = node->children; - xmlNodePtr scannernode = NULL; - - // Get <scanners> node - while(cur != NULL) { - if (!xmlStrcmp(cur->name, (const xmlChar *)"scanners")){ - scanner = true; - scannernode = cur; - break; - } - cur = cur->next; - } - if(! scanner) { - scannernode = xmlNewNode(NULL, (const xmlChar*) "scanners"); - if(scannernode != NULL ) { - xmlAddChild(node, scannernode); - } - else { - cerr << "No <scanners> node created" << endl; - } - } - - // Parse input of scanner-Skript (called by "char* script") - // and write into <scanner> nodes - if( bfs::is_regular(bfs::path(script)) ) - if( (inp = popen(script, "r" )) ) { - while(fgets(line, MAX_LENGTH, inp ) != NULL) { - strline = string(line); - if(strline.length() > 3) { - - queue<unsigned int> temp; - temp.push( strline.find_first_of( delims , 0) ); - - while( temp.back() != string::npos ) { - temp.push( strline.find_first_of( delims, temp.back()+1 ) ); - } - - unsigned int t_front; - string tstr = string(""); - while( tindex != string::npos ) { - - // build scanner-info element - t_front = temp.front(); - - if(tindex == 0) { - tstr = strline.substr(0, t_front); - } - else if(t_front != string::npos) { - tstr = strline.substr(tindex+1, t_front-tindex-1) ; - } - else { - tstr = strline.substr( tindex+1, strline.length() - tindex-2 ); - } - if(tstr.length() > 2) { - info_scanner.push_back( tstr ); - // DEBUG - cout << info_scanner.back() << endl; - } - tindex = t_front; - temp.pop(); - } - - // Construct <scanner> nodes - xmlNodePtr pNode = xmlNewNode(NULL, (const xmlChar*) "scanner"); - xmlNewProp(pNode, (const xmlChar*) "name", (const xmlChar*) info_scanner.at(1).c_str()); - xmlNewProp ( pNode, (const xmlChar*) "path", (const xmlChar*) - string( string( "\\\\" ) + info_scanner.at(0) + string( "\\" ) + info_scanner.at(1) ).c_str() ); - - if(info_scanner.size() > 2) { - xmlAddChild( pNode, xmlNewText( (const xmlChar*) info_scanner.at(2).c_str() ) ); - } - - if(pNode != NULL) { - xmlAddChild( scannernode, pNode); - } - - info_scanner.clear(); - tindex = 0; - } - } - pclose(inp); - } - - return true; -} - diff --git a/src/constants.h b/src/constants.h deleted file mode 100644 index 6f04451..0000000 --- a/src/constants.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef CONSTANTS_H -#define CONSTANTS_H - - -const char* filterscript = "xmlfilter.sh"; - -#endif diff --git a/src/dialog.cpp b/src/dialog.cpp index e4c74a4..a1ab266 100644 --- a/src/dialog.cpp +++ b/src/dialog.cpp @@ -1,16 +1,14 @@ #include "dialog.h" #include "ui_dialog.h" #include "model.h" -#include "DataEntry.h" -#include "functions.h" +#include "session.h" +#include "save_restore_session.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); - //QAbstractListModel *data = new Model(1000, ui->listView); - //ui->listView->setModel(data); } Dialog::~Dialog() @@ -36,16 +34,29 @@ void Dialog::on_listView_activated(QModelIndex index) printf ("Item %d has been activated\n", index.row()); //TODO get rid of this->entries, storing them in the model should be enough // alternatively use references instead of copies? - runImage(this->entries.at(index.row())); - close(); + Session* s(this->entries_.at(index.row())); + if (s->run()) { + writeSessionName(s->shortDescription()); + close(); + } else { + // TODO: error instead of close + close(); + } } -void Dialog::addItems(const std::vector<DataEntry>& entries) { +void Dialog::addItems(const QList<Session*>& entries, const QString& section) { + // TODO: section // TODO: this is not the right way to do this // we probably do not need a copy of the entries vector in Dialog and Model - this->entries = entries; - QAbstractListModel *data = new Model(entries, ui->listView); + printf("Dialog::addItems()\n"); + printf(" before: %d items\n", this->entries_.size()); + printf(" %d new items\n", entries.size()); + this->entries_.append(entries); + printf(" after: %d items\n", this->entries_.size()); + QAbstractListModel *data = new Model(this->entries_, ui->listView); + QItemSelectionModel *m = ui->listView->selectionModel(); ui->listView->setModel(data); + delete m; } void Dialog::on_pushButtonAbort_clicked() diff --git a/src/dialog.h b/src/dialog.h index 033a69d..9f9ac5a 100644 --- a/src/dialog.h +++ b/src/dialog.h @@ -3,8 +3,8 @@ #include <QDialog> #include <QModelIndex> -#include "DataEntry.h" -#include <vector> +#include <QList> +#include "session.h" namespace Ui { class Dialog; @@ -15,14 +15,14 @@ class Dialog : public QDialog { public: Dialog(QWidget *parent = 0); ~Dialog(); - void addItems(const std::vector<DataEntry>&); + void addItems(const QList<Session*>&, const QString& section); protected: void changeEvent(QEvent *e); private: Ui::Dialog *ui; - std::vector<DataEntry> entries; + QList<Session*> entries_; private slots: void on_pushButtonStart_clicked(); diff --git a/src/functions.h b/src/functions.h deleted file mode 100644 index 0e5be33..0000000 --- a/src/functions.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _FUNCTIONS_H_ -#define _FUNCTIONS_H_ - -#include <libxml/xpath.h> - -#include <glob.h> - -#include "DataEntry.h" -#include <vector> - -/* Attention: both return malloced array */ -std::vector<DataEntry> readXmlDir(char* path); -std::vector<DataEntry> readLinSess(char* path); - -/* This is thought as a callback-function for the Select-Browser */ -void runImage(DataEntry); - -/* building & executing command for different Virtualizer */ -void runImage(DataEntry&, string confxml); - -/* Globs for a specific filetype (2. argument) */ -glob_t* globber(char* path, char* filetype); - -/* Gets folder name of this program */ -char* getFolderName(); - -/* Reads output from a skript (2. argument) */ -/* Adds the elements into xmlNode "printers" (1. argument) */ -bool addPrinters(xmlNode* node, char* script); -bool addScanners(xmlNode* node, char* script); -void addInfo(xmlNode* node, DataEntry* dat); /* This is defined in addPrinters.cxx */ -void readGroupXml(DataEntry* dat, string group); -xmlXPathObjectPtr evalXPath(xmlDocPtr doc, const char* path); - -/* Write configuration xml */ -string writeConfXml(DataEntry& dat); - - - -/** Extra functions - defined in userSession.cxx */ -void saveSession(DataEntry* dat); -char* readSession(void); - - -#endif /* _FUNCTIONS_H_ */ - diff --git a/src/globals.cpp b/src/globals.cpp new file mode 100644 index 0000000..91a39b8 --- /dev/null +++ b/src/globals.cpp @@ -0,0 +1,5 @@ +#include <QString> +#include "globals.h" + +const QString filterscript("xmlfilter.sh"); + diff --git a/src/globals.h b/src/globals.h new file mode 100644 index 0000000..96f95e4 --- /dev/null +++ b/src/globals.h @@ -0,0 +1,17 @@ +#ifndef VMCHOOSER_GLOBALS_H +#define VMCHOOSER_GLOBALS_H + +//#define VMCHOOSER_PLUGIN_PATH "/opt/openslx/plugin-repo/vmchooser/" +//#define VMCHOOSER_BIN_PATH "/var/opt/openslx/bin/" +//#define VMCHOOSER_ETC_BASE_PATH "/etc/opt/openslx/plugins/vmchooser/" +//#define VMCHOOSER_VMPATH "/var/lib/virt" + +#define VMCHOOSER_PLUGIN_PATH "/home/zwerg/vmchooser/plugin/" +#define VMCHOOSER_BIN_PATH "/home/zwerg/vmchooser/bin/" +#define VMCHOOSER_ETC_BASE_PATH "/home/zwerg/vmchooser/etc/" +#define VMCHOOSER_VMPATH "/home/zwerg/vmchooser/vm/" + +class QString; +extern const QString filterscript; + +#endif diff --git a/src/main.cpp b/src/main.cpp index 452bb89..1fa71be 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,14 +3,11 @@ #include <iostream> #include <stdlib.h> -#include "DataEntry.h" -#include "functions.h" +#include "save_restore_session.h" +#include "xsession.h" +#include "vsession.h" #include "anyoption.h" -#include "paths.h" - -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xpath.h> +#include "globals.h" #include <boost/filesystem.hpp> @@ -18,10 +15,9 @@ namespace bfs=boost::filesystem; using namespace std; -// defined in readXmlDir.h -extern DataEntry* get_entry(xmlDoc * doc); - int main(int argc, char *argv[]) { + QApplication a(argc, argv); + string version = "0.0.13"; AnyOption* opt = new AnyOption(); char* xmlpath = NULL; @@ -124,6 +120,7 @@ int main(int argc, char *argv[]) { lsesspath = opt->getValue("lpath"); } if (lsesspath == NULL) { + // TODO: absolute paths as constants lsesspath = (char *) "/usr/share/xsessions/"; } @@ -144,7 +141,7 @@ int main(int argc, char *argv[]) { } else { i = size.find_first_of("x"); - if( i == string::npos) { + if (i == string::npos) { cerr << "Please write <width>x<height> as argument for -s|--size." << endl; return 1; } @@ -154,6 +151,7 @@ int main(int argc, char *argv[]) { // additional xml argument -> start image directly +#if 0 if(opt->getArgc() > 0) { string single_arg = opt->getArgv(0); if(bfs::is_directory(single_arg)) { @@ -176,38 +174,22 @@ int main(int argc, char *argv[]) { return 1; } } +#endif delete opt; /* read xml files */ - std::vector<DataEntry> sessions; - std::vector<DataEntry> lsessions; -printf("dummy\n"); - sessions = readXmlDir(xmlpath); -printf("dummy2\n"); - lsessions = readLinSess(lsesspath); -printf("dummy3\n"); + QList<Session*> xsessions(XSession::readSessions(lsesspath)); + QList<Session*> vsessions(VSession::readXmlDir(xmlpath)); -printf ("%d sessions\n", sessions.size()); -printf ("%d lsessions\n", lsessions.size()); + printf ("%d VSessions\n", vsessions.size()); + printf ("%d XSessions\n", xsessions.size()); - bool lin_entries=false; - bool vm_entries=false; - - if(lsessions.size()) { - //win.set_lin_entries(lsessions); - lin_entries = true; - } - if (sessions.size()) { - //win.set_entries(sessions); - vm_entries = true; - } - - sessions.insert(sessions.begin(), lsessions.begin(), lsessions.end()); - - QApplication a(argc, argv); Dialog w; - w.addItems(sessions); + w.resize(width, height); + + w.addItems(xsessions, "X Sessions"); + w.addItems(vsessions, "Virtual Sessions"); w.show(); return a.exec(); } diff --git a/src/model.cpp b/src/model.cpp index 75bd58b..672f91e 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -2,11 +2,11 @@ #include <QIcon> #include <QPixmap> -Model::Model(std::vector<DataEntry> e, QObject *parent) +Model::Model(QList<Session*> e, QObject *parent) : QAbstractListModel(parent), - rc(e.size()), entries(e) + rowCount_(e.size()), entries_(e) { - printf("model with %d entries created\n", this->entries.size()); + printf("model with %d entries created\n", this->entries_.size()); } Model::~Model() @@ -15,7 +15,7 @@ Model::~Model() int Model::rowCount(const QModelIndex &parent) const { - return (parent.isValid() && parent.column() != 0) ? 0 : rc; + return (parent.isValid() && parent.column() != 0) ? 0 : rowCount_; } QVariant Model::data(const QModelIndex &index, int role) const @@ -24,59 +24,23 @@ QVariant Model::data(const QModelIndex &index, int role) const if (!index.isValid()) return QVariant(); if (role == Qt::DisplayRole) - return QString::fromStdString(this->entries.at(index.row()).short_description); + return this->entries_.at(index.row())->shortDescription(); if (role == Qt::ToolTipRole) - return QString::fromStdString(this->entries.at(index.row()).description); + return this->entries_.at(index.row())->description(); if (role == Qt::DecorationRole) { - // TODO: use additional function (with cache) for icons + // TODO: use cache for icons if (index.column() == 0) { - const DataEntry& e(this->entries.at(index.row())); + const Session* e(this->entries_.at(index.row())); - if(e.imgtype == VMWARE) { - if(e.os.find("win") != string::npos || e.os.find("Win") != string::npos) - return QIcon(e.locked ? ":xp_locked" : ":xp"); + QString icon(e->icon()); - if(e.icon.find("gentoo") != string::npos || e.icon.find("Gentoo") != string::npos ) - return QIcon(":gentoo"); - - if(e.icon.find("suse") != string::npos || e.icon.find("Suse") != string::npos ) - return QIcon(":suse"); - - if(e.icon.find("ubuntu") != string::npos || e.icon.find("Ubuntu") != string::npos ) - return QIcon(":ubuntu"); - - - if(e.os.find("linux") != string::npos) - return QIcon(":linux"); - - if(e.icon.find("bsd") != string::npos - || e.icon.find("BSD") != string::npos - || e.icon.find("Bsd") != string::npos) - return QIcon(":bsd"); - - if(e.icon.find("mac") != string::npos - || e.icon.find("Mac") != string::npos - || e.icon.find("apple") != string::npos) - return QIcon(":macos"); - - return QIcon(":vmware"); - } - - if(e.imgtype == LINUX) { - if(e.short_description.find("KDE")!= string::npos) - return QIcon(":kde"); - - if(e.short_description.find("GNOME")!= string::npos) - return QIcon(":gnome"); - - if(e.short_description.find("Xfce")!= string::npos) - return QIcon(":xfce"); - - return QIcon(":linux"); + if (QFileInfo(icon).isAbsolute()) { + // try to load icon from file + return QIcon(icon); + } else { + // try to load icon from QResource + return QIcon(":" + icon.toLower()); } - - //return QIcon(":/img/linux.xpm"); - return iconProvider.icon(QFileIconProvider::File); } } return QVariant(); diff --git a/src/model.h b/src/model.h index d5a529a..a03f015 100644 --- a/src/model.h +++ b/src/model.h @@ -3,30 +3,26 @@ #include <QAbstractListModel> #include <QFileIconProvider> -#include <QVector> -#include "DataEntry.h" -#include <vector> +#include <QList> +#include "session.h" class Model : public QAbstractListModel { Q_OBJECT public: - Model(std::vector<DataEntry>, QObject *parent = 0); + Model(QList<Session*>, QObject *parent = 0); ~Model(); int rowCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; -// QVariant headerData(int section, Qt::Orientation orientation, int role) const; private: - int rc; - std::vector<DataEntry> entries; - //QVector<QString> *list; - QFileIconProvider iconProvider; + int rowCount_; + QList<Session*> entries_; + QFileIconProvider iconProvider; //TODO }; #endif // MODEL_H - diff --git a/src/paths.h b/src/paths.h deleted file mode 100644 index 6a18ef5..0000000 --- a/src/paths.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef PATHS_H -#define PATHS_H - -//#define VMCHOOSER_PLUGIN_PATH "/opt/openslx/plugin-repo/vmchooser/" -//#define VMCHOOSER_BIN_PATH "/var/opt/openslx/bin/" -//#define VMCHOOSER_ETC_BASE_PATH "/etc/opt/openslx/plugins/vmchooser/" -//#define VMCHOOSER_VMPATH "/var/lib/virt" - -#define VMCHOOSER_PLUGIN_PATH "/home/zwerg/vmchooser/plugin/" -#define VMCHOOSER_BIN_PATH "/home/zwerg/vmchooser/bin/" -#define VMCHOOSER_ETC_BASE_PATH "/home/zwerg/vmchooser/etc/" -#define VMCHOOSER_VMPATH "/home/zwerg/vmchooser/vm/" - - -#endif diff --git a/src/readLinSess.cpp b/src/readLinSess.cpp deleted file mode 100644 index 4b38771..0000000 --- a/src/readLinSess.cpp +++ /dev/null @@ -1,124 +0,0 @@ - -/** - * - * @author Bastian Wissler - * @description: Scan a given folder for XML-Files and get information - * about installed Images / SessionManagers - */ - -#include <stdio.h> -#include <glob.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <fstream> -#include <iostream> -#include <cstring> -#include <vector> - -#include "DataEntry.h" -#include "functions.h" - -static int errorfunc(const char* errpath, int errno) -{ - fprintf(stderr, "GLOB(): Fehler aufgetreten unter %s mit Fehlernummer %d \n",errpath, errno); - return 0; -} - - -static glob_t* globber(char* path, const char* filetype) -{ - glob_t* gResult = (glob_t*) malloc(sizeof(glob_t)); - char* temp = (char*) malloc(strlen(path)+strlen(filetype)+1); - strcpy(temp, path); - strcat(temp, filetype); - - if (glob(temp, GLOB_NOSORT, &errorfunc, gResult)) { - fprintf(stderr, "Fehler beim Öffnen des Ordners!\n"); - return NULL; - } - return gResult; - -} - -std::vector<DataEntry> readLinSess(char* path) -{ - - int MAX_LENGTH = 200; - char line[MAX_LENGTH]; - char* found; - char* val; - - if ( path== NULL) { - std::vector<DataEntry>(); - } - - glob_t *gResult = (glob_t*) malloc(sizeof(glob_t)); - gResult = globber(path, "*.desktop"); - - if ( gResult== NULL) { - return std::vector<DataEntry>(); - } - if ( gResult->gl_pathc == 0 ) { - return std::vector<DataEntry>(); - } - std::vector<DataEntry> result; - // DataEntry** result = - //(DataEntry**) malloc(gResult->gl_pathc * sizeof(DataEntry*) +1); - - int c = 0; - - for (int i=0; gResult->gl_pathv[i] != NULL; i++) { - if(string(gResult->gl_pathv[i]).find("default.desktop") != string::npos ) { - continue; - } - - ifstream desk(gResult->gl_pathv[i]); - DataEntry* de = new DataEntry(); - de->imgtype = LINUX; - while( desk.getline(line, MAX_LENGTH) ) { - found = strstr(line, "Name="); - if(found != NULL) { - val = strtok(found, "="); - val = strtok(NULL, "="); - de->short_description = string(val); - } - found = NULL; - - found = strstr(line, "Exec="); - if(found != NULL) { - val = strtok(found, "="); - val = strtok(NULL, "="); - de->command = string(val); - } - found = NULL; - - found = strstr(line, "Comment="); - if(found != NULL && de->description.empty()) { - val = strtok(found, "="); - val = strtok(NULL, "="); - de->description = string(val); - } - found = NULL; - - found = strstr(line, "Comment[de]="); - if(found != NULL) { - val = strtok(found, "="); - val = strtok(NULL, "="); - de->description = string(val); - } - found = NULL; - } - - if(! (de->short_description.empty() || de->command.empty()) ) { - result.push_back(*de); - c++; - } - else { - delete de; - } - } - //result[c] = NULL; - - return result; -} diff --git a/src/readXmlDir.cpp b/src/readXmlDir.cpp deleted file mode 100644 index 592d0ab..0000000 --- a/src/readXmlDir.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/** - * author: Bastian Wissler - * purpose: Scan a given folder for XML-Files and get information - * about installed Images / SessionManagers - */ -#include <stdio.h> -#include <glob.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <libxml/parser.h> -#include <libxml/tree.h> -#include <libxml/xpath.h> - -#include <boost/regex.hpp> -#include <boost/filesystem.hpp> - -#include <cstring> -#include <vector> -#include <iostream> -#include <fstream> - -#include "constants.h" -#include "DataEntry.h" -#include "functions.h" -#include "paths.h" - -namespace bfs=boost::filesystem; - -#ifdef LIBXML_TREE_ENABLED - -string env; -vector<string> xmlVec; - -xmlXPathObjectPtr evalXPath(xmlDocPtr doc, const char* path) { - printf("evalXPath(doc, %s)\n", path); - xmlXPathContextPtr xp = xmlXPathNewContext(doc); - string bla = string(path); - if(xp == NULL) { - fprintf(stderr,"Error: unable to create new XPath context\n"); - xmlFreeDoc(doc); - return NULL; - } - xmlXPathObjectPtr result = xmlXPathEvalExpression((const xmlChar*)bla.c_str(), xp); - if(result == NULL) { - fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", bla.c_str()); - xmlXPathFreeContext(xp); - xmlFreeDoc(doc); - return NULL; - } - xmlXPathFreeContext(xp); - return result; -} - -char* getAttribute(xmlDoc *doc, char* name) -{ - printf("getAttribute(doc, %s)\n", name); - xmlNode* temp; - string path = string("/settings/eintrag/")+ string(name)+ string("/@param"); - char* cpath = strdup(path.c_str()); - - // Get Attribute via XPath - xmlXPathObjectPtr xpp = evalXPath( - doc, - (const char*)cpath - ); - free(cpath); - - //print_xpath_nodes(xpp->nodesetval, stdout); - - int size; - size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0; - for (int i= 0; i < size; i++) { - temp = xpp->nodesetval->nodeTab[i]; - if (temp->type == XML_ATTRIBUTE_NODE ) { - - return (char*) temp->children->content; - } else { - continue; - } - } - - return NULL; -} - -char* getNodeValue(xmlDoc *doc, char* name) -{ - printf("getNodeValue(doc, %s)", name); - xmlNode* temp; - xmlXPathContextPtr xp = xmlXPathNewContext(doc); - string bla = string("/settings/eintrag/")+ string(name); - if(xp == NULL) { - fprintf(stderr,"Error: unable to create new XPath context\n"); - xmlFreeDoc(doc); - return NULL; - } - xmlXPathObjectPtr xpp = xmlXPathEvalExpression((const xmlChar*)bla.c_str(), xp); - if(xpp == NULL) { - fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", bla.c_str()); - xmlXPathFreeContext(xp); - xmlFreeDoc(doc); - return NULL; - } - - //print_xpath_nodes(xpp->nodesetval, stdout); - int size; - size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0; - for (int i= 0; i < size; i++) { - temp = xpp->nodesetval->nodeTab[i]; - if (temp->type == XML_TEXT_NODE ) { - return (char*) temp->content; - } else { - continue; - } - } - return NULL; -} - - - -DataEntry* get_entry(xmlDoc * doc) -{ - printf("get_entry(doc)\n"); - char *tempc = NULL; - DataEntry* de = new DataEntry(); - - tempc = getAttribute(doc,(char *)"short_description"); - if (tempc != NULL ) { - de->short_description = tempc; - // replace a substring - std::string dest_string, dest1_string; - boost::regex re("\n|\r"); - boost::regex_replace(std::back_inserter(dest_string), - de->short_description.begin(), - de->short_description.end(), - re, - " "); - } else { - // TODO: fix this - de->short_description = "short_description failed"; - } - tempc = NULL; - - if (de->short_description.empty()) { - free(de); - fprintf(stderr, "No short_description given\n"); - return NULL; - } - - tempc = getAttribute(doc,(char *) "long_description"); - if (tempc != NULL ) { - de->description = tempc; - } - tempc = NULL; - - tempc = getAttribute(doc,(char *) "creator"); - if (tempc != NULL ) { - de->creator = tempc; - } - tempc = NULL; - - tempc = getAttribute(doc,(char *) "email"); - if (tempc != NULL ) { - de->email = tempc; - } - tempc = NULL; - - tempc = getAttribute(doc,(char *) "phone"); - if (tempc != NULL ) { - de->phone = tempc; - } - tempc = NULL; - - tempc = getAttribute(doc,(char *) "image_name"); - if (tempc != NULL ) { - de->imgname = tempc; - } - tempc = NULL; - - tempc = getAttribute(doc,(char *) "os"); - if (tempc != NULL ) { - de->os = tempc; - } - tempc = NULL; - - tempc = getAttribute(doc,(char *) "network"); - if (tempc != NULL ) { - de->network = tempc; - } - tempc = NULL; - - - tempc = getAttribute(doc,(char *) "virtualmachine"); - if (tempc != NULL ) { - if ( strcmp(tempc,"vmware") == 0 ) { - de->imgtype = VMWARE; - } else if (strcmp(tempc,"virtualbox") == 0) { - de->imgtype = VBOX; - } else { - de->imgtype = OTHER; - } - } - else { - - // Defaults to vmware - if the attribute is unknown - de->imgtype = VMWARE; - - } - tempc = NULL; - - tempc = getAttribute(doc,(char *) "active"); - if (tempc != NULL ) { - de->active = (strstr(tempc,"true")!= NULL?true:false); - // This has to be considered elsewhere - //if(de->active == false) { - // delete de; - // return NULL; - //} - } - tempc = NULL; - - tempc = getAttribute(doc,(char *) "locked"); - if (tempc != NULL ) { - de->locked = (strstr(tempc,"true")!= NULL?true:false); - } - else { - de->locked = false; - } - tempc = NULL; - - tempc = getAttribute(doc,(char *) "pools"); - if (tempc != NULL ) { - de->pools = tempc; - } - tempc = NULL; - - tempc = getAttribute(doc,(char *) "xdm"); - if (tempc != NULL ) { - de->xdm = tempc; - } - tempc = NULL; - - tempc = getAttribute(doc,(char *) "priority"); - if (tempc != NULL ) { - de->priority = atoi(tempc); - } - else { - de->priority = 5; - } - tempc = NULL; - - tempc = getAttribute(doc,(char *) "icon"); - if (tempc != NULL ) { - de->icon = tempc; - } - else { - de->icon = "vmware"; - } - tempc = NULL; - - de->xml = doc; - - return de; -} - - -/** - * The main function of this file: - * - * - 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 DataEntry-struct - */ -std::vector<DataEntry> readXmlDir(char* path) -{ - const int MAX_LENGTH = 256; - char line[MAX_LENGTH]; - char* fpath = getFolderName(); - FILE* inp; - - printf("readXmlDir %s\n", path); - - LIBXML_TEST_VERSION - if ( path== NULL) { - return std::vector<DataEntry>(); - } - - bfs::path filter(string(fpath).append("/").append(filterscript)); - - - if(bfs::is_regular(filter)) { - if( (inp = popen(string(fpath).append("/") - .append(filterscript).append(" ") - .append(path).c_str(), "r" )) ) { - while(fgets(line, MAX_LENGTH, inp ) != NULL) { - xmlVec.push_back(string(line).substr(0,strlen(line)-1) ); - } - pclose(inp); - } - } - else - { - ifstream conffile(string(VMCHOOSER_ETC_BASE_PATH).append("vmchooser.conf").c_str()); - if(conffile) { - int n = 255; - char buf[n]; - string s = ""; - while(!conffile.eof()) { - conffile.getline(buf, n); - s = buf; - if(s.substr(0,13) == "vmchooser_env") { - env = s.substr(15,s.length()-16); - } - } - } - - glob_t globbuf; - glob(string(path).append("*.xml").c_str(), NULL, NULL, &globbuf); - - xmlDocPtr tdoc = 0; - char* tstr = 0; - - for(int c=0; c<globbuf.gl_pathc; c++) { - printf("reading file %s\n", globbuf.gl_pathv[c]); - tdoc = xmlReadFile(globbuf.gl_pathv[c],NULL,XML_PARSE_RECOVER|XML_PARSE_NOERROR); - - if(!tdoc) { - cerr << "Error opening xml file " << globbuf.gl_pathv[c] << "!" << endl; - return std::vector<DataEntry>(); - } - - tstr = getAttribute(tdoc, (char*)"pools"); - - -// if(tstr == 0) { -// xmlFreeDoc(tdoc); -// continue; -// } - -// if(env == tstr) { - printf("xmlVec.push_back(%s)\n", globbuf.gl_pathv[c]); - xmlVec.push_back(string(globbuf.gl_pathv[c]) ); -// } - - xmlFreeDoc(tdoc); - tdoc = 0; tstr = 0; - } - - } - - free(fpath); - - xmlDoc *doc = 0; - int c = 0; - string::size_type loc; - - // We need to reserve the memory for all the pointers here - if(xmlVec.size() == 0) { - return std::vector<DataEntry>(); - } - - std::vector<DataEntry> result; - - for (unsigned int i=0; i < xmlVec.size(); i++) { - loc = xmlVec[i].find( "Vorlage" ); - if( loc != string::npos ) { - // FOUND Vorlage - continue; - } - - struct stat m; - stat(xmlVec[i].c_str(), &m); - - - /* DEBUG */ - printf("File: %s, COUNT: %d\n", xmlVec[i].c_str(), xmlVec.size()); - if ( S_ISDIR(m.st_mode) ) { - continue; - } - - doc = xmlReadFile(xmlVec[i].c_str(), NULL, XML_PARSE_RECOVER|XML_PARSE_NOERROR); - if (doc == NULL) { - fprintf(stderr, "error: could not parse file %s\n", xmlVec[i].c_str()); - continue; - } - - result.push_back(*get_entry(doc)); - //if (result[c] != 0) { - result[c].xml_name = xmlVec[i]; - c++; - //} - /* xmlDoc still needed to write back information for VMware etc. */ - // xmlFreeDoc(doc); - } - - //result[c] = '\0'; - //if(c!= 0) { - return result; - //} - //else { - // return NULL; - //} - -} - - -#else - -#error "Tree Support for libxml2 must be available!" - -#endif diff --git a/src/runImage.cpp b/src/runImage.cpp deleted file mode 100644 index 01aa7e2..0000000 --- a/src/runImage.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include "DataEntry.h" -#include "functions.h" -#include "paths.h" - -#include <sstream> - -#include <errno.h> -#include <sys/wait.h> -#include <iostream> -#include <string> -#include <boost/regex.hpp> - - -/* define MAX_LENGTH for string in getFolderName */ -const int MAX_LENGTH = 200; -extern string env; - -/** ************************************************************* - * void runImage runs a (virtual machine) image using fork() - * calling runImage(DataEntry*) - ***************************************************************/ -void runImage(DataEntry dat) -{ - string confxml; - - /* printf("runImage called\n"); */ - //if ( e == NULL ) { - // return; - //} - - //DataEntry& dat = *((DataEntry*) e); - - if(dat.imgtype == VMWARE || dat.imgtype == VBOX ) { - confxml = writeConfXml(dat); - } - - pid_t pid; - // in case you want to wait hours on your thread - //int status; - char arg1[MAX_LENGTH]; - strncpy(arg1, (char*) string("'\n\nStarte Image: ") - .append(dat.short_description) - .append("\n'").c_str(),MAX_LENGTH); - - char* argv[] = { (char*) string(VMCHOOSER_PLUGIN_PATH).append("mesgdisp").c_str(), - arg1, NULL }; - - //printf("%s", arg1); - // TODO: only fork if we want to display a message (or maybe not fork at all?) - pid = fork(); - - switch( pid ) { - case -1: - // parent: creation of child process failed - //fltk::alert("Error occured during forking a thread of execution!"); - return; - break; - case 0: - // child - // the only purpose of this child is to display a message - //mainwin->destroy(); - //fltk::wait(); - if(dat.imgtype == VMWARE || dat.imgtype == VBOX) { - //cout << "calling " << argv[1] << endl; - execvp(argv[0], argv); - } - break; - default: - // parent - - // this is not really useful, as this - // blocks execution for about 5 seconds - // sometimes ;-) - //if( waitpid( pid, &status, 0 ) == -1 ) { - // cerr << "No child with this pid (" << pid << ")" << endl; - // fltk::alert("Failed to create child thread!"); - // return; - //} - - // TODO: find out what it does and restore this - saveSession(&dat); - runImage(dat, confxml); - break; - } -} - -/** - * Helper-function for runImage(Widget, void) - * - runs the chosen virtualizer image - **/ -void runImage(DataEntry& dat, string confxml) -{ - if(! dat.command.empty() ) { - char* arg[] = { (char*) dat.command.c_str(), '\0' }; - execvp((char*) dat.command.c_str(), arg); - } - char* arg[] = { (char *) string(VMCHOOSER_BIN_PATH).append("run-virt.sh").c_str(), - (char*)confxml.c_str(), - NULL }; - - execvp(string(VMCHOOSER_BIN_PATH).append("run-virt.sh").c_str(), arg); -} - - - - -/** - * Helper-Function: Get folder name - */ -char* getFolderName() { - - /* Var for the folder name */ - char* pname = (char*) malloc(MAX_LENGTH); - int result; - - result = readlink("/proc/self/exe", pname, MAX_LENGTH); - if (result > 0) { - pname[result] = 0; /* add the NULL - not done by readlink */ - } - - int i=result-1; - while(pname[i] != '/' && i >= 0) { - pname[i] = '\0'; - i--; - } - if(pname[i] == '/' ) { - pname[i] = '\0'; - } - - return pname; - -} - - -string writeConfXml(DataEntry& dat) { - - //char* pname = getFolderName(); - string pname = VMCHOOSER_ETC_BASE_PATH; - xmlNodePtr cur = 0; - xmlNodePtr root = 0; - - string pskript = pname +"/printer.sh"; - - cur = xmlDocGetRootElement(dat.xml); - if(cur == NULL) { - printf("Empty XML Document %s!", dat.xml_name.c_str()); - return dat.xml_name.c_str(); - } - - // xmlNode "eintrag" - root = cur->children; - while(xmlStrcmp(root->name, (const xmlChar*)"eintrag") != 0) { - root = root->next; - } - if(xmlStrcmp(root->name, (const xmlChar *)"eintrag") != 0){ - fprintf(stderr, "%s is not a valid xml file!", dat.xml_name.c_str()); - return dat.xml_name.c_str(); - } - - // add "printers" and "scanners" - XML-Nodes - addPrinters(root, (char*)pskript.c_str()); - - pskript = pname + "/scanner.sh"; - addScanners(root, (char*)pskript.c_str()); - - // add hostname and username information - addInfo(root, &dat); - - - // read the group configuration XML - readGroupXml(&dat, env); - - - srand(time(NULL)); - string xmlfile; - ostringstream i; - i << "/tmp/run" << rand() << ".xml"; - xmlfile = i.str(); - - //xmlSaveFile("-", dat.xml); - xmlSaveFile( (char*) xmlfile.c_str(), dat.xml); - return xmlfile; -} diff --git a/src/save_restore_session.cpp b/src/save_restore_session.cpp new file mode 100644 index 0000000..ec292a2 --- /dev/null +++ b/src/save_restore_session.cpp @@ -0,0 +1,35 @@ +#include <QDir> +#include <QIODevice> +#include <QString> + +void writeSessionName(QString name) { + // TODO: use constants + QDir saveFileDir(QDir::homePath() + "/.openslx"); + QString saveFileName("vmchooser_prev_session"); + + if (! saveFileDir.exists()) { + if (! saveFileDir.mkpath(saveFileDir.path())) { + // TODO: error + return; + } + } + + QFile saveFile(saveFileDir.path() + "/" + saveFileName); + if (!saveFile.open(QIODevice::WriteOnly) || + saveFile.write(name.toUtf8().data()) == -1) { + // TODO: error + } +} + +QString readSessionName() { + QString saveFileDir(QDir::homePath() + "/.openslx"); + QString saveFileName("vmchooser_prev_session"); + + QFile saveFile(saveFileDir + "/" + saveFileName); + + 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..ce8ce43 --- /dev/null +++ b/src/session.h @@ -0,0 +1,20 @@ +#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 int priority() const = 0; + virtual QString shortDescription() const = 0; + virtual QString description() const = 0; + virtual QString icon() const = 0; + virtual bool run() = 0; + + virtual bool operator<(const Session& s) const = 0; +}; +#endif /*VMCHOOSER_SESSION_H_*/ diff --git a/src/userSession.cpp b/src/userSession.cpp deleted file mode 100644 index 703235f..0000000 --- a/src/userSession.cpp +++ /dev/null @@ -1,90 +0,0 @@ - - - -#include "DataEntry.h" -#include "functions.h" - -#include <cstdlib> -#include <cstring> -#include <string> -#include <iostream> -#include <fstream> -#include<boost/filesystem/operations.hpp> - -namespace bfs=boost::filesystem; -using namespace std; - -/** - * @function saveSession: Saves chosen session to prechoose this session next time. - * - * @param dat: Pointer to the wanted Image/Linux Session - * @return void - * - */ -void saveSession(DataEntry* dat) { - - // get home folder - char* home = getenv("HOME"); - if(home == NULL) { - cout << "HOME is not set. Not storing session." << endl; - return; - } - - // build path - string fname = home; - string shome = home; - fname.append("/.openslx/vmchooser"); - if(!bfs::exists(fname) ) { - if(!bfs::exists(shome.append("/.openslx")) ) { - bfs::create_directory(shome); - } - } - - // write file with ofstream - ofstream fout(fname.c_str(),ios::trunc); // overwrite file - fout << dat->short_description << endl; -} - - - -/** - * @function readSession: Read predefined session from users home folder - * - * @return: if not found, return null, else description for Image XML/ Linux .desktop file - */ -char* readSession() { - - // read HOME variable - char* home = getenv("HOME"); - if(home==NULL) { - cout << "HOME is not set. Not reading session." << endl; - return NULL; - } - - // build file name - string fname = home; - fname.append("/.openslx/vmchooser"); - - // read presaved session with ifstream - if(!bfs::exists(fname)) { - return NULL; - } - ifstream fin(fname.c_str()); - if (!fin) { - cout << "some error occured reading file!" << endl; - return NULL; - } - - string sessname; - getline(fin,sessname); - char* blub = strdup(sessname.c_str()); - - if(!sessname.empty()) { - return blub; - } - else { - free(blub); - return NULL; - } - -} diff --git a/src/vsession.cpp b/src/vsession.cpp new file mode 100644 index 0000000..3fa385f --- /dev/null +++ b/src/vsession.cpp @@ -0,0 +1,295 @@ +#include <QtXml> +#include <QDir> +#include <QApplication> +#include <QProcess> +#if 0 +#include <QHostInfo> // available since Qt 4.7 +#endif +#include <limits> // for HOST_NAME_MAX +#include <unistd.h> // for gethostname(), getuid() +#include <sys/types.h> // for getuid, getpwuid +#include <pwd.h> // for getpwuid +#include "globals.h" +#include "vsession.h" + +bool VSession::init(const QString& xml, const QString& baseDirPath) { + printf("VSession::init(xml, %s)\n", baseDirPath.toAscii().data()); + //printf("xml = %s\n", xml.toAscii().data()); + this->baseDirPath_ = baseDirPath; + return this->doc_.setContent(xml); +} + +void VSession::addNodeWithAttribute(const QString& nodeName, + const QString& value, + const QString& attribute, + bool replace) { + + printf("VSession:addNodeWithAttribute(%s, %s, %s, %d)\n", + nodeName.toUtf8().data(), + value.toUtf8().data(), + attribute.toUtf8().data(), + replace); + + QDomElement node = + this->doc_.namedItem("eintrag").namedItem(nodeName).toElement(); + + if (replace == false || node.isNull()) { + printf(" creating new node\n"); + // create a new node + node = this->doc_.createElement(nodeName); + this->doc_.namedItem("eintrag").appendChild(node); + } + + printf(" setting attribute\n"); + node.setAttribute(attribute, value); +} + +QString VSession::toXml() const { + return this->doc_.toString(); +} + +QString VSession::getAttribute(const QString &nodeName, + const QString &attribute) const { + printf ("VSession::getAttribute(%s, %s)\n", nodeName.toAscii().data(), attribute.toAscii().data()); + QDomDocument doc = this->doc_; + //printf (" doc xml:\n%s\n", doc.toString().toAscii().data()); + QDomNode n = doc.namedItem("eintrag").namedItem(nodeName); + if (n.isNull()) { + printf(" failed to find node\n"); + } + + printf(" node name: %s\n", n.nodeName().toAscii().data()); + printf(" node type: %d\n", n.nodeType()); + printf(" node value: %s\n", n.nodeValue().toAscii().data()); + printf(" attribute %s=%s\n", attribute.toUtf8().data(), this->doc_.namedItem("eintrag").namedItem(nodeName).toElement().attribute(attribute).toUtf8().data()); + //printf (" --> %s\n", this->doc_.namedItem("eintrag").namedItem(nodeName).namedItem(attribute).toAttr().value()); + 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 { + // default to true + return getAttribute("active").compare("false"); +} + +bool VSession::isLocked() const { + // default to false + return getAttribute("locked").compare("true") == 0; +} + +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; + } + + // TODO: check return values, exceptions, ... + 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() { + printf("VSession::addUserAndHostname()\n"); + QString username(getpwuid(geteuid())->pw_name); + this->addNodeWithAttribute("username", username); + + // Qt >= 4.7 has <QHostInfo> + //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 <eintrag> + // bootpgm needs computername within the first 500 bytes + QDomElement computername(doc_.createElement("computername")); + computername.setAttribute("param", hostname); + this->doc_.namedItem("eintrag").insertBefore(computername, QDomNode()); +} + +bool VSession::run() { + + printf("VSession::run()\n"); + QString command = getAttribute("command"); + if (! command.isEmpty()) { + if (QProcess::startDetached(command)) { + // TODO: save session + return true; + } + + return false; + } + + VSession session = *this; + + QString etcpath(VMCHOOSER_ETC_BASE_PATH); + // TODO: put script names in (global?) constants + session.addPrinters(etcpath + "printer.sh"); + session.addScanners(etcpath + "scanner.sh"); + + session.addUserAndHostname(); + + // TODO: read the group configuration XML + //session.readGroupXml(&dat, env); + + // 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); + + // TODO: put script name in constant + QString runVmScript(QString(VMCHOOSER_BIN_PATH) + "run-virt.sh"); + if (QProcess::startDetached(runVmScript, QStringList(tmpfile.fileName()))) { + // TODO: save session + return true; + } + return false; +} + +QList<Session*> VSession::readXmlFile(const QString& filepath) { + printf("VSession::readXmlFile(%s)\n", filepath.toAscii().data()); + QList<Session*> retval; + + QDomDocument doc; + QFile file(filepath); + if (!file.open(QIODevice::ReadOnly)) { + // TODO: error message + printf("error: cannot open file\n"); + return retval; + } + if (!doc.setContent(&file)) { + // TODO: error message + printf("error: cannot parse file\n"); + file.close(); + return retval; + } + file.close(); + + // TODO: iterate over all <settings> child nodes? + QString dirName(QFileInfo(filepath).dir().absolutePath()); + QDomElement settingsNode = doc.firstChildElement("settings"); + for (QDomElement el(settingsNode.firstChildElement("eintrag")); + !el.isNull(); + el = el.nextSiblingElement("eintrag")) { + printf("reading %s node\n", el.tagName().toAscii().data()); + QDomDocument dummy; + dummy.appendChild(dummy.importNode(el, true)); + VSession* e = new VSession; + if (e->init(dummy.toString(), dirName)) { + printf("appending node\n"); + 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<Session*> VSession::readXmlDir(const QString& path) { + printf("VSession::readXmlDir(%s)\n", path.toAscii().data()); + QList<Session*> retval; + + QDir appDir(QApplication::applicationDirPath()); + if (QFile::exists(appDir.filePath(filterscript))) { + // run filterscript + // treat every output line as a filename and read it + QProcess myFilterScript; + myFilterScript.start(appDir.filePath(filterscript), QStringList(path), + QIODevice::ReadOnly); + while (! myFilterScript.atEnd()) { + QString filename(myFilterScript.readLine()); + if (QDir::isRelativePath(filename)) { + filename.prepend(path + "/"); + } + retval.append(readXmlFile(filename)); + } + + myFilterScript.close(); + } else { + // iterate over all .xml files in directory path and read them + foreach (QFileInfo fi, QDir(path).entryInfoList(QStringList("*.xml"))) { + retval.append(readXmlFile(fi.absoluteFilePath())); + } + } + + printf("VSession::readXmlDir(%s), read %d entries\n", path.toAscii().data(), retval.size()); + 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..bb29f64 --- /dev/null +++ b/src/vsession.h @@ -0,0 +1,81 @@ +#ifndef VMCHOOSER_VSESSION_H_ +#define VMCHOOSER_VSESSION_H_ + +#include <QString> +#include <QList> +#include <QDomDocument> +#include <QDir> +#include "session.h" + +// TODO: check #includes (in all files) + +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; + int priority() const; + + QString shortDescription() const { + return getAttribute("short_description"); + } + + QString description() const { + return getAttribute("description"); + } + + QString icon() const { + QString icon(getAttribute("icon")); + if (icon.contains(".") && QDir::isRelativePath(icon)) { + icon.prepend(baseDirPath_ + "/"); + } + return icon; + } + + QString os() const { + return getAttribute("os"); + } + + QString getAttribute(const QString& nodeName, + const QString& attribute = "param") const; + QString getNodeText(const QString& nodeName) const; + + // TODO: remove next line + void addNode(const QString& nodeName); + void addNodeWithAttribute(const QString& nodeName, + const QString& value, + const QString& attribute = "param", + bool replace = true); + // TODO: remove next line + void addTODO(const QString& value, const QString& nodeName, + const QString& attribute = "param"); // TODO: this adds node and attribute + // TODO: remove next line + void addNodeText(const QString& text, const QString& nodeName); + + void addPrinters(const QString& script, const QString& type = "printer"); + void addScanners(const QString& script); + void addUserAndHostname(); + + QString toXml() const; + + bool run(); + + bool operator<(const Session& other) const; + + static QList<Session*> readXmlDir(const QString& path); + static QList<Session*> readXmlFile(const QString& filepath); + +private: + QDomDocument doc_; + QString baseDirPath_; +}; + +#endif /*VMCHOOSER_VSESSION_H_*/ diff --git a/src/xsession.cpp b/src/xsession.cpp new file mode 100644 index 0000000..2c1ed57 --- /dev/null +++ b/src/xsession.cpp @@ -0,0 +1,135 @@ +#include <QDir> +#include <QSettings> +#include <QLocale> +#include <QApplication> +#include <QProcess> + +#include "xsession.h" + +// TODO: void instead of bool? (or return something useful) +bool XSession::init(const QString& name, const QString& exec, + const QString& comment, const QString& icon) { + printf("XSession::init()\n"); + this->name_ = name; + this->exec_ = exec; + this->comment_ = comment; + this->icon_ = icon; +} + +bool XSession::isActive() 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->name_.contains("kde", Qt::CaseInsensitive)) { + icon = "kde"; + } else if (this->name_.contains("gnome", Qt::CaseInsensitive)) { + icon = "gnome"; + } else if (this->name_.contains("xfce", Qt::CaseInsensitive)) { + icon = "xfce"; + } else { + icon = "linux"; + } + } + + return icon; +} + +bool XSession::run() { + return QProcess::startDetached(this->exec_); +} + +QList<Session*> XSession::readSessions(const QString& path) { + printf("XSession::readSessions(%s)\n", path.toAscii().data()); + QList<Session*> retval; + foreach (QFileInfo fi, QDir(path).entryInfoList(QStringList("*.desktop"))) { + printf(" reading %s\n", fi.absoluteFilePath().toAscii().data()); + if (fi.baseName().compare("default.desktop") == 0) { + continue; + } + + QSettings settings(fi.absoluteFilePath(), QSettings::IniFormat); + settings.setIniCodec("UTF-8"); + + settings.beginGroup("Desktop Entry"); + printf(" keys: %s\n", settings.allKeys().join(",").toAscii().data()); + + if (settings.value("NoDisplay").toString().compare("true") == 0 || + settings.value("Hidden").toString().compare("true") == 0) { + continue; + printf(" session is hidden\n"); + } + + if (!settings.contains("Exec")) { + // TODO: error message + printf(" no exec found\n"); + continue; + } + 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 { + // TODO: error message + printf(" no name found\n"); + continue; + } + + 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(); + } + + printf(" adding session %s\n", name.toAscii().data()); + + XSession* session = new XSession; + session->init(name, exec, comment, icon); + + 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..f5b5049 --- /dev/null +++ b/src/xsession.h @@ -0,0 +1,45 @@ +#ifndef VMCHOOSER_XSESSION_H_ +#define VMCHOOSER_XSESSION_H_ + +#include <QString> +#include <QList> +#include <QDomDocument> +#include <QDir> +#include "session.h" + +// TODO: check includes (in all files) +// TODO: sort (operator<) + +class XSession : public Session { +public: + bool init(const QString& name, const QString& exec, + const QString& comment, const QString& icon); + + bool isActive() const; + bool isLocked() const; + int priority() const; + + QString shortDescription() const { + return this->name_; + } + + QString description() const { + return this->comment_; + } + + QString icon() const; + + bool run(); + + bool operator<(const Session& other) const; + + static QList<Session*> readSessions(const QString& path); + +private: + QString name_; + QString exec_; + QString comment_; + QString icon_; +}; + +#endif /*VMCHOOSER_XSESSION_H_*/ |