diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..81cf0bb --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,34 @@ + + + +##### Expected Behavior + + + +##### Current Behavior + + + +##### Possible Solution + + + +##### Steps to Reproduce (for bugs) + + +1. +2. +3. +4. + +##### Context + + + +##### System Information + +* Distribution & Version: +* Kernel: +* Qt Version: +* cmake Version: +* Package version: diff --git a/CHANGELOG b/CHANGELOG index ae353a4..06c61f5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,70 @@ -libqtxdg-2.0.0 / 2016-09-17 +libqtxdg-3.0.0 / 2017-09-22 =========================== + * Backport support for Scale directory key according to Icon Theme spec + * Bump Major to 3 + * test: Drop Q_FOREACH + * Drop Q_FOREACH + * liblxqt make no sense here + * Copied issue template + * Drops Qt5Core_VERSION_STRING + * Avoid Qt special keywords collision + * XdgDesktopFile: Stops allocating unneeded QMap::keys() + * XdgDesktopFile: Stop allocating unneeded QHash:values() + * XdgDesktopFile: Improve const-ness + * xdgiconloader: Reworks the unthemed/pixmap search + * xdgiconloader: Puts the hicolor at the end of the theme hierarchy + * XdgIcon: Add flag for "FollowsColorScheme" processing + * xdgiconloader: Honor "FolowsColorScheme" theme hint + * xdgiconloader: Support symbolic SVG icons + * More fixes (#131) + * xdgiconloader: Correct hierarchy of fallbacks (#116) + * xdgiconloader: Fix XdgIconLoaderEngine::actualSize() (#130) + * Update CMakeLists.txt + * It adds loadIcon() timing measurements. + * xdgiconloader: Consider all existing files/images + * Check QTXDGX_ICONENGINEPLUGIN_INSTALL_PATH existence + * Mark QTXDGX_ICONENGINEPLUGIN_INSTALL_PATH as advanced + * xdgiconloader: Implement QIconEnginePlugin interface + * Disables uninstall target + * Remove last uses of Java-style (non-mutable) iterators from QtBase + * Adds a development qtxdg-iconfinder utility tool + * Enable strict iterators for debug builds + * Removes extra semi-colons + * Improve build warnings + * Bump year + * QtGui: eradicate Q_FOREACH loops [already const] + * Optimize QIconLoader::findIconHelper() + * Remove unused variable in QIconLoader::findIconHelper() + * Improve use of QHash to minimize double hashing + * QIconLoaderEngine: add missing Q_DECL_OVERRIDEs + * Replace QLatin1Literal with QLatin1String + * QIconCacheGtkReader: use QStringRef more + * Gui: use const (and const APIs) more + * Adds Link Time Optimization + * Replaces CMAKE_SOURCE_DIR by PROJECT_SOURCE_DIR + * Refactors superbuild support + * Remove duplicate use of source header files + * Use AUTOMOC everywhere + * Stop using include_directories() + * Removes test project definition + * Use CMAKE_INCLUDE_CURRENT_DIR + * Adds PROJECT_NAME to the build Qt version message + * Simplify target_compile_definitions() and target_include_directories() + * qiconloader: Reuse Qt implementation + * XdgIconLoader: Fix FTBFS in super-build/in-tree builds + * Allow xdg-user-dirs in the realpath of $HOME. On some systems /home is a symlink and $HOME points to the symlink. This commit allows the xdg-user-dirs to start with the real/canonical path. + * Updates version requirements in pkg-config (.pc) stuff + * Make Qt5Xdg use only the same version Qt5XdgIconLoader + * Adds minimum Qt version requirement (5.4.2) + * test: Fixes false positive in tst_xdgdesktopfile::testReadLocalized() + * Remove cpack (#106) + +2.0.0 / 2016-09-17 +================== + + * Release 2.0.0: Add changelog * Bump version to 2.0.0 * Extend README.md * Updates dependencies diff --git a/debian/changelog b/debian/changelog index 2d5ff51..b98220e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,16 @@ -libqtxdg (2.96.0-1) experimental; urgency=medium +libqtxdg (3.0.0-1) experimental; urgency=medium - * New snapshot: 2.0.0-58-gbc64037 + * Imported new upstream release: 3.0.0 * Switched to experimental * Renamed packages to reflect the new soname - * Bumped standards to 4.0.0, no changes needed + * Added dependency libqt5svg5-dev to QtXdgIconloader dev package. + * Bumped Standards to 4.1.0 + * Added override_dh_missing + * Added tools package + * Fixed symbols + * Reworked copyright - -- Alf Gaida Tue, 25 Jul 2017 00:42:08 +0200 + -- Alf Gaida Fri, 06 Oct 2017 23:02:29 +0200 libqtxdg (2.0.0-7) unstable; urgency=medium diff --git a/debian/control b/debian/control index 7a01260..a28ed84 100644 --- a/debian/control +++ b/debian/control @@ -13,7 +13,7 @@ Build-Depends: debhelper (>= 10), qtbase5-private-dev, qttools5-dev, qttools5-dev-tools -Standards-Version: 4.1.0 +Standards-Version: 4.1.1 Vcs-Browser: https://anonscm.debian.org/cgit/pkg-lxqt/libqtxdg.git/?h=debian/experimental Vcs-Git: https://anonscm.debian.org/git/pkg-lxqt/libqtxdg.git -b debian/experimental Homepage: https://github.com/lxde/libqtxdg @@ -64,6 +64,8 @@ Package: libqt5xdgiconloader-dev Architecture: any Section: libdevel Depends: ${shlibs:Depends}, + ${misc:Depends}, + libqt5svg5-dev, libqt5xdgiconloader3 (= ${binary:Version}) Description: Development files for libqtxdgiconloader This library implements the backend to load icons which are handled according @@ -79,4 +81,3 @@ Depends: ${shlibs:Depends}, libqt5xdgiconloader3 (= ${binary:Version}) Description: Development tools for libqtxdgiconloader This package provide some development tools for qtxdg. - diff --git a/debian/copyright b/debian/copyright index 90c911c..d485aef 100644 --- a/debian/copyright +++ b/debian/copyright @@ -3,22 +3,104 @@ Upstream-Name: libqtxdg Source: https://github.com/lxde/libqtxdg Files: * -Copyright: 2012-2016 LXQt team - 2010-2012 Razor team +Copyright: 2012-2016, LXQt team + 2010-2012, Razor team License: LGPL-2.1+ +Files: qtxdg/desktopenvironment_p.cpp + qtxdg/xdgdesktopfile_p.h + test/qtxdg_test.cpp + test/qtxdg_test.h + test/tst_xdgdirs.cpp + xdgiconloader/plugin/xdgiconengineplugin.cpp + xdgiconloader/plugin/xdgiconengineplugin.h +Copyright: 2013-2017, LXQt team +License: LGPL-2.1+ -Files: xdgiconloader/xdgiconloader_p.h - xdgiconloader/xdgiconloader.cpp -Copyright: 2014 Digia Plc and/or its subsidiary(-ies). -License: LGPL-2.1-or-3-with-Digia-1.1-exception +Files: qtxdg/xdgmacros.h + qtxdg/xdgmimetype.cpp + qtxdg/xdgmimetype.h + test/tst_xdgdesktopfile.cpp + test/tst_xdgdesktopfile.h + util/qtxdg-desktop-file-start.cpp + util/qtxdg-iconfinder.cpp +Copyright: 2014-2017, Luís Pereira +License: LGPL-2.1+ + +Files: cmake/create_pkgconfig_file.cmake + cmake/create_portable_headers.cmake +Copyright: 2015, Luís Pereira +License: BSD-3-clause + +Files: cmake/compiler_settings.cmake +Copyright: 2013, Hong Jen Yee (PCMan) + 2015, Luís Pereira +License: BSD-3-clause Files: debian/* -Copyright: 2014-2016 ChangZhuo Chen (陳昌倬) - 2013-2017 Alf Gaida - 2015 Andrew Lee (李健秋) +Copyright: 2013-2017, Alf Gaida + 2015, Andrew Lee (李健秋) + 2014-2016, ChangZhuo Chen (陳昌倬) License: LGPL-2.1+ +Files: qtxdg/xdgaction.cpp + qtxdg/xdgaction.h + qtxdg/xdgautostart.cpp + qtxdg/xdgautostart.h + qtxdg/xdgdesktopfile.cpp + qtxdg/xdgdesktopfile.h + qtxdg/xdgdirs.cpp + qtxdg/xdgdirs.h + qtxdg/xdgicon.cpp + qtxdg/xdgicon.h + qtxdg/xdgmenu.cpp + qtxdg/xdgmenu.h + qtxdg/xdgmenu_p.h + qtxdg/xdgmenuapplinkprocessor.cpp + qtxdg/xdgmenuapplinkprocessor.h + qtxdg/xdgmenulayoutprocessor.cpp + qtxdg/xdgmenulayoutprocessor.h + qtxdg/xdgmenureader.cpp + qtxdg/xdgmenureader.h + qtxdg/xdgmenurules.cpp + qtxdg/xdgmenurules.h + qtxdg/xdgmenuwidget.cpp + qtxdg/xdgmenuwidget.h + qtxdg/xmlhelper.cpp + qtxdg/xmlhelper.h +Copyright: 2010-2012, Razor team +License: LGPL-2.1+ + +Files: xdgiconloader/xdgiconloader.cpp + xdgiconloader/xdgiconloader_p.h +Copyright: 2014, Digia Plc and/or its subsidiary(-ies) +License: LGPL-2.1-or-3-with-Digia-1.1-exception + +License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + License: LGPL-2.1+ This program or library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/debian/libqt5xdg3.symbols b/debian/libqt5xdg3.symbols index 473ad97..cc607ee 100644 --- a/debian/libqt5xdg3.symbols +++ b/debian/libqt5xdg3.symbols @@ -94,11 +94,11 @@ libQt5Xdg.so.3 libqt5xdg3 #MINVER# (c++)"XdgIcon::defaultApplicationIcon()@Base" 1.0.0 (c++)"XdgIcon::defaultApplicationIconName()@Base" 1.0.0 - (c++)"XdgIcon::followColorScheme()@Base" 2.0.1~ + (c++)"XdgIcon::followColorScheme()@Base" 3.0.0 (c++)"XdgIcon::fromTheme(QString const&, QIcon const&)@Base" 1.0.0 (c++)"XdgIcon::fromTheme(QString const&, QString const&, QString const&, QString const&, QString const&)@Base" 1.0.0 (c++)"XdgIcon::fromTheme(QStringList const&, QIcon const&)@Base" 1.0.0 - (c++)"XdgIcon::setFollowColorScheme(bool)@Base" 2.0.1~ + (c++)"XdgIcon::setFollowColorScheme(bool)@Base" 3.0.0 (c++)"XdgIcon::~XdgIcon()@Base" 1.0.0 (c++)"XdgIcon::XdgIcon()@Base" 1.0.0 diff --git a/debian/libqt5xdgiconloader3.symbols b/debian/libqt5xdgiconloader3.symbols index 4759958..f42690c 100644 --- a/debian/libqt5xdgiconloader3.symbols +++ b/debian/libqt5xdgiconloader3.symbols @@ -6,7 +6,7 @@ libQt5XdgIconLoader.so.3 libqt5xdgiconloader3 #MINVER# (c++)"XdgIconLoaderEngine::actualSize(QSize const&, QIcon::Mode, QIcon::State)@Base" 2.0.0 (c++)"XdgIconLoaderEngine::clone() const@Base" 2.0.0 (c++)"XdgIconLoaderEngine::ensureLoaded()@Base" 2.0.0 - (c++)"XdgIconLoaderEngine::entryForSize(QSize const&)@Base" 2.0.0 + (c++)"XdgIconLoaderEngine::entryForSize(QSize const&, int)@Base" 3.0.0 (c++)"XdgIconLoaderEngine::hasIcon() const@Base" 2.0.0 (c++)"XdgIconLoaderEngine::key() const@Base" 2.0.0 (c++)"XdgIconLoaderEngine::paint(QPainter*, QRect const&, QIcon::Mode, QIcon::State)@Base" 2.0.0 @@ -18,8 +18,8 @@ libQt5XdgIconLoader.so.3 libqt5xdgiconloader3 #MINVER# (c++)"XdgIconLoaderEngine::XdgIconLoaderEngine(QString const&)@Base" 2.0.0 (c++)"XdgIconLoaderEngine::XdgIconLoaderEngine(XdgIconLoaderEngine const&)@Base" 2.0.0 - (c++)"XdgIconLoader::findIconHelper(QString const&, QString const&, QStringList&, bool) const@Base" 2.0.1~ + (c++)"XdgIconLoader::findIconHelper(QString const&, QString const&, QStringList&, bool) const@Base" 3.0.0 (c++)"XdgIconLoader::instance()@Base" 2.0.0 (c++)"XdgIconLoader::loadIcon(QString const&) const@Base" 2.0.0 - (c++)"XdgIconLoader::setFollowColorScheme(bool)@Base" 2.0.1~ - (c++)"XdgIconLoader::unthemedFallback(QString const&, QStringList const&) const@Base" 2.0.1~ + (c++)"XdgIconLoader::setFollowColorScheme(bool)@Base" 3.0.0 + (c++)"XdgIconLoader::unthemedFallback(QString const&, QStringList const&) const@Base" 3.0.0 diff --git a/qtxdg/xdgautostart.cpp b/qtxdg/xdgautostart.cpp index 55ca0de..1bceb40 100644 --- a/qtxdg/xdgautostart.cpp +++ b/qtxdg/xdgautostart.cpp @@ -57,14 +57,14 @@ XdgDesktopFileList XdgAutoStart::desktopFileList(QStringList dirs, bool excludeH QSet processed; XdgDesktopFileList ret; - Q_FOREACH (const QString &dirName, dirs) + for (const QString &dirName : const_cast(dirs)) { QDir dir(dirName); if (!dir.exists()) continue; const QFileInfoList files = dir.entryInfoList(QStringList(QLatin1String("*.desktop")), QDir::Files | QDir::Readable); - Q_FOREACH (const QFileInfo &fi, files) + for (const QFileInfo &fi : files) { if (processed.contains(fi.fileName())) continue; diff --git a/qtxdg/xdgdesktopfile.cpp b/qtxdg/xdgdesktopfile.cpp index b3d6c1b..d21e2df 100644 --- a/qtxdg/xdgdesktopfile.cpp +++ b/qtxdg/xdgdesktopfile.cpp @@ -409,9 +409,9 @@ bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const } bool nonDetach = false; - Q_FOREACH(const QString &s, nonDetachExecs) + for (const QString &s : nonDetachExecs) { - Q_FOREACH(const QString &a, args) + for (const QString &a : const_cast(args)) { if (a.contains(s)) { @@ -953,7 +953,7 @@ QString expandEnvVariables(const QString str) QStringList expandEnvVariables(const QStringList strs) { QStringList res; - Q_FOREACH(const QString &s, strs) + for (const QString &s : strs) res << expandEnvVariables(s); return res; @@ -969,9 +969,9 @@ QStringList XdgDesktopFile::expandExecString(const QStringList& urls) const QString execStr = value(execKey).toString(); unEscapeExec(execStr); - QStringList tokens = parseCombinedArgString(execStr); + const QStringList tokens = parseCombinedArgString(execStr); - Q_FOREACH (QString token, tokens) + for (QString token : tokens) { // The parseCombinedArgString() splits the string by the space symbols, // we temporarily replaced them on the special characters. @@ -1016,7 +1016,7 @@ QStringList XdgDesktopFile::expandExecString(const QStringList& urls) const // program. Local files may either be passed as file: URLs or as file path. if (token == QLatin1String("%U")) { - Q_FOREACH (const QString &s, urls) + for (const QString &s : urls) { QUrl url(expandEnvVariables(s)); result << ((!url.toLocalFile().isEmpty()) ? url.toLocalFile() : QString::fromUtf8(url.toEncoded())); @@ -1079,9 +1079,9 @@ bool checkTryExec(const QString& progName) if (progName.startsWith(QDir::separator())) return QFileInfo(progName).isExecutable(); - QStringList dirs = QFile::decodeName(qgetenv("PATH")).split(QLatin1Char(':')); + const QStringList dirs = QFile::decodeName(qgetenv("PATH")).split(QLatin1Char(':')); - Q_FOREACH (const QString &dir, dirs) + for (const QString &dir : dirs) { if (QFileInfo(QDir(dir), progName).isExecutable()) return true; @@ -1103,7 +1103,7 @@ QString XdgDesktopFile::id(const QString &fileName, bool checkFileExists) QString id = f.absoluteFilePath(); const QStringList dataDirs = XdgDirs::dataDirs(); - Q_FOREACH(const QString &d, dataDirs) { + for (const QString &d : dataDirs) { if (id.startsWith(d)) { // remove only the first occurence id.replace(id.indexOf(d), d.size(), QString()); @@ -1211,7 +1211,8 @@ bool XdgDesktopFile::isSuitable(bool excludeHidden, const QString &environment) QString expandDynamicUrl(QString url) { - Q_FOREACH(const QString &line, QProcess::systemEnvironment()) + const QStringList env = QProcess::systemEnvironment(); + for (const QString &line : env) { QString name = line.section(QLatin1Char('='), 0, 0); QString val = line.section(QLatin1Char('='), 1); @@ -1252,8 +1253,8 @@ QString findDesktopFile(const QString& dirName, const QString& desktopName) return fi.canonicalFilePath(); // Working recursively ............ - QFileInfoList dirs = dir.entryInfoList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot); - Q_FOREACH (const QFileInfo &d, dirs) + const QFileInfoList dirs = dir.entryInfoList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot); + for (const QFileInfo &d : dirs) { QString cn = d.canonicalFilePath(); if (dirName != cn) @@ -1273,7 +1274,7 @@ QString findDesktopFile(const QString& desktopName) QStringList dataDirs = XdgDirs::dataDirs(); dataDirs.prepend(XdgDirs::dataHome(false)); - Q_FOREACH (const QString &dirName, dataDirs) + for (const QString &dirName : const_cast(dataDirs)) { QString f = findDesktopFile(dirName + QLatin1String("/applications"), desktopName); if (!f.isEmpty()) @@ -1461,8 +1462,8 @@ void XdgDesktopFileCache::initialize(const QString& dirName) // Working recursively ............ - QFileInfoList files = dir.entryInfoList(QStringList(), QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); - Q_FOREACH (const QFileInfo &f, files) + const QFileInfoList files = dir.entryInfoList(QStringList(), QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); + for (const QFileInfo &f : files) { if (f.isDir()) { @@ -1480,9 +1481,9 @@ void XdgDesktopFileCache::initialize(const QString& dirName) m_fileCache.insert(f.absoluteFilePath(), df); } - QStringList mimes = df->value(mimeTypeKey).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); + const QStringList mimes = df->value(mimeTypeKey).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); - Q_FOREACH (const QString &mime, mimes) + for (const QString &mime : mimes) { int pref = df->value(initialPreferenceKey, 0).toInt(); // We move the desktopFile forward in the list for this mime, so that @@ -1523,7 +1524,7 @@ void loadMimeCacheDir(const QString& dirName, QHashvalue(mimeTypeKey).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); - Q_FOREACH (const QString &mime, mimes) + for (const QString &mime : mimes) { int pref = df->value(initialPreferenceKey, 0).toInt(); // We move the desktopFile forward in the list for this mime, so that @@ -1582,7 +1583,7 @@ void XdgDesktopFileCache::initialize() QStringList dataDirs = XdgDirs::dataDirs(); dataDirs.prepend(XdgDirs::dataHome(false)); - Q_FOREACH (const QString &dirname, dataDirs) + for (const QString &dirname : const_cast(dataDirs)) { initialize(dirname + QLatin1String("/applications")); // loadMimeCacheDir(dirname + "/applications", m_defaultAppsCache); @@ -1593,7 +1594,8 @@ QList XdgDesktopFileCache::getAppsOfCategory(const QString& cat { QList list; const QString _category = category.toUpper(); - Q_FOREACH (XdgDesktopFile *desktopFile, instance().m_fileCache) + const QHash fileCache = instance().m_fileCache; + for (XdgDesktopFile *desktopFile : fileCache) { QStringList categories = desktopFile->value(categoriesKey).toString().toUpper().split(QLatin1Char(';')); if (!categories.isEmpty() && (categories.contains(_category) || categories.contains(QLatin1String("X-") + _category))) @@ -1614,7 +1616,7 @@ XdgDesktopFile* XdgDesktopFileCache::getDefaultApp(const QString& mimetype) // /usr/share/applications/mimeapps.list (in that order) for a default. QStringList dataDirs = XdgDirs::dataDirs(); dataDirs.prepend(XdgDirs::dataHome(false)); - Q_FOREACH(const QString &dataDir, dataDirs) + for (const QString &dataDir : const_cast(dataDirs)) { QString defaultsListPath = dataDir + QLatin1String("/applications/mimeapps.list"); if (QFileInfo::exists(defaultsListPath)) @@ -1628,7 +1630,8 @@ XdgDesktopFile* XdgDesktopFileCache::getDefaultApp(const QString& mimetype) QVariant value = defaults.value(mimetype); if (value.canConvert()) // A single string can also convert to a stringlist { - Q_FOREACH (const QString &desktopFileName, value.toStringList()) + const QStringList values = value.toStringList(); + for (const QString &desktopFileName : values) { XdgDesktopFile* desktopFile = XdgDesktopFileCache::getFile(desktopFileName); if (desktopFile) diff --git a/qtxdg/xdgdirs.cpp b/qtxdg/xdgdirs.cpp index c1f3b34..bb6400d 100644 --- a/qtxdg/xdgdirs.cpp +++ b/qtxdg/xdgdirs.cpp @@ -336,7 +336,7 @@ QStringList XdgDirs::autostartDirs(const QString &postfix) { QStringList dirs; const QStringList s = configDirs(); - Q_FOREACH(const QString &dir, s) + for (const QString &dir : s) dirs << QString::fromLatin1("%1/autostart").arg(dir) + postfix; return dirs; diff --git a/qtxdg/xdgicon.cpp b/qtxdg/xdgicon.cpp index d10aba9..754e0d1 100644 --- a/qtxdg/xdgicon.cpp +++ b/qtxdg/xdgicon.cpp @@ -118,7 +118,7 @@ QIcon XdgIcon::fromTheme(const QString& iconName, const QIcon& fallback) ************************************************/ QIcon XdgIcon::fromTheme(const QStringList& iconNames, const QIcon& fallback) { - Q_FOREACH (const QString &iconName, iconNames) + for (const QString &iconName : iconNames) { QIcon icon = fromTheme(iconName); if (!icon.isNull()) diff --git a/qtxdg/xdgmenu.cpp b/qtxdg/xdgmenu.cpp index 6af58d4..d5f7efe 100644 --- a/qtxdg/xdgmenu.cpp +++ b/qtxdg/xdgmenu.cpp @@ -412,7 +412,7 @@ QDomElement XdgMenu::findMenu(QDomElement& baseElement, const QString& path, boo const QStringList names = path.split(QLatin1Char('/'), QString::SkipEmptyParts); QDomElement el = baseElement; - Q_FOREACH (const QString &name, names) + for (const QString &name : names) { QDomElement p = el; el = d->mXml.createElement(QLatin1String("Menu")); @@ -537,12 +537,12 @@ void XdgMenuPrivate::processDirectoryEntries(QDomElement& element, const QString dirs << parentDirs; bool found = false; - Q_FOREACH(const QString &file, files){ + for (const QString &file : const_cast(files)){ if (file.startsWith(QLatin1Char('/'))) found = loadDirectoryFile(file, element); else { - Q_FOREACH (const QString &dir, dirs) + for (const QString &dir : const_cast(dirs)) { found = loadDirectoryFile(dir + QLatin1Char('/') + file, element); if (found) break; @@ -651,7 +651,7 @@ QString XdgMenu::getMenuFileName(const QString& baseName) const QStringList configDirs = XdgDirs::configDirs(); QString menuPrefix = QString::fromLocal8Bit(qgetenv("XDG_MENU_PREFIX")); - Q_FOREACH(const QString &configDir, configDirs) + for (const QString &configDir : configDirs) { QFileInfo file(QString::fromLatin1("%1/menus/%2%3").arg(configDir, menuPrefix, baseName)); if (file.exists()) @@ -669,9 +669,9 @@ QString XdgMenu::getMenuFileName(const QString& baseName) wellKnownFiles << QLatin1String("gnome-applications.menu"); wellKnownFiles << QLatin1String("lxde-applications.menu"); - Q_FOREACH(const QString &configDir, configDirs) + for (const QString &configDir : configDirs) { - Q_FOREACH (const QString &f, wellKnownFiles) + for (const QString &f : const_cast(wellKnownFiles)) { QFileInfo file(QString::fromLatin1("%1/menus/%2").arg(configDir, f)); if (file.exists()) diff --git a/qtxdg/xdgmenuapplinkprocessor.cpp b/qtxdg/xdgmenuapplinkprocessor.cpp index 73353e1..7643861 100644 --- a/qtxdg/xdgmenuapplinkprocessor.cpp +++ b/qtxdg/xdgmenuapplinkprocessor.cpp @@ -90,7 +90,8 @@ void XdgMenuApplinkProcessor::step1() } // Process childs menus ............................... - Q_FOREACH (XdgMenuApplinkProcessor* child, mChilds) + + for (XdgMenuApplinkProcessor* child : const_cast&>(mChilds)) child->step1(); } @@ -100,7 +101,7 @@ void XdgMenuApplinkProcessor::step2() // Create AppLinks elements ........................... QDomDocument doc = mElement.ownerDocument(); - Q_FOREACH (XdgMenuAppFileInfo* fileInfo, mSelected) + for (XdgMenuAppFileInfo* fileInfo : const_cast&>(mSelected)) { if (mOnlyUnallocated && fileInfo->allocated()) continue; @@ -141,7 +142,7 @@ void XdgMenuApplinkProcessor::step2() // Process childs menus ............................... - Q_FOREACH (XdgMenuApplinkProcessor* child, mChilds) + for (XdgMenuApplinkProcessor* child : const_cast&>(mChilds)) child->step2(); } @@ -189,7 +190,7 @@ void XdgMenuApplinkProcessor::findDesktopFiles(const QString& dirName, const QSt mMenu->addWatchPath(dir.absolutePath()); const QFileInfoList files = dir.entryInfoList(QStringList(QLatin1String("*.desktop")), QDir::Files); - Q_FOREACH (const QFileInfo &file, files) + for (const QFileInfo &file : files) { XdgDesktopFile* f = XdgDesktopFileCache::getFile(file.canonicalFilePath()); if (f) @@ -199,7 +200,7 @@ void XdgMenuApplinkProcessor::findDesktopFiles(const QString& dirName, const QSt // Working recursively ............ const QFileInfoList dirs = dir.entryInfoList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot); - Q_FOREACH (const QFileInfo &d, dirs) + for (const QFileInfo &d : dirs) { QString dn = d.canonicalFilePath(); if (dn != dirName) @@ -242,7 +243,7 @@ bool XdgMenuApplinkProcessor::checkTryExec(const QString& progName) const QStringList dirs = QFile::decodeName(qgetenv("PATH")).split(QLatin1Char(':')); - Q_FOREACH (const QString &dir, dirs) + for (const QString &dir : dirs) { if (QFileInfo(QDir(dir), progName).isExecutable()) return true; diff --git a/qtxdg/xdgmenureader.cpp b/qtxdg/xdgmenureader.cpp index ef55a74..66f0dec 100644 --- a/qtxdg/xdgmenureader.cpp +++ b/qtxdg/xdgmenureader.cpp @@ -215,7 +215,7 @@ void XdgMenuReader::processMergeFileTag(QDomElement& element, QStringList* merge QString relativeName; QStringList configDirs = XdgDirs::configDirs(); - Q_FOREACH (const QString &configDir, configDirs) + for (const QString &configDir : const_cast(configDirs)) { if (mFileName.startsWith(configDir)) { @@ -236,7 +236,7 @@ void XdgMenuReader::processMergeFileTag(QDomElement& element, QStringList* merge if (relativeName.isEmpty()) return; - Q_FOREACH (const QString &configDir, configDirs) + for (const QString &configDir : configDirs) { if (QFileInfo::exists(configDir + relativeName)) { @@ -295,7 +295,7 @@ void XdgMenuReader::processDefaultMergeDirsTag(QDomElement& element, QStringList QStringList dirs = XdgDirs::configDirs(); dirs << XdgDirs::configHome(); - Q_FOREACH (const QString &dir, dirs) + for (const QString &dir : const_cast(dirs)) { mergeDir(QString::fromLatin1("%1/menus/%2-merged").arg(dir, menuBaseName), element, mergedFiles); } @@ -329,7 +329,7 @@ void XdgMenuReader::processDefaultAppDirsTag(QDomElement& element) QStringList dirs = XdgDirs::dataDirs(); dirs.prepend(XdgDirs::dataHome(false)); - Q_FOREACH (const QString &dir, dirs) + for (const QString &dir : const_cast (dirs)) { //qDebug() << "Add AppDir: " << dir + "/applications/"; addDirTag(element, QLatin1String("AppDir"), dir + QLatin1String("/applications/")); @@ -360,7 +360,7 @@ void XdgMenuReader::processDefaultDirectoryDirsTag(QDomElement& element) QStringList dirs = XdgDirs::dataDirs(); dirs.prepend(XdgDirs::dataHome(false)); - Q_FOREACH (const QString &dir, dirs) + for (const QString &dir : const_cast(dirs)) addDirTag(element, QLatin1String("DirectoryDir"), dir + QLatin1String("/desktop-directories/")); } @@ -379,8 +379,7 @@ void XdgMenuReader::addDirTag(QDomElement& previousElement, const QString& tagNa } } - -/************************************************ +/* If fileName is not an absolute path then the file to be merged should be located relative to the location of this menu file. ************************************************/ @@ -431,7 +430,7 @@ void XdgMenuReader::mergeDir(const QString& dirName, QDomElement& element, QStri QDir dir = QDir(dirInfo.canonicalFilePath()); const QFileInfoList files = dir.entryInfoList(QStringList() << QLatin1String("*.menu"), QDir::Files | QDir::Readable); - Q_FOREACH (const QFileInfo &file, files) + for (const QFileInfo &file : files) mergeFile(file.canonicalFilePath(), element, mergedFiles); } } diff --git a/qtxdg/xdgmimetype.cpp b/qtxdg/xdgmimetype.cpp index fa8d8d4..9c10597 100644 --- a/qtxdg/xdgmimetype.cpp +++ b/qtxdg/xdgmimetype.cpp @@ -96,7 +96,7 @@ QString XdgMimeType::iconName() const names.append(QMimeType::iconName()); names.append(QMimeType::genericIconName()); - Q_FOREACH (const QString &s, names) { + for (const QString &s : const_cast(names)) { if (!XdgIcon::fromTheme(s).isNull()) { dx->iconName = s; break; diff --git a/test/qtxdg_test.cpp b/test/qtxdg_test.cpp index f9232e8..52dd318 100644 --- a/test/qtxdg_test.cpp +++ b/test/qtxdg_test.cpp @@ -47,15 +47,17 @@ void QtXdgTest::testDefaultApp() { QStringList mimedirs = XdgDirs::dataDirs(); mimedirs.prepend(XdgDirs::dataHome(false)); - Q_FOREACH (QString mimedir, mimedirs) + for (const QString &mimedir : const_cast(mimedirs)) { QDir dir(mimedir + "/mime"); qDebug() << dir.path(); QStringList filters = (QStringList() << "*.xml"); - Q_FOREACH(QFileInfo mediaDir, dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) + const QFileInfoList &mediaDirs = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + for (const QFileInfo &mediaDir : mediaDirs) { qDebug() << " " << mediaDir.fileName(); - Q_FOREACH (QString mimeXmlFileName, QDir(mediaDir.absoluteFilePath()).entryList(filters, QDir::Files)) + const QStringList mimeXmlFileNames = QDir(mediaDir.absoluteFilePath()).entryList(filters, QDir::Files); + for (const QString &mimeXmlFileName : mimeXmlFileNames) { QString mimetype = mediaDir.fileName() + "/" + mimeXmlFileName.left(mimeXmlFileName.length() - 4); QString xdg_utils_default = xdgUtilDefaultApp(mimetype); diff --git a/xdgiconloader/xdgiconloader.cpp b/xdgiconloader/xdgiconloader.cpp index 68a0cc7..1f7dadb 100644 --- a/xdgiconloader/xdgiconloader.cpp +++ b/xdgiconloader/xdgiconloader.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -287,6 +288,11 @@ XdgIconTheme::XdgIconTheme(const QString &themeName) dirInfo.maxSize = indexReader.value(directoryKey + QLatin1String("/MaxSize"), size).toInt(); +#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) + dirInfo.scale = indexReader.value(directoryKey + + QLatin1String("/Scale"), + 1).toInt(); +#endif m_keyList.append(dirInfo); } } @@ -594,8 +600,12 @@ void XdgIconLoaderEngine::paint(QPainter *painter, const QRect &rect, * This algorithm is defined by the freedesktop spec: * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html */ -static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize) +static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize, int iconscale) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) + if (dir.scale != iconscale) + return false; +#endif if (dir.type == QIconDirInfo::Fixed) { return dir.size == iconsize; @@ -616,8 +626,29 @@ static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize) * This algorithm is defined by the freedesktop spec: * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html */ -static int directorySizeDistance(const QIconDirInfo &dir, int iconsize) +static int directorySizeDistance(const QIconDirInfo &dir, int iconsize, int iconscale) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) + const int scaledIconSize = iconsize * iconscale; + if (dir.type == QIconDirInfo::Fixed) { + return qAbs(dir.size * dir.scale - scaledIconSize); + + } else if (dir.type == QIconDirInfo::Scalable) { + if (scaledIconSize < dir.minSize * dir.scale) + return dir.minSize * dir.scale - scaledIconSize; + else if (scaledIconSize > dir.maxSize * dir.scale) + return scaledIconSize - dir.maxSize * dir.scale; + else + return 0; + + } else if (dir.type == QIconDirInfo::Threshold) { + if (scaledIconSize < (dir.size - dir.threshold) * dir.scale) + return dir.minSize * dir.scale - scaledIconSize; + else if (scaledIconSize > (dir.size + dir.threshold) * dir.scale) + return scaledIconSize - dir.maxSize * dir.scale; + else return 0; + } +#else if (dir.type == QIconDirInfo::Fixed) { return qAbs(dir.size - iconsize); @@ -636,12 +667,13 @@ static int directorySizeDistance(const QIconDirInfo &dir, int iconsize) return iconsize - dir.maxSize; else return 0; } +#endif Q_ASSERT(1); // Not a valid value return INT_MAX; } -QIconLoaderEngineEntry *XdgIconLoaderEngine::entryForSize(const QSize &size) +QIconLoaderEngineEntry *XdgIconLoaderEngine::entryForSize(const QSize &size, int scale) { int iconsize = qMin(size.width(), size.height()); @@ -653,7 +685,7 @@ QIconLoaderEngineEntry *XdgIconLoaderEngine::entryForSize(const QSize &size) // Search for exact matches first for (int i = 0; i < numEntries; ++i) { QIconLoaderEngineEntry *entry = m_info.entries.at(i); - if (directoryMatchesSize(entry->dir, iconsize)) { + if (directoryMatchesSize(entry->dir, iconsize, scale)) { return entry; } } @@ -663,7 +695,7 @@ QIconLoaderEngineEntry *XdgIconLoaderEngine::entryForSize(const QSize &size) QIconLoaderEngineEntry *closestMatch = 0; for (int i = 0; i < numEntries; ++i) { QIconLoaderEngineEntry *entry = m_info.entries.at(i); - int distance = directorySizeDistance(entry->dir, iconsize); + int distance = directorySizeDistance(entry->dir, iconsize, scale); if (distance < minimalSize) { minimalSize = distance; closestMatch = entry; @@ -716,6 +748,8 @@ QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State st basePixmap.load(filename); QSize actualSize = basePixmap.size(); + // If the size of the best match we have (basePixmap) is larger than the + // requested size, we downscale it to match. if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height())) actualSize.scale(size, Qt::KeepAspectRatio); @@ -879,6 +913,17 @@ void XdgIconLoaderEngine::virtual_hook(int id, void *data) *reinterpret_cast(data) = m_info.entries.isEmpty(); } break; +#endif +#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) + case QIconEngine::ScaledPixmapHook: + { + QIconEngine::ScaledPixmapArgument &arg = *reinterpret_cast(data); + // QIcon::pixmap() multiplies size by the device pixel ratio. + const int integerScale = qCeil(arg.scale); + QIconLoaderEngineEntry *entry = entryForSize(arg.size / integerScale, integerScale); + arg.pixmap = entry ? entry->pixmap(arg.size, arg.mode, arg.state) : QPixmap(); + } + break; #endif default: QIconEngine::virtual_hook(id, data); diff --git a/xdgiconloader/xdgiconloader_p.h b/xdgiconloader/xdgiconloader_p.h index f2e9960..713065c 100644 --- a/xdgiconloader/xdgiconloader_p.h +++ b/xdgiconloader/xdgiconloader_p.h @@ -86,7 +86,7 @@ private: bool hasIcon() const; void ensureLoaded(); void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; - QIconLoaderEngineEntry *entryForSize(const QSize &size); + QIconLoaderEngineEntry *entryForSize(const QSize &size, int scale = 1); XdgIconLoaderEngine(const XdgIconLoaderEngine &other); QThemeIconInfo m_info; QString m_iconName;