From 947133905679e19196663bd9923fd063ae4d5b85 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 9 Jul 2019 11:33:27 +0200 Subject: Gray out and warn about VMs with missing hypervisor --- src/dialog.cpp | 8 +++++++- src/session.h | 22 +++++++++++++++++++++- src/vsession.cpp | 13 ++++++++++--- src/vsession.h | 4 +++- src/xsession.cpp | 15 ++++++++++++--- src/xsession.h | 4 +++- 6 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/dialog.cpp b/src/dialog.cpp index a0b9a47..d87753a 100644 --- a/src/dialog.cpp +++ b/src/dialog.cpp @@ -133,6 +133,10 @@ void Dialog::on_treeView_doubleClicked(const QModelIndex& index) if (s == nullptr) // no valid session has been selected, do nothing return; + // Check preconditions. The method might show error messages and return false + if (!s->canRun(true)) + return; + // These two are up here in case run-virt cares... if (Config::isSet(Config::PVS)) { if (ui->PVS_checkbox->isChecked()) { @@ -203,7 +207,7 @@ void Dialog::on_treeView_doubleClicked(const QModelIndex& index) centerTimer_->stop(); // Stop the auto-center/auto-quit timer, so we don't kill the session :> setVisible(false); } else { - QMessageBox::warning( + QMessageBox::critical( this, trUtf8("vmchooser"), trUtf8("Vmchooser failed to run the selected session!")); } @@ -232,6 +236,8 @@ void Dialog::addItems(const QList& entries, int tab) { || prev.contains(it->shortDescription())) { matches.append(it); } + // Also check for validity + it->checkCanRun(); } if (!matches.isEmpty()) { addItems(matches, TAB_RECENT_COURSES); diff --git a/src/session.h b/src/session.h index 70bee42..01f8ad5 100644 --- a/src/session.h +++ b/src/session.h @@ -2,6 +2,7 @@ #define VMCHOOSER_SESSION_H_ #include +#include class QString; class QIcon; @@ -20,7 +21,20 @@ class Session { virtual bool isActive() const = 0; virtual bool isLocked() const = 0; - virtual bool isValid() const = 0; + virtual void checkCanRun() final { + error = checkCanRunInternal(); + } + virtual bool canRun(bool showError = false) const final { + if (!error.isEmpty()) { + if (showError) { + QMessageBox::critical( + nullptr, QObject::trUtf8("vmchooser"), + QObject::trUtf8("Cannot start selected session:") + QStringLiteral("\n") + error); + } + return false; + } + return true; + } virtual int priority() const = 0; virtual QString shortDescription() const = 0; virtual QString description() const = 0; @@ -40,5 +54,11 @@ class Session { virtual bool containsKeywords(const QList& keywords) const = 0; +protected: + virtual QString checkCanRunInternal() const = 0; + +private: + QString error; + }; #endif /*VMCHOOSER_SESSION_H_*/ diff --git a/src/vsession.cpp b/src/vsession.cpp index 41098b7..78185e4 100644 --- a/src/vsession.cpp +++ b/src/vsession.cpp @@ -19,6 +19,7 @@ #include "vsession.h" #include "sessionsiconholder.h" #include "userldapdata.h" +#include "virtualizer.h" static QProcess _process; @@ -216,8 +217,14 @@ bool VSession::isLocked() const { return getAttribute(QStringLiteral("locked")).compare(QStringLiteral("true")) == 0; } -bool VSession::isValid() const { - return !getAttribute(QStringLiteral("image_name")).isEmpty(); +QString VSession::checkCanRunInternal() const { + if (getAttribute(QStringLiteral("image_name")).isEmpty()) + return QObject::trUtf8("XML error: image_name is empty"); + const Virtualizer* virt = Virtualizer::get(virtualizer()); + if (!virt->isAvailable) + return QObject::trUtf8("Virtualizer '%1' is not enabled.").arg(virt->id); + // Seems OK + return QString(); } int VSession::priority() const { @@ -359,7 +366,7 @@ bool VSession::needsVtx() const { } QVariant VSession::foregroundRole() const { - if (!g_noVtx || !needsVtx()) + if ((!g_noVtx || !needsVtx()) && canRun()) return Session::foregroundRole(); return QColor(180, 180, 180); } diff --git a/src/vsession.h b/src/vsession.h index 609884e..fa3014d 100644 --- a/src/vsession.h +++ b/src/vsession.h @@ -14,7 +14,6 @@ class VSession : public Session { bool isActive() const; bool isLocked() const; - bool isValid() const; int priority() const; @@ -86,6 +85,9 @@ class VSession : public Session { static QList readXmlFile(const QString& filepath); +protected: + virtual QString checkCanRunInternal() const; + private: QList keywords_; diff --git a/src/xsession.cpp b/src/xsession.cpp index 8e26b86..d2e8cfe 100644 --- a/src/xsession.cpp +++ b/src/xsession.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "xsession.h" #include "globals.h" @@ -111,9 +112,17 @@ bool XSession::isActive() const { return true; } -bool XSession::isValid() const { - QFileInfo fi(this->exec_); - return !fi.isAbsolute() || (fi.isFile() && fi.isExecutable()); +QString XSession::checkCanRunInternal() const { + QString exe = this->exec_.left(this->exec_.indexOf(' ')); // -1 means entire string + QFileInfo fi(exe); + if (!fi.isAbsolute()) { + if (!QStandardPaths::findExecutable(exe).isEmpty()) + return QString(); + } + if (fi.isFile() && fi.isExecutable()) + return QString(); + // Not found + return QObject::trUtf8("Binary %1 not found.").arg(exe); } bool XSession::isLocked() const { diff --git a/src/xsession.h b/src/xsession.h index fcef5d4..e014e9e 100644 --- a/src/xsession.h +++ b/src/xsession.h @@ -17,7 +17,6 @@ class XSession : public Session { bool isActive() const; bool isLocked() const; - bool isValid() const; SectionType section() const { return SECTION_XSESSION; @@ -51,6 +50,9 @@ class XSession : public Session { bool containsKeywords(const QList& keywords) const; +protected: + QString checkCanRunInternal() const; + private: QString name_; QString exec_; -- cgit v1.2.3-55-g7522