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/vsession.cpp | 81 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 25 deletions(-) (limited to 'src/vsession.cpp') 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