From 5103900bfeb0feced5b58d68924479bfc73d8ec5 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Sun, 4 May 2014 12:56:35 +0200 Subject: Lots of fixes, cleanup, refactoring * Added command line option to set the base path where images can be accessed locally, in case NFS/CIFS is used. * Sorted command line options in source file to make it easier to add new options (prevent accidental shortopt collisions). * Disable "My Courses" button if the list is empty. * Added some TODO notes :> --- src/choosersettings.cpp | 2 +- src/choosersettings.h | 1 + src/command_line_options.cpp | 57 ++-- src/dialog.cpp | 609 +++++++++++++++++++++---------------------- src/dialog.h | 3 +- src/globals.cpp | 3 +- src/globals.h | 1 + src/i18n/de.ts | 2 +- src/main.cpp | 22 +- src/vsession.cpp | 166 ++++++------ 10 files changed, 439 insertions(+), 427 deletions(-) (limited to 'src') diff --git a/src/choosersettings.cpp b/src/choosersettings.cpp index 2b8b9ac..ecaa6e7 100644 --- a/src/choosersettings.cpp +++ b/src/choosersettings.cpp @@ -20,7 +20,7 @@ ChooserSettings::ChooserSettings() { } } - settings = new QSettings(previousSessionFile + ".ini", QSettings::IniFormat); + settings = new QSettings(previousSessionFile, QSettings::IniFormat); settings->setIniCodec("UTF-8"); if (settings->status() != QSettings::NoError) { diff --git a/src/choosersettings.h b/src/choosersettings.h index 74e01ab..28bf619 100644 --- a/src/choosersettings.h +++ b/src/choosersettings.h @@ -12,6 +12,7 @@ #include #include +// TODO: Proper name. This is the user specific settings, not global class ChooserSettings { public: static QString getSetting(QString key); diff --git a/src/command_line_options.cpp b/src/command_line_options.cpp index 3a133ba..fd946bd 100644 --- a/src/command_line_options.cpp +++ b/src/command_line_options.cpp @@ -3,48 +3,57 @@ #include CommandLineOptions::CommandLineOptions(int argc, char * const argv[]) { - // parse command line arguments + // parse command line arguments (please sort by short option for easier handling) static const struct option longOptions[] = { + {"base", required_argument, NULL, 'b'}, {"config", required_argument, NULL, 'c'}, + {"debug", no_argument, NULL, 'D'}, {"default", required_argument, NULL, 'd'}, - {"env", required_argument, NULL, 'e'}, {"file", required_argument, NULL, 'f'}, - {"xpath", required_argument, NULL, 'x'}, - {"url", required_argument, NULL, 'u'}, + {"help", no_argument, NULL, 'h'}, + {"pool", required_argument, NULL, 'P'}, + {"pvs", no_argument, NULL, 'p'}, + {"runscript", no_argument, NULL, 'S'}, {"size", required_argument, NULL, 's'}, {"theme", required_argument, NULL, 't'}, - {"pvs", no_argument, NULL, 'b'}, - {"debug", no_argument, NULL, 'D'}, + {"url", required_argument, NULL, 'u'}, {"version", no_argument, NULL, 'v'}, - {"help", no_argument, NULL, 'h'}, - {"runscript", no_argument, NULL, 'S'}, + {"xpath", required_argument, NULL, 'x'}, {0, 0, 0, 0} }; int c; - while ((c = getopt_long(argc, argv, "c:d:e:f:x:u:s:t:w:vhbDS", longOptions, NULL)) != -1) { + // Again, please sort alphabetically in getopt_long call and switch statement + while ((c = getopt_long(argc, argv, "b:c:Dd:f:hP:pSs:t:u:vx:?", longOptions, NULL)) != -1) { switch (c) { + case 'b': + options.insert("base", optarg); + break; case 'c': options.insert("config", optarg); break; + case 'D': + options.insert("debugMode", "debugMode"); + break; case 'd': options.insert("default", optarg); break; case 'f': options.insert("file", optarg); break; - case 'D': - options.insert("debugMode", "debugMode"); + case 'h': + case '?': + options.insert("usage", "usage"); break; - case 'e': - options.insert("env", optarg); + case 'P': + options.insert("pool", optarg); break; - case 'x': - options.insert("xpath", optarg); + case 'p': + options.insert("pvs", "pvs"); break; - case 'u': - options.insert("url", optarg); + case 'S': + options.insert("runscript", optarg); break; case 's': options.insert("size", optarg); @@ -52,19 +61,15 @@ CommandLineOptions::CommandLineOptions(int argc, char * const argv[]) { case 't': options.insert("theme", optarg); break; - case 'b': - options.insert("pvs", "pvs"); - break; + case 'u': + options.insert("url", optarg); + break; case 'v': options.insert("version", "version"); break; - case 'h': - options.insert("usage", "usage"); + case 'x': + options.insert("xpath", optarg); break; - case 'S': - options.insert("runscript", optarg); - break; - case '?': default: options.insert("error", "error"); break; diff --git a/src/dialog.cpp b/src/dialog.cpp index 009da02..ecfc097 100644 --- a/src/dialog.cpp +++ b/src/dialog.cpp @@ -23,6 +23,9 @@ Dialog::Dialog(QWidget *parent) model_[2] = new SessionTreeModel(parent); ui->setupUi(this); + tabs_[0] = ui->tabButtonLocal; + tabs_[1] = ui->tabButtonMyClasses; + tabs_[2] = ui->tabButtonAllClasses; pvsSettings_ = NULL; ui->PVSOptionsGroupBox->hide(); @@ -38,13 +41,13 @@ Dialog::Dialog(QWidget *parent) ui->tabButtonLocal->setChecked(true); ui->filterEdit->setEnabled(false); - ui->helpBox->hide(); - ui->newsBox->hide(); - - setListModel(model_[0]); + ui->helpBox->hide(); + ui->newsBox->hide(); QObject::connect(ui->treeView->selectionModel(), SIGNAL(currentChanged ( const QModelIndex&, const QModelIndex&)), - this, SLOT(treeView_selectionChanged(const QModelIndex&, const QModelIndex&))); + this, SLOT(treeView_selectionChanged(const QModelIndex&, const QModelIndex&))); + + this->onTabButtonChanged(2); } Dialog::~Dialog() { @@ -76,7 +79,7 @@ void Dialog::on_treeView_activated(QModelIndex index) { // no valid session has been selected, do nothing return; } - + // Run session start script if (QFile::exists(sessionStartScript)) { QProcess scriptProcess; @@ -99,24 +102,27 @@ void Dialog::on_treeView_activated(QModelIndex index) { } void Dialog::addItems(const QList& entries, int tab) { - if (tab < 0 || tab > 2) { - return; - } + if (tab < 0 || tab > 2) { + return; + } this->model_[tab]->addItems(entries); + tabs_[tab]->setEnabled(this->model_[tab]->rowCount() != 0); } void Dialog::addLabelItem(const QString& label, int tab) { - if (tab < 0 || tab > 2) { - return; - } - this->model_[tab]->addLabelItem(label); + if (tab < 0 || tab > 2) { + return; + } + this->model_[tab]->addLabelItem(label); + tabs_[tab]->setEnabled(this->model_[tab]->rowCount() != 0); } void Dialog::removeItem(const QString& name, int tab) { - if (tab < 0 || tab > 2) { - return; - } - this->model_[tab]->removeItem(name); + if (tab < 0 || tab > 2) { + return; + } + this->model_[tab]->removeItem(name); + tabs_[tab]->setEnabled(this->model_[tab]->rowCount() != 0); } void Dialog::on_pushButtonAbort_clicked() { @@ -190,39 +196,39 @@ bool Dialog::selectSession(const QString& name) { QModelIndex root(ui->treeView->rootIndex()); for (int tab = 0; tab <= 2; ++tab) { - for (int i = 0; i < model_[tab]->rowCount(root); ++i) { - QModelIndex index = model_[tab]->index(i, 0, root); - if (!index.isValid()) { - break; - } - SessionTreeItem* item = static_cast(index.internalPointer()); - const Session* s(item->session()); - if (!s) { - continue; - } - if (s->shortDescription() == name) { - // change the tab - onTabButtonChanged(tab); - // set selection - ui->treeView->selectionModel()->clearSelection(); - ui->treeView->selectionModel() - ->setCurrentIndex(index, QItemSelectionModel::Select); - return true; - } - } + for (int i = 0; i < model_[tab]->rowCount(root); ++i) { + QModelIndex index = model_[tab]->index(i, 0, root); + if (!index.isValid()) { + break; + } + SessionTreeItem* item = static_cast(index.internalPointer()); + const Session* s(item->session()); + if (!s) { + continue; + } + if (s->shortDescription() == name) { + // change the tab + onTabButtonChanged(tab); + // set selection + ui->treeView->selectionModel()->clearSelection(); + ui->treeView->selectionModel() + ->setCurrentIndex(index, QItemSelectionModel::Select); + return true; + } + } } return false; } void Dialog::selectPreviousSession() { - if (!ChooserSettings::getSetting("last-session").isEmpty()) { - ui->treeView->clearSelection(); - if (!selectSession(ChooserSettings::getSetting("last-session"))) { - // could not find last session, change to last used tab - this->onTabButtonChanged(ChooserSettings::getSetting("last-tab").toInt()); - } - } + if (!ChooserSettings::getSetting("last-session").isEmpty()) { + ui->treeView->clearSelection(); + if (!selectSession(ChooserSettings::getSetting("last-session"))) { + // could not find last session, change to last used tab + this->onTabButtonChanged(ChooserSettings::getSetting("last-tab").toInt()); + } + } } void Dialog::startSession(const QString& name) { @@ -240,38 +246,38 @@ void Dialog::showSettingsPVS() { } void Dialog::setTheme() { - QString label_l_style, label_r_style; - QString backgroundColor, imageLeft, imageRight; - QString themePathBase, themePathIni, themePathImgLeft, themePathImgRight; + QString label_l_style, label_r_style; + QString backgroundColor, imageLeft, imageRight; + QString themePathBase, themePathIni, themePathImgLeft, themePathImgRight; - if (theme.isEmpty()) return; + if (theme.isEmpty()) return; - themePathBase = QString("%1/%2/").arg(VMCHOOSER_THEME_BASE).arg(theme); - themePathIni = QString("%1%2.ini").arg(themePathBase).arg(theme); + themePathBase = QString("%1/%2/").arg(VMCHOOSER_THEME_BASE).arg(theme); + themePathIni = QString("%1%2.ini").arg(themePathBase).arg(theme); - if (!QFile::exists(themePathIni)) return; + if (!QFile::exists(themePathIni)) return; - QSettings themeSettings(themePathIni, QSettings::IniFormat); - backgroundColor = themeSettings.value("background-color").toString(); - imageLeft = themeSettings.value("image-left").toString(); - imageRight = themeSettings.value("image-right").toString(); + 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); + themePathImgLeft = QString("%1%2").arg(themePathBase).arg(imageLeft); + themePathImgRight = QString("%1%2").arg(themePathBase).arg(imageRight); - QRegExp re; + 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); + 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); + ui->label_l->setStyleSheet(label_l_style); + ui->label_r->setStyleSheet(label_r_style); } void Dialog::onCenterTimer() { @@ -294,58 +300,56 @@ void Dialog::onCenterTimer() { } void Dialog::addSessionsAfterDownload(QNetworkReply* reply) { - QString temp_filename; - - if (reply->error() != QNetworkReply::NoError) { - if (debugMode) { - qDebug() << "Error reading from URL: " << reply->error(); - } - - QFile backup_file(xml_filename); - - if (!backup_file.open(QIODevice::ReadOnly)) { - if (debugMode) { - qDebug() << "Cannot read backup file " << xml_filename << " either"; - } - this->removeItem(QCoreApplication::instance()->translate("Dialog", "Loading..."), 1); - this->addLabelItem(QCoreApplication::instance()->translate("Dialog", "URL Error"), 1); - return; - } - if (debugMode) { - qDebug() << "Used backup file " << xml_filename; - } - backup_file.close(); - - QList sessions = VSession::readXmlFile(xml_filename); - qSort(sessions.begin(), sessions.end(), myLessThan); - this->addItems(sessions, 1); - } else { - QByteArray data = reply->readAll(); - - // write xml to temporary file - temp_filename = QDir::tempPath() + "/vmchooser2/vmchooser-XXXXXX.xml"; - QTemporaryFile tmpfile(temp_filename); - if (!tmpfile.open() || tmpfile.write(data) == -1) { - return; - } - tmpfile.close(); - tmpfile.setAutoRemove(false); - temp_filename = tmpfile.fileName(); - } - - QList sessions = VSession::readXmlFile(temp_filename); - - this->removeItem(QCoreApplication::instance()->translate("Dialog", "Loading..."), 1); - - if (!sessions.isEmpty()) { - qSort(sessions.begin(), sessions.end(), myLessThan); - this->addItems(sessions, 1); - } else { - this->addLabelItem(QCoreApplication::instance()->translate("Dialog", "No Items"), 1); - } - - // select last-session - selectPreviousSession(); + QString temp_filename; + + if (reply->error() != QNetworkReply::NoError) { + if (debugMode) { + qDebug() << "Error reading from URL: " << reply->error(); + } + + QFile backup_file(xml_filename); + + if (!backup_file.open(QIODevice::ReadOnly)) { + if (debugMode) { + qDebug() << "Cannot read backup file " << xml_filename << " either"; + } + this->removeItem(QCoreApplication::instance()->translate("Dialog", "Loading..."), 1); + this->addLabelItem(QCoreApplication::instance()->translate("Dialog", "URL Error"), 1); + return; + } + if (debugMode) { + qDebug() << "Using backup file " << xml_filename; + } + backup_file.close(); + + temp_filename = xml_filename; + } else { + QByteArray data = reply->readAll(); + + // write xml to temporary file + temp_filename = QDir::tempPath() + "/vmchooser2/vmchooser-XXXXXX.xml"; + QTemporaryFile tmpfile(temp_filename); + if (!tmpfile.open() || tmpfile.write(data) == -1) { + return; + } + tmpfile.close(); + tmpfile.setAutoRemove(false); + temp_filename = tmpfile.fileName(); + } + + QList sessions = VSession::readXmlFile(temp_filename); + + this->removeItem(QCoreApplication::instance()->translate("Dialog", "Loading..."), 1); + + if (!sessions.isEmpty()) { + qSort(sessions.begin(), sessions.end(), myLessThan); + this->addItems(sessions, 2); // TODO: No magic number; handle user specific classes + } else { + this->addLabelItem(QCoreApplication::instance()->translate("Dialog", "No Items"), 1); + } + + // select last-session + selectPreviousSession(); } void Dialog::treeView_selectionChanged(const QModelIndex& current, const QModelIndex&) { @@ -354,253 +358,240 @@ void Dialog::treeView_selectionChanged(const QModelIndex& current, const QModelI const Session* s(item->session()); if (!s) { - if (debugMode) { - qDebug() << "invalid selection"; - } + if (debugMode) { + qDebug() << "invalid selection"; + } // no valid session has been selected, do nothing return; } if (s->type() == Session::VSESSION) { - const VSession* vs = (VSession*) s; + const VSession* vs = (VSession*) s; - ui->label_name->setText(vs->getAttribute("short_description", "param")); - ui->label_name->setToolTip(vs->getAttribute("short_description", "param")); + ui->label_name->setText(vs->getAttribute("short_description", "param")); + ui->label_name->setToolTip(vs->getAttribute("short_description", "param")); - ui->label_creator->setText(vs->getAttribute("creator", "param")); - ui->label_creator->setToolTip(vs->getAttribute("creator", "param")); + ui->label_creator->setText(vs->getAttribute("creator", "param")); + ui->label_creator->setToolTip(vs->getAttribute("creator", "param")); - ui->label_os->setText(vs->getAttribute("os", "param")); - ui->label_os->setToolTip(vs->getAttribute("os", "param")); + ui->label_os->setText(vs->getAttribute("os", "param")); + ui->label_os->setToolTip(vs->getAttribute("os", "param")); - QString description(vs->getAttribute("long_description", "param") + "\n\nKeywords: "); - for (int i = 0; i < vs->keywords().length(); ++i) { - description += vs->keywords()[i] + ", "; - } + QString description(vs->getAttribute("long_description", "param") + "\n\nKeywords: "); + for (int i = 0; i < vs->keywords().length(); ++i) { + description += vs->keywords()[i] + ", "; + } - ui->textBrowser->setText(description); + ui->textBrowser->setText(description); } else { - ui->label_name->setText(s->shortDescription()); - ui->label_creator->setText(""); - ui->label_os->setText(QCoreApplication::instance()->translate("Dialog", "Native")); - ui->textBrowser->setPlainText(QCoreApplication::instance()->translate("Dialog", "Running on this machine.")); + ui->label_name->setText(s->shortDescription()); + ui->label_creator->setText(""); + ui->label_os->setText(QCoreApplication::instance()->translate("Dialog", "Native")); + ui->textBrowser->setPlainText(QCoreApplication::instance()->translate("Dialog", "Running on this machine.")); } } void Dialog::on_tabButtonLocal_clicked() { - onTabButtonChanged(0); + onTabButtonChanged(0); } void Dialog::on_tabButtonMyClasses_clicked() { - onTabButtonChanged(1); + onTabButtonChanged(1); } void Dialog::on_tabButtonAllClasses_clicked() { - onTabButtonChanged(2); + onTabButtonChanged(2); } void Dialog::onTabButtonChanged(int tab) { - if (tab < 0 || tab > 2) { - // no valid button - return; - } - - // give focus to treeView - ui->treeView->setFocus(); - - // when button was pressed disable the other buttons - if (tab == 0) { - ui->tabButtonLocal->setChecked(true); - ui->tabButtonMyClasses->setChecked(false); - ui->tabButtonAllClasses->setChecked(false); - ui->filterEdit->setEnabled(false); - } else if (tab == 1) { - ui->tabButtonLocal->setChecked(false); - ui->tabButtonMyClasses->setChecked(true); - ui->tabButtonAllClasses->setChecked(false); - ui->filterEdit->setEnabled(true); - } else { - ui->tabButtonLocal->setChecked(false); - ui->tabButtonMyClasses->setChecked(false); - ui->tabButtonAllClasses->setChecked(true); - ui->filterEdit->setEnabled(true); - } - - // clear filter if necessary - if (activeTab != tab) { - this->ui->filterEdit->setText(""); - } - - // load the new list - setListModel(model_[tab]); - this->activeTab = tab; + if (tab < 0 || tab > 2) { + // no valid button + return; + } + + // give focus to treeView + ui->treeView->setFocus(); + + // Update pressed status of buttons + for (int i = 0; i < 3; ++i) { + tabs_[i]->setChecked(tab == i); + } + + // clear filter if necessary + if (activeTab != tab) { + this->ui->filterEdit->setText(""); + } + + // load the new list + setListModel(model_[tab]); + this->activeTab = tab; } void Dialog::on_filterEdit_textChanged() { - SessionTreeModel *newModel; - - // filter the current model - if (ui->filterEdit->text() != "" && ui->filterEdit->text().replace(" ", "").length() > 2) { - newModel = new SessionTreeModel(this); - newModel->addItems(this->model_[activeTab]->lookForItem(ui->filterEdit->text())); - } else { - newModel = model_[activeTab]; - } - setListModel(newModel); + SessionTreeModel *newModel; + + // filter the current model + if (ui->filterEdit->text() != "" && ui->filterEdit->text().replace(" ", "").length() > 2) { + newModel = new SessionTreeModel(this); + newModel->addItems(this->model_[activeTab]->lookForItem(ui->filterEdit->text())); + } else { + newModel = model_[activeTab]; + } + setListModel(newModel); } void Dialog::setListModel(QAbstractItemModel *model) { - if (ui->treeView->model() == model_[0] || ui->treeView->model() == model_[1] || ui->treeView->model() == model_[2]) { - } else { - ui->treeView->model()->deleteLater(); - } - ui->treeView->setModel(model); + if (ui->treeView->model() == model_[0] || ui->treeView->model() == model_[1] || ui->treeView->model() == model_[2]) { + } else { + ui->treeView->model()->deleteLater(); + } + ui->treeView->setModel(model); - // reconnect the treeModel + // reconnect the treeModel QObject::connect(ui->treeView->selectionModel(), SIGNAL(currentChanged ( const QModelIndex&, const QModelIndex&)), - this, SLOT(treeView_selectionChanged(const QModelIndex&, const QModelIndex&))); + this, SLOT(treeView_selectionChanged(const QModelIndex&, const QModelIndex&))); - if (ui->treeView->selectionModel()->selectedRows(0).count() == 0) { - ui->treeView->selectionModel()->clearSelection(); - ui->treeView->selectionModel()->setCurrentIndex(ui->treeView->model()->index(0, 0, ui->treeView->rootIndex()), QItemSelectionModel::Select); - } + if (ui->treeView->selectionModel()->selectedRows(0).count() == 0) { + ui->treeView->selectionModel()->clearSelection(); + ui->treeView->selectionModel()->setCurrentIndex(ui->treeView->model()->index(0, 0, ui->treeView->rootIndex()), QItemSelectionModel::Select); + } } void Dialog::on_helpNewsButton_clicked() { - if (ui->helpBox->isVisible()) { - ui->helpBox->hide(); - ui->newsBox->hide(); - } else { - ui->helpBox->show(); - ui->newsBox->show(); - } + if (ui->helpBox->isVisible()) { + ui->helpBox->hide(); + ui->newsBox->hide(); + } else { + ui->helpBox->show(); + ui->newsBox->show(); + } } void Dialog::addNewsAfterDownload(QNetworkReply* reply) { - if (reply->error() != QNetworkReply::NoError) { - if (debugMode) { - qDebug() << "Could not get news. Try to get cached news."; - } - - // try to get cached news - QFile backup_file(news_backup_filename); - - if (!backup_file.open(QIODevice::ReadOnly)) { - if (debugMode) { - qDebug() << "Cannot read backup file " << news_backup_filename << " either"; - } - this->ui->newsTextBrowser->setText(QCoreApplication::instance()->translate("Dialog", "Could not get news.")); - return; - } - if (debugMode) { - qDebug() << "Used backup file " << news_backup_filename; - } - backup_file.close(); - return; - } - QByteArray data = reply->readAll(); - QDomDocument doc; - if (!doc.setContent(data)) { - qDebug() << "News XML contains errors."; - return; - } + if (reply->error() != QNetworkReply::NoError) { + if (debugMode) { + qDebug() << "Could not get news. Try to get cached news."; + } + + // try to get cached news + QFile backup_file(news_backup_filename); + + if (!backup_file.open(QIODevice::ReadOnly)) { + if (debugMode) { + qDebug() << "Cannot read backup file " << news_backup_filename << " either"; + } + this->ui->newsTextBrowser->setText(QCoreApplication::instance()->translate("Dialog", "Could not get news.")); + return; + } + if (debugMode) { + qDebug() << "Used backup file " << news_backup_filename; + } + backup_file.close(); + return; + } + QByteArray data = reply->readAll(); + QDomDocument doc; + if (!doc.setContent(data)) { + qDebug() << "News XML contains errors."; + return; + } QDomElement newsNode = doc.firstChildElement("news"); QDateTime timestamp; timestamp.setTime_t(newsNode.firstChildElement("date").text().toInt()); // format and print news ui->newsTextBrowser->setText(QString("

" + newsNode.firstChildElement("headline").text() + "

" - + timestamp.toString(Qt::SystemLocaleShortDate) + "

" - + newsNode.firstChildElement("info").text() + "

")); + + timestamp.toString(Qt::SystemLocaleShortDate) + "

" + + newsNode.firstChildElement("info").text() + "

")); if (ChooserSettings::getSetting("last-news").toUInt() < timestamp.toTime_t()) { - // show news if not seen before - on_helpNewsButton_clicked(); + // show news if not seen before + on_helpNewsButton_clicked(); } // update ini ChooserSettings::setSetting("last-news", QString::number(timestamp.toTime_t())); - // make backup - QFile file(news_backup_filename); - if (!file.open(QIODevice::WriteOnly)) { - if (debugMode) { - qDebug() << "Could not write XML to " << xml_filename; - } - return; - } - - if (file.write(data) != data.length()) { - return; - } - if (!file.setPermissions(QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther)) { - if (debugMode) { - qDebug() << "Could not change permissions of file: " << news_backup_filename; - } - } - file.close(); + // make backup + QFile file(news_backup_filename); + if (!file.open(QIODevice::WriteOnly)) { + if (debugMode) { + qDebug() << "Could not write XML to " << news_backup_filename; + } + return; + } + + if (file.write(data) != data.length()) { + return; + } + if (!file.setPermissions(QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther)) { + if (debugMode) { + qDebug() << "Could not change permissions of file: " << news_backup_filename; + } + } + file.close(); } void Dialog::addHelpAfterDownload(QNetworkReply* reply) { - if (reply->error() != QNetworkReply::NoError) { - if (debugMode) { - qDebug() << "Could not get help xml. Try to get cached help..."; - } - - // try to get cached news - QFile backup_file(help_backup_filename); - - if (!backup_file.open(QIODevice::ReadOnly)) { - if (debugMode) { - qDebug() << "Cannot read backup file " << help_backup_filename << " either"; - } - this->ui->helpTextBrowser->setText(QCoreApplication::instance()->translate("Dialog", "Could not get help.")); - return; - } - if (debugMode) { - qDebug() << "Used backup file " << help_backup_filename; - } - backup_file.close(); - return; - } - - QByteArray data = reply->readAll(); - QDomDocument doc; - - if (!doc.setContent(data)) { - if (debugMode) { - qDebug() << "Help file contains errors."; - } - return; - } - - ui->helpTextBrowser->setText(QString(data)); - - // make backup - QFile file(help_backup_filename); - if (!file.open(QIODevice::WriteOnly)) { - if (debugMode) { - qDebug() << "Could not write XML to " << xml_filename; - } - return; - } - - if (file.write(data) != data.length()) { - return; - } - if (!file.setPermissions(QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther)) { - if (debugMode) { - qDebug() << "Could not change permissions of file: " << help_backup_filename; - } - } - file.close(); + if (reply->error() != QNetworkReply::NoError) { + if (debugMode) { + qDebug() << "Could not get help xml. Try to get cached help..."; + } + + // try to get cached news + QFile backup_file(help_backup_filename); + + if (!backup_file.open(QIODevice::ReadOnly)) { + if (debugMode) { + qDebug() << "Cannot read backup file " << help_backup_filename << " either"; + } + this->ui->helpTextBrowser->setText(QCoreApplication::instance()->translate("Dialog", "Could not get help.")); + return; + } + if (debugMode) { + qDebug() << "Used backup file " << help_backup_filename; + } + backup_file.close(); + return; + } + + QByteArray data = reply->readAll(); + QDomDocument doc; + + if (!doc.setContent(data)) { + if (debugMode) { + qDebug() << "Help file contains errors."; + } + return; + } + + ui->helpTextBrowser->setText(QString(data)); + + // make backup + QFile file(help_backup_filename); + if (!file.open(QIODevice::WriteOnly)) { + if (debugMode) { + qDebug() << "Could not write XML to " << help_backup_filename; + } + return; + } + + if (file.write(data) != data.length()) { + return; + } + if (!file.setPermissions(QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther)) { + if (debugMode) { + qDebug() << "Could not change permissions of file: " << help_backup_filename; + } + } + file.close(); } void Dialog::keyPressEvent(QKeyEvent* event) { - switch(event->key()) { - case Qt::Key_Return: this->on_pushButtonStart_clicked(); break; - case Qt::Key_Escape: this->on_pushButtonAbort_clicked(); break; - case Qt::Key_H: this->on_helpNewsButton_clicked(); break; - } + switch(event->key()) { + case Qt::Key_Return: this->on_pushButtonStart_clicked(); break; + case Qt::Key_Escape: this->on_pushButtonAbort_clicked(); break; + case Qt::Key_H: this->on_helpNewsButton_clicked(); break; + } } diff --git a/src/dialog.h b/src/dialog.h index f11b674..dee7304 100644 --- a/src/dialog.h +++ b/src/dialog.h @@ -35,7 +35,8 @@ class Dialog : public QDialog { private: Ui::Dialog *ui; - SessionTreeModel *model_[3]; + SessionTreeModel *model_[3]; // TODO: Constants/Enum for indices + QPushButton *tabs_[3]; QSettings *pvsSettings_; QPoint oldCenter_; QTimer *centerTimer_; diff --git a/src/globals.cpp b/src/globals.cpp index 876d35c..cbaca28 100644 --- a/src/globals.cpp +++ b/src/globals.cpp @@ -15,13 +15,14 @@ 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"); +const QString previousSessionFile(userPath + "/vmchooser_prev_session.ini"); bool debugMode = false; bool pvsEnabled = false; QString pool; QString theme; +QString basePath; const QString iconsTempPath("/tmp/vmchooser2/icons/"); const QString xml_filename("/tmp/vmchooser2/vmchooser2.xml"); diff --git a/src/globals.h b/src/globals.h index d1ad8f4..ed70e06 100644 --- a/src/globals.h +++ b/src/globals.h @@ -42,6 +42,7 @@ extern const QString previousSessionFile; extern QString pool; extern QString theme; +extern QString basePath; extern const QString iconsTempPath; extern const QString xml_filename; diff --git a/src/i18n/de.ts b/src/i18n/de.ts index f3dda2c..a0aea72 100644 --- a/src/i18n/de.ts +++ b/src/i18n/de.ts @@ -221,7 +221,7 @@ p, li { white-space: pre-wrap; } Local - Lokal + Natives Linux My Classes diff --git a/src/main.cpp b/src/main.cpp index e646620..2c80919 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,15 +31,16 @@ int main(int argc, char *argv[]) { std::string usage( a.translate("Console", "Usage: vmchooser [ OPTIONS ]\n\n" + " -b --base base directory where VM images are accessible\n" " -d, --default name of default session\n" " -c, --config alternative config file\n" - " -e, --env name of the environment\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 x\n" " -t, --theme theme\n" - " -b, --pvs show pvs options\n" + " -p, --pvs show pvs options\n" " -D, --debug print debug information\n" " -v, --version print version and exit\n" " -h, --help print usage information and exit\n" @@ -94,6 +95,7 @@ int main(int argc, char *argv[]) { } else { confFile = globalConfFile; } + // TODO: This is the system wide settings, give proper name QSettings settings(confFile, QSettings::IniFormat); settings.setIniCodec("UTF-8"); @@ -106,12 +108,6 @@ int main(int argc, char *argv[]) { defaultSession = ChooserSettings::getSetting("last-session"); } - 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")) { @@ -171,8 +167,8 @@ int main(int argc, char *argv[]) { height = VMCHOOSER_DEFAULT_HEIGHT; } - if (cmdOptions.contains("env")) { - pool = cmdOptions.value("env"); + if (cmdOptions.contains("pool")) { + pool = cmdOptions.value("pool"); } else if (settings.contains("pool")) { pool = settings.value("pool").toString(); } @@ -187,6 +183,12 @@ int main(int argc, char *argv[]) { debugMode = true; } + if (cmdOptions.contains("base")) { + basePath = cmdOptions.value("base"); + } else if (settings.contains("base")) { + basePath = settings.value("base").toString(); + } + /* read session files */ QList xsessions(XSession::readSessions(xSessionPath)); diff --git a/src/vsession.cpp b/src/vsession.cpp index c2b1aef..7656868 100644 --- a/src/vsession.cpp +++ b/src/vsession.cpp @@ -41,9 +41,9 @@ void VSession::addNodeWithAttribute(const QString& nodeName, QString VSession::icon() const { QString icon(getAttribute("icon")); if (icon.isEmpty()) { - if (imgtype() == VMWARE) icon = "vmware"; - else if (imgtype() == VBOX) icon = "virtualbox"; - else icon = "none"; + if (imgtype() == VMWARE) icon = "vmware"; + else if (imgtype() == VBOX) icon = "virtualbox"; + else icon = "none"; } return icon; } @@ -70,34 +70,34 @@ QString VSession::getAttribute(const QString &nodeName, } QList VSession::keywords() const { - return this->keywords_; + return this->keywords_; } void VSession::readKeywords() { - QDomNode keywordsNode = this->doc_.namedItem("eintrag").namedItem("keywords"); - for (QDomElement el(keywordsNode.firstChildElement("keyword")); - !el.isNull(); - el = el.nextSiblingElement("keyword")) { - this->keywords_.append(el.text()); - } + QDomNode keywordsNode = this->doc_.namedItem("eintrag").namedItem("keywords"); + for (QDomElement el(keywordsNode.firstChildElement("keyword")); + !el.isNull(); + el = el.nextSiblingElement("keyword")) { + this->keywords_.append(el.text()); + } } bool VSession::containsKeywords(const QList& keywords) const { - for (int j = 0; j < keywords.length(); ++j) { - bool keywordFlag = true; - if (!this->shortDescription().contains(keywords[j], Qt::CaseInsensitive) - && !this->description().contains(keywords[j], Qt::CaseInsensitive) - && !this->getAttribute("creator", "param").contains(keywords[j], Qt::CaseInsensitive)) { - keywordFlag = false; - for (int i = 0; i < this->keywords().length(); ++i) { - if (this->keywords()[i].contains(keywords[j], Qt::CaseInsensitive)) { - keywordFlag = true; - } - } - if (!keywordFlag) return false; - } - } - return true; + for (int j = 0; j < keywords.length(); ++j) { + bool keywordFlag = true; + if (!this->shortDescription().contains(keywords[j], Qt::CaseInsensitive) + && !this->description().contains(keywords[j], Qt::CaseInsensitive) + && !this->getAttribute("creator", "param").contains(keywords[j], Qt::CaseInsensitive)) { + keywordFlag = false; + for (int i = 0; i < this->keywords().length(); ++i) { + if (this->keywords()[i].contains(keywords[j], Qt::CaseInsensitive)) { + keywordFlag = true; + } + } + if (!keywordFlag) return false; + } + } + return true; } QString VSession::getNodeText(const QString& nodeName) const { @@ -120,6 +120,7 @@ bool VSession::isActive() const { QString value(getAttribute("active")); if (value.compare("false") == 0) { + if (debugMode) qDebug() << "'" << shortDescription() << "' not active. Reason: active == false"; return false; } else if (value.count("/") == 1) { // try to interpret value as date range @@ -140,13 +141,13 @@ bool VSession::isActive() const { if (fromDate.isValid() && fromDate > today) { // fromDate is in the future - if (debugMode) qDebug() << "Not active. Reason: fromDate is in the future"; + if (debugMode) qDebug() << "'" << shortDescription() << "' 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"; + if (debugMode) qDebug() << "'" << shortDescription() << "' not active. Reason: tillDate is in the past"; return false; } } @@ -155,7 +156,7 @@ bool VSession::isActive() const { 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"; + if (debugMode) qDebug() << "'" << shortDescription() << "' not active. Reason: '" << pool << "' is not part of active pool list (" << pools << ")"; return false; } } @@ -184,8 +185,12 @@ void VSession::addUserAndHostname() { // Qt >= 4.7 has // QString hostname(QHostInfo::localHostName()); char hname[HOST_NAME_MAX + 1]; - gethostname(hname, HOST_NAME_MAX); - QString hostname(hname); + QString hostname; + if (gethostname(hname, HOST_NAME_MAX) == 0) { + hostname = QString::fromUtf8(hname); + } else { + hostname = QString::fromUtf8("unknown-%1").arg(qrand()); + } this->addNodeWithAttribute("hostname", hostname); QString image(this->getAttribute("image_name")); @@ -194,13 +199,13 @@ void VSession::addUserAndHostname() { this->addNodeWithAttribute("image_path", this->baseDirPath_ + "/" + image); } else { - this->addNodeWithAttribute("image_path", image); + this->addNodeWithAttribute("image_path", 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); + computername.setAttribute("param", hostname.append("-%1").arg(qrand())); this->doc_.namedItem("eintrag").insertBefore(computername, QDomNode()); } @@ -251,9 +256,9 @@ void VSession::mergePoolXml() { } bool VSession::run() const { - if (debugMode) { - qDebug() << "Sarting session " << this->getAttribute("short_description", "param") << " ..."; - } + if (debugMode) { + qDebug() << "Sarting session " << this->getAttribute("short_description", "param") << " ..."; + } QString command = getAttribute("command"); if (!command.isEmpty()) { @@ -296,62 +301,67 @@ QList VSession::readXmlFile(const QString& filepath) { if (!file.open(QIODevice::ReadOnly)) { if (debugMode) { - qDebug() << "Cannot read file: " << file.fileName(); + qDebug() << "Cannot read file: " << file.fileName(); } return retval; } if (!doc.setContent(&file)) { - if (debugMode) { - qDebug() << "XML file not valid: " << file.fileName(); - } - - file.close(); - - // try to use backup file - if (!backup_file.open(QIODevice::ReadOnly)) { - if (debugMode) { - qDebug() << "Cannot read backup file " << xml_filename << " either"; - } - return retval; - } - - if (!doc.setContent(&backup_file)) { - if (debugMode) { - qDebug() << "XML file not valid: " << backup_file.fileName(); - } - backup_file.close(); - return retval; - } - - if (debugMode) { - qDebug() << "Used backup file " << xml_filename; - } - - backup_file.close(); + if (debugMode) { + qDebug() << "XML file not valid: " << file.fileName(); + } + + file.close(); + + // try to use backup file + if (!backup_file.open(QIODevice::ReadOnly)) { + if (debugMode) { + qDebug() << "Cannot read backup file " << xml_filename << " either"; + } + return retval; + } + + if (!doc.setContent(&backup_file)) { + if (debugMode) { + qDebug() << "XML file not valid: " << backup_file.fileName(); + } + backup_file.close(); + return retval; + } + + if (debugMode) { + qDebug() << "Used backup file " << xml_filename; + } + + backup_file.close(); } else { - file.close(); - - // file is valid --> create backup file - QFile::remove(xml_filename); - QFile::rename(filepath, xml_filename); - if (!QFile::setPermissions(xml_filename, QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther)) { - if (debugMode) { - qDebug() << "Could not change permissions of file: " << news_backup_filename; - } - } + file.close(); + + // file is valid --> create backup file + QFile::remove(xml_filename); + QFile::rename(filepath, xml_filename); + if (!QFile::setPermissions(xml_filename, QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther)) { + if (debugMode) { + qDebug() << "Could not change permissions of file: " << news_backup_filename; + } + } } - QString dirName(QFileInfo(xml_filename).dir().absolutePath()); + QString dirName; + if (basePath.isEmpty()) { + dirName = QFileInfo(xml_filename).dir().absolutePath(); + } else { + dirName = basePath; + } QDomElement settingsNode = doc.firstChildElement("settings"); for (QDomElement el(settingsNode.firstChildElement("eintrag")); - !el.isNull(); - el = el.nextSiblingElement("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)) { - e->readKeywords(); + if (e->init(dummy.toString(), dirName) && e->isActive()) { + e->readKeywords(); retval.append(e); } } -- cgit v1.2.3-55-g7522