From 01ee02258797cef715e958ce6d32e7dee0b9831b Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Mon, 24 Jun 2019 15:26:58 +0200
Subject: Improve OS icon detection, add Win9x and Win 10
---
src/images.qrc | 4 ++-
src/img/bsd.png | Bin 7482 -> 0 bytes
src/img/freebsd.png | Bin 0 -> 7482 bytes
src/img/win10.png | Bin 0 -> 1421 bytes
src/img/win9x.png | Bin 0 -> 4110 bytes
src/vsession.cpp | 81 ++++++++++++++++++++++++++++++++++++----------------
6 files changed, 59 insertions(+), 26 deletions(-)
delete mode 100644 src/img/bsd.png
create mode 100644 src/img/freebsd.png
create mode 100644 src/img/win10.png
create mode 100644 src/img/win9x.png
diff --git a/src/images.qrc b/src/images.qrc
index 938fac5..dda48f1 100644
--- a/src/images.qrc
+++ b/src/images.qrc
@@ -8,7 +8,7 @@
img/gentoo.png
img/redhat.png
img/fedora.png
- img/bsd.png
+ img/freebsd.png
img/osx.png
img/macos.png
img/gnome.png
@@ -34,8 +34,10 @@
img/opensolaris.png
img/solaris.png
img/win311.png
+ img/win9x.png
img/win7.png
img/win8.png
+ img/win10.png
img/winxp.png
img/win2000.png
img/msdos.png
diff --git a/src/img/bsd.png b/src/img/bsd.png
deleted file mode 100644
index ac370ca..0000000
Binary files a/src/img/bsd.png and /dev/null differ
diff --git a/src/img/freebsd.png b/src/img/freebsd.png
new file mode 100644
index 0000000..ac370ca
Binary files /dev/null and b/src/img/freebsd.png differ
diff --git a/src/img/win10.png b/src/img/win10.png
new file mode 100644
index 0000000..3f61325
Binary files /dev/null and b/src/img/win10.png differ
diff --git a/src/img/win9x.png b/src/img/win9x.png
new file mode 100644
index 0000000..75f0a56
Binary files /dev/null and b/src/img/win9x.png differ
diff --git a/src/vsession.cpp b/src/vsession.cpp
index 92cc9c4..d5cc966 100644
--- a/src/vsession.cpp
+++ b/src/vsession.cpp
@@ -10,6 +10,8 @@
#include
#include
#include // available since Qt 4.7
+#include
+#include
#include // for getuid()
#include // for getuid(), getpwuid()
#include // for getpwuid()
@@ -20,6 +22,45 @@
static QProcess _process;
+struct IconMap {
+ QString icon;
+ QRegularExpression expr;
+ IconMap(const QString &icon, const QString ®exp)
+ : icon(icon), expr(regexp) {}
+};
+
+// It's first match wins, so put a check for windows95 before windows9
+static const QList iconMapping(
+{
+ IconMap("dos", "^(ms)?dos"),
+ IconMap("win311", "^win(dows)?3($|1)"),
+ IconMap("win9x", "^win(dows)?(95|98|me|nt)"),
+ IconMap("winxp", "^win(dows)?(xp|2003|2k3)"),
+ IconMap("win2000", "^win(dows)?(2000|2k)"), // After win2k3!
+ IconMap("win7", "^win(dows)?7"),
+ IconMap("win8", "^win(dows)?8"),
+ IconMap("win10", "^win(dows)?(9|10)"), // After win95!
+ IconMap("osx", "^darwin"),
+ IconMap("suse", "^opensuse"),
+});
+
+// These match via .startsWith and need to exist as a resource with this exact name
+static const QStringList directOsNames(
+{
+ "amiga", "atari",
+ "beos",
+ "debian",
+ "fedora", "freebsd",
+ "gentoo",
+ "macos",
+ "opensolaris", "os2", "osx",
+ "redhat", "riscos",
+ "solaris", "suse",
+ "ubuntu",
+});
+
+static const QRegularExpression cleanNameRegex("[^a-z0-9]");
+
bool VSession::init(const QDomElement& xml) {
QDomElement settingsNode = this->doc_.createElement("settings");
this->doc_.appendChild(settingsNode);
@@ -49,45 +90,35 @@ QIcon VSession::icon() const {
if (icon.startsWith("http://") || icon.startsWith("https://")) {
// try to load icon from url
QIcon url_icon(iconHolder->getIcon(QUrl(icon)));
- if (!url_icon.isNull()) {
+ if (!url_icon.isNull())
return url_icon;
- }
}
if (!icon.isEmpty()) {
+ // See if we have a resource with this name, or if it's an absolute path
QIcon res_icon(iconHolder->getIcon(icon));
- if (!res_icon.isNull()) {
+ if (!res_icon.isNull())
return res_icon;
- }
}
// Everything failed, try to guess the OS
QString os(getAttribute("os", "param").toLower());
+ os = os.replace(cleanNameRegex, QString());
if (!os.isEmpty()) {
- QIcon osi = iconHolder->getIcon(os);
- if (!osi.isNull())
- return osi;
- // These match vmware guestOS keywords mostly, extend for vbox...
- if (os == "dos")
- return iconHolder->getIcon("dos");
- if (os.startsWith("windows7"))
- return iconHolder->getIcon("win7");
- if (os.startsWith("win31"))
- return iconHolder->getIcon("win311");
- if (os.startsWith("windows8"))
- return iconHolder->getIcon("win8");
- if (os.startsWith("win2000"))
- return iconHolder->getIcon("win2000");
- if (os.startsWith("winxp"))
- return iconHolder->getIcon("winxp");
- if (os.startsWith("debian"))
- return iconHolder->getIcon("debian");
- if (os.startsWith("ubuntu"))
- return iconHolder->getIcon("ubuntu");
+ // Now try known good OS names via .startsWith()
+ for (const QString& str : directOsNames) {
+ if (os.startsWith(str))
+ return iconHolder->getIcon(str);
+ }
+ // Fuzzy matching via regex
+ for (const IconMap& map : iconMapping) {
+ if (map.expr.match(os).hasMatch())
+ return iconHolder->getIcon(map.icon);
+ }
+ // Running out of ideas...
if (os.startsWith("win"))
return iconHolder->getIcon("windows");
if (os.contains("linux"))
return iconHolder->getIcon("linux");
}
- // TODO: Maybe parse title of entry for an OS guess?
// Fallback to generic virtualizer icon
if (imgtype() == VMWARE)
return iconHolder->getIcon("vmware");
--
cgit v1.2.3-55-g7522