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