From c1a8fa1d8f5763de5b4ac1fe713c11087450bdb1 Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Sat, 9 Jul 2016 19:40:08 +0200 Subject: [PATCH 01/14] preparing new pre-release --- debian/.gitignore | 4 + debian/changelog | 18 +++ debian/control | 37 ++++- debian/copyright | 12 +- debian/docs | 1 + debian/libqt5xdg-dev.install | 10 +- debian/libqt5xdg1.install | 2 +- debian/libqt5xdg1.symbols | 208 +++++++++++-------------- debian/libqt5xdgiconloader-dev.install | 9 ++ debian/libqt5xdgiconloader1.install | 2 + debian/libqt5xdgiconloader1.symbols | 27 ++++ debian/rules | 2 +- 12 files changed, 200 insertions(+), 132 deletions(-) create mode 100644 debian/libqt5xdgiconloader-dev.install create mode 100644 debian/libqt5xdgiconloader1.install create mode 100644 debian/libqt5xdgiconloader1.symbols diff --git a/debian/.gitignore b/debian/.gitignore index 5908e9c..c3581ee 100644 --- a/debian/.gitignore +++ b/debian/.gitignore @@ -1,9 +1,13 @@ /*.debhelper /*.log /*.substvars +/debhelper-build-stamp /files + /libqt5xdg1/ /libqt5xdg1-dbg/ /libqt5xdg-dev/ +/libqt5xdgiconloader-dev/ +/libqt5xdgiconloader1/ /tmp diff --git a/debian/changelog b/debian/changelog index 193049f..c2eb939 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,21 @@ +libqtxdg (1.3.1~50-g4fde773-1) experimental; urgency=medium + + * New pre-release 1.3.1 + * Fixed libqt5xdgiconloader-dev.install + * Reworked descriptions in debian/control to prevent lintian whining + * Fixed symbols version + * Fixed copyright for xdgiconloader + * Fixed package descrioptions + * Introduced the new package libqt5xdgiconloader1 + * Bumped standards to 3.9.8, no changes needed + * Symbols sorted and unified + * Added missed Symbol + * Bump years in copyright + * Added hardening=+all + * Added README.md to debian/docs + + -- Alf Gaida Sat, 09 Jul 2016 19:39:42 +0200 + libqtxdg (1.3.0-3) unstable; urgency=medium * Remove dbg package in favor of dbgsym. diff --git a/debian/control b/debian/control index 595b4bd..6518f16 100644 --- a/debian/control +++ b/debian/control @@ -12,9 +12,9 @@ Build-Depends: cmake (>= 3.0.2), qtbase5-private-dev, qttools5-dev, qttools5-dev-tools -Standards-Version: 3.9.6 -Vcs-Browser: http://anonscm.debian.org/cgit/pkg-lxqt/libqtxdg.git/?h=debian/sid -Vcs-Git: git://anonscm.debian.org/pkg-lxqt/libqtxdg.git -b debian/sid +Standards-Version: 3.9.8 +Vcs-Browser: https://anonscm.debian.org/git/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 Package: libqt5xdg1 @@ -24,19 +24,44 @@ Depends: ${shlibs:Depends}, ${misc:Depends} Pre-Depends: ${misc:Pre-Depends} Provides: libqt5xdg -Description: Implementation of the XDG Specifications for Qt, libs +Description: Implementation of the XDG Specifications for Qt (shared lib) This library implements functions of the XDG Specifications in Qt. It is part of LXQt. . This package provides the shared library. +Package: libqt5xdgiconloader1 +Architecture: any +Multi-Arch: same +Depends: ${shlibs:Depends}, + ${misc:Depends} +Pre-Depends: ${misc:Pre-Depends} +Provides: libqt5xdgiconloader +Description: Implementation of the XDG Iconloader for Qt (shared lib) + This library implements the backend to load icons which are handled according + to the XDG Icon Theme Specification in Qt. It is part of LXQt. + . + This package provides the shared library. + Package: libqt5xdg-dev Architecture: any Section: libdevel Depends: ${misc:Depends}, - libqt5xdg1 (= ${binary:Version}) + libqt5xdg1 (= ${binary:Version}), + libqt5xdgiconloader-dev (= ${binary:Version}) Description: Development files for libqtxdg - This library implements functions of the XDG Specifications in Qt. It is part + This library implements functions of the XDG Specifications in Qt. It is part of LXQt. . This package provides development files. + +Package: libqt5xdgiconloader-dev +Architecture: any +Section: libdevel +Depends: ${misc:Depends}, + libqt5xdgiconloader1 (= ${binary:Version}) +Description: Development files for libqtxdgiconloader + This library implements the backend to load icons which are handled according + to the XDG Icon Theme Specification in Qt. It is part of LXQt. + . + This package provides development files. diff --git a/debian/copyright b/debian/copyright index ec3ee77..afb3712 100644 --- a/debian/copyright +++ b/debian/copyright @@ -3,17 +3,19 @@ Upstream-Name: libqtxdg Source: https://github.com/lxde/libqtxdg Files: * -Copyright: 2012-2015 LXQt team +Copyright: 2012-2016 LXQt team 2010-2012 Razor team License: LGPL-2.1+ -Files: qiconfix/qiconloader_p.h qiconfix/qiconloader.cpp -Copyright: 2013 Digia Plc and/or its subsidiary(-ies) + +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: debian/* -Copyright: 2014-2015 ChangZhuo Chen (陳昌倬) - 2013-2015 Alf Gaida +Copyright: 2014-2016 ChangZhuo Chen (陳昌倬) + 2013-2016 Alf Gaida 2015 Andrew Lee (李健秋) License: LGPL-2.1+ diff --git a/debian/docs b/debian/docs index 62deb04..0b6e0f3 100644 --- a/debian/docs +++ b/debian/docs @@ -1 +1,2 @@ AUTHORS +README.md diff --git a/debian/libqt5xdg-dev.install b/debian/libqt5xdg-dev.install index c7c4df5..7f95fb6 100644 --- a/debian/libqt5xdg-dev.install +++ b/debian/libqt5xdg-dev.install @@ -1,4 +1,6 @@ -usr/include/* -usr/lib/*/lib*.so -usr/lib/*/pkgconfig/* -usr/share/cmake/* +usr/include/qt5xdg + +usr/lib/*/libQt5Xdg.so +usr/lib/*/pkgconfig/Qt5Xdg.pc + +usr/share/cmake/qt5xdg/ diff --git a/debian/libqt5xdg1.install b/debian/libqt5xdg1.install index 3ddde58..9516091 100644 --- a/debian/libqt5xdg1.install +++ b/debian/libqt5xdg1.install @@ -1 +1 @@ -usr/lib/*/lib*.so.* +usr/lib/*/libQt5Xdg.so.* diff --git a/debian/libqt5xdg1.symbols b/debian/libqt5xdg1.symbols index ee3c47c..64d3af5 100644 --- a/debian/libqt5xdg1.symbols +++ b/debian/libqt5xdg1.symbols @@ -1,157 +1,135 @@ libQt5Xdg.so.1 libqt5xdg1 #MINVER# - (c++)"XdgMimeType::XdgMimeType(QMimeType const&)@Base" 1.0.0 - (c++)"XdgMimeType::XdgMimeType(XdgMimeType const&)@Base" 1.0.0 - (c++)"XdgMimeType::XdgMimeType()@Base" 1.0.0 - (c++)"XdgMimeType::XdgMimeType(QMimeType const&)@Base" 1.0.0 - (c++)"XdgMimeType::XdgMimeType(XdgMimeType const&)@Base" 1.0.0 - (c++)"XdgMimeType::XdgMimeType()@Base" 1.0.0 - (c++)"XdgMimeType::~XdgMimeType()@Base" 1.0.0 - (c++)"XdgMimeType::operator=(XdgMimeType const&)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(QObject*)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(QString const&, QObject*)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(XdgAction const&, QObject*)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(XdgDesktopFile const&, QObject*)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(XdgDesktopFile const*, QObject*)@Base" 1.0.0 + (c++)"XdgAction::isValid() const@Base" 1.0.0 + (c++)"XdgAction::load(XdgDesktopFile const&)@Base" 1.0.0 + (c++)"XdgAction::metaObject() const@Base" 1.0.0 + (c++)"XdgAction::operator=(XdgAction const&)@Base" 1.0.0 + (c++)"XdgAction::qt_metacall(QMetaObject::Call, int, void**)@Base" 1.0.0 + (c++)"XdgAction::qt_metacast(char const*)@Base" 1.0.0 + (c++)"XdgAction::runConmmand() const@Base" 1.0.0 + (c++)"XdgAction::staticMetaObject@Base" 1.0.0 + (c++)"XdgAction::updateIcon()@Base" 1.0.0 + (c++)"XdgAction::~XdgAction()@Base" 1.0.0 (c++)"XdgAutoStart::desktopFileList(QStringList, bool)@Base" 1.0.0 (c++)"XdgAutoStart::desktopFileList(bool)@Base" 1.0.0 (c++)"XdgAutoStart::localPath(XdgDesktopFile const&)@Base" 1.0.0 - (c++)"XdgMenuWidget::qt_metacall(QMetaObject::Call, int, void**)@Base" 1.0.0 - (c++)"XdgMenuWidget::qt_metacast(char const*)@Base" 1.0.0 - (c++)"XdgMenuWidget::staticMetaObject@Base" 1.0.0 - (c++)"XdgMenuWidget::event(QEvent*)@Base" 1.0.0 - (c++)"XdgMenuWidget::XdgMenuWidget(QDomElement const&, QWidget*)@Base" 1.0.0 - (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenu const&, QString const&, QWidget*)@Base" 1.0.0 - (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenuWidget const&, QWidget*)@Base" 1.0.0 - (c++)"XdgMenuWidget::XdgMenuWidget(QDomElement const&, QWidget*)@Base" 1.0.0 - (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenu const&, QString const&, QWidget*)@Base" 1.0.0 - (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenuWidget const&, QWidget*)@Base" 1.0.0 - (c++)"XdgMenuWidget::~XdgMenuWidget()@Base" 1.0.0 - (c++)"XdgMenuWidget::operator=(XdgMenuWidget const&)@Base" 1.0.0 + (c++)"XdgDesktopFile::XdgDesktopFile()@Base" 1.0.0 + (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile const&)@Base" 1.0.0 + (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile::Type, QString const&, QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFile::categories() const@Base" 1.2.0 + (c++)"XdgDesktopFile::contains(QString const&) const@Base" 1.0.0 + (c++)"XdgDesktopFile::expandExecString(QStringList const&) const@Base" 1.0.0 + (c++)"XdgDesktopFile::fileName() const@Base" 1.0.0 + (c++)"XdgDesktopFile::icon(QIcon const&) const@Base" 1.0.0 + (c++)"XdgDesktopFile::iconName() const@Base" 1.0.0 + (c++)"XdgDesktopFile::id(QString const&, bool)@Base" 1.3.1~ + (c++)"XdgDesktopFile::isShown(QString const&) const@Base" 1.0.0 + (c++)"XdgDesktopFile::isSuitable(bool, QString const&) const@Base" 1.0.0 + (c++)"XdgDesktopFile::isValid() const@Base" 1.0.0 + (c++)"XdgDesktopFile::load(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFile::localizedKey(QString const&) const@Base" 1.0.0 + (c++)"XdgDesktopFile::localizedValue(QString const&, QVariant const&) const@Base" 1.0.0 + (c++)"XdgDesktopFile::mimeTypes() const@Base" 1.3.0 + (c++)"XdgDesktopFile::operator=(XdgDesktopFile const&)@Base" 1.0.0 + (c++)"XdgDesktopFile::operator==(XdgDesktopFile const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::removeEntry(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFile::save(QIODevice*) const@Base" 1.0.0 + (c++)"XdgDesktopFile::save(QString const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::setLocalizedValue(QString const&, QVariant const&)@Base" 1.0.0 - (c++)"XdgDesktopFile::load(QString const&)@Base" 1.0.0 (c++)"XdgDesktopFile::setValue(QString const&, QVariant const&)@Base" 1.0.0 - (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile::Type, QString const&, QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile const&)@Base" 1.0.0 - (c++)"XdgDesktopFile::XdgDesktopFile()@Base" 1.0.0 - (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile::Type, QString const&, QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile const&)@Base" 1.0.0 - (c++)"XdgDesktopFile::XdgDesktopFile()@Base" 1.0.0 + (c++)"XdgDesktopFile::startDetached(QString const&) const@Base" 1.0.0 + (c++)"XdgDesktopFile::startDetached(QStringList const&) const@Base" 1.0.0 + (c++)"XdgDesktopFile::type() const@Base" 1.0.0 + (c++)"XdgDesktopFile::url() const@Base" 1.0.0 + (c++)"XdgDesktopFile::value(QString const&, QVariant const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::~XdgDesktopFile()@Base" 1.0.0 - (c++)"XdgDesktopFile::operator=(XdgDesktopFile const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::initialize(QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::initialize()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::getAllFiles()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::getDefaultApp(QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::getAppsOfCategory(QString const&)@Base" 1.2.0 + (c++)"XdgDesktopFileCache::XdgDesktopFileCache()@Base" 1.0.0 (c++)"XdgDesktopFileCache::desktopFileSettingsFormat()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::load(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::getAllFiles()@Base" 1.0.0 (c++)"XdgDesktopFileCache::getApps(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::getAppsOfCategory(QString const&)@Base" 1.2.0 + (c++)"XdgDesktopFileCache::getDefaultApp(QString const&)@Base" 1.0.0 (c++)"XdgDesktopFileCache::getFile(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::initialize()@Base" 1.0.0 + (c++)"XdgDesktopFileCache::initialize(QString const&)@Base" 1.0.0 (c++)"XdgDesktopFileCache::instance()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::XdgDesktopFileCache()@Base" 1.0.0 + (c++)"XdgDesktopFileCache::load(QString const&)@Base" 1.0.0 (c++)"XdgDesktopFileCache::~XdgDesktopFileCache()@Base" 1.0.0 - (c++)"QtXdg::QIconLoader::setThemeName(QString const&)@Base" 1.0.0 - (c++)"QtXdg::QIconLoader::ensureInitialized()@Base" 1.0.0 - (c++)"QtXdg::QIconLoader::updateSystemTheme()@Base" 1.0.0 - (c++)"QtXdg::QIconLoader::setThemeSearchPath(QStringList const&)@Base" 1.0.0 - (c++)"QtXdg::QIconLoader::instance()@Base" 1.0.0 - (c++)"QtXdg::QIconLoader::QIconLoader()@Base" 1.0.0 + (c++)"XdgDirs::autostartDirs(QString const&)@Base" 1.0.0 + (c++)"XdgDirs::autostartHome(bool)@Base" 1.0.0 + (c++)"XdgDirs::cacheHome(bool)@Base" 1.0.0 (c++)"XdgDirs::configDirs(QString const&)@Base" 1.0.0 (c++)"XdgDirs::configHome(bool)@Base" 1.0.0 + (c++)"XdgDirs::dataDirs(QString const&)@Base" 1.0.0 + (c++)"XdgDirs::dataHome(bool)@Base" 1.0.0 (c++)"XdgDirs::runtimeDir()@Base" 1.0.0 (c++)"XdgDirs::setUserDir(XdgDirs::UserDirectory, QString const&, bool)@Base" 1.0.0 - (c++)"XdgDirs::autostartDirs(QString const&)@Base" 1.0.0 - (c++)"XdgDirs::autostartHome(bool)@Base" 1.0.0 (c++)"XdgDirs::userDir(XdgDirs::UserDirectory)@Base" 1.0.0 - (c++)"XdgDirs::dataDirs(QString const&)@Base" 1.0.0 - (c++)"XdgDirs::dataHome(bool)@Base" 1.0.0 - (c++)"XdgDirs::cacheHome(bool)@Base" 1.0.0 - (c++)"XdgIcon::setThemeName(QString const&)@Base" 1.0.0 + (c++)"XdgDirs::userDirDefault(XdgDirs::UserDirectory)@Base" 1.3.0 + (c++)"XdgIcon::XdgIcon()@Base" 1.0.0 (c++)"XdgIcon::defaultApplicationIcon()@Base" 1.0.0 (c++)"XdgIcon::defaultApplicationIconName()@Base" 1.0.0 - (c++)"XdgIcon::fromTheme(QStringList const&, QIcon const&)@Base" 1.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::setThemeName(QString const&)@Base" 1.0.0 (c++)"XdgIcon::themeName()@Base" 1.0.0 - (c++)"XdgIcon::XdgIcon()@Base" 1.0.0 (c++)"XdgIcon::~XdgIcon()@Base" 1.0.0 - (c++)"XdgMenu::qt_metacall(QMetaObject::Call, int, void**)@Base" 1.0.0 - (c++)"XdgMenu::qt_metacast(char const*)@Base" 1.0.0 + (c++)"XdgMenu::XdgMenu(QObject*)@Base" 1.0.0 (c++)"XdgMenu::addWatchPath(QString const&)@Base" 1.0.0 + (c++)"XdgMenu::changed()@Base" 1.0.0 (c++)"XdgMenu::environments()@Base" 1.0.0 + (c++)"XdgMenu::errorString() const@Base" 1.0.0 + (c++)"XdgMenu::findMenu(QDomElement&, QString const&, bool)@Base" 1.0.0 (c++)"XdgMenu::getMenuFileName(QString const&)@Base" 1.0.0 - (c++)"XdgMenu::setEnvironments(QStringList const&)@Base" 1.0.0 - (c++)"XdgMenu::setEnvironments(QString const&)@Base" 1.0.0 - (c++)"XdgMenu::staticMetaObject@Base" 1.0.0 + (c++)"XdgMenu::isOutDated() const@Base" 1.0.0 + (c++)"XdgMenu::logDir() const@Base" 1.0.0 + (c++)"XdgMenu::menuFileName() const@Base" 1.0.0 + (c++)"XdgMenu::metaObject() const@Base" 1.0.0 + (c++)"XdgMenu::qt_metacall(QMetaObject::Call, int, void**)@Base" 1.0.0 + (c++)"XdgMenu::qt_metacast(char const*)@Base" 1.0.0 (c++)"XdgMenu::read(QString const&)@Base" 1.0.0 (c++)"XdgMenu::save(QString const&)@Base" 1.0.0 - (c++)"XdgMenu::changed()@Base" 1.0.0 - (c++)"XdgMenu::findMenu(QDomElement&, QString const&, bool)@Base" 1.0.0 + (c++)"XdgMenu::setEnvironments(QString const&)@Base" 1.0.0 + (c++)"XdgMenu::setEnvironments(QStringList const&)@Base" 1.0.0 (c++)"XdgMenu::setLogDir(QString const&)@Base" 1.0.0 - (c++)"XdgMenu::XdgMenu(QObject*)@Base" 1.0.0 + (c++)"XdgMenu::staticMetaObject@Base" 1.0.0 + (c++)"XdgMenu::xml() const@Base" 1.0.0 (c++)"XdgMenu::~XdgMenu()@Base" 1.0.0 - (c++)"XdgAction::updateIcon()@Base" 1.0.0 - (c++)"XdgAction::qt_metacall(QMetaObject::Call, int, void**)@Base" 1.0.0 - (c++)"XdgAction::qt_metacast(char const*)@Base" 1.0.0 - (c++)"XdgAction::staticMetaObject@Base" 1.0.0 - (c++)"XdgAction::load(XdgDesktopFile const&)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(XdgDesktopFile const*, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(XdgDesktopFile const&, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(QString const&, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(XdgAction const&, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(XdgDesktopFile const*, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(XdgDesktopFile const&, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(QString const&, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(XdgAction const&, QObject*)@Base" 1.0.0 - (c++)"XdgAction::~XdgAction()@Base" 1.0.0 - (c++)"XdgAction::operator=(XdgAction const&)@Base" 1.0.0 + (c++)"XdgMenuWidget::XdgMenuWidget(QDomElement const&, QWidget*)@Base" 1.0.0 + (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenu const&, QString const&, QWidget*)@Base" 1.0.0 + (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenuWidget const&, QWidget*)@Base" 1.0.0 + (c++)"XdgMenuWidget::event(QEvent*)@Base" 1.0.0 + (c++)"XdgMenuWidget::metaObject() const@Base" 1.0.0 + (c++)"XdgMenuWidget::operator=(XdgMenuWidget const&)@Base" 1.0.0 + (c++)"XdgMenuWidget::qt_metacall(QMetaObject::Call, int, void**)@Base" 1.0.0 + (c++)"XdgMenuWidget::qt_metacast(char const*)@Base" 1.0.0 + (c++)"XdgMenuWidget::staticMetaObject@Base" 1.0.0 + (c++)"XdgMenuWidget::~XdgMenuWidget()@Base" 1.0.0 + (c++)"XdgMimeType::XdgMimeType()@Base" 1.0.0 + (c++)"XdgMimeType::XdgMimeType(QMimeType const&)@Base" 1.0.0 + (c++)"XdgMimeType::XdgMimeType(XdgMimeType const&)@Base" 1.0.0 (c++)"XdgMimeType::icon() const@Base" 1.0.0 (c++)"XdgMimeType::iconName() const@Base" 1.0.0 - (c++)"XdgMenuWidget::metaObject() const@Base" 1.0.0 - (c++)"XdgDesktopFile::categories() const@Base" 1.2.0 - (c++)"XdgDesktopFile::isSuitable(bool, QString const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::isApplicable(bool, QString const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::localizedKey(QString const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::startDetached(QStringList const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::startDetached(QString const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::localizedValue(QString const&, QVariant const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::expandExecString(QStringList const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::url() const@Base" 1.0.0 - (c++)"XdgDesktopFile::icon(QIcon const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::save(QIODevice*) const@Base" 1.0.0 - (c++)"XdgDesktopFile::save(QString const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::type() const@Base" 1.0.0 - (c++)"XdgDesktopFile::value(QString const&, QVariant const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::isShow(QString const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::isShown(QString const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::isValid() const@Base" 1.0.0 - (c++)"XdgDesktopFile::contains(QString const&) const@Base" 1.0.0 - (c++)"XdgDesktopFile::fileName() const@Base" 1.0.0 - (c++)"XdgDesktopFile::iconName() const@Base" 1.0.0 - (c++)"XdgDesktopFile::operator==(XdgDesktopFile const&) const@Base" 1.0.0 - (c++)"QtXdg::QIconLoader::findIconHelper(QString const&, QString const&, QStringList&) const@Base" 1.0.0 - (c++)"QtXdg::QIconLoader::themeSearchPaths() const@Base" 1.0.0 - (c++)"QtXdg::QIconLoader::loadIcon(QString const&) const@Base" 1.0.0 - (c++)"XdgMenu::isOutDated() const@Base" 1.0.0 - (c++)"XdgMenu::metaObject() const@Base" 1.0.0 - (c++)"XdgMenu::errorString() const@Base" 1.0.0 - (c++)"XdgMenu::menuFileName() const@Base" 1.0.0 - (c++)"XdgMenu::xml() const@Base" 1.0.0 - (c++)"XdgMenu::logDir() const@Base" 1.0.0 - (c++)"XdgAction::metaObject() const@Base" 1.0.0 - (c++)"XdgAction::runConmmand() const@Base" 1.0.0 - (c++)"XdgAction::isValid() const@Base" 1.0.0 - (c++)"typeinfo for XdgMenuWidget@Base" 1.0.0 + (c++)"XdgMimeType::operator=(XdgMimeType const&)@Base" 1.0.0 + (c++)"XdgMimeType::~XdgMimeType()@Base" 1.0.0 + (c++)"non-virtual thunk to XdgMenuWidget::~XdgMenuWidget()@Base" 1.0.0 + (c++)"typeinfo for XdgAction@Base" 1.0.0 (c++)"typeinfo for XdgDesktopFile@Base" 1.0.0 (c++)"typeinfo for XdgIcon@Base" 1.0.0 (c++)"typeinfo for XdgMenu@Base" 1.0.0 - (c++)"typeinfo for XdgAction@Base" 1.0.0 - (c++)"typeinfo name for XdgMenuWidget@Base" 1.0.0 + (c++)"typeinfo for XdgMenuWidget@Base" 1.0.0 + (c++)"typeinfo name for XdgAction@Base" 1.0.0 (c++)"typeinfo name for XdgDesktopFile@Base" 1.0.0 (c++)"typeinfo name for XdgIcon@Base" 1.0.0 (c++)"typeinfo name for XdgMenu@Base" 1.0.0 - (c++)"typeinfo name for XdgAction@Base" 1.0.0 - (c++)"vtable for XdgMenuWidget@Base" 1.0.0 + (c++)"typeinfo name for XdgMenuWidget@Base" 1.0.0 + (c++)"vtable for XdgAction@Base" 1.0.0 (c++)"vtable for XdgDesktopFile@Base" 1.0.0 (c++)"vtable for XdgIcon@Base" 1.0.0 (c++)"vtable for XdgMenu@Base" 1.0.0 - (c++)"vtable for XdgAction@Base" 1.0.0 - (c++)"non-virtual thunk to XdgMenuWidget::~XdgMenuWidget()@Base" 1.0.0 + (c++)"vtable for XdgMenuWidget@Base" 1.0.0 diff --git a/debian/libqt5xdgiconloader-dev.install b/debian/libqt5xdgiconloader-dev.install new file mode 100644 index 0000000..bed378c --- /dev/null +++ b/debian/libqt5xdgiconloader-dev.install @@ -0,0 +1,9 @@ +usr/include/qt5xdgiconloader + +usr/lib/*/libQt5XdgIconLoader.so +usr/lib/*/pkgconfig/Qt5XdgIconLoader.pc + +usr/share/cmake/qt5xdgiconloader/qt5xdgiconloader-config-version.cmake +usr/share/cmake/qt5xdgiconloader/qt5xdgiconloader-config.cmake +usr/share/cmake/qt5xdgiconloader/qt5xdgiconloader-targets.cmake +usr/share/cmake/qt5xdgiconloader/qt5xdgiconloader-targets-none.cmake diff --git a/debian/libqt5xdgiconloader1.install b/debian/libqt5xdgiconloader1.install new file mode 100644 index 0000000..11fd40c --- /dev/null +++ b/debian/libqt5xdgiconloader1.install @@ -0,0 +1,2 @@ +usr/lib/*/libQt5XdgIconLoader.so.* + diff --git a/debian/libqt5xdgiconloader1.symbols b/debian/libqt5xdgiconloader1.symbols new file mode 100644 index 0000000..5e671ad --- /dev/null +++ b/debian/libqt5xdgiconloader1.symbols @@ -0,0 +1,27 @@ +libQt5XdgIconLoader.so.1 libqt5xdgiconloader1 #MINVER# + (c++)"XdgIconLoader::XdgIconLoader()@Base" 1.3.1~ + (c++)"XdgIconLoader::ensureInitialized()@Base" 1.3.1~ + (c++)"XdgIconLoader::findIconHelper(QString const&, QString const&, QStringList&) const@Base" 1.3.1~ + (c++)"XdgIconLoader::instance()@Base" 1.3.1~ + (c++)"XdgIconLoader::loadIcon(QString const&) const@Base" 1.3.1~ + (c++)"XdgIconLoader::setThemeName(QString const&)@Base" 1.3.1~ + (c++)"XdgIconLoader::setThemeSearchPath(QStringList const&)@Base" 1.3.1~ + (c++)"XdgIconLoader::themeSearchPaths() const@Base" 1.3.1~ + (c++)"XdgIconLoader::updateSystemTheme()@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::XdgIconLoaderEngine(QString const&)@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::XdgIconLoaderEngine(XdgIconLoaderEngine const&)@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::actualSize(QSize const&, QIcon::Mode, QIcon::State)@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::clone() const@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::ensureLoaded()@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::entryForSize(QSize const&)@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::hasIcon() const@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::key() const@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::paint(QPainter*, QRect const&, QIcon::Mode, QIcon::State)@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::pixmap(QSize const&, QIcon::Mode, QIcon::State)@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::read(QDataStream&)@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::virtual_hook(int, void*)@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::write(QDataStream&) const@Base" 1.3.1~ + (c++)"XdgIconLoaderEngine::~XdgIconLoaderEngine()@Base" 1.3.1~ + (c++)"typeinfo for XdgIconLoaderEngine@Base" 1.3.1~ + (c++)"typeinfo name for XdgIconLoaderEngine@Base" 1.3.1~ + (c++)"vtable for XdgIconLoaderEngine@Base" 1.3.1~ diff --git a/debian/rules b/debian/rules index 9b24d4d..367cf7b 100755 --- a/debian/rules +++ b/debian/rules @@ -2,7 +2,7 @@ #export DH_VERBOSE = 1 export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed - +export DEB_BUILD_MAINT_OPTIONS = hardening=+all %: dh ${@} --buildsystem cmake \ From ea1929614702d4c782fb61fd83ba1f9f2014908d Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Sat, 9 Jul 2016 20:16:47 +0200 Subject: [PATCH 02/14] New pre-release 1.3.1~50-g4fde773 Fixed libqt5xdgiconloader-dev.install Reworked descriptions in debian/control to prevent lintian whining Fixed symbols version Fixed copyright for xdgiconloader Fixed package descrioptions Introduced the new package libqt5xdgiconloader1 Bumped standards to 3.9.8, no changes needed Symbols sorted and unified Bump years in copyright Added hardening=+all Added README.md to debian/docs set CMAKE_BUILD_TYPE=RelWithDebInfo --- AUTHORS | 7 +- CMakeLists.txt | 239 +++---- Digia-Qt-LGPL-Exception-1.1 | 22 + README | 25 - README.md | 21 + cmake/compiler_settings.cmake | 11 + cmake/qt5xdg-config.cmake.in | 1 + cmake/qt5xdgiconloader-config.cmake.in | 10 + debian/changelog | 5 +- debian/libqt5xdgiconloader-dev.install | 2 +- debian/rules | 5 + qtxdg/CMakeLists.txt | 146 +++++ .../desktopenvironment_p.cpp | 0 xdgaction.cpp => qtxdg/xdgaction.cpp | 4 +- xdgaction.h => qtxdg/xdgaction.h | 0 xdgautostart.cpp => qtxdg/xdgautostart.cpp | 8 +- xdgautostart.h => qtxdg/xdgautostart.h | 0 .../xdgdesktopfile.cpp | 604 ++++++++++-------- xdgdesktopfile.h => qtxdg/xdgdesktopfile.h | 36 +- .../xdgdesktopfile_p.h | 0 xdgdirs.cpp => qtxdg/xdgdirs.cpp | 88 ++- xdgdirs.h => qtxdg/xdgdirs.h | 8 + xdgicon.cpp => qtxdg/xdgicon.cpp | 21 +- xdgicon.h => qtxdg/xdgicon.h | 0 xdgmacros.h => qtxdg/xdgmacros.h | 0 xdgmenu.cpp => qtxdg/xdgmenu.cpp | 180 +++--- xdgmenu.h => qtxdg/xdgmenu.h | 2 +- xdgmenu_p.h => qtxdg/xdgmenu_p.h | 0 .../xdgmenuapplinkprocessor.cpp | 47 +- .../xdgmenuapplinkprocessor.h | 0 .../xdgmenulayoutprocessor.cpp | 78 +-- .../xdgmenulayoutprocessor.h | 0 xdgmenureader.cpp => qtxdg/xdgmenureader.cpp | 60 +- xdgmenureader.h => qtxdg/xdgmenureader.h | 0 xdgmenurules.cpp => qtxdg/xdgmenurules.cpp | 14 +- xdgmenurules.h => qtxdg/xdgmenurules.h | 0 xdgmenuwidget.cpp => qtxdg/xdgmenuwidget.cpp | 32 +- xdgmenuwidget.h => qtxdg/xdgmenuwidget.h | 0 xdgmimetype.cpp => qtxdg/xdgmimetype.cpp | 2 +- xdgmimetype.h => qtxdg/xdgmimetype.h | 0 xmlhelper.cpp => qtxdg/xmlhelper.cpp | 6 +- xmlhelper.h => qtxdg/xmlhelper.h | 0 release.sh | 2 +- test/CMakeLists.txt | 8 +- test/tst_xdgdesktopfile.cpp | 118 ++++ test/tst_xdgdesktopfile.h | 35 + util/CMakeLists.txt | 26 + util/qtxdg-desktop-file-start.cpp | 71 ++ xdgiconloader/CMakeLists.txt | 82 +++ .../xdgiconloader.cpp | 123 ++-- .../xdgiconloader_p.h | 49 +- 51 files changed, 1371 insertions(+), 827 deletions(-) create mode 100644 Digia-Qt-LGPL-Exception-1.1 delete mode 100644 README create mode 100644 README.md create mode 100644 cmake/qt5xdgiconloader-config.cmake.in create mode 100644 qtxdg/CMakeLists.txt rename desktopenvironment_p.cpp => qtxdg/desktopenvironment_p.cpp (100%) rename xdgaction.cpp => qtxdg/xdgaction.cpp (94%) rename xdgaction.h => qtxdg/xdgaction.h (100%) rename xdgautostart.cpp => qtxdg/xdgautostart.cpp (89%) rename xdgautostart.h => qtxdg/xdgautostart.h (100%) rename xdgdesktopfile.cpp => qtxdg/xdgdesktopfile.cpp (66%) rename xdgdesktopfile.h => qtxdg/xdgdesktopfile.h (89%) rename xdgdesktopfile_p.h => qtxdg/xdgdesktopfile_p.h (100%) rename xdgdirs.cpp => qtxdg/xdgdirs.cpp (76%) rename xdgdirs.h => qtxdg/xdgdirs.h (95%) rename xdgicon.cpp => qtxdg/xdgicon.cpp (88%) rename xdgicon.h => qtxdg/xdgicon.h (100%) rename xdgmacros.h => qtxdg/xdgmacros.h (100%) rename xdgmenu.cpp => qtxdg/xdgmenu.cpp (68%) rename xdgmenu.h => qtxdg/xdgmenu.h (97%) rename xdgmenu_p.h => qtxdg/xdgmenu_p.h (100%) rename xdgmenuapplinkprocessor.cpp => qtxdg/xdgmenuapplinkprocessor.cpp (74%) rename xdgmenuapplinkprocessor.h => qtxdg/xdgmenuapplinkprocessor.h (100%) rename xdgmenulayoutprocessor.cpp => qtxdg/xdgmenulayoutprocessor.cpp (78%) rename xdgmenulayoutprocessor.h => qtxdg/xdgmenulayoutprocessor.h (100%) rename xdgmenureader.cpp => qtxdg/xdgmenureader.cpp (86%) rename xdgmenureader.h => qtxdg/xdgmenureader.h (100%) rename xdgmenurules.cpp => qtxdg/xdgmenurules.cpp (94%) rename xdgmenurules.h => qtxdg/xdgmenurules.h (100%) rename xdgmenuwidget.cpp => qtxdg/xdgmenuwidget.cpp (83%) rename xdgmenuwidget.h => qtxdg/xdgmenuwidget.h (100%) rename xdgmimetype.cpp => qtxdg/xdgmimetype.cpp (98%) rename xdgmimetype.h => qtxdg/xdgmimetype.h (100%) rename xmlhelper.cpp => qtxdg/xmlhelper.cpp (85%) rename xmlhelper.h => qtxdg/xmlhelper.h (100%) create mode 100644 test/tst_xdgdesktopfile.cpp create mode 100644 test/tst_xdgdesktopfile.h create mode 100644 util/CMakeLists.txt create mode 100644 util/qtxdg-desktop-file-start.cpp create mode 100644 xdgiconloader/CMakeLists.txt rename qiconfix/qiconloader.cpp => xdgiconloader/xdgiconloader.cpp (84%) rename qiconfix/qiconloader_p.h => xdgiconloader/xdgiconloader_p.h (83%) diff --git a/AUTHORS b/AUTHORS index 190d298..dd2061e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -4,7 +4,8 @@ Upstream Authors: Copyright: Copyright (c) 2010-2012 Razor team - Copyright (c) 2012-2014 LXQt team + Copyright (c) 2012-2016 LXQt team -License: GPL-2 and LGPL-2.1+ -The full text of the licenses can be found in the 'COPYING' file. +License: LGPL-2.1+ and LGPL-2.1-or-3-with-Digia-1.1-exception +The full text of the LGPL-2.1+ license can be found in the 'COPYING' file. +The Digia-1.1 exception can be found in the 'Digia-Qt-LGPL-Exception-1.1' file. diff --git a/CMakeLists.txt b/CMakeLists.txt index d7c6686..7c4586c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,10 +2,29 @@ cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) project(libqtxdg) option(BUILD_TESTS "Builds tests" OFF) +option(BUILD_DEV_UTILS "Builds and install development utils" OFF) # additional cmake files set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +if (CMAKE_VERSION VERSION_LESS "3.1") + include(CheckCXXCompilerFlag) + CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) + if(COMPILER_SUPPORTS_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + else() + CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) + # -std=c++0x is deprecated but some tools e.g. qmake or older gcc are still using it + if(COMPILER_SUPPORTS_CXX0X) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") + else() + message(FATAL_ERROR "Compiler ${CMAKE_CXX_COMPILER} does not support c++11/c++0x") + endif() + endif() +else() + set(CMAKE_CXX_STANDARD 11) +endif() + set(QTXDG_MAJOR_VERSION 1) set(QTXDG_MINOR_VERSION 3) set(QTXDG_PATCH_VERSION 0) @@ -13,6 +32,7 @@ set(QTXDG_VERSION_STRING ${QTXDG_MAJOR_VERSION}.${QTXDG_MINOR_VERSION}.${QTXDG_P include(GNUInstallDirs) # Standard directories for installation include(CMakePackageConfigHelpers) +include(GenerateExportHeader) include(create_portable_headers) include(create_pkgconfig_file) include(compiler_settings NO_POLICY_SCOPE) @@ -20,6 +40,7 @@ include(compiler_settings NO_POLICY_SCOPE) find_package(Qt5Widgets REQUIRED QUIET) find_package(Qt5Xml REQUIRED QUIET) find_package(Qt5DBus REQUIRED QUIET) + if (BUILD_TESTS) find_package(Qt5Test REQUIRED QUIET) endif() @@ -28,15 +49,16 @@ endif() set(QTXDGX_LIBRARY_NAME "Qt5Xdg") set(QTXDGX_FILE_NAME "qt5xdg") +set(QTXDGX_ICONLOADER_LIBRARY_NAME "Qt5XdgIconLoader") +set(QTXDGX_ICONLOADER_FILE_NAME "qt5xdgiconloader") + set(QTXDGX_PKG_CONFIG_DESCRIPTION "Qt5Xdg, a Qt5 implementation of XDG standards") -set(QTXDGX_PKG_CONFIG_REQUIRES "Qt5Core, Qt5Xml, Qt5Widgets, Qt5DBus") -set(QTXDGX_INTREE_INCLUDEDIR "${CMAKE_CURRENT_BINARY_DIR}/InTreeBuild/include") +set(QTXDGX_PKG_CONFIG_REQUIRES "Qt5Core, Qt5Xml, Qt5Widgets, Qt5DBus, Qt5XdgIconLoader") -include_directories( - "${Qt5Gui_PRIVATE_INCLUDE_DIRS}" -) +set(QTXDGX_ICONLOADER_PKG_CONFIG_DESCRIPTION "Qt5XdgIconLader, a Qt5 XDG Icon Loader") +set(QTXDGX_ICONLOADER_PKG_CONFIG_REQUIRES "Qt5Gui") -set(QTX_LIBRARIES Qt5::Widgets Qt5::Xml Qt5::DBus) +set(QTXDGX_INTREE_INCLUDEDIR "${CMAKE_CURRENT_BINARY_DIR}/InTreeBuild/include") if (NOT CMAKE_BUILD_TYPE) set ( CMAKE_BUILD_TYPE Release ) @@ -44,101 +66,45 @@ endif (NOT CMAKE_BUILD_TYPE) message(STATUS "Building with Qt ${Qt5Core_VERSION_STRING}") -set(libqtxdg_PUBLIC_H_FILES - xdgaction.h - xdgdesktopfile.h - xdgdirs.h - xdgicon.h - xdgmenu.h - xdgmenuwidget.h - xmlhelper.h - xdgautostart.h - xdgmacros.h - xdgmimetype.h -) - -set(libqtxdg_PUBLIC_CLASSES - XdgAction - XdgDesktopFile - XdgDirs - XdgIcon - XdgMenu - XdgMenuWidget - XmlHelper - XdgAutoStart - XdgMimeType -) +add_subdirectory(xdgiconloader) +add_subdirectory(qtxdg) -set(libqtxdg_PRIVATE_H_FILES - xdgmenuapplinkprocessor.h - xdgmenulayoutprocessor.h - xdgmenu_p.h - xdgmenureader.h - xdgmenurules.h - xdgdesktopfile_p.h -) - -set(libqtxdg_CPP_FILES - xdgaction.cpp - xdgdesktopfile.cpp - xdgdirs.cpp - xdgicon.cpp - xdgmenuapplinkprocessor.cpp - xdgmenu.cpp - xdgmenulayoutprocessor.cpp - xdgmenureader.cpp - xdgmenurules.cpp - xdgmenuwidget.cpp - xmlhelper.cpp - xdgautostart.cpp - xdgmimetype.cpp - qiconfix/qiconloader.cpp -) - -set(libqtxdg_MOCS - xdgaction.h - xdgmenuapplinkprocessor.h - xdgmenu.h - xdgmenu_p.h - xdgmenureader.h - xdgmenurules.h - xdgmenuwidget.h -) - -set(libqtxdg_PRIVATE_INSTALLABLE_H_FILES - qiconfix/qiconloader_p.h -) - -QT5_WRAP_CPP(libqtxdg_CXX_FILES ${libqtxdg_MOCS}) - -add_library(${QTXDGX_LIBRARY_NAME} SHARED - ${libqtxdg_PUBLIC_H_FILES} - ${libqtxdg_PRIVATE_H_FILES} - ${libqtxdg_PRIVATE_INSTALLABLE_H_FILES} - ${libqtxdg_PRIVATE_H_FILES} - ${libqtxdg_CPP_FILES} - ${libqtxdg_CXX_FILES} -) +if(BUILD_TESTS) + enable_testing() + target_compile_definitions(${QTXDGX_LIBRARY_NAME} + PRIVATE "QTXDG_TESTS=\"1\"" + ) + add_subdirectory(test) +else() + message(STATUS "") + message(STATUS "For building tests use -DBUILD_TESTS=Yes option.") + message(STATUS "") +endif() +if (BUILD_DEV_UTILS) + add_subdirectory(util) +endif() -target_link_libraries(${QTXDGX_LIBRARY_NAME} - PUBLIC - ${QTX_LIBRARIES} +configure_package_config_file( + "${PROJECT_SOURCE_DIR}/cmake/${QTXDGX_FILE_NAME}-config.cmake.in" + "${CMAKE_BINARY_DIR}/${QTXDGX_FILE_NAME}-config.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTXDGX_FILE_NAME}" ) -set_target_properties(${QTXDGX_LIBRARY_NAME} PROPERTIES - VERSION ${QTXDG_VERSION_STRING} - SOVERSION ${QTXDG_MAJOR_VERSION} +write_basic_package_version_file( + "${CMAKE_BINARY_DIR}/${QTXDGX_FILE_NAME}-config-version.cmake" + VERSION ${QTXDG_VERSION_STRING} + COMPATIBILITY AnyNewerVersion ) configure_package_config_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/${QTXDGX_FILE_NAME}-config.cmake.in" - "${CMAKE_BINARY_DIR}/${QTXDGX_FILE_NAME}-config.cmake" - INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTXDGX_FILE_NAME}" + "${PROJECT_SOURCE_DIR}/cmake/${QTXDGX_ICONLOADER_FILE_NAME}-config.cmake.in" + "${CMAKE_BINARY_DIR}/${QTXDGX_ICONLOADER_FILE_NAME}-config.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTXDGX_ICONLOADER_FILE_NAME}" ) write_basic_package_version_file( - "${CMAKE_BINARY_DIR}/${QTXDGX_FILE_NAME}-config-version.cmake" + "${CMAKE_BINARY_DIR}/${QTXDGX_ICONLOADER_FILE_NAME}-config-version.cmake" VERSION ${QTXDG_VERSION_STRING} COMPATIBILITY AnyNewerVersion ) @@ -150,97 +116,50 @@ create_pkgconfig_file( INCLUDEDIRS ${QTXDGX_FILE_NAME} LIBS ${QTXDGX_LIBRARY_NAME} REQUIRES ${QTXDGX_PKG_CONFIG_REQUIRES} + REQUIRES_PRIVATE ${QTXDGX_ICONLOADER_LIBRARY_NAME} VERSION ${QTXDG_VERSION_STRING} INSTALL ) -target_compile_definitions(${QTXDGX_LIBRARY_NAME} - PRIVATE "QTXDG_COMPILATION=\"1\"" -) - -target_include_directories(${QTXDGX_LIBRARY_NAME} - INTERFACE "$" - INTERFACE "$" - INTERFACE "$" -) - -# include directories and targets for the in tree build -target_include_directories(${QTXDGX_LIBRARY_NAME} - INTERFACE "$" - INTERFACE "$" - INTERFACE "$" -) - -export(TARGETS ${QTXDGX_LIBRARY_NAME} FILE "${CMAKE_BINARY_DIR}/${QTXDGX_FILE_NAME}-targets.cmake") -# end of in tree build stuff - -# create the portble headers -create_portable_headers(libqtxdg_PORTABLE_HEADERS - HEADER_NAMES ${libqtxdg_PUBLIC_CLASSES} - OUTPUT_DIR "${QTXDGX_INTREE_INCLUDEDIR}/${QTXDGX_FILE_NAME}" -) - -# Copy public headers (in tree building) -foreach(h ${libqtxdg_PUBLIC_H_FILES}) - get_filename_component(bh ${h} NAME) - configure_file(${h} "${QTXDGX_INTREE_INCLUDEDIR}/${QTXDGX_FILE_NAME}/${bh}" COPYONLY) -endforeach() - -# Copy private headers (in tree building) -foreach(h ${libqtxdg_PRIVATE_INSTALLABLE_H_FILES}) - get_filename_component(bh ${h} NAME) - configure_file(${h} "${QTXDGX_INTREE_INCLUDEDIR}/${QTXDGX_FILE_NAME}/${QTXDG_VERSION_STRING}/private/qtxdg/${bh}" COPYONLY) -endforeach() - -install(TARGETS - ${QTXDGX_LIBRARY_NAME} DESTINATION "${CMAKE_INSTALL_LIBDIR}" - EXPORT "${QTXDGX_FILE_NAME}-targets" - COMPONENT Runtime -) - -install(EXPORT - "${QTXDGX_FILE_NAME}-targets" - DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTXDGX_FILE_NAME}" - COMPONENT Devel +create_pkgconfig_file( + PACKAGE_NAME ${QTXDGX_ICONLOADER_LIBRARY_NAME} + DESCRIPTIVE_NAME ${QTXDGX_ICONLOADER_LIBRARY_NAME} + DESCRIPTION ${QTXDGX_ICONLOADER_PKG_CONFIG_DESCRIPTION} + INCLUDEDIRS ${QTXDGX_ICONLOADER_FILE_NAME} + LIBS ${QTXDGX_ICONLOADER_LIBRARY_NAME} + REQUIRES ${QTXDGX_ICONLOADER_PKG_CONFIG_REQUIRES} + VERSION ${QTXDG_VERSION_STRING} + INSTALL ) install(FILES - ${libqtxdg_PUBLIC_H_FILES} - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_FILE_NAME}" + "${CMAKE_BINARY_DIR}/${QTXDGX_FILE_NAME}-config.cmake" + "${CMAKE_BINARY_DIR}/${QTXDGX_FILE_NAME}-config-version.cmake" + DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTXDGX_FILE_NAME}" COMPONENT Devel ) install(FILES - ${libqtxdg_PRIVATE_INSTALLABLE_H_FILES} - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_FILE_NAME}/${QTXDG_VERSION_STRING}/private/qtxdg" + "${CMAKE_BINARY_DIR}/${QTXDGX_ICONLOADER_FILE_NAME}-config.cmake" + "${CMAKE_BINARY_DIR}/${QTXDGX_ICONLOADER_FILE_NAME}-config-version.cmake" + DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTXDGX_ICONLOADER_FILE_NAME}" COMPONENT Devel ) -install(FILES - "${CMAKE_BINARY_DIR}/${QTXDGX_FILE_NAME}-config.cmake" - "${CMAKE_BINARY_DIR}/${QTXDGX_FILE_NAME}-config-version.cmake" +install(EXPORT + "${QTXDGX_FILE_NAME}-targets" DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTXDGX_FILE_NAME}" + FILE "${QTXDGX_FILE_NAME}-targets.cmake" COMPONENT Devel ) -install(FILES - ${libqtxdg_PORTABLE_HEADERS} - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_FILE_NAME}" +install(EXPORT + "${QTXDGX_ICONLOADER_FILE_NAME}-targets" + DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTXDGX_ICONLOADER_FILE_NAME}" + FILE "${QTXDGX_ICONLOADER_FILE_NAME}-targets.cmake" COMPONENT Devel ) -if(BUILD_TESTS) - enable_testing() - target_compile_definitions(${QTXDGX_LIBRARY_NAME} - PRIVATE "QTXDG_TESTS=\"1\"" - ) - add_subdirectory(test) -else() - message(STATUS "") - message(STATUS "For building tests use -DBUILD_TESTS=Yes option.") - message(STATUS "") -endif() - # uninstall target configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" diff --git a/Digia-Qt-LGPL-Exception-1.1 b/Digia-Qt-LGPL-Exception-1.1 new file mode 100644 index 0000000..7e2e30f --- /dev/null +++ b/Digia-Qt-LGPL-Exception-1.1 @@ -0,0 +1,22 @@ +Digia Qt LGPL Exception version 1.1 + +As an additional permission to the GNU Lesser General Public License version +2.1, the object code form of a "work that uses the Library" may incorporate +material from a header file that is part of the Library. You may distribute +such object code under terms of your choice, provided that: + (i) the header files of the Library have not been modified; and + (ii) the incorporated material is limited to numerical parameters, data + structure layouts, accessors, macros, inline functions and + templates; and + (iii) you comply with the terms of Section 6 of the GNU Lesser General + Public License version 2.1. + +Moreover, you may apply this exception to a modified version of the Library, +provided that such modification does not involve copying material from the +Library into the modified Library's header files unless such material is +limited to (i) numerical parameters; (ii) data structure layouts; +(iii) accessors; and (iv) small macros, templates and inline functions of +five lines or less in length. + +Furthermore, you are not required to apply this additional permission to a +modified version of the Library. diff --git a/README b/README deleted file mode 100644 index 4abf265..0000000 --- a/README +++ /dev/null @@ -1,25 +0,0 @@ -Overview -======== -libqtxdg is An Qt implementation of freedesktop.org xdg specifications. -It's built with Qt5. - - -Dependencies -============ - Qt5 - - -Configuration -============ -libqtxdg uses the CMake build system. Everything that applies to CMake also -applies here. - -Configuration options: - BUILD_TESTS Builds tests, defaults to OFF - -Configuration Examples: - Build library and build self tests: - cmake -DBUILD_TESTS=ON .. - - Build the library without building self tests - cmake .. diff --git a/README.md b/README.md new file mode 100644 index 0000000..1bc511e --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +##Overview + +```libqtxdg``` is a Qt implementation of freedesktop.org XDG specifications which is built with Qt5. + +##Dependencies + + - Qt5 + +##Configuration + +```libqtxdg``` uses the CMake build system. Everything that applies to CMake also +applies here. + +###Configuration options: + BUILD_TESTS Builds tests, defaults to OFF + BUILD_DEV_UTILS Builds and install development utils, defaults to OFF + +###Configuration Examples: +Build library and build self tests: ```cmake -DBUILD_TESTS=ON ..``` + +Build the library without building self tests : ```cmake ..``` diff --git a/cmake/compiler_settings.cmake b/cmake/compiler_settings.cmake index da31e77..044b36a 100644 --- a/cmake/compiler_settings.cmake +++ b/cmake/compiler_settings.cmake @@ -92,3 +92,14 @@ set(QTXDG_COMMON_WARNING_FLAGS "-Wall") #----------------------------------------------------------------------------- list(APPEND QTXDG_WARNING_FLAGS ${QTXDG_COMMON_WARNING_FLAGS}) add_definitions(${QTXDG_WARNING_FLAGS}) + +#----------------------------------------------------------------------------- +# String conversion flags +#----------------------------------------------------------------------------- +add_definitions( + -DQT_USE_QSTRINGBUILDER + -DQT_NO_CAST_FROM_ASCII + -DQT_NO_CAST_TO_ASCII + -DQT_NO_URL_CAST_FROM_STRING + -DQT_NO_CAST_FROM_BYTEARRAY +) diff --git a/cmake/qt5xdg-config.cmake.in b/cmake/qt5xdg-config.cmake.in index dc312d7..045c920 100644 --- a/cmake/qt5xdg-config.cmake.in +++ b/cmake/qt5xdg-config.cmake.in @@ -5,6 +5,7 @@ include(CMakeFindDependencyMacro) find_dependency(Qt5Widgets) find_dependency(Qt5Xml) find_dependency(Qt5DBus) +find_dependency(Qt5XdgIconLoader) if (CMAKE_VERSION VERSION_GREATER 2.8.12) cmake_policy(SET CMP0024 OLD) diff --git a/cmake/qt5xdgiconloader-config.cmake.in b/cmake/qt5xdgiconloader-config.cmake.in new file mode 100644 index 0000000..0582b60 --- /dev/null +++ b/cmake/qt5xdgiconloader-config.cmake.in @@ -0,0 +1,10 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +find_dependency(Qt5Gui) + +if (CMAKE_VERSION VERSION_GREATER 2.8.12) + cmake_policy(SET CMP0024 OLD) +endif() +include("${CMAKE_CURRENT_LIST_DIR}/qt5xdgiconloader-targets.cmake") diff --git a/debian/changelog b/debian/changelog index c2eb939..2786bc8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,6 @@ libqtxdg (1.3.1~50-g4fde773-1) experimental; urgency=medium - * New pre-release 1.3.1 + * New pre-release 1.3.1~50-g4fde773 * Fixed libqt5xdgiconloader-dev.install * Reworked descriptions in debian/control to prevent lintian whining * Fixed symbols version @@ -13,8 +13,9 @@ libqtxdg (1.3.1~50-g4fde773-1) experimental; urgency=medium * Bump years in copyright * Added hardening=+all * Added README.md to debian/docs + * set CMAKE_BUILD_TYPE=RelWithDebInfo - -- Alf Gaida Sat, 09 Jul 2016 19:39:42 +0200 + -- Alf Gaida Sat, 09 Jul 2016 20:16:32 +0200 libqtxdg (1.3.0-3) unstable; urgency=medium diff --git a/debian/libqt5xdgiconloader-dev.install b/debian/libqt5xdgiconloader-dev.install index bed378c..b24b62b 100644 --- a/debian/libqt5xdgiconloader-dev.install +++ b/debian/libqt5xdgiconloader-dev.install @@ -6,4 +6,4 @@ usr/lib/*/pkgconfig/Qt5XdgIconLoader.pc usr/share/cmake/qt5xdgiconloader/qt5xdgiconloader-config-version.cmake usr/share/cmake/qt5xdgiconloader/qt5xdgiconloader-config.cmake usr/share/cmake/qt5xdgiconloader/qt5xdgiconloader-targets.cmake -usr/share/cmake/qt5xdgiconloader/qt5xdgiconloader-targets-none.cmake +usr/share/cmake/qt5xdgiconloader/qt5xdgiconloader-targets-relwithdebinfo.cmake diff --git a/debian/rules b/debian/rules index 367cf7b..32812f6 100755 --- a/debian/rules +++ b/debian/rules @@ -8,3 +8,8 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all dh ${@} --buildsystem cmake \ --parallel \ --fail-missing + +override_dh_auto_configure: + dh_auto_configure -- \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo + diff --git a/qtxdg/CMakeLists.txt b/qtxdg/CMakeLists.txt new file mode 100644 index 0000000..6eaea07 --- /dev/null +++ b/qtxdg/CMakeLists.txt @@ -0,0 +1,146 @@ +set(QTX_LIBRARIES Qt5::Widgets Qt5::Xml Qt5::DBus) + +include_directories( + "${Qt5Gui_PRIVATE_INCLUDE_DIRS}" +) +set(libqtxdg_PUBLIC_H_FILES + xdgaction.h + xdgdesktopfile.h + xdgdirs.h + xdgicon.h + xdgmenu.h + xdgmenuwidget.h + xmlhelper.h + xdgautostart.h + xdgmacros.h + xdgmimetype.h +) + +set(libqtxdg_PUBLIC_CLASSES + XdgAction + XdgDesktopFile + XdgDirs + XdgIcon + XdgMenu + XdgMenuWidget + XmlHelper + XdgAutoStart + XdgMimeType +) + +set(libqtxdg_PRIVATE_H_FILES + xdgmenuapplinkprocessor.h + xdgmenulayoutprocessor.h + xdgmenu_p.h + xdgmenureader.h + xdgmenurules.h + xdgdesktopfile_p.h +) + +set(libqtxdg_CPP_FILES + xdgaction.cpp + xdgdesktopfile.cpp + xdgdirs.cpp + xdgicon.cpp + xdgmenuapplinkprocessor.cpp + xdgmenu.cpp + xdgmenulayoutprocessor.cpp + xdgmenureader.cpp + xdgmenurules.cpp + xdgmenuwidget.cpp + xmlhelper.cpp + xdgautostart.cpp + xdgmimetype.cpp +) + +set(libqtxdg_MOCS + xdgaction.h + xdgmenuapplinkprocessor.h + xdgmenu.h + xdgmenu_p.h + xdgmenureader.h + xdgmenurules.h + xdgmenuwidget.h +) + +QT5_WRAP_CPP(libqtxdg_CXX_FILES ${libqtxdg_MOCS}) + +add_library(${QTXDGX_LIBRARY_NAME} SHARED + ${libqtxdg_PUBLIC_H_FILES} + ${libqtxdg_PRIVATE_H_FILES} + ${libqtxdg_PRIVATE_H_FILES} + ${libqtxdg_CPP_FILES} + ${libqtxdg_CXX_FILES} +) + +target_link_libraries(${QTXDGX_LIBRARY_NAME} + PUBLIC + ${QTX_LIBRARIES} + ${QTXDGX_ICONLOADER_LIBRARY_NAME} +) + +set_target_properties(${QTXDGX_LIBRARY_NAME} PROPERTIES + VERSION ${QTXDG_VERSION_STRING} + SOVERSION ${QTXDG_MAJOR_VERSION} +) + +target_compile_definitions(${QTXDGX_LIBRARY_NAME} + PRIVATE "QTXDG_COMPILATION=\"1\"" + PRIVATE "QTXDG_VERSION=\"${QTXDG_VERSION_STRING}\"" +) + +target_include_directories(${QTXDGX_LIBRARY_NAME} + INTERFACE "$" + INTERFACE "$" +) + +# include directories and targets for the in tree build +target_include_directories(${QTXDGX_LIBRARY_NAME} + INTERFACE "$" + INTERFACE "$" +) + +export(TARGETS ${QTXDGX_LIBRARY_NAME} APPEND FILE "${CMAKE_BINARY_DIR}/${QTXDGX_FILE_NAME}-targets.cmake") +# end of in tree build stuff + +# create the portble headers +create_portable_headers(libqtxdg_PORTABLE_HEADERS + HEADER_NAMES ${libqtxdg_PUBLIC_CLASSES} + OUTPUT_DIR "${QTXDGX_INTREE_INCLUDEDIR}/${QTXDGX_FILE_NAME}" +) + +# Copy public headers (in tree building) +foreach(h ${libqtxdg_PUBLIC_H_FILES}) + get_filename_component(bh ${h} NAME) + configure_file(${h} "${QTXDGX_INTREE_INCLUDEDIR}/${QTXDGX_FILE_NAME}/${bh}" COPYONLY) +endforeach() + +# Copy private headers (in tree building) +foreach(h ${libqtxdg_PRIVATE_INSTALLABLE_H_FILES}) + get_filename_component(bh ${h} NAME) + configure_file(${h} "${QTXDGX_INTREE_INCLUDEDIR}/${QTXDGX_FILE_NAME}/${QTXDG_VERSION_STRING}/private/qtxdg/${bh}" COPYONLY) +endforeach() + +install(TARGETS + ${QTXDGX_LIBRARY_NAME} DESTINATION "${CMAKE_INSTALL_LIBDIR}" + EXPORT "${QTXDGX_FILE_NAME}-targets" + COMPONENT Runtime +) + +install(FILES + ${libqtxdg_PUBLIC_H_FILES} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_FILE_NAME}" + COMPONENT Devel +) + +install(FILES + ${libqtxdg_PRIVATE_INSTALLABLE_H_FILES} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_FILE_NAME}/${QTXDG_VERSION_STRING}/private/qtxdg" + COMPONENT Devel +) + +install(FILES + ${libqtxdg_PORTABLE_HEADERS} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_FILE_NAME}" + COMPONENT Devel +) diff --git a/desktopenvironment_p.cpp b/qtxdg/desktopenvironment_p.cpp similarity index 100% rename from desktopenvironment_p.cpp rename to qtxdg/desktopenvironment_p.cpp diff --git a/xdgaction.cpp b/qtxdg/xdgaction.cpp similarity index 94% rename from xdgaction.cpp rename to qtxdg/xdgaction.cpp index 44d70ea..b0ba66c 100644 --- a/xdgaction.cpp +++ b/qtxdg/xdgaction.cpp @@ -91,7 +91,7 @@ void XdgAction::load(const XdgDesktopFile& desktopFile) if (mDesktopFile.isValid()) { // & is reserved for mnemonics - setText(mDesktopFile.name().replace('&', QLatin1String("&&"))); + setText(mDesktopFile.name().replace(QLatin1Char('&'), QLatin1String("&&"))); setToolTip(mDesktopFile.comment()); connect(this, SIGNAL(triggered()), this, SLOT(runConmmand())); @@ -117,6 +117,6 @@ void XdgAction::updateIcon() { setIcon(mDesktopFile.icon()); if (icon().isNull()) - setIcon(XdgIcon::fromTheme("application-x-executable")); + setIcon(XdgIcon::fromTheme(QLatin1String("application-x-executable"))); QCoreApplication::processEvents(); } diff --git a/xdgaction.h b/qtxdg/xdgaction.h similarity index 100% rename from xdgaction.h rename to qtxdg/xdgaction.h diff --git a/xdgautostart.cpp b/qtxdg/xdgautostart.cpp similarity index 89% rename from xdgautostart.cpp rename to qtxdg/xdgautostart.cpp index 85344d1..402937e 100644 --- a/xdgautostart.cpp +++ b/qtxdg/xdgautostart.cpp @@ -57,14 +57,14 @@ XdgDesktopFileList XdgAutoStart::desktopFileList(QStringList dirs, bool excludeH QSet processed; XdgDesktopFileList ret; - foreach (QString dirName, dirs) + foreach (const QString &dirName, dirs) { QDir dir(dirName); if (!dir.exists()) continue; - QFileInfoList files = dir.entryInfoList(QStringList("*.desktop"), QDir::Files | QDir::Readable); - foreach (QFileInfo fi, files) + const QFileInfoList files = dir.entryInfoList(QStringList(QLatin1String("*.desktop")), QDir::Files | QDir::Readable); + foreach (const QFileInfo &fi, files) { if (processed.contains(fi.fileName())) continue; @@ -88,5 +88,5 @@ XdgDesktopFileList XdgAutoStart::desktopFileList(QStringList dirs, bool excludeH QString XdgAutoStart::localPath(const XdgDesktopFile& file) { QFileInfo fi(file.fileName()); - return QString("%1/%2").arg(XdgDirs::autostartHome(), fi.fileName()); + return QString::fromLatin1("%1/%2").arg(XdgDirs::autostartHome(), fi.fileName()); } diff --git a/xdgautostart.h b/qtxdg/xdgautostart.h similarity index 100% rename from xdgautostart.h rename to qtxdg/xdgautostart.h diff --git a/xdgdesktopfile.cpp b/qtxdg/xdgdesktopfile.cpp similarity index 66% rename from xdgdesktopfile.cpp rename to qtxdg/xdgdesktopfile.cpp index 75a80bf..4972c37 100644 --- a/xdgdesktopfile.cpp +++ b/qtxdg/xdgdesktopfile.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -48,7 +49,6 @@ #include #include #include -#include // for the % operator #include #include #include @@ -63,10 +63,23 @@ static const QStringList nonDetachExecs = QStringList() << QLatin1String("pkexec"); -static const char onlyShowInKey[] = "OnlyShowIn"; -static const char notShowInKey[] = "NotShowIn"; -static const char categoriesKey[] = "Categories"; -static const char extendPrefixKey[] = "X-"; +static const QLatin1String onlyShowInKey("OnlyShowIn"); +static const QLatin1String notShowInKey("NotShowIn"); +static const QLatin1String categoriesKey("Categories"); +static const QLatin1String extendPrefixKey("X-"); +static const QLatin1String mimeTypeKey("MimeType"); +static const QLatin1String applicationsStr("applications"); + +static const QLatin1String nameKey("Name"); +static const QLatin1String typeKey("Type"); +static const QLatin1String ApplicationStr("Application"); +static const QLatin1String LinkStr("Link"); +static const QLatin1String DirectoryStr("Directory"); +static const QLatin1String execKey("Exec"); +static const QLatin1String urlKey("URL"); +static const QLatin1String iconKey("Icon"); + +static const QLatin1String initialPreferenceKey("InitialPreference"); // Helper functions prototypes bool checkTryExec(const QString& progName); @@ -90,13 +103,13 @@ void loadMimeCacheDir(const QString& dirName, QHash &repl) { // First we replace slash. - str.replace('\\', "\\\\"); + str.replace(QLatin1Char('\\'), QLatin1String("\\\\")); QHashIterator i(repl); while (i.hasNext()) { i.next(); - if (i.key() != '\\') - str.replace(i.key(), QString("\\\\%1").arg(i.value())); + if (i.key() != QLatin1Char('\\')) + str.replace(i.key(), QString::fromLatin1("\\\\%1").arg(i.value())); } return str; @@ -110,9 +123,9 @@ QString &doEscape(QString& str, const QHash &repl) QString &escape(QString& str) { QHash repl; - repl.insert('\n', 'n'); - repl.insert('\t', 't'); - repl.insert('\r', 'r'); + repl.insert(QLatin1Char('\n'), QLatin1Char('n')); + repl.insert(QLatin1Char('\t'), QLatin1Char('t')); + repl.insert(QLatin1Char('\r'), QLatin1Char('r')); return doEscape(str, repl); } @@ -143,10 +156,10 @@ QString &escapeExec(QString& str) // The parseCombinedArgString() splits the string by the space symbols, // we temporarily replace them on the special characters. // Replacement will reverse after the splitting. - repl.insert('"', '"'); // double quote, - repl.insert('\'', '\''); // single quote ("'"), - repl.insert('\\', '\\'); // backslash character ("\"), - repl.insert('$', '$'); // dollar sign ("$"), + repl.insert(QLatin1Char('"'), QLatin1Char('"')); // double quote, + repl.insert(QLatin1Char('\''), QLatin1Char('\'')); // single quote ("'"), + repl.insert(QLatin1Char('\\'), QLatin1Char('\\')); // backslash character ("\"), + repl.insert(QLatin1Char('$'), QLatin1Char('$')); // dollar sign ("$"), return doEscape(str, repl); } @@ -157,7 +170,7 @@ QString &doUnEscape(QString& str, const QHash &repl) int n = 0; while (1) { - n=str.indexOf("\\", n); + n=str.indexOf(QLatin1String("\\"), n); if (n < 0 || n > str.length() - 2) break; @@ -181,11 +194,11 @@ QString &doUnEscape(QString& str, const QHash &repl) QString &unEscape(QString& str) { QHash repl; - repl.insert('\\', '\\'); - repl.insert('s', ' '); - repl.insert('n', '\n'); - repl.insert('t', '\t'); - repl.insert('r', '\r'); + repl.insert(QLatin1Char('\\'), QLatin1Char('\\')); + repl.insert(QLatin1Char('s'), QLatin1Char(' ')); + repl.insert(QLatin1Char('n'), QLatin1Char('\n')); + repl.insert(QLatin1Char('t'), QLatin1Char('\t')); + repl.insert(QLatin1Char('r'), QLatin1Char('\r')); return doUnEscape(str, repl); } @@ -237,26 +250,26 @@ QString &unEscapeExec(QString& str) // The parseCombinedArgString() splits the string by the space symbols, // we temporarily replace them on the special characters. // Replacement will reverse after the splitting. - repl.insert(' ', 01); // space - repl.insert('\t', 02); // tab - repl.insert('\n', 03); // newline, - - repl.insert('"', '"'); // double quote, - repl.insert('\'', '\''); // single quote ("'"), - repl.insert('\\', '\\'); // backslash character ("\"), - repl.insert('>', '>'); // greater-than sign (">"), - repl.insert('<', '<'); // less-than sign ("<"), - repl.insert('~', '~'); // tilde ("~"), - repl.insert('|', '|'); // vertical bar ("|"), - repl.insert('&', '&'); // ampersand ("&"), - repl.insert(';', ';'); // semicolon (";"), - repl.insert('$', '$'); // dollar sign ("$"), - repl.insert('*', '*'); // asterisk ("*"), - repl.insert('?', '?'); // question mark ("?"), - repl.insert('#', '#'); // hash mark ("#"), - repl.insert('(', '('); // parenthesis ("(") - repl.insert(')', ')'); // parenthesis (")") - repl.insert('`', '`'); // backtick character ("`"). + repl.insert(QLatin1Char(' '), 01); // space + repl.insert(QLatin1Char('\t'), 02); // tab + repl.insert(QLatin1Char('\n'), 03); // newline, + + repl.insert(QLatin1Char('"'), QLatin1Char('"')); // double quote, + repl.insert(QLatin1Char('\''), QLatin1Char('\'')); // single quote ("'"), + repl.insert(QLatin1Char('\\'), QLatin1Char('\\')); // backslash character ("\"), + repl.insert(QLatin1Char('>'), QLatin1Char('>')); // greater-than sign (">"), + repl.insert(QLatin1Char('<'), QLatin1Char('<')); // less-than sign ("<"), + repl.insert(QLatin1Char('~'), QLatin1Char('~')); // tilde ("~"), + repl.insert(QLatin1Char('|'), QLatin1Char('|')); // vertical bar ("|"), + repl.insert(QLatin1Char('&'), QLatin1Char('&')); // ampersand ("&"), + repl.insert(QLatin1Char(';'), QLatin1Char(';')); // semicolon (";"), + repl.insert(QLatin1Char('$'), QLatin1Char('$')); // dollar sign ("$"), + repl.insert(QLatin1Char('*'), QLatin1Char('*')); // asterisk ("*"), + repl.insert(QLatin1Char('?'), QLatin1Char('?')); // question mark ("?"), + repl.insert(QLatin1Char('#'), QLatin1Char('#')); // hash mark ("#"), + repl.insert(QLatin1Char('('), QLatin1Char('(')); // parenthesis ("(") + repl.insert(QLatin1Char(')'), QLatin1Char(')')); // parenthesis (")") + repl.insert(QLatin1Char('`'), QLatin1Char('`')); // backtick character ("`"). return doUnEscape(str, repl); } @@ -281,8 +294,12 @@ public: XdgDesktopFileData::XdgDesktopFileData(): + mFileName(), mIsValid(false), - mValidIsChecked(false) + mValidIsChecked(false), + mIsShow(), + mItems(), + mType(XdgDesktopFile::UnknownType) { } @@ -301,12 +318,12 @@ bool XdgDesktopFileData::read(const QString &prefix) QString line = stream.readLine().trimmed(); // Skip comments ...................... - if (line.startsWith('#')) + if (line.startsWith(QLatin1Char('#'))) continue; // Section .............................. - if (line.startsWith('[') && line.endsWith(']')) + if (line.startsWith(QLatin1Char('[')) && line.endsWith(QLatin1Char(']'))) { section = line.mid(1, line.length()-2); if (section == prefix) @@ -315,13 +332,13 @@ bool XdgDesktopFileData::read(const QString &prefix) continue; } - QString key = line.section('=', 0, 0).trimmed(); - QString value = line.section('=', 1).trimmed(); + QString key = line.section(QLatin1Char('='), 0, 0).trimmed(); + QString value = line.section(QLatin1Char('='), 1).trimmed(); if (key.isEmpty()) continue; - mItems[section + "/" + key] = QVariant(value); + mItems[section + QLatin1Char('/') + key] = QVariant(value); } @@ -332,41 +349,62 @@ bool XdgDesktopFileData::read(const QString &prefix) XdgDesktopFile::Type XdgDesktopFileData::detectType(XdgDesktopFile *q) const { - QString typeStr = q->value("Type").toString(); - if (typeStr == "Application") + QString typeStr = q->value(typeKey).toString(); + if (typeStr == ApplicationStr) return XdgDesktopFile::ApplicationType; - if (typeStr == "Link") + if (typeStr == LinkStr) return XdgDesktopFile::LinkType; - if (typeStr == "Directory") + if (typeStr == DirectoryStr) return XdgDesktopFile::DirectoryType; - if (!q->value("Exec").toString().isEmpty()) + if (!q->value(execKey).toString().isEmpty()) return XdgDesktopFile::ApplicationType; return XdgDesktopFile::UnknownType; } - bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const QStringList& urls) const { //DBusActivatable handling - if (q->value(QLatin1String("DBusActivatable"), false).toBool()) - return startByDBus(urls); - + if (q->value(QLatin1String("DBusActivatable"), false).toBool()) { + /* WARNING: We fallback to use Exec when the DBusActivatable fails. + * + * This is a violation of the standard and we know it! + * + * From the Standard: + * DBusActivatable A boolean value specifying if D-Bus activation is + * supported for this application. If this key is missing, the default + * value is false. If the value is true then implementations should + * ignore the Exec key and send a D-Bus message to launch the + * application. See D-Bus Activation for more information on how this + * works. Applications should still include Exec= lines in their desktop + * files for compatibility with implementations that do not understand + * the DBusActivatable key. + * + * So, why are we doing it ? In the benefit of user experience. + * We first ignore the Exec line and in use the D-Bus to lauch the + * application. But if it fails, we try the Exec method. + * + * We consider that this violation is more acceptable than an failure + * in launching an application. + */ + if (startByDBus(urls)) + return true; + } QStringList args = q->expandExecString(urls); if (args.isEmpty()) return false; - if (q->value("Terminal").toBool()) + if (q->value(QLatin1String("Terminal")).toBool()) { - QString term = getenv("TERM"); + QString term = QString::fromLocal8Bit(qgetenv("TERM")); if (term.isEmpty()) - term = "xterm"; + term = QLatin1String("xterm"); - args.prepend("-e"); + args.prepend(QLatin1String("-e")); args.prepend(term); } @@ -383,12 +421,17 @@ bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const } QString cmd = args.takeFirst(); + QString workingDir = q->value(QLatin1String("Path")).toString(); + if (!workingDir.isEmpty() && !QDir(workingDir).exists()) + workingDir = QString(); if (nonDetach) { QScopedPointer p(new QProcess); p->setStandardInputFile(QProcess::nullDevice()); p->setProcessChannelMode(QProcess::ForwardedChannels); + if (!workingDir.isEmpty()) + p->setWorkingDirectory(workingDir); p->start(cmd, args); bool started = p->waitForStarted(); if (started) @@ -400,7 +443,7 @@ bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const } else { - return QProcess::startDetached(cmd, args); + return QProcess::startDetached(cmd, args, workingDir); } } @@ -417,7 +460,7 @@ bool XdgDesktopFileData::startLinkDetached(const XdgDesktopFile *q) const QString scheme = QUrl(url).scheme(); - if (scheme.isEmpty() || scheme.toUpper() == "FILE") + if (scheme.isEmpty() || scheme.toUpper() == QLatin1String("FILE")) { // Local file QFileInfo fi(url); @@ -443,12 +486,28 @@ bool XdgDesktopFileData::startByDBus(const QStringList& urls) const { QFileInfo f(mFileName); QString path(f.completeBaseName()); + path = path.replace(QLatin1Char('.'), QLatin1Char('/')).prepend(QLatin1Char('/')); QVariantMap platformData; - platformData.insert(QLatin1String("desktop-startup-id"), QString::fromUtf8(qgetenv("DESKTOP_STARTUP_ID"))); + platformData.insert(QLatin1String("desktop-startup-id"), QString::fromLocal8Bit(qgetenv("DESKTOP_STARTUP_ID"))); - path = path.replace(QLatin1Char('.'), QLatin1Char('/')).prepend(QLatin1Char('/')); + QDBusObjectPath d_path(path); + if (d_path.path().isEmpty()) + { + qWarning() << "XdgDesktopFileData::startByDBus: invalid name" << f.fileName() << "of DBusActivatable .desktop file" + ", assembled DBus object path" << path << "is invalid!"; + return false; + } QDBusInterface app(f.completeBaseName(), path, QLatin1String("org.freedesktop.Application")); + //Note: after the QDBusInterface construction, it can *invalid* (has reasonable lastError()) + // but this can be due to some intermediate DBus call(s) which doesn't need to be fatal and + // our next call() can succeed + // see discussion https://github.com/lxde/libqtxdg/pull/75 + if (app.lastError().isValid()) + { + qWarning().noquote() << "XdgDesktopFileData::startByDBus: invalid interface:" << app.lastError().message() + << ", but trying to continue..."; + } QDBusMessage reply; if (urls.isEmpty()) reply = app.call(QLatin1String("Activate"), platformData); @@ -474,23 +533,23 @@ XdgDesktopFile::XdgDesktopFile(const XdgDesktopFile& other): XdgDesktopFile::XdgDesktopFile(Type type, const QString& name, const QString &value): d(new XdgDesktopFileData) { - d->mFileName = name + ".desktop"; + d->mFileName = name + QLatin1String(".desktop"); d->mType = type; - setValue("Version", "1.0"); - setValue("Name", name); + setValue(QLatin1String("Version"), QLatin1String("1.0")); + setValue(nameKey, name); if (type == XdgDesktopFile::ApplicationType) { - setValue("Type", "Application"); - setValue("Exec", value); + setValue(typeKey, ApplicationStr); + setValue(execKey, value); } else if (type == XdgDesktopFile::LinkType) { - setValue("Type", "Link"); - setValue("URL", value); + setValue(typeKey, LinkStr); + setValue(urlKey, value); } else if (type == XdgDesktopFile::DirectoryType) { - setValue("Type", "Directory"); + setValue(typeKey, DirectoryStr); } d->mIsValid = check(); } @@ -541,14 +600,15 @@ bool XdgDesktopFile::save(QIODevice *device) const while (i != d->mItems.constEnd()) { QString path = i.key(); - QString sect = path.section('/',0,0); + QString sect = path.section(QLatin1Char('/'),0,0); if (sect != section) { section = sect; - stream << "[" << section << "]" << endl; + stream << QLatin1Char('[') << section << QLatin1Char(']') << endl; + } - QString key = path.section('/', 1); - stream << key << "=" << i.value().toString() << endl; + QString key = path.section(QLatin1Char('/'), 1); + stream << key << QLatin1Char('=') << i.value().toString() << endl; ++i; } return true; @@ -567,7 +627,7 @@ bool XdgDesktopFile::save(const QString &fileName) const QVariant XdgDesktopFile::value(const QString& key, const QVariant& defaultValue) const { - QString path = (!prefix().isEmpty()) ? prefix() + "/" + key : key; + QString path = (!prefix().isEmpty()) ? prefix() + QLatin1Char('/') + key : key; QVariant res = d->mItems.value(path, defaultValue); if (res.type() == QVariant::String) { @@ -581,19 +641,19 @@ QVariant XdgDesktopFile::value(const QString& key, const QVariant& defaultValue) void XdgDesktopFile::setValue(const QString &key, const QVariant &value) { - QString path = (!prefix().isEmpty()) ? prefix() + "/" + key : key; + QString path = (!prefix().isEmpty()) ? prefix() + QLatin1Char('/') + key : key; if (value.type() == QVariant::String) { QString s=value.toString(); - if (key.toUpper() == "EXEC") + if (key.toUpper() == QLatin1String("EXEC")) escapeExec(s); else escape(s); d->mItems[path] = QVariant(s); - if (key.toUpper() == "TYPE") + if (key.toUpper() == QLatin1String("TYPE")) d->mType = d->detectType(this); } else @@ -619,28 +679,28 @@ void XdgDesktopFile::setLocalizedValue(const QString &key, const QVariant &value ************************************************/ QString XdgDesktopFile::localizedKey(const QString& key) const { - QString lang = getenv("LC_MESSAGES"); + QString lang = QString::fromLocal8Bit(qgetenv("LC_MESSAGES")); if (lang.isEmpty()) - lang = getenv("LC_ALL"); + lang = QString::fromLocal8Bit(qgetenv("LC_ALL")); if (lang.isEmpty()) - lang = getenv("LANG"); + lang = QString::fromLocal8Bit(qgetenv("LANG")); - QString modifier = lang.section('@', 1); + QString modifier = lang.section(QLatin1Char('@'), 1); if (!modifier.isEmpty()) lang.truncate(lang.length() - modifier.length() - 1); - QString encoding = lang.section('.', 1); + QString encoding = lang.section(QLatin1Char('.'), 1); if (!encoding.isEmpty()) lang.truncate(lang.length() - encoding.length() - 1); - QString country = lang.section('_', 1); + QString country = lang.section(QLatin1Char('_'), 1); if (!country.isEmpty()) lang.truncate(lang.length() - country.length() - 1); - //qDebug() << "LC_MESSAGES: " << getenv("LC_MESSAGES"); + //qDebug() << "LC_MESSAGES: " << qgetenv("LC_MESSAGES"); //qDebug() << "Lang:" << lang; //qDebug() << "Country:" << country; //qDebug() << "Encoding:" << encoding; @@ -649,7 +709,7 @@ QString XdgDesktopFile::localizedKey(const QString& key) const if (!modifier.isEmpty() && !country.isEmpty()) { - QString k = QString("%1[%2_%3@%4]").arg(key, lang, country, modifier); + QString k = QString::fromLatin1("%1[%2_%3@%4]").arg(key, lang, country, modifier); //qDebug() << "\t try " << k << contains(k); if (contains(k)) return k; @@ -657,7 +717,7 @@ QString XdgDesktopFile::localizedKey(const QString& key) const if (!country.isEmpty()) { - QString k = QString("%1[%2_%3]").arg(key, lang, country); + QString k = QString::fromLatin1("%1[%2_%3]").arg(key, lang, country); //qDebug() << "\t try " << k << contains(k); if (contains(k)) return k; @@ -665,13 +725,13 @@ QString XdgDesktopFile::localizedKey(const QString& key) const if (!modifier.isEmpty()) { - QString k = QString("%1[%2@%3]").arg(key, lang, modifier); + QString k = QString::fromLatin1("%1[%2@%3]").arg(key, lang, modifier); //qDebug() << "\t try " << k << contains(k); if (contains(k)) return k; } - QString k = QString("%1[%2]").arg(key, lang); + QString k = QString::fromLatin1("%1[%2]").arg(key, lang); //qDebug() << "\t try " << k << contains(k); if (contains(k)) return k; @@ -691,13 +751,13 @@ QVariant XdgDesktopFile::localizedValue(const QString& key, const QVariant& defa QStringList XdgDesktopFile::categories() const { QString key; - if (contains(QLatin1String(categoriesKey))) + if (contains(categoriesKey)) { - key = QLatin1String(categoriesKey); + key = categoriesKey; } else { - key = QLatin1String(extendPrefixKey) % QLatin1String(categoriesKey); + key = extendPrefixKey + categoriesKey; if (!contains(key)) return QStringList(); } @@ -709,14 +769,14 @@ QStringList XdgDesktopFile::categories() const void XdgDesktopFile::removeEntry(const QString& key) { - QString path = (!prefix().isEmpty()) ? prefix() + "/" + key : key; + QString path = (!prefix().isEmpty()) ? prefix() + QLatin1Char('/') + key : key; d->mItems.remove(path); } bool XdgDesktopFile::contains(const QString& key) const { - QString path = (!prefix().isEmpty()) ? prefix() + "/" + key : key; + QString path = (!prefix().isEmpty()) ? prefix() + QLatin1Char('/') + key : key; return d->mItems.contains(path); } @@ -735,10 +795,10 @@ QString XdgDesktopFile::fileName() const QIcon const XdgDesktopFile::icon(const QIcon& fallback) const { - QIcon result = XdgIcon::fromTheme(value("Icon").toString(), fallback); + QIcon result = XdgIcon::fromTheme(value(iconKey).toString(), fallback); if (result.isNull() && type() == ApplicationType) { - result = XdgIcon::fromTheme("application-x-executable.png"); + result = XdgIcon::fromTheme(QLatin1String("application-x-executable.png")); // TODO Maybe defaults for other desktopfile types as well.. } @@ -748,7 +808,13 @@ QIcon const XdgDesktopFile::icon(const QIcon& fallback) const QString const XdgDesktopFile::iconName() const { - return value("Icon").toString(); + return value(iconKey).toString(); +} + + +QStringList XdgDesktopFile::mimeTypes() const +{ + return value(mimeTypeKey).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); } @@ -774,9 +840,11 @@ bool XdgDesktopFile::startDetached(const QStringList& urls) const { case ApplicationType: return d->startApplicationDetached(this, urls); + break; case LinkType: return d->startLinkDetached(this); + break; default: return false; @@ -839,8 +907,8 @@ static QStringList parseCombinedArgString(const QString &program) void replaceVar(QString &str, const QString &varName, const QString &after) { - str.replace(QRegExp(QString("\\$%1(?!\\w)").arg(varName)), after); - str.replace(QRegExp(QString("\\$\\{%1\\}").arg(varName)), after); + str.replace(QRegExp(QString::fromLatin1("\\$%1(?!\\w)").arg(varName)), after); + str.replace(QRegExp(QString::fromLatin1("\\$\\{%1\\}").arg(varName)), after); } @@ -848,33 +916,35 @@ QString expandEnvVariables(const QString str) { QString scheme = QUrl(str).scheme(); - if (scheme == "http" || scheme == "https" || scheme == "shttp" || - scheme == "ftp" || scheme == "ftps" || - scheme == "pop" || scheme == "pops" || - scheme == "imap" || scheme == "imaps" || - scheme == "mailto" || - scheme == "nntp" || - scheme == "irc" || - scheme == "telnet" || - scheme == "xmpp" || - scheme == "irc" || - scheme == "nfs" + if (scheme == QLatin1String("http") || scheme == QLatin1String("https") || scheme == QLatin1String("shttp") || + scheme == QLatin1String("ftp") || scheme == QLatin1String("ftps") || + scheme == QLatin1String("pop") || scheme == QLatin1String("pops") || + scheme == QLatin1String("imap") || scheme == QLatin1String("imaps") || + scheme == QLatin1String("mailto") || + scheme == QLatin1String("nntp") || + scheme == QLatin1String("irc") || + scheme == QLatin1String("telnet") || + scheme == QLatin1String("xmpp") || + scheme == QLatin1String("irc") || + scheme == QLatin1String("nfs") ) return str; + const QString homeDir = QFile::decodeName(qgetenv("HOME")); + QString res = str; - res.replace(QRegExp("~(?=$|/)"), getenv("HOME")); + res.replace(QRegExp(QString::fromLatin1("~(?=$|/)")), homeDir); - replaceVar(res, "HOME", getenv("HOME")); - replaceVar(res, "USER", getenv("USER")); + replaceVar(res, QLatin1String("HOME"), homeDir); + replaceVar(res, QLatin1String("USER"), QString::fromLocal8Bit(qgetenv("USER"))); - replaceVar(res, "XDG_DESKTOP_DIR", QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)); - replaceVar(res, "XDG_TEMPLATES_DIR", QStandardPaths::writableLocation(QStandardPaths::TempLocation)); - replaceVar(res, "XDG_DOCUMENTS_DIR", QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)); - replaceVar(res, "XDG_MUSIC_DIR", QStandardPaths::writableLocation(QStandardPaths::MusicLocation)); - replaceVar(res, "XDG_PICTURES_DIR", QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)); - replaceVar(res, "XDG_VIDEOS_DIR", QStandardPaths::writableLocation(QStandardPaths::MoviesLocation)); - replaceVar(res, "XDG_PHOTOS_DIR", QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)); + replaceVar(res, QLatin1String("XDG_DESKTOP_DIR"), XdgDirs::userDir(XdgDirs::Desktop)); + replaceVar(res, QLatin1String("XDG_TEMPLATES_DIR"), XdgDirs::userDir(XdgDirs::Templates)); + replaceVar(res, QLatin1String("XDG_DOCUMENTS_DIR"), XdgDirs::userDir(XdgDirs::Documents)); + replaceVar(res, QLatin1String("XDG_MUSIC_DIR"), XdgDirs::userDir(XdgDirs::Music)); + replaceVar(res, QLatin1String("XDG_PICTURES_DIR"), XdgDirs::userDir(XdgDirs::Pictures)); + replaceVar(res, QLatin1String("XDG_VIDEOS_DIR"), XdgDirs::userDir(XdgDirs::Videos)); + replaceVar(res, QLatin1String("XDG_PHOTOS_DIR"), XdgDirs::userDir(XdgDirs::Pictures)); return res; } @@ -883,7 +953,7 @@ QString expandEnvVariables(const QString str) QStringList expandEnvVariables(const QStringList strs) { QStringList res; - foreach(QString s, strs) + foreach(const QString &s, strs) res << expandEnvVariables(s); return res; @@ -897,7 +967,7 @@ QStringList XdgDesktopFile::expandExecString(const QStringList& urls) const QStringList result; - QString execStr = value("Exec").toString(); + QString execStr = value(execKey).toString(); unEscapeExec(execStr); QStringList tokens = parseCombinedArgString(execStr); @@ -906,13 +976,13 @@ QStringList XdgDesktopFile::expandExecString(const QStringList& urls) const // The parseCombinedArgString() splits the string by the space symbols, // we temporarily replaced them on the special characters. // Now we reverse it. - token.replace(01, ' '); - token.replace(02, '\t'); - token.replace(03, '\n'); + token.replace(01, QLatin1Char(' ')); + token.replace(02, QLatin1Char('\t')); + token.replace(03, QLatin1Char('\n')); // ---------------------------------------------------------- // A single file name, even if multiple files are selected. - if (token == "%f") + if (token == QLatin1String("%f")) { if (!urls.isEmpty()) result << expandEnvVariables(urls.at(0)); @@ -922,7 +992,7 @@ QStringList XdgDesktopFile::expandExecString(const QStringList& urls) const // ---------------------------------------------------------- // A list of files. Use for apps that can open several local files at once. // Each file is passed as a separate argument to the executable program. - if (token == "%F") + if (token == QLatin1String("%F")) { result << expandEnvVariables(urls); continue; @@ -930,13 +1000,13 @@ QStringList XdgDesktopFile::expandExecString(const QStringList& urls) const // ---------------------------------------------------------- // A single URL. Local files may either be passed as file: URLs or as file path. - if (token == "%u") + if (token == QLatin1String("%u")) { if (!urls.isEmpty()) { QUrl url; url.setUrl(expandEnvVariables(urls.at(0))); - result << ((!url.toLocalFile().isEmpty()) ? url.toLocalFile() : url.toEncoded()); + result << ((!url.toLocalFile().isEmpty()) ? url.toLocalFile() : QString::fromUtf8(url.toEncoded())); } continue; } @@ -944,12 +1014,12 @@ QStringList XdgDesktopFile::expandExecString(const QStringList& urls) const // ---------------------------------------------------------- // A list of URLs. Each URL is passed as a separate argument to the executable // program. Local files may either be passed as file: URLs or as file path. - if (token == "%U") + if (token == QLatin1String("%U")) { - foreach (QString s, urls) + foreach (const QString &s, urls) { QUrl url(expandEnvVariables(s)); - result << ((!url.toLocalFile().isEmpty()) ? url.toLocalFile() : url.toEncoded()); + result << ((!url.toLocalFile().isEmpty()) ? url.toLocalFile() : QString::fromUtf8(url.toEncoded())); } continue; } @@ -958,11 +1028,11 @@ QStringList XdgDesktopFile::expandExecString(const QStringList& urls) const // The Icon key of the desktop entry expanded as two arguments, first --icon // and then the value of the Icon key. Should not expand to any arguments if // the Icon key is empty or missing. - if (token == "%i") + if (token == QLatin1String("%i")) { - QString icon = value("Icon").toString(); + QString icon = value(iconKey).toString(); if (!icon.isEmpty()) - result << "-icon" << icon.replace('%', "%%"); + result << QLatin1String("-icon") << icon.replace(QLatin1Char('%'), QLatin1String("%%")); continue; } @@ -970,27 +1040,27 @@ QStringList XdgDesktopFile::expandExecString(const QStringList& urls) const // ---------------------------------------------------------- // The translated name of the application as listed in the appropriate Name key // in the desktop entry. - if (token == "%c") + if (token == QLatin1String("%c")) { - result << localizedValue("Name").toString().replace('%', "%%"); + result << localizedValue(nameKey).toString().replace(QLatin1Char('%'), QLatin1String("%%")); continue; } // ---------------------------------------------------------- // The location of the desktop file as either a URI (if for example gotten from // the vfolder system) or a local filename or empty if no location is known. - if (token == "%k") + if (token == QLatin1String("%k")) { - result << fileName().replace('%', "%%"); + result << fileName().replace(QLatin1Char('%'), QLatin1String("%%")); break; } // ---------------------------------------------------------- // Deprecated. // Deprecated field codes should be removed from the command line and ignored. - if (token == "%d" || token == "%D" || - token == "%n" || token == "%N" || - token == "%v" || token == "%m" + if (token == QLatin1String("%d") || token == QLatin1String("%D") || + token == QLatin1String("%n") || token == QLatin1String("%N") || + token == QLatin1String("%v") || token == QLatin1String("%m") ) { continue; @@ -1009,9 +1079,9 @@ bool checkTryExec(const QString& progName) if (progName.startsWith(QDir::separator())) return QFileInfo(progName).isExecutable(); - QStringList dirs = QString(getenv("PATH")).split(":"); + QStringList dirs = QFile::decodeName(qgetenv("PATH")).split(QLatin1Char(':')); - foreach (QString dir, dirs) + foreach (const QString &dir, dirs) { if (QFileInfo(QDir(dir), progName).isExecutable()) return true; @@ -1021,25 +1091,34 @@ bool checkTryExec(const QString& progName) } -bool XdgDesktopFile::isShow(const QString& environment) const +QString XdgDesktopFile::id(const QString &fileName, bool checkFileExists) { - const QString env = environment.toUpper(); + const QFileInfo f(fileName); + if (checkFileExists) { + if (!f.exists()) { + return QString(); + } + } - if (d->mIsShow.contains(env)) - return d->mIsShow.value(env); + QString id = f.absoluteFilePath(); + const QStringList dataDirs = XdgDirs::dataDirs(); - d->mIsShow.insert(env, false); - // Means "this application exists, but don't display it in the menus". - if (value("NoDisplay").toBool()) - return false; + foreach(const QString &d, dataDirs) { + if (id.startsWith(d)) { + // remove only the first occurence + id.replace(id.indexOf(d), d.size(), QString()); + } + } - // The file is inapplicable to the current environment - if (!isSuitable(true, env)) - return false; + const QLatin1Char slash('/'); + const QString s = slash + applicationsStr + slash; + if (!id.startsWith(s)) + return QString(); + id.replace(id.indexOf(s), s.size(), QString()); + id.replace(slash, QLatin1Char('-')); - d->mIsShow.insert(env, true); - return true; + return id; } @@ -1053,7 +1132,7 @@ bool XdgDesktopFile::isShown(const QString &environment) const d->mIsShow.insert(env, false); // Means "this application exists, but don't display it in the menus". - if (value("NoDisplay").toBool()) + if (value(QLatin1String("NoDisplay")).toBool()) return false; // The file is not suitable to the current environment @@ -1065,45 +1144,11 @@ bool XdgDesktopFile::isShown(const QString &environment) const } -bool XdgDesktopFile::isApplicable(bool excludeHidden, const QString& environment) const -{ - // Hidden should have been called Deleted. It means the user deleted - // (at his level) something that was present - if (excludeHidden && value("Hidden").toBool()) - return false; - - // A list of strings identifying the environments that should display/not - // display a given desktop entry. - // OnlyShowIn ........ - if (contains("OnlyShowIn")) - { - QStringList s = value("OnlyShowIn").toString().split(';'); - if (!s.contains(environment)) - return false; - } - - // NotShowIn ......... - if (contains("NotShowIn")) - { - QStringList s = value("NotShowIn").toString().split(';'); - if (s.contains(environment)) - return false; - } - - // actually installed. If not, entry may not show in menus, etc. - QString s = value("TryExec").toString(); - if (!s.isEmpty() && ! checkTryExec(s)) - return false; - - return true; -} - - bool XdgDesktopFile::isSuitable(bool excludeHidden, const QString &environment) const { // Hidden should have been called Deleted. It means the user deleted // (at his level) something that was present - if (excludeHidden && value("Hidden").toBool()) + if (excludeHidden && value(QLatin1String("Hidden")).toBool()) return false; // A list of strings identifying the environments that should display/not @@ -1111,21 +1156,21 @@ bool XdgDesktopFile::isSuitable(bool excludeHidden, const QString &environment) // OnlyShowIn ........ QString env; if (environment.isEmpty()) - env = QString(detectDesktopEnvironment()); + env = QString::fromLocal8Bit(detectDesktopEnvironment()); else { env = environment.toUpper(); } QString key; bool keyFound = false; - if (contains(QLatin1String(onlyShowInKey))) + if (contains(onlyShowInKey)) { - key = QLatin1String(onlyShowInKey); + key = onlyShowInKey; keyFound = true; } else { - key = QLatin1String(extendPrefixKey) % QLatin1String(onlyShowInKey); + key = extendPrefixKey + onlyShowInKey; keyFound = contains(key) ? true : false; } @@ -1137,15 +1182,14 @@ bool XdgDesktopFile::isSuitable(bool excludeHidden, const QString &environment) } // NotShowIn ......... - keyFound = false; - if (contains(QLatin1String(notShowInKey))) + if (contains(notShowInKey)) { - key = QLatin1String(notShowInKey); + key = notShowInKey; keyFound = true; } else { - key = QLatin1String(extendPrefixKey) % QLatin1String(notShowInKey); + key = extendPrefixKey + notShowInKey; keyFound = contains(key) ? true : false; } @@ -1157,7 +1201,7 @@ bool XdgDesktopFile::isSuitable(bool excludeHidden, const QString &environment) } // actually installed. If not, entry may not show in menus, etc. - QString s = value("TryExec").toString(); + QString s = value(QLatin1String("TryExec")).toString(); if (!s.isEmpty() && ! checkTryExec(s)) return false; @@ -1167,12 +1211,12 @@ bool XdgDesktopFile::isSuitable(bool excludeHidden, const QString &environment) QString expandDynamicUrl(QString url) { - foreach(QString line, QProcess::systemEnvironment()) + foreach(const QString &line, QProcess::systemEnvironment()) { - QString name = line.section("=", 0, 0); - QString val = line.section("=", 1); - url.replace(QString("$%1").arg(name), val); - url.replace(QString("${%1}").arg(name), val); + QString name = line.section(QLatin1Char('='), 0, 0); + QString val = line.section(QLatin1Char('='), 1); + url.replace(QString::fromLatin1("$%1").arg(name), val); + url.replace(QString::fromLatin1("${%1}").arg(name), val); } return url; @@ -1186,12 +1230,12 @@ QString XdgDesktopFile::url() const QString url; - url = value("URL").toString(); + url = value(urlKey).toString(); if (!url.isEmpty()) return url; // WTF? What standard describes it? - url = expandDynamicUrl(value("URL[$e]").toString()); + url = expandDynamicUrl(value(QLatin1String("URL[$e]")).toString()); if (!url.isEmpty()) return url; @@ -1209,7 +1253,7 @@ QString findDesktopFile(const QString& dirName, const QString& desktopName) // Working recursively ............ QFileInfoList dirs = dir.entryInfoList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot); - foreach (QFileInfo d, dirs) + foreach (const QFileInfo &d, dirs) { QString cn = d.canonicalFilePath(); if (dirName != cn) @@ -1229,9 +1273,9 @@ QString findDesktopFile(const QString& desktopName) QStringList dataDirs = XdgDirs::dataDirs(); dataDirs.prepend(XdgDirs::dataHome(false)); - foreach (QString dirName, dataDirs) + foreach (const QString &dirName, dataDirs) { - QString f = findDesktopFile(dirName + "/applications", desktopName); + QString f = findDesktopFile(dirName + QLatin1String("/applications"), desktopName); if (!f.isEmpty()) return f; } @@ -1242,45 +1286,51 @@ QString findDesktopFile(const QString& desktopName) XdgDesktopFile* XdgDesktopFileCache::getFile(const QString& fileName) { + if (fileName.isEmpty()) + return nullptr; + if (instance().m_fileCache.contains(fileName)) { return instance().m_fileCache.value(fileName); } - if (fileName.startsWith(QDir::separator())) + QString file; + if (!fileName.startsWith(QDir::separator())) { - // Absolute path ........................ - //qDebug() << "XdgDesktopFileCache: add new file" << fileName; - XdgDesktopFile* desktopFile = load(fileName); - if (desktopFile->isValid()) - instance().m_fileCache.insert(fileName, desktopFile); - return desktopFile; + // Relative path + // Search desktop file .................. + file = findDesktopFile(fileName); + if (file.isEmpty()) + return nullptr; } else { - // Search desktop file .................. - QString filePath = findDesktopFile(fileName); - XdgDesktopFile* desktopFile; - //qDebug() << "Sokoloff XdgDesktopFileCache::getFile found fileName" << fileName << filePath; - if (!filePath.isEmpty()) - { - // The file was found - if (!instance().m_fileCache.contains(filePath)) - { - desktopFile = load(filePath); - instance().m_fileCache.insert(filePath, desktopFile); - } - else - desktopFile = instance().m_fileCache.value(filePath); + file = fileName; + } - return desktopFile; + XdgDesktopFile* desktopFile; + // The file was found + if (!instance().m_fileCache.contains(file)) + { + desktopFile = load(file); + if (desktopFile) + { + instance().m_fileCache.insert(file, desktopFile); + return desktopFile; } else { - return new XdgDesktopFile; + return nullptr; } } + else + { + // already in the cache + desktopFile = instance().m_fileCache.value(file); + return desktopFile; + } + } QList XdgDesktopFileCache::getAllFiles() @@ -1318,18 +1368,18 @@ bool readDesktopFile(QIODevice & device, QSettings::SettingsMap & map) QString line = stream.readLine().trimmed(); // Skip comments and empty lines - if (line.startsWith('#') || line.isEmpty()) + if (line.startsWith(QLatin1Char('#')) || line.isEmpty()) continue; // Section .............................. - if (line.startsWith('[') && line.endsWith(']')) + if (line.startsWith(QLatin1Char('[')) && line.endsWith(QLatin1Char(']'))) { section = line.mid(1, line.length()-2); continue; } - QString key = line.section('=', 0, 0).trimmed(); - QString value = line.section('=', 1).trimmed(); + QString key = line.section(QLatin1Char('='), 0, 0).trimmed(); + QString value = line.section(QLatin1Char('='), 1).trimmed(); if (key.isEmpty()) continue; @@ -1340,12 +1390,12 @@ bool readDesktopFile(QIODevice & device, QSettings::SettingsMap & map) return false; } - key.prepend("/"); + key.prepend(QLatin1Char('/')); key.prepend(section); - if (value.contains(";")) + if (value.contains(QLatin1Char(';'))) { - map.insert(key, value.split(";")); + map.insert(key, value.split(QLatin1Char(';'))); } else { @@ -1365,14 +1415,14 @@ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map) QTextStream stream(&device); QString section; - foreach (QString key, map.keys()) + foreach (const QString &key, map.keys()) { if (! map.value(key).canConvert()) { return false; } - QString thisSection = key.section("/", 0, 0); + QString thisSection = key.section(QLatin1Char('/'), 0, 0); if (thisSection.isEmpty()) { qWarning() << "No section defined"; @@ -1381,11 +1431,11 @@ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map) if (thisSection != section) { - stream << "[" << thisSection << "]" << "\n"; + stream << QLatin1Char('[') << thisSection << QLatin1Char(']') << QLatin1Char('\n'); section = thisSection; } - QString remainingKey = key.section("/", 1, -1); + QString remainingKey = key.section(QLatin1Char('/'), 1, -1); if (remainingKey.isEmpty()) { @@ -1393,7 +1443,7 @@ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map) return false; } - stream << remainingKey << "=" << map.value(key).toString() << "\n"; + stream << remainingKey << QLatin1Char('=') << map.value(key).toString() << QLatin1Char('\n'); } @@ -1407,12 +1457,12 @@ void XdgDesktopFileCache::initialize(const QString& dirName) // Directories have the type "application/x-directory", but in the desktop file // are shown as "inode/directory". To handle these cases, we use this hash. QHash specials; - specials.insert("inode/directory", "application/x-directory"); + specials.insert(QLatin1String("inode/directory"), QLatin1String("application/x-directory")); // Working recursively ............ QFileInfoList files = dir.entryInfoList(QStringList(), QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); - foreach (QFileInfo f, files) + foreach (const QFileInfo &f, files) { if (f.isDir()) { @@ -1430,15 +1480,15 @@ void XdgDesktopFileCache::initialize(const QString& dirName) m_fileCache.insert(f.absoluteFilePath(), df); } - QStringList mimes = df->value("MimeType").toString().split(';', QString::SkipEmptyParts); + QStringList mimes = df->value(mimeTypeKey).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); - foreach (QString mime, mimes) + foreach (const QString &mime, mimes) { - int pref = df->value("InitialPreference", 0).toInt(); + int pref = df->value(initialPreferenceKey, 0).toInt(); // We move the desktopFile forward in the list for this mime, so that // no desktopfile in front of it have a lower initialPreference. int position = m_defaultAppsCache[mime].length(); - while (position > 0 && m_defaultAppsCache[mime][position - 1]->value("InitialPreference, 0").toInt() < pref) + while (position > 0 && m_defaultAppsCache[mime][position - 1]->value(initialPreferenceKey, 0).toInt() < pref) { position--; } @@ -1452,8 +1502,13 @@ void XdgDesktopFileCache::initialize(const QString& dirName) XdgDesktopFile* XdgDesktopFileCache::load(const QString& fileName) { XdgDesktopFile* desktopFile = new XdgDesktopFile(); - desktopFile->load(fileName); - return desktopFile; + + Q_CHECK_PTR(desktopFile); + if (desktopFile && desktopFile->load(fileName)) + return desktopFile; + + delete desktopFile; + return nullptr; } @@ -1463,12 +1518,12 @@ void loadMimeCacheDir(const QString& dirName, QHash specials; - specials.insert("inode/directory", "application/x-directory"); + specials.insert(QLatin1String("inode/directory"), QLatin1String("application/x-directory")); // Working recursively ............ QFileInfoList files = dir.entryInfoList(QStringList(), QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); - foreach (QFileInfo f, files) + foreach (const QFileInfo &f, files) { if (f.isDir()) { @@ -1481,15 +1536,15 @@ void loadMimeCacheDir(const QString& dirName, QHashvalue("MimeType").toString().split(';', QString::SkipEmptyParts); + QStringList mimes = df->value(mimeTypeKey).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); - foreach (QString mime, mimes) + foreach (const QString &mime, mimes) { - int pref = df->value("InitialPreference", 0).toInt(); + int pref = df->value(initialPreferenceKey, 0).toInt(); // We move the desktopFile forward in the list for this mime, so that // no desktopfile in front of it have a lower initialPreference. int position = cache[mime].length(); - while (position > 0 && cache[mime][position - 1]->value("InitialPreference, 0").toInt() < pref) + while (position > 0 && cache[mime][position - 1]->value(initialPreferenceKey, 0).toInt() < pref) { position--; } @@ -1503,10 +1558,7 @@ QSettings::Format XdgDesktopFileCache::desktopFileSettingsFormat() static QSettings::Format format = QSettings::InvalidFormat; if (format == QSettings::InvalidFormat) - { - format = QSettings::registerFormat("*.list", readDesktopFile, writeDesktopFile); - qDebug() << "registerFormat returned:" << format; - } + format = QSettings::registerFormat(QLatin1String("*.list"), readDesktopFile, writeDesktopFile); return format; } @@ -1530,9 +1582,9 @@ void XdgDesktopFileCache::initialize() QStringList dataDirs = XdgDirs::dataDirs(); dataDirs.prepend(XdgDirs::dataHome(false)); - foreach (const QString dirname, dataDirs) + foreach (const QString &dirname, dataDirs) { - initialize(dirname + "/applications"); + initialize(dirname + QLatin1String("/applications")); // loadMimeCacheDir(dirname + "/applications", m_defaultAppsCache); } } @@ -1543,8 +1595,8 @@ QList XdgDesktopFileCache::getAppsOfCategory(const QString& cat const QString _category = category.toUpper(); foreach (XdgDesktopFile *desktopFile, instance().m_fileCache.values()) { - QStringList categories = desktopFile->value("Categories").toString().toUpper().split(QLatin1Char(';')); - if (!categories.isEmpty() && (categories.contains(_category) || categories.contains(QLatin1String("X-") % _category))) + QStringList categories = desktopFile->value(categoriesKey).toString().toUpper().split(QLatin1Char(';')); + if (!categories.isEmpty() && (categories.contains(_category) || categories.contains(QLatin1String("X-") + _category))) list.append(desktopFile); } return list; @@ -1562,24 +1614,24 @@ 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)); - foreach(const QString dataDir, dataDirs) + foreach(const QString &dataDir, dataDirs) { - QString defaultsListPath = dataDir + "/applications/mimeapps.list"; + QString defaultsListPath = dataDir + QLatin1String("/applications/mimeapps.list"); if (QFileInfo(defaultsListPath).exists()) { QSettings defaults(defaultsListPath, desktopFileSettingsFormat()); - defaults.beginGroup("Default Applications"); + defaults.beginGroup(QLatin1String("Default Applications")); if (defaults.contains(mimetype)) { QVariant value = defaults.value(mimetype); if (value.canConvert()) // A single string can also convert to a stringlist { - foreach (const QString desktopFileName, value.toStringList()) + foreach (const QString &desktopFileName, value.toStringList()) { XdgDesktopFile* desktopFile = XdgDesktopFileCache::getFile(desktopFileName); - if (desktopFile->isValid()) + if (desktopFile) { return desktopFile; } diff --git a/xdgdesktopfile.h b/qtxdg/xdgdesktopfile.h similarity index 89% rename from xdgdesktopfile.h rename to qtxdg/xdgdesktopfile.h index da7c90f..63c0994 100644 --- a/xdgdesktopfile.h +++ b/qtxdg/xdgdesktopfile.h @@ -79,7 +79,7 @@ public: - ApplicationType, "value" should be the Exec value; - LinkType, "value" should be the URL; - DirectoryType, "value" should be omitted */ - XdgDesktopFile(XdgDesktopFile::Type type, const QString& name, const QString& value = 0); + XdgDesktopFile(XdgDesktopFile::Type type, const QString& name, const QString& value = QString()); //! Destroys the object. virtual ~XdgDesktopFile(); @@ -146,11 +146,18 @@ public: //! Returns an icon name specified in this file. QString const iconName() const; + //! Returns an list of mimetypes specified in this file. + /*! @return Returns a list of the "MimeType=" entries. + * If the file doens't contain the MimeType entry, an empty QStringList is + * returned. Empty values are removed from the returned list. + */ + QStringList mimeTypes() const; + //! This function is provided for convenience. It's equivalent to calling localizedValue("Name").toString(). - QString name() const { return localizedValue("Name").toString(); } + QString name() const { return localizedValue(QLatin1String("Name")).toString(); } //! This function is provided for convenience. It's equivalent to calling localizedValue("Comment").toString(). - QString comment() const { return localizedValue("Comment").toString(); } + QString comment() const { return localizedValue(QLatin1String("Comment")).toString(); } /*! Returns the desktop file type. @see XdgDesktopFile::Type */ @@ -177,9 +184,16 @@ public: /*! Returns the URL for the Link desktop file; otherwise an empty string is returned. */ QString url() const; - /*! The desktop entry specification defines a number of fields to control the visibility of the application menu. This function - checks whether to display a this application or not. */ - QTXDG_DEPRECATED bool isShow(const QString& environment = "Razor") const; + /*! Computes the desktop file ID. It is the identifier of an installed + * desktop entry file. + * @par fileName - The desktop file complete name. + * @par checkFileExists If true and the file doesn't exist the computed ID + * will be an empty QString(). Defaults to true. + * @return The computed ID. Returns an empty QString() if it's impossible to + * compute the ID. Reference: + * https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id + */ + static QString id(const QString &fileName, bool checkFileExists = true); /*! The desktop entry specification defines a number of fields to control the visibility of the application menu. Thisfunction checks whether @@ -192,12 +206,6 @@ public: */ bool isShown(const QString &environment = QString()) const; - /*! This fuction returns true if the desktop file is applicable to the current environment. - @par excludeHidden - if set to true (default), files with "Hidden=true" will be considered "not applicable". - Setting this to false is be useful when the user wants to enable/disable items and wants to see those - that are Hidden */ - QTXDG_DEPRECATED bool isApplicable(bool excludeHidden = true, const QString& environment = "Razor") const; - /*! This fuction returns true if the desktop file is applicable to the current environment. @par excludeHidden - if set to true (default), files with @@ -213,7 +221,7 @@ public: bool isSuitable(bool excludeHidden = true, const QString &environment = QString()) const; protected: - virtual QString prefix() const { return "Desktop Entry"; } + virtual QString prefix() const { return QLatin1String("Desktop Entry"); } virtual bool check() const { return true; } private: /*! Returns the localized version of the key if the Desktop File already contains a localized version of it. @@ -261,5 +269,3 @@ private: #endif // QTXDG_XDGDESKTOPFILE_H - - diff --git a/xdgdesktopfile_p.h b/qtxdg/xdgdesktopfile_p.h similarity index 100% rename from xdgdesktopfile_p.h rename to qtxdg/xdgdesktopfile_p.h diff --git a/xdgdirs.cpp b/qtxdg/xdgdirs.cpp similarity index 76% rename from xdgdirs.cpp rename to qtxdg/xdgdirs.cpp index 0d7debe..45d5367 100644 --- a/xdgdirs.cpp +++ b/qtxdg/xdgdirs.cpp @@ -28,21 +28,20 @@ #include "xdgdirs.h" #include #include -#include // for the % operator #include #include static const QString userDirectoryString[8] = { - "Desktop", - "Download", - "Templates", - "Publicshare", - "Documents", - "Music", - "Pictures", - "Videos" + QLatin1String("Desktop"), + QLatin1String("Download"), + QLatin1String("Templates"), + QLatin1String("Publicshare"), + QLatin1String("Documents"), + QLatin1String("Music"), + QLatin1String("Pictures"), + QLatin1String("Videos") }; // Helper functions prototypes @@ -51,7 +50,7 @@ void removeEndingSlash(QString &s); QString createDirectory(const QString &dir); void cleanAndAddPostfix(QStringList &dirs, const QString& postfix); - +QString userDirFallback(XdgDirs::UserDirectory dir); /************************************************ Helper func. @@ -59,7 +58,7 @@ void cleanAndAddPostfix(QStringList &dirs, const QString& postfix); void fixBashShortcuts(QString &s) { if (s.startsWith(QLatin1Char('~'))) - s = QString(getenv("HOME")) + (s).mid(1); + s = QFile::decodeName(qgetenv("HOME")) + (s).mid(1); } @@ -78,9 +77,9 @@ QString createDirectory(const QString &dir) QDir d(dir); if (!d.exists()) { - if (!d.mkpath(".")) + if (!d.mkpath(QLatin1String("."))) { - qWarning() << QString("Can't create %1 directory.").arg(d.absolutePath()); + qWarning() << QString::fromLatin1("Can't create %1 directory.").arg(d.absolutePath()); } } QString r = d.absolutePath(); @@ -101,31 +100,53 @@ void cleanAndAddPostfix(QStringList &dirs, const QString& postfix) } +QString userDirFallback(XdgDirs::UserDirectory dir) +{ + QString fallback; + const QString home = QFile::decodeName(qgetenv("HOME")); + + if (home.isEmpty()) + return QString::fromLatin1("/tmp"); + else if (dir == XdgDirs::Desktop) + fallback = QString::fromLatin1("%1/%2").arg(home).arg(QLatin1String("Desktop")); + else + fallback = home; + + return fallback; +} + + +QString XdgDirs::userDirDefault(XdgDirs::UserDirectory dir) +{ + // possible values for UserDirectory + Q_ASSERT(!(dir < XdgDirs::Desktop || dir > XdgDirs::Videos)); + if (dir < XdgDirs::Desktop || dir > XdgDirs::Videos) + return QString(); + + return userDirFallback(dir); +} + + QString XdgDirs::userDir(XdgDirs::UserDirectory dir) { // possible values for UserDirectory - if (dir < 0 || dir > 7) + Q_ASSERT(!(dir < XdgDirs::Desktop || dir > XdgDirs::Videos)); + if (dir < XdgDirs::Desktop || dir > XdgDirs::Videos) return QString(); QString folderName = userDirectoryString[dir]; - QString fallback; - if (getenv("HOME") == NULL) - return QString("/tmp"); - else if (dir == XdgDirs::Desktop) - fallback = QString("%1/%2").arg(getenv("HOME")).arg("Desktop"); - else - fallback = QString(getenv("HOME")); + const QString fallback = userDirFallback(dir); QString configDir(configHome()); - QFile configFile(configDir + "/user-dirs.dirs"); + QFile configFile(configDir + QLatin1String("/user-dirs.dirs")); if (!configFile.exists()) return fallback; if (!configFile.open(QIODevice::ReadOnly | QIODevice::Text)) return fallback; - QString userDirVar("XDG_" + folderName.toUpper() + "_DIR"); + QString userDirVar(QLatin1String("XDG_") + folderName.toUpper() + QLatin1String("_DIR")); QTextStream in(&configFile); QString line; while (!in.atEnd()) @@ -137,6 +158,8 @@ QString XdgDirs::userDir(XdgDirs::UserDirectory dir) // get path between quotes line = line.section(QLatin1Char('"'), 1, 1); + if (line.isEmpty()) + return fallback; line.replace(QLatin1String("$HOME"), QLatin1String("~")); fixBashShortcuts(line); return line; @@ -151,18 +174,19 @@ QString XdgDirs::userDir(XdgDirs::UserDirectory dir) bool XdgDirs::setUserDir(XdgDirs::UserDirectory dir, const QString& value, bool createDir) { // possible values for UserDirectory - if (dir < 0 || dir > 7) + Q_ASSERT(!(dir < XdgDirs::Desktop || dir > XdgDirs::Videos)); + if (dir < XdgDirs::Desktop || dir > XdgDirs::Videos) return false; if (!(value.startsWith(QLatin1String("$HOME")) || value.startsWith(QLatin1String("~/")) - || value.startsWith(QString(getenv("HOME"))))) + || value.startsWith(QFile::decodeName(qgetenv("HOME"))))) return false; QString folderName = userDirectoryString[dir]; QString configDir(configHome()); - QFile configFile(configDir % QLatin1String("/user-dirs.dirs")); + QFile configFile(configDir + QLatin1String("/user-dirs.dirs")); // create the file if doesn't exist and opens it if (!configFile.open(QIODevice::ReadWrite | QIODevice::Text)) @@ -191,10 +215,10 @@ bool XdgDirs::setUserDir(XdgDirs::UserDirectory dir, const QString& value, bool stream.reset(); configFile.resize(0); if (!foundVar) - stream << QString("XDG_%1_DIR=\"%2\"\n").arg(folderName.toUpper()).arg(value); + stream << QString::fromLatin1("XDG_%1_DIR=\"%2\"\n").arg(folderName.toUpper()).arg(value); for (QVector::iterator i = lines.begin(); i != lines.end(); ++i) - stream << *i << "\n"; + stream << *i << QLatin1Char('\n'); configFile.close(); @@ -293,7 +317,7 @@ QString XdgDirs::runtimeDir() QString XdgDirs::autostartHome(bool createDir) { - QString s = QString("%1/autostart").arg(configHome(createDir)); + QString s = QString::fromLatin1("%1/autostart").arg(configHome(createDir)); fixBashShortcuts(s); if (createDir) @@ -309,9 +333,9 @@ QString XdgDirs::autostartHome(bool createDir) QStringList XdgDirs::autostartDirs(const QString &postfix) { QStringList dirs; - QStringList s = configDirs(); - foreach(QString dir, s) - dirs << QString("%1/autostart").arg(dir) + postfix; + const QStringList s = configDirs(); + foreach(const QString &dir, s) + dirs << QString::fromLatin1("%1/autostart").arg(dir) + postfix; return dirs; } diff --git a/xdgdirs.h b/qtxdg/xdgdirs.h similarity index 95% rename from xdgdirs.h rename to qtxdg/xdgdirs.h index fb333d2..1d2f791 100644 --- a/xdgdirs.h +++ b/qtxdg/xdgdirs.h @@ -62,6 +62,14 @@ public: */ static QString userDir(UserDirectory dir); + + /*! @brief Returns the default path to the user specified directory. + * Returns /tmp if no $HOME defined, $HOME/Desktop if dir equals + * XdgDirs::Desktop or $HOME othewise. If dir value is invalid, an empty + * QString is returned. + */ + static QString userDirDefault(UserDirectory dir); + /*! @brief Returns true if writting into configuration file $XDG_CONFIG_HOME/user-dirs.dirs * the path in value for the directory in dir is succesfull. Returns false otherwise. If * createDir is true, dir will be created if it doesn't exist. diff --git a/xdgicon.cpp b/qtxdg/xdgicon.cpp similarity index 88% rename from xdgicon.cpp rename to qtxdg/xdgicon.cpp index 231a3d5..bb1e153 100644 --- a/xdgicon.cpp +++ b/qtxdg/xdgicon.cpp @@ -33,10 +33,10 @@ #include #include #include -#include "qiconfix/qiconloader_p.h" +#include "../xdgiconloader/xdgiconloader_p.h" #include -#define DEFAULT_APP_ICON "application-x-executable" +static const QLatin1String DEFAULT_APP_ICON("application-x-executable"); static void qt_cleanup_icon_cache(); typedef QCache IconCache; @@ -83,7 +83,7 @@ QString XdgIcon::themeName() void XdgIcon::setThemeName(const QString& themeName) { QIcon::setThemeName(themeName); - QtXdg::QIconLoader::instance()->updateSystemTheme(); + XdgIconLoader::instance()->updateSystemTheme(); } @@ -96,12 +96,12 @@ QIcon XdgIcon::fromTheme(const QString& iconName, const QIcon& fallback) if (iconName.isEmpty()) return fallback; - bool isAbsolute = (iconName[0] == '/'); + bool isAbsolute = (iconName[0] == QLatin1Char('/')); QString name = QFileInfo(iconName).fileName(); - if (name.endsWith(".png", Qt::CaseInsensitive) || - name.endsWith(".svg", Qt::CaseInsensitive) || - name.endsWith(".xpm", Qt::CaseInsensitive)) + if (name.endsWith(QLatin1String(".png"), Qt::CaseInsensitive) || + name.endsWith(QLatin1String(".svg"), Qt::CaseInsensitive) || + name.endsWith(QLatin1String(".xpm"), Qt::CaseInsensitive)) { name.truncate(name.length() - 4); } @@ -113,11 +113,12 @@ QIcon XdgIcon::fromTheme(const QString& iconName, const QIcon& fallback) } else { QIcon *cachedIcon; if (!isAbsolute) - cachedIcon = new QIcon(new QtXdg::QIconLoaderEngineFixed(name)); + cachedIcon = new QIcon(new XdgIconLoaderEngine(name)); else cachedIcon = new QIcon(iconName); - qtIconCache()->insert(name, cachedIcon); icon = *cachedIcon; + + qtIconCache()->insert(name, cachedIcon); } // Note the qapp check is to allow lazy loading of static icons @@ -136,7 +137,7 @@ QIcon XdgIcon::fromTheme(const QString& iconName, const QIcon& fallback) ************************************************/ QIcon XdgIcon::fromTheme(const QStringList& iconNames, const QIcon& fallback) { - foreach (QString iconName, iconNames) + foreach (const QString &iconName, iconNames) { QIcon icon = fromTheme(iconName); if (!icon.isNull()) diff --git a/xdgicon.h b/qtxdg/xdgicon.h similarity index 100% rename from xdgicon.h rename to qtxdg/xdgicon.h diff --git a/xdgmacros.h b/qtxdg/xdgmacros.h similarity index 100% rename from xdgmacros.h rename to qtxdg/xdgmacros.h diff --git a/xdgmenu.cpp b/qtxdg/xdgmenu.cpp similarity index 68% rename from xdgmenu.cpp rename to qtxdg/xdgmenu.cpp index c17259f..b59a001 100644 --- a/xdgmenu.cpp +++ b/qtxdg/xdgmenu.cpp @@ -157,37 +157,37 @@ bool XdgMenu::read(const QString& menuFileName) d->mXml = reader.xml(); QDomElement root = d->mXml.documentElement(); - d->saveLog("00-reader.xml"); + d->saveLog(QLatin1String("00-reader.xml")); d->simplify(root); - d->saveLog("01-simplify.xml"); + d->saveLog(QLatin1String("01-simplify.xml")); d->mergeMenus(root); - d->saveLog("02-mergeMenus.xml"); + d->saveLog(QLatin1String("02-mergeMenus.xml")); d->moveMenus(root); - d->saveLog("03-moveMenus.xml"); + d->saveLog(QLatin1String("03-moveMenus.xml")); d->mergeMenus(root); - d->saveLog("04-mergeMenus.xml"); + d->saveLog(QLatin1String("04-mergeMenus.xml")); d->deleteDeletedMenus(root); - d->saveLog("05-deleteDeletedMenus.xml"); + d->saveLog(QLatin1String("05-deleteDeletedMenus.xml")); d->processDirectoryEntries(root, QStringList()); - d->saveLog("06-processDirectoryEntries.xml"); + d->saveLog(QLatin1String("06-processDirectoryEntries.xml")); d->processApps(root); - d->saveLog("07-processApps.xml"); + d->saveLog(QLatin1String("07-processApps.xml")); d->processLayouts(root); - d->saveLog("08-processLayouts.xml"); + d->saveLog(QLatin1String("08-processLayouts.xml")); d->deleteEmpty(root); - d->saveLog("09-deleteEmpty.xml"); + d->saveLog(QLatin1String("09-deleteEmpty.xml")); d->fixSeparators(root); - d->saveLog("10-fixSeparators.xml"); + d->saveLog(QLatin1String("10-fixSeparators.xml")); d->mOutDated = false; @@ -204,7 +204,7 @@ void XdgMenu::save(const QString& fileName) QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { - qWarning() << QString("Cannot write file %1:\n%2.") + qWarning() << QString::fromLatin1("Cannot write file %1:\n%2.") .arg(fileName) .arg(file.errorString()); return; @@ -225,7 +225,7 @@ void XdgMenuPrivate::load(const QString& fileName) QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { - qWarning() << QString("%1 not loading: %2").arg(fileName).arg(file.errorString()); + qWarning() << QString::fromLatin1("%1 not loading: %2").arg(fileName).arg(file.errorString()); return; } mXml.setContent(&file, true); @@ -236,7 +236,7 @@ void XdgMenuPrivate::saveLog(const QString& logFileName) { Q_Q(XdgMenu); if (!mLogDir.isEmpty()) - q->save(mLogDir + "/" + logFileName); + q->save(mLogDir + QLatin1Char('/') + logFileName); } @@ -244,13 +244,13 @@ void XdgMenuPrivate::mergeMenus(QDomElement& element) { QHash menus; - MutableDomElementIterator it(element, "Menu"); + MutableDomElementIterator it(element, QLatin1String("Menu")); it.toFront(); while(it.hasNext()) { it.next(); - menus[it.current().attribute("name")] = it.current(); + menus[it.current().attribute(QLatin1String("name"))] = it.current(); } @@ -258,7 +258,7 @@ void XdgMenuPrivate::mergeMenus(QDomElement& element) while (it.hasPrevious()) { QDomElement src = it.previous(); - QDomElement dest = menus[src.attribute("name")]; + QDomElement dest = menus[src.attribute(QLatin1String("name"))]; if (dest != src) { prependChilds(src, dest); @@ -267,11 +267,11 @@ void XdgMenuPrivate::mergeMenus(QDomElement& element) } - QDomElement n = element.firstChildElement("Menu"); + QDomElement n = element.firstChildElement(QLatin1String("Menu")); while (!n.isNull()) { mergeMenus(n); - n = n.nextSiblingElement("Menu"); + n = n.nextSiblingElement(QLatin1String("Menu")); } it.toFront(); @@ -288,46 +288,46 @@ void XdgMenuPrivate::simplify(QDomElement& element) { QDomElement n = it.next(); - if (n.tagName() == "Name") + if (n.tagName() == QLatin1String("Name")) { // The field must not contain the slash character ("/"); // implementations should discard any name containing a slash. - element.setAttribute("name", n.text().remove('/')); + element.setAttribute(QLatin1String("name"), n.text().remove(QLatin1Char('/'))); n.parentNode().removeChild(n); } // ...................................... - else if(n.tagName() == "Deleted") + else if(n.tagName() == QLatin1String("Deleted")) { - element.setAttribute("deleted", true); + element.setAttribute(QLatin1String("deleted"), true); n.parentNode().removeChild(n); } - else if(n.tagName() == "NotDeleted") + else if(n.tagName() == QLatin1String("NotDeleted")) { - element.setAttribute("deleted", false); + element.setAttribute(QLatin1String("deleted"), false); n.parentNode().removeChild(n); } // ...................................... - else if(n.tagName() == "OnlyUnallocated") + else if(n.tagName() == QLatin1String("OnlyUnallocated")) { - element.setAttribute("onlyUnallocated", true); + element.setAttribute(QLatin1String("onlyUnallocated"), true); n.parentNode().removeChild(n); } - else if(n.tagName() == "NotOnlyUnallocated") + else if(n.tagName() == QLatin1String(QLatin1String("NotOnlyUnallocated"))) { - element.setAttribute("onlyUnallocated", false); + element.setAttribute(QLatin1String("onlyUnallocated"), false); n.parentNode().removeChild(n); } // ...................................... - else if(n.tagName() == "FileInfo") + else if(n.tagName() == QLatin1String("FileInfo")) { n.parentNode().removeChild(n); } // ...................................... - else if(n.tagName() == "Menu") + else if(n.tagName() == QLatin1String("Menu")) { simplify(n); } @@ -348,15 +348,15 @@ void XdgMenuPrivate::prependChilds(QDomElement& srcElement, QDomElement& destEle destElement.insertBefore(n, destElement.firstChild()); } - if (srcElement.attributes().contains("deleted") && - !destElement.attributes().contains("deleted") + if (srcElement.attributes().contains(QLatin1String("deleted")) && + !destElement.attributes().contains(QLatin1String("deleted")) ) - destElement.setAttribute("deleted", srcElement.attribute("deleted")); + destElement.setAttribute(QLatin1String("deleted"), srcElement.attribute(QLatin1String("deleted"))); - if (srcElement.attributes().contains("onlyUnallocated") && - !destElement.attributes().contains("onlyUnallocated") + if (srcElement.attributes().contains(QLatin1String("onlyUnallocated")) && + !destElement.attributes().contains(QLatin1String("onlyUnallocated")) ) - destElement.setAttribute("onlyUnallocated", srcElement.attribute("onlyUnallocated")); + destElement.setAttribute(QLatin1String("onlyUnallocated"), srcElement.attribute(QLatin1String("onlyUnallocated"))); } @@ -367,11 +367,11 @@ void XdgMenuPrivate::appendChilds(QDomElement& srcElement, QDomElement& destElem while(it.hasNext()) destElement.appendChild(it.next()); - if (srcElement.attributes().contains("deleted")) - destElement.setAttribute("deleted", srcElement.attribute("deleted")); + if (srcElement.attributes().contains(QLatin1String("deleted"))) + destElement.setAttribute(QLatin1String("deleted"), srcElement.attribute(QLatin1String("deleted"))); - if (srcElement.attributes().contains("onlyUnallocated")) - destElement.setAttribute("onlyUnallocated", srcElement.attribute("onlyUnallocated")); + if (srcElement.attributes().contains(QLatin1String("onlyUnallocated"))) + destElement.setAttribute(QLatin1String("onlyUnallocated"), srcElement.attribute(QLatin1String("onlyUnallocated"))); } @@ -384,10 +384,10 @@ QDomElement XdgMenu::findMenu(QDomElement& baseElement, const QString& path, boo { Q_D(XdgMenu); // Absolute path .................. - if (path.startsWith('/')) + if (path.startsWith(QLatin1Char('/'))) { QDomElement root = d->mXml.documentElement(); - return findMenu(root, path.section('/', 2), createNonExisting); + return findMenu(root, path.section(QLatin1Char('/'), 2), createNonExisting); } // Relative path .................. @@ -395,13 +395,13 @@ QDomElement XdgMenu::findMenu(QDomElement& baseElement, const QString& path, boo return baseElement; - QString name = path.section('/', 0, 0); + QString name = path.section(QLatin1Char('/'), 0, 0); MutableDomElementIterator it(baseElement); while(it.hasNext()) { QDomElement n = it.next(); - if (n.attribute("name") == name) - return findMenu(n, path.section('/', 1), createNonExisting); + if (n.attribute(QLatin1String("name")) == name) + return findMenu(n, path.section(QLatin1Char('/'), 1), createNonExisting); } @@ -411,14 +411,14 @@ QDomElement XdgMenu::findMenu(QDomElement& baseElement, const QString& path, boo return QDomElement(); - QStringList names = path.split('/', QString::SkipEmptyParts); + const QStringList names = path.split(QLatin1Char('/'), QString::SkipEmptyParts); QDomElement el = baseElement; - foreach (QString name, names) + foreach (const QString &name, names) { QDomElement p = el; - el = d->mXml.createElement("Menu"); + el = d->mXml.createElement(QLatin1String("Menu")); p.appendChild(el); - el.setAttribute("name", name); + el.setAttribute(QLatin1String("name"), name); } return el; @@ -454,17 +454,17 @@ void XdgMenuPrivate::moveMenus(QDomElement& element) Q_Q(XdgMenu); { - MutableDomElementIterator i(element, "Menu"); + MutableDomElementIterator i(element, QLatin1String("Menu")); while(i.hasNext()) moveMenus(i.next()); } - MutableDomElementIterator i(element, "Move"); + MutableDomElementIterator i(element, QLatin1String("Move")); while(i.hasNext()) { i.next(); - QString oldPath = i.current().lastChildElement("Old").text(); - QString newPath = i.current().lastChildElement("New").text(); + QString oldPath = i.current().lastChildElement(QLatin1String("Old")).text(); + QString newPath = i.current().lastChildElement(QLatin1String("New")).text(); element.removeChild(i.current()); @@ -494,12 +494,12 @@ void XdgMenuPrivate::moveMenus(QDomElement& element) ************************************************/ void XdgMenuPrivate::deleteDeletedMenus(QDomElement& element) { - MutableDomElementIterator i(element, "Menu"); + MutableDomElementIterator i(element, QLatin1String("Menu")); while(i.hasNext()) { QDomElement e = i.next(); - if (e.attribute("deleted") == "1" || - e.attribute("name") == ".hidden" + if (e.attribute(QLatin1String("deleted")) == QLatin1String("1") || + e.attribute(QLatin1String("name")) == QLatin1String(".hidden") ) element.removeChild(e); else @@ -514,7 +514,7 @@ void XdgMenuPrivate::processDirectoryEntries(QDomElement& element, const QString QStringList dirs; QStringList files; - element.setAttribute("title", element.attribute("name")); + element.setAttribute(QLatin1String("title"), element.attribute(QLatin1String("name"))); MutableDomElementIterator i(element, QString()); i.toBack(); @@ -522,13 +522,13 @@ void XdgMenuPrivate::processDirectoryEntries(QDomElement& element, const QString { QDomElement e = i.previous(); - if (e.tagName() == "Directory") + if (e.tagName() == QLatin1String("Directory")) { files << e.text(); element.removeChild(e); } - else if (e.tagName() == "DirectoryDir") + else if (e.tagName() == QLatin1String("DirectoryDir")) { dirs << e.text(); element.removeChild(e); @@ -538,14 +538,14 @@ void XdgMenuPrivate::processDirectoryEntries(QDomElement& element, const QString dirs << parentDirs; bool found = false; - foreach(QString file, files){ - if (file.startsWith('/')) + foreach(const QString &file, files){ + if (file.startsWith(QLatin1Char('/'))) found = loadDirectoryFile(file, element); else { - foreach (QString dir, dirs) + foreach (const QString &dir, dirs) { - found = loadDirectoryFile(dir + "/" + file, element); + found = loadDirectoryFile(dir + QLatin1Char('/') + file, element); if (found) break; } } @@ -553,7 +553,7 @@ void XdgMenuPrivate::processDirectoryEntries(QDomElement& element, const QString } - MutableDomElementIterator it(element, "Menu"); + MutableDomElementIterator it(element, QLatin1String("Menu")); while(it.hasNext()) { QDomElement e = it.next(); @@ -572,9 +572,9 @@ bool XdgMenuPrivate::loadDirectoryFile(const QString& fileName, QDomElement& ele return false; - element.setAttribute("title", file.localizedValue("Name").toString()); - element.setAttribute("comment", file.localizedValue("Comment").toString()); - element.setAttribute("icon", file.value("Icon").toString()); + element.setAttribute(QLatin1String("title"), file.localizedValue(QLatin1String("Name")).toString()); + element.setAttribute(QLatin1String("comment"), file.localizedValue(QLatin1String("Comment")).toString()); + element.setAttribute(QLatin1String("icon"), file.value(QLatin1String("Icon")).toString()); Q_Q(XdgMenu); q->addWatchPath(QFileInfo(file.fileName()).absolutePath()); @@ -592,15 +592,15 @@ void XdgMenuPrivate::processApps(QDomElement& element) void XdgMenuPrivate::deleteEmpty(QDomElement& element) { - MutableDomElementIterator it(element, "Menu"); + MutableDomElementIterator it(element, QLatin1String("Menu")); while(it.hasNext()) deleteEmpty(it.next()); - if (element.attribute("keep") == "true") + if (element.attribute(QLatin1String("keep")) == QLatin1String("true")) return; - QDomElement childMenu = element.firstChildElement("Menu"); - QDomElement childApps = element.firstChildElement("AppLink"); + QDomElement childMenu = element.firstChildElement(QLatin1String("Menu")); + QDomElement childApps = element.firstChildElement(QLatin1String("AppLink")); if (childMenu.isNull() && childApps.isNull()) { @@ -619,25 +619,25 @@ void XdgMenuPrivate::processLayouts(QDomElement& element) void XdgMenuPrivate::fixSeparators(QDomElement& element) { - MutableDomElementIterator it(element, "Separator"); + MutableDomElementIterator it(element, QLatin1String("Separator")); while(it.hasNext()) { QDomElement s = it.next(); - if (s.previousSiblingElement().tagName() == "Separator") + if (s.previousSiblingElement().tagName() == QLatin1String("Separator")) element.removeChild(s); } QDomElement first = element.firstChild().toElement(); - if (first.tagName() == "Separator") + if (first.tagName() == QLatin1String("Separator")) element.removeChild(first); QDomElement last = element.lastChild().toElement(); - if (last.tagName() == "Separator") + if (last.tagName() == QLatin1String("Separator")) element.removeChild(last); - MutableDomElementIterator mi(element, "Menu"); + MutableDomElementIterator mi(element, QLatin1String("Menu")); while(mi.hasNext()) fixSeparators(mi.next()); } @@ -649,32 +649,32 @@ void XdgMenuPrivate::fixSeparators(QDomElement& element) ************************************************/ QString XdgMenu::getMenuFileName(const QString& baseName) { - QStringList configDirs = XdgDirs::configDirs(); - QString menuPrefix = getenv("XDG_MENU_PREFIX"); + const QStringList configDirs = XdgDirs::configDirs(); + QString menuPrefix = QString::fromLocal8Bit(qgetenv("XDG_MENU_PREFIX")); - foreach(QString configDir, configDirs) + foreach(const QString &configDir, configDirs) { - QFileInfo file(QString("%1/menus/%2%3").arg(configDir, menuPrefix, baseName)); + QFileInfo file(QString::fromLatin1("%1/menus/%2%3").arg(configDir, menuPrefix, baseName)); if (file.exists()) return file.filePath(); } QStringList wellKnownFiles; // razor- is a priority for us - wellKnownFiles << "razor-applications.menu"; + wellKnownFiles << QLatin1String("razor-applications.menu"); // the "global" menu file name on suse and fedora - wellKnownFiles << "applications.menu"; + wellKnownFiles << QLatin1String("applications.menu"); // rest files ordered by priority (descending) - wellKnownFiles << "kde4-applications.menu"; - wellKnownFiles << "kde-applications.menu"; - wellKnownFiles << "gnome-applications.menu"; - wellKnownFiles << "lxde-applications.menu"; + wellKnownFiles << QLatin1String("kde4-applications.menu"); + wellKnownFiles << QLatin1String("kde-applications.menu"); + wellKnownFiles << QLatin1String("gnome-applications.menu"); + wellKnownFiles << QLatin1String("lxde-applications.menu"); - foreach(QString configDir, configDirs) + foreach(const QString &configDir, configDirs) { - foreach (QString f, wellKnownFiles) + foreach (const QString &f, wellKnownFiles) { - QFileInfo file(QString("%1/menus/%2").arg(configDir, f)); + QFileInfo file(QString::fromLatin1("%1/menus/%2").arg(configDir, f)); if (file.exists()) return file.filePath(); } diff --git a/xdgmenu.h b/qtxdg/xdgmenu.h similarity index 97% rename from xdgmenu.h rename to qtxdg/xdgmenu.h index a88aa64..e18e0c3 100644 --- a/xdgmenu.h +++ b/qtxdg/xdgmenu.h @@ -108,7 +108,7 @@ public: */ void setLogDir(const QString& directory); - static QString getMenuFileName(const QString& baseName = "applications.menu"); + static QString getMenuFileName(const QString& baseName = QLatin1String("applications.menu")); bool isOutDated() const; diff --git a/xdgmenu_p.h b/qtxdg/xdgmenu_p.h similarity index 100% rename from xdgmenu_p.h rename to qtxdg/xdgmenu_p.h diff --git a/xdgmenuapplinkprocessor.cpp b/qtxdg/xdgmenuapplinkprocessor.cpp similarity index 74% rename from xdgmenuapplinkprocessor.cpp rename to qtxdg/xdgmenuapplinkprocessor.cpp index 02265d6..f031940 100644 --- a/xdgmenuapplinkprocessor.cpp +++ b/qtxdg/xdgmenuapplinkprocessor.cpp @@ -40,9 +40,9 @@ XdgMenuApplinkProcessor::XdgMenuApplinkProcessor(QDomElement& element, XdgMenu* mParent = parent; mMenu = menu; - mOnlyUnallocated = element.attribute("onlyUnallocated") == "1"; + mOnlyUnallocated = element.attribute(QLatin1String("onlyUnallocated")) == QLatin1String("1"); - MutableDomElementIterator i(element, "Menu"); + MutableDomElementIterator i(element, QLatin1String("Menu")); while(i.hasNext()) { QDomElement e = i.next(); @@ -122,18 +122,18 @@ void XdgMenuApplinkProcessor::step2() if (!show) continue; - QDomElement appLink = doc.createElement("AppLink"); + QDomElement appLink = doc.createElement(QLatin1String("AppLink")); - appLink.setAttribute("id", fileInfo->id()); - appLink.setAttribute("title", file->localizedValue("Name").toString()); - appLink.setAttribute("comment", file->localizedValue("Comment").toString()); - appLink.setAttribute("genericName", file->localizedValue("GenericName").toString()); - appLink.setAttribute("exec", file->value("Exec").toString()); - appLink.setAttribute("terminal", file->value("Terminal").toBool()); - appLink.setAttribute("startupNotify", file->value("StartupNotify").toBool()); - appLink.setAttribute("path", file->value("Path").toString()); - appLink.setAttribute("icon", file->value("Icon").toString()); - appLink.setAttribute("desktopFile", file->fileName()); + appLink.setAttribute(QLatin1String("id"), fileInfo->id()); + appLink.setAttribute(QLatin1String("title"), file->localizedValue(QLatin1String("Name")).toString()); + appLink.setAttribute(QLatin1String("comment"), file->localizedValue(QLatin1String("Comment")).toString()); + appLink.setAttribute(QLatin1String("genericName"), file->localizedValue(QLatin1String("GenericName")).toString()); + appLink.setAttribute(QLatin1String("exec"), file->value(QLatin1String("Exec")).toString()); + appLink.setAttribute(QLatin1String("terminal"), file->value(QLatin1String("Terminal")).toBool()); + appLink.setAttribute(QLatin1String("startupNoify"), file->value(QLatin1String("StartupNotify")).toBool()); + appLink.setAttribute(QLatin1String("path"), file->value(QLatin1String("Path")).toString()); + appLink.setAttribute(QLatin1String("icon"), file->value(QLatin1String("Icon")).toString()); + appLink.setAttribute(QLatin1String("desktopFile"), file->fileName()); mElement.appendChild(appLink); @@ -159,7 +159,7 @@ void XdgMenuApplinkProcessor::fillAppFileInfoList() { // Build a pool by collecting entries found in { - MutableDomElementIterator i(mElement, "AppDir"); + MutableDomElementIterator i(mElement, QLatin1String("AppDir")); i.toBack(); while(i.hasPrevious()) { @@ -187,9 +187,9 @@ void XdgMenuApplinkProcessor::findDesktopFiles(const QString& dirName, const QSt { QDir dir(dirName); mMenu->addWatchPath(dir.absolutePath()); - QFileInfoList files = dir.entryInfoList(QStringList("*.desktop"), QDir::Files); + const QFileInfoList files = dir.entryInfoList(QStringList(QLatin1String("*.desktop")), QDir::Files); - foreach (QFileInfo file, files) + foreach (const QFileInfo &file, files) { XdgDesktopFile* f = XdgDesktopFileCache::getFile(file.canonicalFilePath()); if (f) @@ -198,13 +198,13 @@ void XdgMenuApplinkProcessor::findDesktopFiles(const QString& dirName, const QSt // Working recursively ............ - QFileInfoList dirs = dir.entryInfoList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot); - foreach (QFileInfo d, dirs) + const QFileInfoList dirs = dir.entryInfoList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot); + foreach (const QFileInfo &d, dirs) { QString dn = d.canonicalFilePath(); if (dn != dirName) { - findDesktopFiles(dn, QString("%1%2-").arg(prefix, d.fileName())); + findDesktopFiles(dn, QString::fromLatin1("%1%2-").arg(prefix, d.fileName())); } } } @@ -216,13 +216,13 @@ void XdgMenuApplinkProcessor::createRules() while(i.hasNext()) { QDomElement e = i.next(); - if (e.tagName()=="Include") + if (e.tagName()== QLatin1String("Include")) { mRules.addInclude(e); mElement.removeChild(e); } - else if (e.tagName()=="Exclude") + else if (e.tagName()== QLatin1String("Exclude")) { mRules.addExclude(e); mElement.removeChild(e); @@ -240,9 +240,9 @@ bool XdgMenuApplinkProcessor::checkTryExec(const QString& progName) if (progName.startsWith(QDir::separator())) return QFileInfo(progName).isExecutable(); - QStringList dirs = QString(getenv("PATH")).split(":"); + const QStringList dirs = QFile::decodeName(qgetenv("PATH")).split(QLatin1Char(':')); - foreach (QString dir, dirs) + foreach (const QString &dir, dirs) { if (QFileInfo(QDir(dir), progName).isExecutable()) return true; @@ -250,4 +250,3 @@ bool XdgMenuApplinkProcessor::checkTryExec(const QString& progName) return false; } - diff --git a/xdgmenuapplinkprocessor.h b/qtxdg/xdgmenuapplinkprocessor.h similarity index 100% rename from xdgmenuapplinkprocessor.h rename to qtxdg/xdgmenuapplinkprocessor.h diff --git a/xdgmenulayoutprocessor.cpp b/qtxdg/xdgmenulayoutprocessor.cpp similarity index 78% rename from xdgmenulayoutprocessor.cpp rename to qtxdg/xdgmenulayoutprocessor.cpp index 75089c2..76afb54 100644 --- a/xdgmenulayoutprocessor.cpp +++ b/qtxdg/xdgmenulayoutprocessor.cpp @@ -68,20 +68,20 @@ XdgMenuLayoutProcessor::XdgMenuLayoutProcessor(QDomElement& element): mDefaultParams.mInlineHeader = true; mDefaultParams.mInlineAlias = false; - mDefaultLayout = findLastElementByTag(element, "DefaultLayout"); + mDefaultLayout = findLastElementByTag(element, QLatin1String("DefaultLayout")); if (mDefaultLayout.isNull()) { // Create DefaultLayout node QDomDocument doc = element.ownerDocument(); - mDefaultLayout = doc.createElement("DefaultLayout"); + mDefaultLayout = doc.createElement(QLatin1String("DefaultLayout")); - QDomElement menus = doc.createElement("Merge"); - menus.setAttribute("type", "menus"); + QDomElement menus = doc.createElement(QLatin1String("Merge")); + menus.setAttribute(QLatin1String("type"), QLatin1String("menus")); mDefaultLayout.appendChild(menus); - QDomElement files = doc.createElement("Merge"); - files.setAttribute("type", "files"); + QDomElement files = doc.createElement(QLatin1String("Merge")); + files.setAttribute(QLatin1String("type"), QLatin1String("files")); mDefaultLayout.appendChild(files); mElement.appendChild(mDefaultLayout); @@ -91,7 +91,7 @@ XdgMenuLayoutProcessor::XdgMenuLayoutProcessor(QDomElement& element): // If a menu does not contain a element or if it contains an empty element // then the default layout should be used. - mLayout = findLastElementByTag(element, "Layout"); + mLayout = findLastElementByTag(element, QLatin1String("Layout")); if (mLayout.isNull() || !mLayout.hasChildNodes()) mLayout = mDefaultLayout; } @@ -103,7 +103,7 @@ XdgMenuLayoutProcessor::XdgMenuLayoutProcessor(QDomElement& element, XdgMenuLayo mDefaultParams = parent->mDefaultParams; // DefaultLayout ............................ - QDomElement defaultLayout = findLastElementByTag(element, "DefaultLayout"); + QDomElement defaultLayout = findLastElementByTag(element, QLatin1String("DefaultLayout")); if (defaultLayout.isNull()) mDefaultLayout = parent->mDefaultLayout; @@ -114,7 +114,7 @@ XdgMenuLayoutProcessor::XdgMenuLayoutProcessor(QDomElement& element, XdgMenuLayo // If a menu does not contain a element or if it contains an empty element // then the default layout should be used. - mLayout = findLastElementByTag(element, "Layout"); + mLayout = findLastElementByTag(element, QLatin1String("Layout")); if (mLayout.isNull() || !mLayout.hasChildNodes()) mLayout = mDefaultLayout; @@ -123,20 +123,20 @@ XdgMenuLayoutProcessor::XdgMenuLayoutProcessor(QDomElement& element, XdgMenuLayo void XdgMenuLayoutProcessor::setParams(QDomElement defaultLayout, LayoutParams *result) { - if (defaultLayout.hasAttribute("show_empty")) - result->mShowEmpty = defaultLayout.attribute("show_empty") == "true"; + if (defaultLayout.hasAttribute(QLatin1String("show_empty"))) + result->mShowEmpty = defaultLayout.attribute(QLatin1String("show_empty")) == QLatin1String("true"); - if (defaultLayout.hasAttribute("inline")) - result->mInline = defaultLayout.attribute("inline") == "true"; + if (defaultLayout.hasAttribute(QLatin1String("inline"))) + result->mInline = defaultLayout.attribute(QLatin1String("inline")) == QLatin1String("true"); - if (defaultLayout.hasAttribute("inline_limit")) - result->mInlineLimit = defaultLayout.attribute("inline_limit").toInt(); + if (defaultLayout.hasAttribute(QLatin1String("inline_limit"))) + result->mInlineLimit = defaultLayout.attribute(QLatin1String("inline_limit")).toInt(); - if (defaultLayout.hasAttribute("inline_header")) - result->mInlineHeader = defaultLayout.attribute("inline_header") == "true"; + if (defaultLayout.hasAttribute(QLatin1String("inline_header"))) + result->mInlineHeader = defaultLayout.attribute(QLatin1String("inline_header")) == QLatin1String("true"); - if (defaultLayout.hasAttribute("inline_alias")) - result->mInlineAlias = defaultLayout.attribute("inline_alias") == "true"; + if (defaultLayout.hasAttribute(QLatin1String("inline_alias"))) + result->mInlineAlias = defaultLayout.attribute(QLatin1String("inline_alias")) == QLatin1String("true"); } @@ -163,7 +163,7 @@ int childsCount(const QDomElement& element) while (it.hasNext()) { QString tag = it.next().tagName(); - if (tag == "AppLink" || tag == "Menu" || tag == "Separator") + if (tag == QLatin1String("AppLink") || tag == QLatin1String("Menu") || tag == QLatin1String("Separator")) count ++; } @@ -174,12 +174,12 @@ int childsCount(const QDomElement& element) void XdgMenuLayoutProcessor::run() { QDomDocument doc = mLayout.ownerDocument(); - mResult = doc.createElement("Result"); + mResult = doc.createElement(QLatin1String("Result")); mElement.appendChild(mResult); // Process childs menus ............................... { - DomElementIterator it(mElement, "Menu"); + DomElementIterator it(mElement, QLatin1String("Menu")); while (it.hasNext()) { QDomElement e = it.next(); @@ -196,26 +196,26 @@ void XdgMenuLayoutProcessor::run() { QDomElement e = it.next(); - if (e.tagName() == "Filename") + if (e.tagName() == QLatin1String("Filename")) processFilenameTag(e); - else if (e.tagName() == "Menuname") + else if (e.tagName() == QLatin1String("Menuname")) processMenunameTag(e); - else if (e.tagName() == "Separator") + else if (e.tagName() == QLatin1String("Separator")) processSeparatorTag(e); - else if (e.tagName() == "Merge") + else if (e.tagName() == QLatin1String("Merge")) { - QDomElement merge = mResult.ownerDocument().createElement("Merge"); - merge.setAttribute("type", e.attribute("type")); + QDomElement merge = mResult.ownerDocument().createElement(QLatin1String("Merge")); + merge.setAttribute(QLatin1String("type"), e.attribute(QLatin1String("type"))); mResult.appendChild(merge); } } // Step 2 ................................... { - MutableDomElementIterator ri(mResult, "Merge"); + MutableDomElementIterator ri(mResult, QLatin1String("Merge")); while (ri.hasNext()) { processMergeTag(ri.next()); @@ -249,7 +249,7 @@ void XdgMenuLayoutProcessor::processFilenameTag(const QDomElement &element) { QString id = element.text(); - QDomElement appLink = searchElement("AppLink", "id", id); + QDomElement appLink = searchElement(QLatin1String("AppLink"), QLatin1String("id"), id); if (!appLink.isNull()) mResult.appendChild(appLink); } @@ -290,7 +290,7 @@ void XdgMenuLayoutProcessor::processFilenameTag(const QDomElement &element) void XdgMenuLayoutProcessor::processMenunameTag(const QDomElement &element) { QString id = element.text(); - QDomElement menu = searchElement("Menu", "name", id); + QDomElement menu = searchElement(QLatin1String("Menu"), QLatin1String("name"), id); if (menu.isNull()) return; @@ -303,7 +303,7 @@ void XdgMenuLayoutProcessor::processMenunameTag(const QDomElement &element) { if (params.mShowEmpty) { - menu.setAttribute("keep", "true"); + menu.setAttribute(QLatin1String("keep"), QLatin1String("true")); mResult.appendChild(menu); } return; @@ -330,7 +330,7 @@ void XdgMenuLayoutProcessor::processMenunameTag(const QDomElement &element) // Header .................................... if (doHeader) { - QDomElement header = mLayout.ownerDocument().createElement("Header"); + QDomElement header = mLayout.ownerDocument().createElement(QLatin1String("Header")); QDomNamedNodeMap attrs = menu.attributes(); for (int i=0; i < attrs.count(); ++i) @@ -344,7 +344,7 @@ void XdgMenuLayoutProcessor::processMenunameTag(const QDomElement &element) // Alias ..................................... if (doAlias) { - menu.firstChild().toElement().setAttribute("title", menu.attribute("title")); + menu.firstChild().toElement().setAttribute(QLatin1String("title"), menu.attribute(QLatin1String("title"))); } // Inline .................................... @@ -364,7 +364,7 @@ void XdgMenuLayoutProcessor::processMenunameTag(const QDomElement &element) ************************************************/ void XdgMenuLayoutProcessor::processSeparatorTag(const QDomElement &element) { - QDomElement separator = element.ownerDocument().createElement("Separator"); + QDomElement separator = element.ownerDocument().createElement(QLatin1String("Separator")); mResult.appendChild(separator); } @@ -387,7 +387,7 @@ void XdgMenuLayoutProcessor::processSeparatorTag(const QDomElement &element) ************************************************/ void XdgMenuLayoutProcessor::processMergeTag(const QDomElement &element) { - QString type = element.attribute("type"); + QString type = element.attribute(QLatin1String("type")); QMap map; MutableDomElementIterator it(mElement); @@ -395,10 +395,10 @@ void XdgMenuLayoutProcessor::processMergeTag(const QDomElement &element) { QDomElement e = it.next(); if ( - ((type == "menus" || type == "all") && e.tagName() == "Menu" ) || - ((type == "files" || type == "all") && e.tagName() == "AppLink") + ((type == QLatin1String("menus") || type == QLatin1String("all")) && e.tagName() == QLatin1String("Menu" )) || + ((type == QLatin1String("files") || type == QLatin1String("all")) && e.tagName() == QLatin1String("AppLink")) ) - map.insert(e.attribute("title"), e); + map.insert(e.attribute(QLatin1String("title")), e); } QMapIterator mi(map); diff --git a/xdgmenulayoutprocessor.h b/qtxdg/xdgmenulayoutprocessor.h similarity index 100% rename from xdgmenulayoutprocessor.h rename to qtxdg/xdgmenulayoutprocessor.h diff --git a/xdgmenureader.cpp b/qtxdg/xdgmenureader.cpp similarity index 86% rename from xdgmenureader.cpp rename to qtxdg/xdgmenureader.cpp index 8333c9a..f4e4393 100644 --- a/xdgmenureader.cpp +++ b/qtxdg/xdgmenureader.cpp @@ -76,7 +76,7 @@ bool XdgMenuReader::load(const QString& fileName, const QString& baseDir) QFile file(mFileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { - mErrorStr = QString("%1 not loading: %2").arg(fileName).arg(file.errorString()); + mErrorStr = QString::fromLatin1("%1 not loading: %2").arg(fileName).arg(file.errorString()); return false; } //qDebug() << "Load file:" << mFileName; @@ -88,7 +88,7 @@ bool XdgMenuReader::load(const QString& fileName, const QString& baseDir) if (!mXml.setContent(&file, true, &errorStr, &errorLine, &errorColumn)) { - mErrorStr = QString("Parse error at line %1, column %2:\n%3") + mErrorStr = QString::fromLatin1("Parse error at line %1, column %2:\n%3") .arg(errorLine) .arg(errorColumn) .arg(errorStr); @@ -97,10 +97,10 @@ bool XdgMenuReader::load(const QString& fileName, const QString& baseDir) QDomElement root = mXml.documentElement(); - QDomElement debugElement = mXml.createElement("FileInfo"); - debugElement.setAttribute("file", mFileName); + QDomElement debugElement = mXml.createElement(QLatin1String("FileInfo")); + debugElement.setAttribute(QLatin1String("file"), mFileName); if (mParentReader) - debugElement.setAttribute("parent", mParentReader->fileName()); + debugElement.setAttribute(QLatin1String("parent"), mParentReader->fileName()); QDomNode null; root.insertBefore(debugElement, null); @@ -124,49 +124,49 @@ void XdgMenuReader::processMergeTags(QDomElement& element) { QDomElement next = n.previousSiblingElement(); // MergeFile .................. - if (n.tagName() == "MergeFile") + if (n.tagName() == QLatin1String("MergeFile")) { processMergeFileTag(n, &mergedFiles); n.parentNode().removeChild(n); } // MergeDir ................... - else if(n.tagName() == "MergeDir") + else if(n.tagName() == QLatin1String("MergeDir")) { processMergeDirTag(n, &mergedFiles); n.parentNode().removeChild(n); } // DefaultMergeDirs ........... - else if (n.tagName() == "DefaultMergeDirs") + else if (n.tagName() == QLatin1String("DefaultMergeDirs")) { processDefaultMergeDirsTag(n, &mergedFiles); n.parentNode().removeChild(n); } // AppDir ................... - else if(n.tagName() == "AppDir") + else if(n.tagName() == QLatin1String("AppDir")) { processAppDirTag(n); n.parentNode().removeChild(n); } // DefaultAppDirs ............. - else if(n.tagName() == "DefaultAppDirs") + else if(n.tagName() == QLatin1String("DefaultAppDirs")) { processDefaultAppDirsTag(n); n.parentNode().removeChild(n); } // DirectoryDir ................... - else if(n.tagName() == "DirectoryDir") + else if(n.tagName() == QLatin1String("DirectoryDir")) { processDirectoryDirTag(n); n.parentNode().removeChild(n); } // DefaultDirectoryDirs ........... - else if(n.tagName() == "DefaultDirectoryDirs") + else if(n.tagName() == QLatin1String("DefaultDirectoryDirs")) { processDefaultDirectoryDirsTag(n); n.parentNode().removeChild(n); @@ -174,7 +174,7 @@ void XdgMenuReader::processMergeTags(QDomElement& element) // Menu ....................... - else if(n.tagName() == "Menu") + else if(n.tagName() == QLatin1String("Menu")) { processMergeTags(n); } @@ -205,7 +205,7 @@ void XdgMenuReader::processMergeFileTag(QDomElement& element, QStringList* merge { //qDebug() << "Process " << element;// << "in" << mFileName; - if (element.attribute("type") != "parent") + if (element.attribute(QLatin1String("type")) != QLatin1String("parent")) { mergeFile(element.text(), element, mergedFiles); } @@ -215,7 +215,7 @@ void XdgMenuReader::processMergeFileTag(QDomElement& element, QStringList* merge QString relativeName; QStringList configDirs = XdgDirs::configDirs(); - foreach (QString configDir, configDirs) + foreach (const QString &configDir, configDirs) { if (mFileName.startsWith(configDir)) { @@ -236,7 +236,7 @@ void XdgMenuReader::processMergeFileTag(QDomElement& element, QStringList* merge if (relativeName.isEmpty()) return; - foreach (QString configDir, configDirs) + foreach (const QString &configDir, configDirs) { if (QFileInfo(configDir + relativeName).exists()) { @@ -288,20 +288,20 @@ void XdgMenuReader::processDefaultMergeDirsTag(QDomElement& element, QStringList //qDebug() << "Process " << element;// << "in" << mFileName; QString menuBaseName = QFileInfo(mMenu->menuFileName()).baseName(); - int n = menuBaseName.lastIndexOf('-'); + int n = menuBaseName.lastIndexOf(QLatin1Char('-')); if (n>-1) menuBaseName = menuBaseName.mid(n+1); QStringList dirs = XdgDirs::configDirs(); dirs << XdgDirs::configHome(); - foreach (QString dir, dirs) + foreach (const QString &dir, dirs) { - mergeDir(QString("%1/menus/%2-merged").arg(dir).arg(menuBaseName), element, mergedFiles); + mergeDir(QString::fromLatin1("%1/menus/%2-merged").arg(dir).arg(menuBaseName), element, mergedFiles); } - if (menuBaseName == "applications") - mergeFile(QString("%1/menus/applications-kmenuedit.menu").arg(XdgDirs::configHome()), element, mergedFiles); + if (menuBaseName == QLatin1String("applications")) + mergeFile(QString::fromLatin1("%1/menus/applications-kmenuedit.menu").arg(XdgDirs::configHome()), element, mergedFiles); } @@ -312,7 +312,7 @@ void XdgMenuReader::processDefaultMergeDirsTag(QDomElement& element, QStringList void XdgMenuReader::processAppDirTag(QDomElement& element) { //qDebug() << "Process " << element; - addDirTag(element, "AppDir", element.text()); + addDirTag(element, QLatin1String("AppDir"), element.text()); } @@ -329,10 +329,10 @@ void XdgMenuReader::processDefaultAppDirsTag(QDomElement& element) QStringList dirs = XdgDirs::dataDirs(); dirs.prepend(XdgDirs::dataHome(false)); - foreach (QString dir, dirs) + foreach (const QString &dir, dirs) { //qDebug() << "Add AppDir: " << dir + "/applications/"; - addDirTag(element, "AppDir", dir + "/applications/"); + addDirTag(element, QLatin1String("AppDir"), dir + QLatin1String("/applications/")); } } @@ -343,7 +343,7 @@ void XdgMenuReader::processDefaultAppDirsTag(QDomElement& element) void XdgMenuReader::processDirectoryDirTag(QDomElement& element) { //qDebug() << "Process " << element; - addDirTag(element, "DirectoryDir", element.text()); + addDirTag(element, QLatin1String("DirectoryDir"), element.text()); } @@ -360,8 +360,8 @@ void XdgMenuReader::processDefaultDirectoryDirsTag(QDomElement& element) QStringList dirs = XdgDirs::dataDirs(); dirs.prepend(XdgDirs::dataHome(false)); - foreach (QString dir, dirs) - addDirTag(element, "DirectoryDir", dir + "/desktop-directories/"); + foreach (const QString &dir, dirs) + addDirTag(element, QLatin1String("DirectoryDir"), dir + QLatin1String("/desktop-directories/")); } /************************************************ @@ -409,7 +409,7 @@ void XdgMenuReader::mergeFile(const QString& fileName, QDomElement& element, QSt { // As a special exception, remove the element from the root // element of each file being merged. - if (n.tagName() != "Name") + if (n.tagName() != QLatin1String("Name")) { QDomNode imp = mXml.importNode(n, true); element.parentNode().insertBefore(imp, element); @@ -429,9 +429,9 @@ void XdgMenuReader::mergeDir(const QString& dirName, QDomElement& element, QStri { //qDebug() << "Merge dir: " << dirInfo.canonicalFilePath(); QDir dir = QDir(dirInfo.canonicalFilePath()); - const QFileInfoList files = dir.entryInfoList(QStringList() << "*.menu", QDir::Files | QDir::Readable); + const QFileInfoList files = dir.entryInfoList(QStringList() << QLatin1String("*.menu"), QDir::Files | QDir::Readable); - foreach (QFileInfo file, files) + foreach (const QFileInfo &file, files) mergeFile(file.canonicalFilePath(), element, mergedFiles); } } diff --git a/xdgmenureader.h b/qtxdg/xdgmenureader.h similarity index 100% rename from xdgmenureader.h rename to qtxdg/xdgmenureader.h diff --git a/xdgmenurules.cpp b/qtxdg/xdgmenurules.cpp similarity index 94% rename from xdgmenurules.cpp rename to qtxdg/xdgmenurules.cpp index 514c4a0..b8ee197 100644 --- a/xdgmenurules.cpp +++ b/qtxdg/xdgmenurules.cpp @@ -63,26 +63,26 @@ XdgMenuRuleOr::XdgMenuRuleOr(const QDomElement& element, QObject* parent) : { QDomElement e = iter.next(); - if (e.tagName() == "Or") + if (e.tagName() == QLatin1String("Or")) mChilds.append(new XdgMenuRuleOr(e, this)); - else if (e.tagName() == "And") + else if (e.tagName() == QLatin1String("And")) mChilds.append(new XdgMenuRuleAnd(e, this)); - else if (e.tagName() == "Not") + else if (e.tagName() == QLatin1String("Not")) mChilds.append(new XdgMenuRuleNot(e, this)); - else if (e.tagName() == "Filename") + else if (e.tagName() == QLatin1String("Filename")) mChilds.append(new XdgMenuRuleFileName(e, this)); - else if (e.tagName() == "Category") + else if (e.tagName() == QLatin1String("Category")) mChilds.append(new XdgMenuRuleCategory(e, this)); - else if (e.tagName() == "All") + else if (e.tagName() == QLatin1String("All")) mChilds.append(new XdgMenuRuleAll(e, this)); else - qWarning() << "Unknown rule" << e.tagName(); + qWarning() << QString::fromLatin1("Unknown rule") << e.tagName(); } } diff --git a/xdgmenurules.h b/qtxdg/xdgmenurules.h similarity index 100% rename from xdgmenurules.h rename to qtxdg/xdgmenurules.h diff --git a/xdgmenuwidget.cpp b/qtxdg/xdgmenuwidget.cpp similarity index 83% rename from xdgmenuwidget.cpp rename to qtxdg/xdgmenuwidget.cpp index d2e6c79..acabb8f 100644 --- a/xdgmenuwidget.cpp +++ b/qtxdg/xdgmenuwidget.cpp @@ -99,13 +99,13 @@ void XdgMenuWidgetPrivate::init(const QDomElement& xml) q->clear(); QString title; - if (! xml.attribute("title").isEmpty()) - title = xml.attribute("title"); + if (! xml.attribute(QLatin1String("title")).isEmpty()) + title = xml.attribute(QLatin1String("title")); else - title = xml.attribute("name"); + title = xml.attribute(QLatin1String("name")); q->setTitle(escape(title)); - q->setToolTip(xml.attribute("comment")); + q->setToolTip(xml.attribute(QLatin1String("comment"))); QIcon parentIcon; @@ -113,7 +113,7 @@ void XdgMenuWidgetPrivate::init(const QDomElement& xml) if (parentMenu) parentIcon = parentMenu->icon(); - q->setIcon(XdgIcon::fromTheme(mXml.attribute("icon"), parentIcon)); + q->setIcon(XdgIcon::fromTheme(mXml.attribute(QLatin1String("icon")), parentIcon)); buildMenu(); } @@ -195,15 +195,15 @@ void XdgMenuWidgetPrivate::buildMenu() QDomElement xml = it.next(); // Build submenu ........................ - if (xml.tagName() == "Menu") + if (xml.tagName() == QLatin1String("Menu")) q->insertMenu(first, new XdgMenuWidget(xml, q)); //Build application link ................ - else if (xml.tagName() == "AppLink") + else if (xml.tagName() == QLatin1String("AppLink")) q->insertAction(first, createAction(xml)); //Build separator ....................... - else if (xml.tagName() == "Separator") + else if (xml.tagName() == QLatin1String("Separator")) q->insertSeparator(first); } @@ -213,18 +213,18 @@ void XdgMenuWidgetPrivate::buildMenu() XdgAction* XdgMenuWidgetPrivate::createAction(const QDomElement& xml) { Q_Q(XdgMenuWidget); - XdgAction* action = new XdgAction(xml.attribute("desktopFile"), q); + XdgAction* action = new XdgAction(xml.attribute(QLatin1String("desktopFile")), q); QString title; - if (!xml.attribute("title").isEmpty()) - title = xml.attribute("title"); + if (!xml.attribute(QLatin1String("title")).isEmpty()) + title = xml.attribute(QLatin1String("title")); else - title = xml.attribute("name"); + title = xml.attribute(QLatin1String("name")); - if (!xml.attribute("genericName").isEmpty() && - xml.attribute("genericName") != title) - title += QString(" (%1)").arg(xml.attribute("genericName")); + if (!xml.attribute(QLatin1String("genericName")).isEmpty() && + xml.attribute(QLatin1String("genericName")) != title) + title += QString::fromLatin1(" (%1)").arg(xml.attribute(QLatin1String("genericName"))); action->setText(escape(title)); return action; @@ -237,5 +237,5 @@ XdgAction* XdgMenuWidgetPrivate::createAction(const QDomElement& xml) ************************************************/ QString XdgMenuWidgetPrivate::escape(QString string) { - return string.replace("&", "&&"); + return string.replace(QLatin1Char('&'), QLatin1String("&&")); } diff --git a/xdgmenuwidget.h b/qtxdg/xdgmenuwidget.h similarity index 100% rename from xdgmenuwidget.h rename to qtxdg/xdgmenuwidget.h diff --git a/xdgmimetype.cpp b/qtxdg/xdgmimetype.cpp similarity index 98% rename from xdgmimetype.cpp rename to qtxdg/xdgmimetype.cpp index 7bb8987..ed9ab91 100644 --- a/xdgmimetype.cpp +++ b/qtxdg/xdgmimetype.cpp @@ -96,7 +96,7 @@ QString XdgMimeType::iconName() const names.append(QMimeType::iconName()); names.append(QMimeType::genericIconName()); - foreach (QString s, names) { + foreach (const QString &s, names) { if (!XdgIcon::fromTheme(s).isNull()) { dx->iconName = s; break; diff --git a/xdgmimetype.h b/qtxdg/xdgmimetype.h similarity index 100% rename from xdgmimetype.h rename to qtxdg/xdgmimetype.h diff --git a/xmlhelper.cpp b/qtxdg/xmlhelper.cpp similarity index 85% rename from xmlhelper.cpp rename to qtxdg/xmlhelper.cpp index 648500c..6239ad4 100644 --- a/xmlhelper.cpp +++ b/qtxdg/xmlhelper.cpp @@ -39,10 +39,8 @@ QDebug operator<<(QDebug dbg, const QDomElement &el) QString args; for (int i=0; i%3").arg(el.tagName()).arg(args).arg(el.text()); + dbg.nospace() << QString::fromLatin1("<%1%2>%3").arg(el.tagName()).arg(args).arg(el.text()); return dbg.space(); } - - diff --git a/xmlhelper.h b/qtxdg/xmlhelper.h similarity index 100% rename from xmlhelper.h rename to qtxdg/xmlhelper.h diff --git a/release.sh b/release.sh index f60eb6a..29ca2c8 100755 --- a/release.sh +++ b/release.sh @@ -25,4 +25,4 @@ sha256sum --tag *.tar.gz *.tar.xz >> CHECKSUMS cd .. echo "Uploading to lxqt.org..." -scp -r "$version" "lxde.org:/var/www/lxqt/downloads/$PROJECT/" +scp -r "$version" "downloads.lxqt.org:/srv/downloads.lxqt.org/$PROJECT/" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 19b0df6..8d7b580 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,10 @@ set(PROJECT_NAME "qtxdg_test") +remove_definitions( + -DQT_USE_QSTRINGBUILDER + -DQT_NO_CAST_FROM_ASCII +) + set(CMAKE_AUTOMOC TRUE) macro(qtxdg_add_test) @@ -11,7 +16,7 @@ macro(qtxdg_add_test) endmacro() include_directories ( - ${CMAKE_SOURCE_DIR} + "${CMAKE_SOURCE_DIR}/qtxdg" ${CMAKE_CURRENT_BINARY_DIR} ) @@ -22,4 +27,5 @@ set_property(DIRECTORY APPEND qtxdg_add_test( qtxdg_test tst_xdgdirs + tst_xdgdesktopfile ) diff --git a/test/tst_xdgdesktopfile.cpp b/test/tst_xdgdesktopfile.cpp new file mode 100644 index 0000000..63dd6a3 --- /dev/null +++ b/test/tst_xdgdesktopfile.cpp @@ -0,0 +1,118 @@ +/* + * libqtxdg - An Qt implementation of freedesktop.org xdg specs. + * Copyright (C) 2016 Luís Pereira + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "tst_xdgdesktopfile.h" +#include "XdgDesktopFile" +#include + + +class Language +{ +public: + Language (const QString& lang) + : mPreviousLang(QString::fromLocal8Bit(qgetenv("LANG"))) + { + qputenv("LANG", lang.toLocal8Bit()); + } + ~Language() + { + qputenv("LANG", mPreviousLang.toLocal8Bit()); + } +private: + QString mPreviousLang; +}; + + +QTEST_MAIN(tst_xdgdesktopfile); + +void tst_xdgdesktopfile::testRead() +{ + QTemporaryFile file("testReadXXXXXX.desktop"); + QVERIFY(file.open()); + const QString fileName = file.fileName(); + QTextStream ts(&file); + ts << + "[Desktop Entry]\n" + "Type=Application\n" + "Name=MyApp\n" + "Icon=foobar\n" + "MimeType=text/plain;image/png;;\n" + "\n"; + file.close(); + QVERIFY(QFile::exists(fileName)); + + XdgDesktopFile df; + df.load(fileName); + + QVERIFY(df.isValid()); + QCOMPARE(df.type(), XdgDesktopFile::ApplicationType); + QCOMPARE(df.name(), QString::fromLatin1("MyApp")); + QCOMPARE(df.iconName(), QString::fromLatin1("foobar")); + QCOMPARE(df.mimeTypes(), QStringList() << QString::fromLatin1("text/plain") + << QString::fromLatin1("image/png")); + QCOMPARE(df.fileName(), QFileInfo(fileName).canonicalFilePath()); +} + +void tst_xdgdesktopfile::testReadLocalized_data() +{ + QTest::addColumn("locale"); + QTest::addColumn("translation"); + + const QString pt = QString::fromUtf8("A Minha Aplicação"); + const QString pt_BR = QString::fromUtf8("O Meu Aplicativo"); + + QTest::newRow("pt") << QStringLiteral("pt") << pt; + QTest::newRow("pt_PT") << QStringLiteral("pt_PT") << pt; + QTest::newRow("pt_BR") << QStringLiteral("pt_BR") << pt_BR; + + QTest::newRow("de") << QStringLiteral("de") << QStringLiteral("My Application"); +} + +void tst_xdgdesktopfile::testReadLocalized() +{ + QTemporaryFile file("testReadLocalizedXXXXXX.desktop"); + QVERIFY(file.open()); + const QString fileName = file.fileName(); + QTextStream ts(&file); + ts << QString::fromUtf8( + "[Desktop Entry]\n" + "Type=Application\n" + "Name=My Application\n" + "Name[pt]=A Minha Aplicação\n" + "Name[pt_BR]=O Meu Aplicativo\n" + "Icon=foo\n" + "\n"); + file.close(); + + QVERIFY(QFile::exists(fileName)); + + XdgDesktopFile df; + df.load(fileName); + QVERIFY(df.isValid()); + + QFETCH(QString, locale); + QFETCH(QString, translation); + + Language lang(locale); + + QCOMPARE(df.localizedValue("Name").toString(), translation); +} + +#include "test/tst_xdgdesktopfile.moc" diff --git a/test/tst_xdgdesktopfile.h b/test/tst_xdgdesktopfile.h new file mode 100644 index 0000000..337530c --- /dev/null +++ b/test/tst_xdgdesktopfile.h @@ -0,0 +1,35 @@ +/* + * libqtxdg - An Qt implementation of freedesktop.org xdg specs. + * Copyright (C) 2016 Luís Pereira + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef TST_XDGDESKTOPFILE_H +#define TST_XDGDESKTOPFILE_H + +#include + +class tst_xdgdesktopfile : public QObject { + Q_OBJECT +private slots: + + void testRead(); + void testReadLocalized(); + void testReadLocalized_data(); +}; + +#endif // TST_XDGDESKTOPFILE_H diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt new file mode 100644 index 0000000..7d871ae --- /dev/null +++ b/util/CMakeLists.txt @@ -0,0 +1,26 @@ +include_directories ( + "${CMAKE_PROJECT_DIR}/qtxdg" + ${CMAKE_CURRENT_BINARY_DIR} +) + +set(QTXDG_DESKTOP_FILE_START_SRCS + qtxdg-desktop-file-start.cpp +) + +add_executable(qtxdg-desktop-file-start + ${QTXDG_DESKTOP_FILE_START_SRCS} +) + +target_compile_definitions(qtxdg-desktop-file-start + PRIVATE "-DQTXDG_VERSION=\"${QTXDG_VERSION_STRING}\"" +) + +target_link_libraries(qtxdg-desktop-file-start + ${QTXDGX_LIBRARY_NAME} +) + +install(TARGETS + qtxdg-desktop-file-start + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + COMPONENT Runtime +) diff --git a/util/qtxdg-desktop-file-start.cpp b/util/qtxdg-desktop-file-start.cpp new file mode 100644 index 0000000..21f057e --- /dev/null +++ b/util/qtxdg-desktop-file-start.cpp @@ -0,0 +1,71 @@ +/* + * libqtxdg - An Qt implementation of freedesktop.org xdg specs + * Copyright (C) 2016 Luís Pereira + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include + +#include + +static void printErr(const QString & out) +{ + std::cerr << qPrintable(out); +} + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + QCoreApplication::setApplicationName(QLatin1String("qtxdg-desktop-file-start")); + QCoreApplication::setApplicationVersion(QLatin1String(QTXDG_VERSION)); + + QCommandLineParser parser; + parser.setApplicationDescription(QLatin1String("QtXdg XdgDesktopFile start Tester")); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument(QLatin1String("file [urls...]"), QLatin1String("desktop file to start and it's urls"),QLatin1String("file [urls...]")); + parser.process(app); + + if (parser.positionalArguments().isEmpty()) { + parser.showHelp(EXIT_FAILURE); + } + + QStringList userArgs = parser.positionalArguments(); + const QString userFileName = userArgs.takeFirst(); + const QFileInfo fileInfo(userFileName); + const QString canonicalFileName = fileInfo.canonicalFilePath(); + + if (!fileInfo.exists()) { + printErr(QString::fromLatin1("File %1 does not exist\n").arg(userFileName)); + return EXIT_FAILURE; + } + + XdgDesktopFile f; + const bool valid = f.load(canonicalFileName); + if (valid) { + f.startDetached(userArgs); + } else { + printErr(QString::fromLatin1("%1 is not a valid .desktop file\n").arg(canonicalFileName)); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/xdgiconloader/CMakeLists.txt b/xdgiconloader/CMakeLists.txt new file mode 100644 index 0000000..81a3fc0 --- /dev/null +++ b/xdgiconloader/CMakeLists.txt @@ -0,0 +1,82 @@ +include_directories( + "${Qt5Gui_PRIVATE_INCLUDE_DIRS}" +) + +set(xdgiconloader_PUBLIC_H_FILES +) + +set(xdgiconloader_PUBLIC_CLASSES +) + +set(xdgiconloader_PRIVATE_H_FILES +) + +set(xdgiconloader_CPP_FILES + xdgiconloader.cpp +) + +set(xdgiconloader_MOCS +) + +set(xdgiconloader_PRIVATE_INSTALLABLE_H_FILES + xdgiconloader_p.h +) + + +add_library(${QTXDGX_ICONLOADER_LIBRARY_NAME} SHARED + ${xdgiconloader_CPP_FILES} + ${xdgiconloader_PRIVATE_INSTALLABLE_H_FILES} +) + +generate_export_header(${QTXDGX_ICONLOADER_LIBRARY_NAME} BASE_NAME XdgIconLoader) + +# Copy public headers (in tree building) +set(XDGICONLOADER_EXPORT_FILE "xdgiconloader_export.h") +configure_file( + "${CMAKE_CURRENT_BINARY_DIR}/${XDGICONLOADER_EXPORT_FILE}" + "${QTXDGX_INTREE_INCLUDEDIR}/${QTXDGX_ICONLOADER_FILE_NAME}/${XDGICONLOADER_EXPORT_FILE}" + COPYONLY +) + +target_include_directories(${QTXDGX_ICONLOADER_LIBRARY_NAME} + INTERFACE "$" + INTERFACE "$" + INTERFACE "$" +) + +# include directories and targets for the in tree build +target_include_directories(${QTXDGX_ICONLOADER_LIBRARY_NAME} + PUBLIC "$" + PUBLIC "$" + PUBLIC "$" +) + +target_link_libraries(${QTXDGX_ICONLOADER_LIBRARY_NAME} + PUBLIC + Qt5::Gui +) + +set_target_properties(${QTXDGX_ICONLOADER_LIBRARY_NAME} + PROPERTIES + VERSION ${QTXDG_VERSION_STRING} + SOVERSION ${QTXDG_MAJOR_VERSION} +) + +export(TARGETS ${QTXDGX_ICONLOADER_LIBRARY_NAME} FILE "${CMAKE_BINARY_DIR}/${QTXDGX_ICONLOADER_FILE_NAME}-targets.cmake") + +install(TARGETS + ${QTXDGX_ICONLOADER_LIBRARY_NAME} DESTINATION "${CMAKE_INSTALL_LIBDIR}" + EXPORT "${QTXDGX_ICONLOADER_FILE_NAME}-targets" + COMPONENT Runtime +) + +install(FILES + ${xdgiconloader_PRIVATE_INSTALLABLE_H_FILES} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_ICONLOADER_FILE_NAME}/${QTXDG_VERSION_STRING}/private/xdgiconloader" + COMPONENT Devel +) + +install(FILES + "${QTXDGX_INTREE_INCLUDEDIR}/${QTXDGX_ICONLOADER_FILE_NAME}/${XDGICONLOADER_EXPORT_FILE}" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_ICONLOADER_FILE_NAME}" +) diff --git a/qiconfix/qiconloader.cpp b/xdgiconloader/xdgiconloader.cpp similarity index 84% rename from qiconfix/qiconloader.cpp rename to xdgiconloader/xdgiconloader.cpp index 8d8fe7e..adc4ed7 100644 --- a/qiconfix/qiconloader.cpp +++ b/xdgiconloader/xdgiconloader.cpp @@ -31,7 +31,7 @@ ** ****************************************************************************/ #ifndef QT_NO_ICON -#include "qiconloader_p.h" +#include "xdgiconloader_p.h" #include #include @@ -55,9 +55,8 @@ //QT_BEGIN_NAMESPACE -namespace QtXdg { -Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance) +Q_GLOBAL_STATIC(XdgIconLoader, iconLoaderInstance) /* Theme to use in last resort, if the theme does not have the icon, neither the parents */ static QString fallbackTheme() @@ -67,10 +66,10 @@ static QString fallbackTheme() if (themeHint.isValid()) return themeHint.toString(); } - return QString("hicolor"); + return QLatin1String("hicolor"); } -QIconLoader::QIconLoader() : +XdgIconLoader::XdgIconLoader() : m_themeKey(1), m_supportsSvg(false), m_initialized(false) { } @@ -102,7 +101,7 @@ static inline QStringList systemIconSearchPaths() //extern QFactoryLoader *qt_iconEngineFactoryLoader(); // qicon.cpp #endif -void QIconLoader::ensureInitialized() +void XdgIconLoader::ensureInitialized() { if (!m_initialized) { m_initialized = true; @@ -120,7 +119,7 @@ void QIconLoader::ensureInitialized() } } -QIconLoader *QIconLoader::instance() +XdgIconLoader *XdgIconLoader::instance() { iconLoaderInstance()->ensureInitialized(); return iconLoaderInstance(); @@ -128,7 +127,7 @@ QIconLoader *QIconLoader::instance() // Queries the system theme and invalidates existing // icons if the theme has changed. -void QIconLoader::updateSystemTheme() +void XdgIconLoader::updateSystemTheme() { // Only change if this is not explicitly set by the user if (m_userTheme.isEmpty()) { @@ -142,20 +141,20 @@ void QIconLoader::updateSystemTheme() } } -void QIconLoader::setThemeName(const QString &themeName) +void XdgIconLoader::setThemeName(const QString &themeName) { m_userTheme = themeName; invalidateKey(); } -void QIconLoader::setThemeSearchPath(const QStringList &searchPaths) +void XdgIconLoader::setThemeSearchPath(const QStringList &searchPaths) { m_iconDirs = searchPaths; themeList.clear(); invalidateKey(); } -QStringList QIconLoader::themeSearchPaths() const +QStringList XdgIconLoader::themeSearchPaths() const { if (m_iconDirs.isEmpty()) { m_iconDirs = systemIconSearchPaths(); @@ -182,7 +181,7 @@ QIconTheme::QIconTheme(const QString &themeName) QStringList themeSearchPaths = QIcon::themeSearchPaths(); foreach (QString path, themeSearchPaths) { - if (!path.startsWith(':') && QFileInfo(path).isDir()) + if (!path.startsWith(QLatin1Char(':')) && QFileInfo(path).isDir()) m_contentDirs.append(path + QLatin1Char('/') + themeName); } @@ -201,18 +200,18 @@ QIconTheme::QIconTheme(const QString &themeName) // slashes in key names, hence we have to cheat if (int size = indexReader.value(key).toInt()) { QString directoryKey = key.left(key.size() - 5); - QIconDirInfo dirInfo(directoryKey); + XdgIconDirInfo dirInfo(directoryKey); dirInfo.size = size; QString type = indexReader.value(directoryKey + QLatin1String("/Type") ).toString(); if (type == QLatin1String("Fixed")) - dirInfo.type = QIconDirInfo::Fixed; + dirInfo.type = XdgIconDirInfo::Fixed; else if (type == QLatin1String("Scalable")) - dirInfo.type = QIconDirInfo::Scalable; + dirInfo.type = XdgIconDirInfo::Scalable; else - dirInfo.type = QIconDirInfo::Threshold; + dirInfo.type = XdgIconDirInfo::Threshold; dirInfo.threshold = indexReader.value(directoryKey + QLatin1String("/Threshold"), @@ -249,7 +248,7 @@ QIconTheme::QIconTheme(const QString &themeName) #endif //QT_NO_SETTINGS } -QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName, +QThemeIconInfo XdgIconLoader::findIconHelper(const QString &themeName, const QString &iconName, QStringList &visited) const { @@ -271,7 +270,7 @@ QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName, } const QStringList contentDirs = theme.contentDirs(); - const QVector subDirs = theme.keyList(); + const QVector subDirs = theme.keyList(); const QString svgext(QLatin1String(".svg")); const QString pngext(QLatin1String(".png")); @@ -290,7 +289,7 @@ QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName, for (int i = 0; i < contentDirs.size(); ++i) { QString contentDir = contentDirs.at(i) + QLatin1Char('/'); for (int j = 0; j < subDirs.size() ; ++j) { - const QIconDirInfo &dirInfo = subDirs.at(j); + const XdgIconDirInfo &dirInfo = subDirs.at(j); QString subdir = dirInfo.path; QDir currentDir(contentDir + subdir); if (currentDir.exists(pngIconName)) { @@ -390,7 +389,7 @@ QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName, const QString pixmaps(QLatin1String("/usr/share/pixmaps")); const QDir currentDir(pixmaps); - const QIconDirInfo dirInfo(pixmaps); + const XdgIconDirInfo dirInfo(pixmaps); if (currentDir.exists(iconName + pngext)) { PixmapEntry *iconEntry = new PixmapEntry; iconEntry->dir = dirInfo; @@ -418,7 +417,7 @@ QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName, return info; } -QThemeIconInfo QIconLoader::loadIcon(const QString &name) const +QThemeIconInfo XdgIconLoader::loadIcon(const QString &name) const { if (!themeName().isEmpty()) { QStringList visited; @@ -432,59 +431,59 @@ QThemeIconInfo QIconLoader::loadIcon(const QString &name) const // -------- Icon Loader Engine -------- // -QIconLoaderEngineFixed::QIconLoaderEngineFixed(const QString& iconName) +XdgIconLoaderEngine::XdgIconLoaderEngine(const QString& iconName) : m_iconName(iconName), m_key(0) { } -QIconLoaderEngineFixed::~QIconLoaderEngineFixed() +XdgIconLoaderEngine::~XdgIconLoaderEngine() { qDeleteAll(m_info.entries); } -QIconLoaderEngineFixed::QIconLoaderEngineFixed(const QIconLoaderEngineFixed &other) +XdgIconLoaderEngine::XdgIconLoaderEngine(const XdgIconLoaderEngine &other) : QIconEngine(other), m_iconName(other.m_iconName), m_key(0) { } -QIconEngine *QIconLoaderEngineFixed::clone() const +QIconEngine *XdgIconLoaderEngine::clone() const { - return new QIconLoaderEngineFixed(*this); + return new XdgIconLoaderEngine(*this); } -bool QIconLoaderEngineFixed::read(QDataStream &in) { +bool XdgIconLoaderEngine::read(QDataStream &in) { in >> m_iconName; return true; } -bool QIconLoaderEngineFixed::write(QDataStream &out) const +bool XdgIconLoaderEngine::write(QDataStream &out) const { out << m_iconName; return true; } -bool QIconLoaderEngineFixed::hasIcon() const +bool XdgIconLoaderEngine::hasIcon() const { return !(m_info.entries.isEmpty()); } // Lazily load the icon -void QIconLoaderEngineFixed::ensureLoaded() +void XdgIconLoaderEngine::ensureLoaded() { - if (!(QIconLoader::instance()->themeKey() == m_key)) { + if (!(XdgIconLoader::instance()->themeKey() == m_key)) { qDeleteAll(m_info.entries); m_info.entries.clear(); m_info.iconName.clear(); Q_ASSERT(m_info.entries.size() == 0); - m_info = QIconLoader::instance()->loadIcon(m_iconName); - m_key = QIconLoader::instance()->themeKey(); + m_info = XdgIconLoader::instance()->loadIcon(m_iconName); + m_key = XdgIconLoader::instance()->themeKey(); } } -void QIconLoaderEngineFixed::paint(QPainter *painter, const QRect &rect, +void XdgIconLoaderEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) { QSize pixmapSize = rect.size(); @@ -498,16 +497,16 @@ void QIconLoaderEngineFixed::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 XdgIconDirInfo &dir, int iconsize) { - if (dir.type == QIconDirInfo::Fixed) { + if (dir.type == XdgIconDirInfo::Fixed) { return dir.size == iconsize; - } else if (dir.type == QIconDirInfo::Scalable) { - return dir.size <= dir.maxSize && + } else if (dir.type == XdgIconDirInfo::Scalable) { + return iconsize <= dir.maxSize && iconsize >= dir.minSize; - } else if (dir.type == QIconDirInfo::Threshold) { + } else if (dir.type == XdgIconDirInfo::Threshold) { return iconsize >= dir.size - dir.threshold && iconsize <= dir.size + dir.threshold; } @@ -520,12 +519,12 @@ 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 XdgIconDirInfo &dir, int iconsize) { - if (dir.type == QIconDirInfo::Fixed) { + if (dir.type == XdgIconDirInfo::Fixed) { return qAbs(dir.size - iconsize); - } else if (dir.type == QIconDirInfo::Scalable) { + } else if (dir.type == XdgIconDirInfo::Scalable) { if (iconsize < dir.minSize) return dir.minSize - iconsize; else if (iconsize > dir.maxSize) @@ -533,7 +532,7 @@ static int directorySizeDistance(const QIconDirInfo &dir, int iconsize) else return 0; - } else if (dir.type == QIconDirInfo::Threshold) { + } else if (dir.type == XdgIconDirInfo::Threshold) { if (iconsize < dir.size - dir.threshold) return dir.minSize - iconsize; else if (iconsize > dir.size + dir.threshold) @@ -545,7 +544,7 @@ static int directorySizeDistance(const QIconDirInfo &dir, int iconsize) return INT_MAX; } -QIconLoaderEngineEntry *QIconLoaderEngineFixed::entryForSize(const QSize &size) +XdgIconLoaderEngineEntry *XdgIconLoaderEngine::entryForSize(const QSize &size) { int iconsize = qMin(size.width(), size.height()); @@ -556,7 +555,7 @@ QIconLoaderEngineEntry *QIconLoaderEngineFixed::entryForSize(const QSize &size) // Search for exact matches first for (int i = 0; i < numEntries; ++i) { - QIconLoaderEngineEntry *entry = m_info.entries.at(i); + XdgIconLoaderEngineEntry *entry = m_info.entries.at(i); if (directoryMatchesSize(entry->dir, iconsize)) { return entry; } @@ -564,9 +563,9 @@ QIconLoaderEngineEntry *QIconLoaderEngineFixed::entryForSize(const QSize &size) // Find the minimum distance icon int minimalSize = INT_MAX; - QIconLoaderEngineEntry *closestMatch = 0; + XdgIconLoaderEngineEntry *closestMatch = 0; for (int i = 0; i < numEntries; ++i) { - QIconLoaderEngineEntry *entry = m_info.entries.at(i); + XdgIconLoaderEngineEntry *entry = m_info.entries.at(i); int distance = directorySizeDistance(entry->dir, iconsize); if (distance < minimalSize) { minimalSize = distance; @@ -582,18 +581,27 @@ QIconLoaderEngineEntry *QIconLoaderEngineFixed::entryForSize(const QSize &size) * we can never return a bigger size than the requested size. * */ -QSize QIconLoaderEngineFixed::actualSize(const QSize &size, QIcon::Mode mode, +QSize XdgIconLoaderEngine::actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) { ensureLoaded(); - QIconLoaderEngineEntry *entry = entryForSize(size); + XdgIconLoaderEngineEntry *entry = entryForSize(size); if (entry) { - const QIconDirInfo &dir = entry->dir; - if (dir.type == QIconDirInfo::Scalable) + const XdgIconDirInfo &dir = entry->dir; + if (dir.type == XdgIconDirInfo::Scalable || dynamic_cast(entry)) return size; else { - int result = qMin(dir.size, qMin(size.width(), size.height())); + int dir_size = dir.size; + //Note: fallback for directories that don't have its content size defined + // -> get the actual size based on the image if possible + PixmapEntry * pix_e; + if (0 == dir_size && nullptr != (pix_e = dynamic_cast(entry))) + { + QSize pix_size = pix_e->basePixmap.size(); + dir_size = qMin(pix_size.width(), pix_size.height()); + } + int result = qMin(dir_size, qMin(size.width(), size.height())); return QSize(result, result); } } @@ -644,24 +652,24 @@ QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State return svgIcon.pixmap(size, mode, state); } -QPixmap QIconLoaderEngineFixed::pixmap(const QSize &size, QIcon::Mode mode, +QPixmap XdgIconLoaderEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) { ensureLoaded(); - QIconLoaderEngineEntry *entry = entryForSize(size); + XdgIconLoaderEngineEntry *entry = entryForSize(size); if (entry) return entry->pixmap(size, mode, state); return QPixmap(); } -QString QIconLoaderEngineFixed::key() const +QString XdgIconLoaderEngine::key() const { - return QLatin1String("QIconLoaderEngineFixed"); + return QLatin1String("XdgIconLoaderEngine"); } -void QIconLoaderEngineFixed::virtual_hook(int id, void *data) +void XdgIconLoaderEngine::virtual_hook(int id, void *data) { ensureLoaded(); @@ -693,7 +701,6 @@ void QIconLoaderEngineFixed::virtual_hook(int id, void *data) } } -} // QtXdg //QT_END_NAMESPACE diff --git a/qiconfix/qiconloader_p.h b/xdgiconloader/xdgiconloader_p.h similarity index 83% rename from qiconfix/qiconloader_p.h rename to xdgiconloader/xdgiconloader_p.h index f3abbb9..0511ab3 100644 --- a/qiconfix/qiconloader_p.h +++ b/xdgiconloader/xdgiconloader_p.h @@ -48,6 +48,8 @@ // We mean it. // +#include + #include #include #include @@ -59,14 +61,12 @@ //QT_BEGIN_NAMESPACE -namespace QtXdg { - -class QIconLoader; +class XdgIconLoader; -struct QIconDirInfo +struct XdgIconDirInfo { enum Type { Fixed, Scalable, Threshold }; - QIconDirInfo(const QString &_path = QString()) : + XdgIconDirInfo(const QString &_path = QString()) : path(_path), size(0), maxSize(0), @@ -81,31 +81,31 @@ struct QIconDirInfo Type type : 4; }; -class QIconLoaderEngineEntry +class XdgIconLoaderEngineEntry { public: - virtual ~QIconLoaderEngineEntry() {} + virtual ~XdgIconLoaderEngineEntry() {} virtual QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) = 0; QString filename; - QIconDirInfo dir; + XdgIconDirInfo dir; static int count; }; -struct ScalableEntry : public QIconLoaderEngineEntry +struct ScalableEntry : public XdgIconLoaderEngineEntry { QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE; QIcon svgIcon; }; -struct PixmapEntry : public QIconLoaderEngineEntry +struct PixmapEntry : public XdgIconLoaderEngineEntry { QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE; QPixmap basePixmap; }; -typedef QList QThemeIconEntries; +typedef QList QThemeIconEntries; struct QThemeIconInfo { @@ -114,11 +114,11 @@ struct QThemeIconInfo }; //class QIconLoaderEngine : public QIconEngine -class QIconLoaderEngineFixed : public QIconEngine +class XDGICONLOADER_EXPORT XdgIconLoaderEngine : public QIconEngine { public: - QIconLoaderEngineFixed(const QString& iconName = QString()); - ~QIconLoaderEngineFixed(); + XdgIconLoaderEngine(const QString& iconName = QString()); + ~XdgIconLoaderEngine(); void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state); QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); @@ -132,13 +132,13 @@ private: bool hasIcon() const; void ensureLoaded(); void virtual_hook(int id, void *data); - QIconLoaderEngineEntry *entryForSize(const QSize &size); - QIconLoaderEngineFixed(const QIconLoaderEngineFixed &other); + XdgIconLoaderEngineEntry *entryForSize(const QSize &size); + XdgIconLoaderEngine(const XdgIconLoaderEngine &other); QThemeIconInfo m_info; QString m_iconName; uint m_key; - friend class QIconLoader; + friend class XdgIconLoader; }; class QIconTheme @@ -147,21 +147,21 @@ public: QIconTheme(const QString &name); QIconTheme() : m_valid(false) {} QStringList parents() { return m_parents; } - QVector keyList() { return m_keyList; } + QVector keyList() { return m_keyList; } QStringList contentDirs() { return m_contentDirs; } bool isValid() { return m_valid; } private: QStringList m_contentDirs; - QVector m_keyList; + QVector m_keyList; QStringList m_parents; bool m_valid; }; -class Q_GUI_EXPORT QIconLoader +class XDGICONLOADER_EXPORT XdgIconLoader { public: - QIconLoader(); + XdgIconLoader(); QThemeIconInfo loadIcon(const QString &iconName) const; uint themeKey() const { return m_themeKey; } @@ -170,8 +170,8 @@ public: QIconTheme theme() { return themeList.value(themeName()); } void setThemeSearchPath(const QStringList &searchPaths); QStringList themeSearchPaths() const; - QIconDirInfo dirInfo(int dirindex); - static QIconLoader *instance(); + XdgIconDirInfo dirInfo(int dirindex); + static XdgIconLoader *instance(); void updateSystemTheme(); void invalidateKey() { m_themeKey++; } void ensureInitialized(); @@ -190,11 +190,10 @@ private: mutable QHash themeList; }; -} // QtXdg // Note: class template specialization of 'QTypeInfo' must occur at // global scope -Q_DECLARE_TYPEINFO(QtXdg::QIconDirInfo, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(XdgIconDirInfo, Q_MOVABLE_TYPE); //QT_END_NAMESPACE From de6d2811555cb7f531ccae483b542b0081699750 Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Sat, 16 Jul 2016 20:27:54 +0200 Subject: [PATCH 03/14] Added build dependencies gcc (>= 4:6), g++ (>= 4:6) Exported LC_ALL=C.UTF-8 - define language settings for reproducable builds --- debian/changelog | 8 ++++++++ debian/control | 2 ++ debian/rules | 1 + 3 files changed, 11 insertions(+) diff --git a/debian/changelog b/debian/changelog index 2786bc8..67e1065 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +libqtxdg (1.3.1~50-g4fde773-2) experimental; urgency=medium + + * Added build dependencies gcc (>= 4:6), g++ (>= 4:6) + * Exported LC_ALL=C.UTF-8 - define language settings for + reproducable builds + + -- Alf Gaida Sat, 16 Jul 2016 20:26:26 +0200 + libqtxdg (1.3.1~50-g4fde773-1) experimental; urgency=medium * New pre-release 1.3.1~50-g4fde773 diff --git a/debian/control b/debian/control index 6518f16..3af3da3 100644 --- a/debian/control +++ b/debian/control @@ -6,6 +6,8 @@ Uploaders: Alf Gaida , Section: libs Priority: optional Build-Depends: cmake (>= 3.0.2), + gcc (>= 4:6), + g++ (>= 4:6), debhelper (>= 9), libmagic-dev, pkg-config, diff --git a/debian/rules b/debian/rules index 32812f6..d310e6d 100755 --- a/debian/rules +++ b/debian/rules @@ -1,6 +1,7 @@ #!/usr/bin/make -f #export DH_VERBOSE = 1 +export LC_ALL=C.UTF-8 export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed export DEB_BUILD_MAINT_OPTIONS = hardening=+all From 79fd6f5c26f405f3e9dea15a7ec880d9d4662cdb Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Sat, 23 Jul 2016 13:05:53 +0200 Subject: [PATCH 04/14] Fixed typo in changelog --- debian/changelog | 8 +++++++- debian/control | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 67e1065..1bdc545 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,14 @@ +libqtxdg (1.3.1~50-g4fde773-3) experimental; urgency=medium + + * Fixed typo in changelog + + -- Alf Gaida Sat, 23 Jul 2016 13:05:14 +0200 + libqtxdg (1.3.1~50-g4fde773-2) experimental; urgency=medium * Added build dependencies gcc (>= 4:6), g++ (>= 4:6) * Exported LC_ALL=C.UTF-8 - define language settings for - reproducable builds + reproducible builds -- Alf Gaida Sat, 16 Jul 2016 20:26:26 +0200 diff --git a/debian/control b/debian/control index 3af3da3..7644812 100644 --- a/debian/control +++ b/debian/control @@ -5,10 +5,10 @@ Uploaders: Alf Gaida , Andrew Lee (李健秋) Section: libs Priority: optional -Build-Depends: cmake (>= 3.0.2), +Build-Depends: debhelper (>= 9), + cmake (>= 3.0.2), gcc (>= 4:6), g++ (>= 4:6), - debhelper (>= 9), libmagic-dev, pkg-config, qtbase5-private-dev, From 09d221d744b6ae2be8cfacbb062949a1c54a8d84 Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Wed, 10 Aug 2016 22:54:39 +0200 Subject: [PATCH 05/14] Added libfile-mimeinfo-perl as dependency, we really need this, a recommendation is not enough. Thanks tsujan. --- debian/changelog | 7 +++++++ debian/control | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 1bdc545..bc5626c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +libqtxdg (1.3.1~50-g4fde773-4) experimental; urgency=medium + + * Added libfile-mimeinfo-perl as dependency, we really need this, a + recommendation is not enough. Thanks tsujan. + + -- Alf Gaida Wed, 10 Aug 2016 22:48:40 +0200 + libqtxdg (1.3.1~50-g4fde773-3) experimental; urgency=medium * Fixed typo in changelog diff --git a/debian/control b/debian/control index 7644812..a4101a6 100644 --- a/debian/control +++ b/debian/control @@ -23,7 +23,8 @@ Package: libqt5xdg1 Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, - ${misc:Depends} + ${misc:Depends}, + libfile-mimeinfo-perl Pre-Depends: ${misc:Pre-Depends} Provides: libqt5xdg Description: Implementation of the XDG Specifications for Qt (shared lib) From 02ce77958913466af008ed18d2ccb18032d9c32f Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Sun, 18 Sep 2016 02:28:59 +0200 Subject: [PATCH 06/14] Cherry-picked new upstream release 2.0.0. Added current signing key Bumped compat to 10 Bumped debhelper to (>=10) Added build dependency libqt5svg5-dev Renamed package libqt5xdg1 -> libqt5xdg2 (soname bump) Renamed package libqt5xdgiconloader1 -> libqt5xdgiconloader2 (soname bump) Added dependency gtk-update-icon-cache to libqt5xdgiconloader2 Renamed install and symbols files Fixed symbols Fixed .gitignore --- .gitignore | 8 + CHANGELOG | 361 ++++++++++++++++++ CMakeLists.txt | 7 +- README.md | 32 +- cmake/qt5xdgiconloader-config.cmake.in | 1 + debian/.gitignore | 5 +- debian/changelog | 16 + debian/compat | 2 +- debian/control | 18 +- ...{libqt5xdg1.install => libqt5xdg2.install} | 0 ...{libqt5xdg1.symbols => libqt5xdg2.symbols} | 4 +- debian/libqt5xdgiconloader1.symbols | 27 -- ...1.install => libqt5xdgiconloader2.install} | 0 debian/libqt5xdgiconloader2.symbols | 27 ++ debian/upstream/signing-key.asc | 107 +++--- debian/watch | 2 +- xdgiconloader/CMakeLists.txt | 1 + xdgiconloader/xdgiconloader.cpp | 196 +++++++++- xdgiconloader/xdgiconloader_p.h | 8 +- 19 files changed, 682 insertions(+), 140 deletions(-) create mode 100644 .gitignore create mode 100644 CHANGELOG rename debian/{libqt5xdg1.install => libqt5xdg2.install} (100%) rename debian/{libqt5xdg1.symbols => libqt5xdg2.symbols} (98%) delete mode 100644 debian/libqt5xdgiconloader1.symbols rename debian/{libqt5xdgiconloader1.install => libqt5xdgiconloader2.install} (100%) create mode 100644 debian/libqt5xdgiconloader2.symbols diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..429cda3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +build* +*.qm +*~ +*.autosave +*-swp +*.swp +CMakeLists.txt.user* +nbproject/ diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..ae353a4 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,361 @@ + +libqtxdg-2.0.0 / 2016-09-17 +=========================== + + * Bump version to 2.0.0 + * Extend README.md + * Updates dependencies + * Fixes QIcon::hasThemeIcon() behavior with our Icon Loader Engine + * Adds Qt5Svg explicitly to the required packages + * QIconLoader: Use the GTK+ icon caches + * QIcon: add a hook in the engine so a non null QIconEngine can still be a null icon + * QIconLoader: don't make QIconDirInfo::type a bit-field + * Do not support static QIcon instances + * Respect manual set icon themes. + * Remove where it's not used + * Make it more obvious that Q_WS_ is dead code, and should perhaps be ported + * XdgDesktopFileData: Explicitly initialize members (#91) + * build: Create separate Qt5XdgIconLoader target + * XdgDesktopFile: Adds tests + * xdgdesktopfile: Removes an not needed debug info + * xdgdesktopfile: Removes double QLatin1String's contruction + * XdgDesktopFileCache: Check if a file isValid() only when needed + * XdgDesktopFile: Reworks XdgDesktopFileCache::getFile() + * XdgDesktopFileCache: Check new acquired objects before using it + * XdgDesktopFile: Removes unneeded assignment + * XdgDesktopFile: Add break to switch case + * qtxdg: Get the HOME environment variable just one time + * Replace the QString % operator by the + operator + * No more implicit string conversions + * Moves QT_USE_QSTRINGBUILDER to the compiler_settings CMake module + * XdgDesktopFileCache: Fixes an coding typing error + * xdgiconloader: Fix typo in directoryMatchesSize + * Xdgiconloader (#84) + * Improve foreach iteraror performance + * XdgDesktopFile: Improve the performance of the foreach loop + * XdgDesktopFile: Use XdgDirs::userDir(), drop QStandardPaths() + * XdgDesktopFile: Standardize text strings scope + * XdgDesktopFile: Adds a Desktop File ID calculator method + * XdgDesktopFile: Document Exec fallback when DBusActivatable fails + * Adds QT_USE_QSTRINGBUILDER to the compile definitions + * Adds the BUILD_DEV_UTILS to README.md + * Makes the development utils build/install optional + * XdgDesktopFile: Adds Exec fallback when DBusActivatable fails + * Adds an .desktop file start tester + * XdgDirs: Use Q_ASSERT to check for XdgDirs::userDirectory invalid values + * XdgDirs: Use XdgDirs::UserDirectory enum instead of int + * XdgDirs: Makes XdgDirs::userDir use userDirectoryFallback() + * XdgDirs: Adds userDirDefault() method. + * Adds XdgDesktopFile::mimeTypes() member + * build: Enable C++11 usage + * iconloader: Fix actualSize() for non-themed icons + * desktopfile: Change validity check + * Added Digia-Qt-LGPL-Exception-1.1 + * Update years and Licenses + * desktopfile: Check validity of DBus object path + * desktopfile: Don't invoke DBus call on invalid interface + * XdgUserDirs: Return a fallback when the path is empty + * README.md: Fix grammatical error, adjust wording + * Update and rename README to README.md + * xdgdesktopfile: handle 'Path' entry for application's working directory + * Fix possible use of cachedIcon after free + * Update release.sh server url + +1.3.0 / 2015-10-27 +================== + + * Release 1.3.0 + * desktopfile: Remove support for $XDG_MOVIES_DIR (which doesn't exist) + * Assorted style cleanups + * Adds XdgDesktopFile != operator + * Fixes the XdgMimeType == operator + * Handles CMake policy CMP0063 + * Adds an compiler_settings CMake "module" + * CMake: Adds Runtime install COMPONENT + * Drops find_package(), use find_dependency() + * Marks link libraries as PUBLIC + * Handles in-tree builds headers the right way. + * Narrows the scope of compile definitions + * Improves create_pkgconfig_file.cmake + * Use the Targets CMake stuff + * Adds package version config info file + * Code reordering + * Use Qt5 style library names + * Remove unneeded add_definitions() + * Simplifies version variables a little bit + * Removes unneeded include_directories() + * Uses standard GNUInstallDirs instead of FindLibSuffix + * Remove trailing whitespaces + * added missing licensing headers + * Backports Fixed icons lookup in QIcon::fromTheme + * Adds XdgDirs tests + * Adds XdgDirs::configHome() fallback default locations + * XdgDesktopFile: Handles NotShowIn correctly + * Fixes XdgDirs::dataHome() regression + * QIconLoader: Change the order fallback icon lookup order + * Gets rid of translations stuff + * Cleans up empty comment lines + * Remove Qt4 stuff from the documentation + * Remove Qt4 stuff from the example and tests + * Remove Qt4 stuff from the source files + * Get rid of Qt4 stuff in the build system + +1.2.0 / 2015-03-29 +================== + + * Release 1.2.0 + * Fixes XdgDesktop::isShow() caching mechanism + * Add QtDBus/Qt5DBus dependency + * Adds support for X-Categories + * Adds support for X-OnlyShowIn and X-NotShowIn + * Fixes an Qt4 FTBFS + * Use QLatin1Char() + * Adds platform-data handling + * Make DBusActivatable work for Qt4 too + * desktopfile: support for DBusActivatable applications + * Adds a list of special non detachable execs + * desktopfile: run new process as a direct child + * Qt5: Use QStandardPaths() where possible + * XdgDirs: Updates documentation. + * String manipulation enhancements + * Make sure returned directories don't have an trailing '/' + * XdgDirs: postfix should always start with an / + * XdgDirs::configHome() handle postfix slash + * Fix XdgDirs::dataDirs() postfix handling + * Replace empty quotes by QString() + * XdgDesktopFileCache: Retrieve apps of a category + * Quote all paths in the CMake stuff + * Qt5: Use Qt5 private headers + * Ignore empty dirs in xdgDirList() + * Makes needed helper functions available to tests + * - Fix compilation when using internal mime + * Release with a proper versioned prefix + * Avoid adding empty parent icon theme + * Update license headers and add new license files + * Use QPlatformTheme::SystemIconFallbackThemeName in static QString fallbackTheme() + * QIconLoader: enable an easy case of transactional processing + * QIconLoader: don't inherit QObject + * QIconLoader: replace an inefficient QList with a QVector + * QIconLoader: mark virtual overrides + * QIconLoader: mark a helper type as movable + * QIconLoader: replace while(!empty()) delete takeLast() with qDeleteAll() + * QIconLoader: don't re-evaluate container.size() all the time (II) + * QIconLoader: don't re-evaluate container.size() all the time + * QIconLoader: remove another unused variable + * QIconLoader: remove an unused variable + +1.1.0 / 2015-02-07 +================== + + * Update the release script to sign packages + * Sets visibility to hidden symbols for Clang + * Move static const variable from a public .h file to the .cpp + * Use gcc visibility attribute and Q_DECL_EXPORT macro to avoid exporting private symbols in the lib. This greatly reduced the size of dynamic symbol table and might potentially speed up loading. Also, turn off exception handling to save more since we don't use it. For non-gcc compilers, this change does nothing. + * Makes the Qt5 build the default + * Qt5: Updates CMake minimum required version + * Qt4: Backport add fallback for unthemed app icons + * add fallback for unthemed app icons + * XdgDesktopFileCache::getFile(): Don't insert/removes non existent files + * Enhance the loading of a .desktop file. + * Adds helper functions prototypes + * Fixes issue #7 + * Updates .gitignore + * Removes i18n/i10n + * Updates translations + * Updates the translation infrastructure + * Update Russian translation + * Qt4: Fixes an FTBFS on Gentoo x86_64 when USE_QTMIMETYPES=On + * Add a release script + +1.0.0 / 2014-09-06 +================== + + * Release 1.0.0 + * Replaces XdgMimeInfo with XdgMimeType + * Updates the cmake_minimum_required() version + * Build system maintenance + * if QT_VERSION < 5 load the qt4 header + * Allows QIconLoader to search in multiple theme directories. + * Fixes an FTBFS in the Qt4 build + * Merge branch 'use-qt5-qiconloader' + * Revert "Merge branch 'use-qt5-qiconloader'" + * Revert "Fixes an FTBFS in the Qt4 build" + * Fixes an FTBFS in the Qt4 build + * Get and set XDG user dirs variables in config file + * Honors /usr/share/pixmaps when searching for icons. + * Adds xpm icon support + * Adds Qt5 QIconLoader for the Qt5 build + * Ports Qt5 commit: Make sure QIconLoader is always initialized + * Use environment to trigger Qt5 builds + * Fixes an XdgMimeInfo memory leak + * Use case insensitive comparisons with desktop environment names + * Updates some XdgDesktopFile methods documentation + * Make desktop enviroment names comparisons case insensitive + * solve failed comp LXQT with LXQt (OnlyShowIn=LXQt;) in desktop files + * Re-adds Support XDG_CURRENT_DESKTOP in autostart handling + * Deprecates non desktop environment neutral XdgDesktopFile methods + * Revert "Support XDG_CURRENT_DESKTOP in autostart handling." + * Adds QTXDG_DEPRECATED macro + * Install pkgconfig files to /usr/local/libdata/pkgconfig in FreeBSD. + * Set library dirs properly in qtxdg-config and use files. + +0.5.3 / 2014-05-08 +================== + + * Release 0.5.3 + * Update some comments + +0.5.1 / 2014-05-05 +================== + + * libqtxdg 0.5.1 + * Revert "Change default environment to LXQt" + * Revert "Check for lxqt-applications instead of razor-applications" + * Support XDG_CURRENT_DESKTOP in autostart handling. + * Update .gitignore + * Check for lxqt-applications instead of razor-applications + * Change default environment to LXQt + * Avoid XdgAction mnemonics caused by '&' symbol in the name of desktop app. + +0.1.0 / 2014-04-29 +================== + + * Update AUTHORS and COPYING + * Add CPack rules for creating tarball + * Put iconloaderfix into own namespace + * Adds an uninstall target + * Fixes an FTBFS on the test target + * Fixes an FTBFS when a mix of PIC and PIE compiler flags are used + * Updates CMake's minimum required version + * Adds Qt5Widgets to the required pkg-config required packages + * test: Removes meaningless add_dependencies(..... razorqt) + * Don't use STREQUAL to test the BUILD_TESTS option + * Removed CMAKE_SOURCE_DIR usage from test/CMakeLists.txt + * Adds missing ${CMAKE_INSTALL_PREFIX} + * Fixes bugs in create_pkgconfig_file cmake macro + * Use GNU installation directories + * prefix parameter for autostartDirs, configDirs and dataDirs. (part2) + * prefix parameter for autostartDirs, configDirs and dataDirs. + * Updates buildsystem typical use documentation + * Reformatting for an easy reading in a 80x24 terminal + * Documents the QTXDG_QT_LIBRARIES variable + * Adds an tiny example on how to use the lib + * RazorLibSuffix.cmake -> ../cmake/FindLibSuffix.cmake and QUIET mode for find_package + * Adds ${CMAKE_CURRENT_BINARY_DIR} to the include_directories list + * Fix qtxdg_use.cmake and qtxdg-config.cmake generation location + * Replace QDomNodeList::length() by QDomNodeList::size() + * Portable headers + * Adds pkg-config to Qt5Xdg + * Renames the Qt5 build + * Packs Qt version specific stuff + * Removes unneeded set(QT_USE_QTXML TRUE) + * qtxdg/test: Adapts the build system to support Qt4 and Qt5 + * qtxdg/test: Removes Qt4 CMake stuff + * Adds missing library (Qt5Xml) to qtxdg target + * qtxdg/test: Removes the project command and cmake_minimum_required() + * Explicitly requires QtTest module + * Make BUILD_TESTS an option + * Replace Q_GLOBAL_STATIC_WITH_INITIALIZER + * Replaces QIconEngineV2 with QIconEngine + * Adds QMimeData include file + * Port QString::toAscii() + * Port QDesktopServices + * Ran fixqt4headers + * Adds support to Qt5 in the buildsystem + * Adds test target to CMake + * Use the QtTestLib facilities + * Cmake find_package files for the QtXdg + * Revert "Cmake find_package files" + * Cmake find_package files + * Add COPYING and AUTHORS files + * X-RAZOR changed to Razor in desktop files + * config-file-associations, mimetypeviewer: Replaced QTreeWidget with QTreeView and new class MimetypeItemModel as model + * Improved (hopefuly) layout and look of config-fileassociations, application chooser + * Clang complained about type mismatch + * application-x-executable now fallback icon for desktopfiles of type Application + * Added XdgMimeInfoCache + * Added more info to XdgMime + * XdgDesktopFileCache now holds list of all apps that can handle a given mimetype + * Make QtXdg build by itself again + * libraries: Removes unneeded include(RazorLibSuffix) + * libraries: Removes unneeded cmake_minimum_required(VERSION 2.6) + * libraries: Removes unneeded find_package(Qt4) + * xdgdesktopfilecache now looks in /applications/defaults.list for default app + * Add getApps method to XdgDesktopFileCache - returns all applications that can handle a mimetype + * Fix building with C++11 + * XdgDesktopFile: Don't strip quotes + * initial fix for #520 XdgDesktopFileCache::getDefaultApp cache wrong behavior + * Closes Issue #487 + * Set minimum percent to 1% for transifex in cmake + * Translations updated + * Translations updated + * Soname was changed + * Update translations + * Translations updated + * Removed line num from TS files. + * Fix autostart dir detection when the env var is set + * Updated .tx file + * version bump to 0.4.99 (public "release candiates") for qtxdg + * Translation for razor-sesion + * Fixes in the qtxdg translations + * Transifex resource renamed qtxdg->libqtxdg + * Fix for Issue #290 Fails to build on BSD + * New translations for libqtxdg + * Starting the razor-confupdate from the razor-session. + * Razor-confupdate: fixes and .upd file for 0.4.1-0.5 + * Language name zh_CN.GB2312 braked cmake process. + * Translations updated + * Add operator== for XdgDesktopFile + * Don't replace space with \s + * Fixed for Preloading menu + * Cleaning the code. + * Move autostart directory code to XdgDirs + * Improvements to the XdgMenu. Added changed signal. + * Small speed opetimistaion in the qiconloader + * Add function to remove entries from desktop files + * Transifex desktop: sr_BA.ts should be a local + * Transifex desktop: local translations + * Transifex desktop: Translations pulled + * Icons for the desktop menu + * Add Traditional Chinese Translations + * Translations update + * Added support for the online translation service. www.transifex.net + * Serbian translation files + * Class documentation for XdgMimeInfo + * Greek translation by iosifidis + * Fix for issue #170. Escaping. + * Fix for issue #170. Escaping. + * Fix for issue #170 + * Fix for issue #170 + * Added danish translations + * X-RAZOR -> Razor for autostart + * Russian translation + * RAZOR -> X-RAZOR + * MINOR_VERSION & PATCH_VERSION for libraries + * fix #169: italian translation + * XdgAutoStart rewriten (lgpl2+) + * Closes #158 + * Support icons with absolute path file names + * LGPL2+ for qtxdg + * Escape &'s to prevent Qt from using them for mnemonics + * Revert "XdgDesktopFile: Display an actual ampersand character" + * Update german [de] translation + * Add setLocalizedValue() function + * fixed qtxdg/translations/translate.sh + * Add a constructor to generate basic XdgDesktopFiles + * Correct the XdgAutoStart behavior + * SVK translation finalized + * Replaces return"" by return QString() + * License audit + * implemented #70: pkg-config for libs + * Add Chinese(simplified) translation files. + * fix #119 qtxdg bug and patch + * License audit + * Add Slovak (sk) translation + * Czech translations (cs_CZ) + * Fix doxygen documentation in xdgdesktopfile + * New doxygen ifrastructure + * devel-docs generated in CMAKE_BINARY_DIR/docs includig dummy index.html + * missing translations in CMakeLists + * XdgDesktopFile is implicitly shared + * huge refactoring of the libraries build organization diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c4586c..103d5ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,8 +25,8 @@ else() set(CMAKE_CXX_STANDARD 11) endif() -set(QTXDG_MAJOR_VERSION 1) -set(QTXDG_MINOR_VERSION 3) +set(QTXDG_MAJOR_VERSION 2) +set(QTXDG_MINOR_VERSION 0) set(QTXDG_PATCH_VERSION 0) set(QTXDG_VERSION_STRING ${QTXDG_MAJOR_VERSION}.${QTXDG_MINOR_VERSION}.${QTXDG_PATCH_VERSION}) @@ -38,6 +38,7 @@ include(create_pkgconfig_file) include(compiler_settings NO_POLICY_SCOPE) find_package(Qt5Widgets REQUIRED QUIET) +find_package(Qt5Svg REQUIRED QUIET) find_package(Qt5Xml REQUIRED QUIET) find_package(Qt5DBus REQUIRED QUIET) @@ -56,7 +57,7 @@ set(QTXDGX_PKG_CONFIG_DESCRIPTION "Qt5Xdg, a Qt5 implementation of XDG standards set(QTXDGX_PKG_CONFIG_REQUIRES "Qt5Core, Qt5Xml, Qt5Widgets, Qt5DBus, Qt5XdgIconLoader") set(QTXDGX_ICONLOADER_PKG_CONFIG_DESCRIPTION "Qt5XdgIconLader, a Qt5 XDG Icon Loader") -set(QTXDGX_ICONLOADER_PKG_CONFIG_REQUIRES "Qt5Gui") +set(QTXDGX_ICONLOADER_PKG_CONFIG_REQUIRES "Qt5Gui, Qt5Svg") set(QTXDGX_INTREE_INCLUDEDIR "${CMAKE_CURRENT_BINARY_DIR}/InTreeBuild/include") diff --git a/README.md b/README.md index 1bc511e..7a4f429 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,27 @@ -##Overview +# libqtxdg -```libqtxdg``` is a Qt implementation of freedesktop.org XDG specifications which is built with Qt5. +## Overview -##Dependencies +`libqtxdg` is a Qt 5 implementation of freedesktop.org XDG specifications. - - Qt5 +It is maintained by the LXQt project and nearly all LXQt components are depending on it. Yet it can be used independently from this desktop environment, too. -##Configuration +The library is able to use GTK+ icon theme caches for faster icon lookup. The cache file can be generated with utility `gtk-update-icon-cache` on a theme directory. If the cache is not present, corrupted, or outdated, the normal slow lookup is still run. -```libqtxdg``` uses the CMake build system. Everything that applies to CMake also -applies here. +## Installation -###Configuration options: - BUILD_TESTS Builds tests, defaults to OFF - BUILD_DEV_UTILS Builds and install development utils, defaults to OFF +### Sources -###Configuration Examples: -Build library and build self tests: ```cmake -DBUILD_TESTS=ON ..``` +At runtime qtbase is needed. gtk-update-icon-cache represents an optional runtime dependency for the reasons stated above. +Additional build dependencies are CMake, qtsvg, qttools and optionally Git to pull latest VCS checkouts. -Build the library without building self tests : ```cmake ..``` +The code configuration is handled by CMake so all corresponding generic instructions apply. Specific CMake variables are +* BUILD_TESTS to build tests. Disabled by default (`OFF`). +* BUILD_DEV_UTILS which builds and installs development utils. Disabled by default as well. + +To build and install run `make` and `make install`respectively. + +### Binary packages + +The library is provided by all major Linux distributions like Arch Linux, Debian, Fedora and openSUSE. +Just use the distributions' package managers to search for string `libqtxdg`. diff --git a/cmake/qt5xdgiconloader-config.cmake.in b/cmake/qt5xdgiconloader-config.cmake.in index 0582b60..f5ed0ac 100644 --- a/cmake/qt5xdgiconloader-config.cmake.in +++ b/cmake/qt5xdgiconloader-config.cmake.in @@ -3,6 +3,7 @@ include(CMakeFindDependencyMacro) find_dependency(Qt5Gui) +find_dependency(Qt5Svg) if (CMAKE_VERSION VERSION_GREATER 2.8.12) cmake_policy(SET CMP0024 OLD) diff --git a/debian/.gitignore b/debian/.gitignore index c3581ee..643c6a8 100644 --- a/debian/.gitignore +++ b/debian/.gitignore @@ -5,9 +5,8 @@ /files -/libqt5xdg1/ -/libqt5xdg1-dbg/ +/libqt5xdg2/ /libqt5xdg-dev/ /libqt5xdgiconloader-dev/ -/libqt5xdgiconloader1/ +/libqt5xdgiconloader2/ /tmp diff --git a/debian/changelog b/debian/changelog index bc5626c..78ff318 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,19 @@ +libqtxdg (2.0.0-1) experimental; urgency=medium + + * Cherry-picked new upstream release 2.0.0. + * Added current signing key + * Bumped compat to 10 + * Bumped debhelper to (>=10) + * Added build dependency libqt5svg5-dev + * Renamed package libqt5xdg1 -> libqt5xdg2 (soname bump) + * Renamed package libqt5xdgiconloader1 -> libqt5xdgiconloader2 (soname bump) + * Added dependency gtk-update-icon-cache to libqt5xdgiconloader2 + * Renamed install and symbols files + * Fixed symbols + * Fixed .gitignore + + -- Alf Gaida Sun, 18 Sep 2016 02:28:47 +0200 + libqtxdg (1.3.1~50-g4fde773-4) experimental; urgency=medium * Added libfile-mimeinfo-perl as dependency, we really need this, a diff --git a/debian/compat b/debian/compat index ec63514..9a03714 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -9 +10 \ No newline at end of file diff --git a/debian/control b/debian/control index a4101a6..4e16816 100644 --- a/debian/control +++ b/debian/control @@ -5,21 +5,20 @@ Uploaders: Alf Gaida , Andrew Lee (李健秋) Section: libs Priority: optional -Build-Depends: debhelper (>= 9), +Build-Depends: debhelper (>= 10), cmake (>= 3.0.2), - gcc (>= 4:6), - g++ (>= 4:6), libmagic-dev, + libqt5svg5-dev, pkg-config, qtbase5-private-dev, qttools5-dev, qttools5-dev-tools Standards-Version: 3.9.8 -Vcs-Browser: https://anonscm.debian.org/git/pkg-lxqt/libqtxdg.git/?h=debian/experimental +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 -Package: libqt5xdg1 +Package: libqt5xdg2 Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, @@ -33,11 +32,12 @@ Description: Implementation of the XDG Specifications for Qt (shared lib) . This package provides the shared library. -Package: libqt5xdgiconloader1 +Package: libqt5xdgiconloader2 Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, - ${misc:Depends} + ${misc:Depends}, + gtk-update-icon-cache Pre-Depends: ${misc:Pre-Depends} Provides: libqt5xdgiconloader Description: Implementation of the XDG Iconloader for Qt (shared lib) @@ -50,7 +50,7 @@ Package: libqt5xdg-dev Architecture: any Section: libdevel Depends: ${misc:Depends}, - libqt5xdg1 (= ${binary:Version}), + libqt5xdg2 (= ${binary:Version}), libqt5xdgiconloader-dev (= ${binary:Version}) Description: Development files for libqtxdg This library implements functions of the XDG Specifications in Qt. It is part @@ -62,7 +62,7 @@ Package: libqt5xdgiconloader-dev Architecture: any Section: libdevel Depends: ${misc:Depends}, - libqt5xdgiconloader1 (= ${binary:Version}) + libqt5xdgiconloader2 (= ${binary:Version}) Description: Development files for libqtxdgiconloader This library implements the backend to load icons which are handled according to the XDG Icon Theme Specification in Qt. It is part of LXQt. diff --git a/debian/libqt5xdg1.install b/debian/libqt5xdg2.install similarity index 100% rename from debian/libqt5xdg1.install rename to debian/libqt5xdg2.install diff --git a/debian/libqt5xdg1.symbols b/debian/libqt5xdg2.symbols similarity index 98% rename from debian/libqt5xdg1.symbols rename to debian/libqt5xdg2.symbols index 64d3af5..f059df7 100644 --- a/debian/libqt5xdg1.symbols +++ b/debian/libqt5xdg2.symbols @@ -1,4 +1,4 @@ -libQt5Xdg.so.1 libqt5xdg1 #MINVER# +libQt5Xdg.so.2 libqt5xdg2 #MINVER# (c++)"XdgAction::XdgAction(QObject*)@Base" 1.0.0 (c++)"XdgAction::XdgAction(QString const&, QObject*)@Base" 1.0.0 (c++)"XdgAction::XdgAction(XdgAction const&, QObject*)@Base" 1.0.0 @@ -26,7 +26,7 @@ libQt5Xdg.so.1 libqt5xdg1 #MINVER# (c++)"XdgDesktopFile::fileName() const@Base" 1.0.0 (c++)"XdgDesktopFile::icon(QIcon const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::iconName() const@Base" 1.0.0 - (c++)"XdgDesktopFile::id(QString const&, bool)@Base" 1.3.1~ + (c++)"XdgDesktopFile::id(QString const&, bool)@Base" 2.0.0 (c++)"XdgDesktopFile::isShown(QString const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::isSuitable(bool, QString const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::isValid() const@Base" 1.0.0 diff --git a/debian/libqt5xdgiconloader1.symbols b/debian/libqt5xdgiconloader1.symbols deleted file mode 100644 index 5e671ad..0000000 --- a/debian/libqt5xdgiconloader1.symbols +++ /dev/null @@ -1,27 +0,0 @@ -libQt5XdgIconLoader.so.1 libqt5xdgiconloader1 #MINVER# - (c++)"XdgIconLoader::XdgIconLoader()@Base" 1.3.1~ - (c++)"XdgIconLoader::ensureInitialized()@Base" 1.3.1~ - (c++)"XdgIconLoader::findIconHelper(QString const&, QString const&, QStringList&) const@Base" 1.3.1~ - (c++)"XdgIconLoader::instance()@Base" 1.3.1~ - (c++)"XdgIconLoader::loadIcon(QString const&) const@Base" 1.3.1~ - (c++)"XdgIconLoader::setThemeName(QString const&)@Base" 1.3.1~ - (c++)"XdgIconLoader::setThemeSearchPath(QStringList const&)@Base" 1.3.1~ - (c++)"XdgIconLoader::themeSearchPaths() const@Base" 1.3.1~ - (c++)"XdgIconLoader::updateSystemTheme()@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::XdgIconLoaderEngine(QString const&)@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::XdgIconLoaderEngine(XdgIconLoaderEngine const&)@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::actualSize(QSize const&, QIcon::Mode, QIcon::State)@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::clone() const@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::ensureLoaded()@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::entryForSize(QSize const&)@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::hasIcon() const@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::key() const@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::paint(QPainter*, QRect const&, QIcon::Mode, QIcon::State)@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::pixmap(QSize const&, QIcon::Mode, QIcon::State)@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::read(QDataStream&)@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::virtual_hook(int, void*)@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::write(QDataStream&) const@Base" 1.3.1~ - (c++)"XdgIconLoaderEngine::~XdgIconLoaderEngine()@Base" 1.3.1~ - (c++)"typeinfo for XdgIconLoaderEngine@Base" 1.3.1~ - (c++)"typeinfo name for XdgIconLoaderEngine@Base" 1.3.1~ - (c++)"vtable for XdgIconLoaderEngine@Base" 1.3.1~ diff --git a/debian/libqt5xdgiconloader1.install b/debian/libqt5xdgiconloader2.install similarity index 100% rename from debian/libqt5xdgiconloader1.install rename to debian/libqt5xdgiconloader2.install diff --git a/debian/libqt5xdgiconloader2.symbols b/debian/libqt5xdgiconloader2.symbols new file mode 100644 index 0000000..7bf7093 --- /dev/null +++ b/debian/libqt5xdgiconloader2.symbols @@ -0,0 +1,27 @@ +libQt5XdgIconLoader.so.2 libqt5xdgiconloader2 #MINVER# + (c++)"XdgIconLoader::XdgIconLoader()@Base" 2.0.0 + (c++)"XdgIconLoader::ensureInitialized()@Base" 2.0.0 + (c++)"XdgIconLoader::findIconHelper(QString const&, QString const&, QStringList&) const@Base" 2.0.0 + (c++)"XdgIconLoader::instance()@Base" 2.0.0 + (c++)"XdgIconLoader::loadIcon(QString const&) const@Base" 2.0.0 + (c++)"XdgIconLoader::setThemeName(QString const&)@Base" 2.0.0 + (c++)"XdgIconLoader::setThemeSearchPath(QStringList const&)@Base" 2.0.0 + (c++)"XdgIconLoader::themeSearchPaths() const@Base" 2.0.0 + (c++)"XdgIconLoader::updateSystemTheme()@Base" 2.0.0 + (c++)"XdgIconLoaderEngine::XdgIconLoaderEngine(QString const&)@Base" 2.0.0 + (c++)"XdgIconLoaderEngine::XdgIconLoaderEngine(XdgIconLoaderEngine const&)@Base" 2.0.0 + (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::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 + (c++)"XdgIconLoaderEngine::pixmap(QSize const&, QIcon::Mode, QIcon::State)@Base" 2.0.0 + (c++)"XdgIconLoaderEngine::read(QDataStream&)@Base" 2.0.0 + (c++)"XdgIconLoaderEngine::virtual_hook(int, void*)@Base" 2.0.0 + (c++)"XdgIconLoaderEngine::write(QDataStream&) const@Base" 2.0.0 + (c++)"XdgIconLoaderEngine::~XdgIconLoaderEngine()@Base" 2.0.0 + (c++)"typeinfo for XdgIconLoaderEngine@Base" 2.0.0 + (c++)"typeinfo name for XdgIconLoaderEngine@Base" 2.0.0 + (c++)"vtable for XdgIconLoaderEngine@Base" 2.0.0 diff --git a/debian/upstream/signing-key.asc b/debian/upstream/signing-key.asc index 05cd1df..4936633 100644 --- a/debian/upstream/signing-key.asc +++ b/debian/upstream/signing-key.asc @@ -1,63 +1,50 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2.0.22 (GNU/Linux) -mQINBFJevCYBEACx+Hvy+Vsuf+V5jeLUnzjAmHoy8DfTeGWr3ts30IapLHrfi0+U -WpzNnISO77yTr4VNboVZH+GHM/rnPfieODfB4ZW6CZLlInMSKUXcgQsEqXpyBZhA -Ib/SPy2bOfHly1uRJes0uRDsH5+v/hD74sByfnjQlrvI68O6wvGZmDFMNNPVO8+/ -OWBSBNkBuVrrZOMSPsLwQGJ4UtUQ4whburaPJG4VZJc5DLbzJGbEuACc0IAEYJS3 -7AfXVXn4j4Gc9F3o1xTUnbOBnwGPquWwUIm3FM7Ec2OdkvMt3EwvnkMAfeVrq3iE -FDD/KZTxdL0BZH3QD8gB7Jm4v4f3Nkobg6JCvCbcH3wBdZW4mASbwWzfRaDC2zHb -ErTglD7PpShLKZZ0pr9okWZEGw4Ku3q8ALi1JXK/ePTmsBlvkVskOJ3Nnd0avgH4 -+Q/vZoKfH8EhNY745rI+8CE9iv6V9XiSUt4CKEWAENt4A8hq6U2vV+jZv3B6AgD7 -ZjiI59yD4YuYubu8rCnNizTgh1voVw3ietknn/x2H5yH8fByWZ5uL87C0ky/uma6 -ZGbiiAtM4kdkyDMrfRV5nlEG9EKAGPVu5mjeSCrfkETwZ9OFPz1AuDye4ZEXrrcC -iRQ7RX6/GtW18aHER0kzGnfwx5KJzkDrRBY8A2PdXLBcrsN4WpK9EX01PQARAQAB -tCNKZXJvbWUgTGVjbGFuY2hlIDxqZXJvbWVAbGVjbGFuLmNoPokCPwQTAQIAKQUC -Ul68JgIbAwUJAeEzgAcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEDfgrx/a -SPNzSHIP/1ewXcC0TFBcvDD7MrIP7anyNfiWfW7cxkR8GSamkg6HTa6Ndyr1FFjJ -OoDFUP37jWhu59CsHxs2D0zRWJktezfvElscRgqbHcdpIznqsGdI8hXCZafhBGVb -sdAB2LRawcXGxnXt7XajPcSVwLWRE62caBqohznU2iWvI780WNjEbZoA0LhZwaFF -UUPJm8ea9v0IkZVKUyg9WONZ1U7FEG9SaEiSpI8kJdx1fvCwZVDV/NRO5GqnJaho -P1LCne4YdwS6pt1/fRgk32IHxxZfHlLzLHxb6v1JmIg72x28qCmGyK9oFBDbbnYu -6Aq8XbHogOrD5vJM2Pfm2IhV0+JHOjfQbddv8tsAH1M+LI+tToXmg5st1AU3wnTn -pda3hjA1avKwkfBPW/osHc8782ViyS9iX2e9iDtMv608guij4NjpGExzGCypHOd8 -+VXRwJDjvgDynkL206MZ+wn0j5wHsIE8F3Y5Bp1thQOrdDli5MYNQoXhjFmH46XT -bcr84IgW0+AiXZdoFUqvwtzrWy2Onuw5R3k4OyV4skN4DkWXyAk/V+Y4K39JvTKf -H9YuiQ9blNzCu8WiAnjKnh9kNl9E/TyEwI6cHFmIPqF8ST9tJytWHtrKvU9csvXX -n8XNJmpcv2R1e6N+VuWWm5zUPTouv3AxCacLbm8Lh3ymGsk7ZEyhiQIcBBABAgAG -BQJSsFYyAAoJEBMY76xfu9vO6v0P/3wSj3/kE4nP4HfgcVJSzi+lm1ycpbLDZtgh -P1G+zJLVmA+E41vEZimeiYQxBAelatJz+CHzQo3LZ2oVChzVrZcVHn9k4P3pib69 -qCVif3/y0Wmecn+u2TWbOvJ7mthfO7T3W7rkW1/9ES7bUaXcXWQ2sjUBVqFkFsVt -xgJDo8wcxA+K4Yf06GCbxFwrB7X5GraWIkzqGnyse3XAQn8aORAXmE8Yd0FHOjEZ -Beb9shChnkYc3lEvNY8ioCaYSF9xr/Iz9cwpfPkpqFiVYWadtb+Gqeh6zC7vPmcT -zHxrgkq1WwQlSBm724tPt9xuGQoOglqEa23vlQZfv20nyrYjLeYUy6pMCRq7vn/n -nkQOcXF7yQlnqR6xKk0tWsM4e6du0ZvbjBbhHV/kBFVGCLm/upTwoMVm0WJTbr4T -5XfIZo7eA0lvGtUhe1PgcOidBikHfAIfYxu0BoMXoL4jbcQdR5+YBDEfsS0jPhCl -mew2ScW/R/UhUknJUVFTma0KHXzEmKiqeeUCDtwEi6fxdicAYkbcekgkfFiD/w8N -Lk3Uf+0x2MdKA36nUobFkk38oU+GW37kFWJs3f1YRuQFao896eNW/E8ekVMLNxOl -nCjnSbabaxDnxPTyW2KlNjf/QUEK4pT6S5QmuCSrle3PQpaSbAZDHzLBIL9gd3m6 -MH7+SvV4uQINBFJevCYBEADiXDUqstSdhIyuionS2KtE3IeEBIqS7GY8QPRBylIZ -ACVHFI/1HxChBqYVGFaDEQn3gj5lUUQPubfWaxzjF6+UNVQW4+cxmTocndAwfDbI -+E5BLdieFUzbAA05MV5ZjPhTNbSk1jpy4bNy0FILwNqc89Y6SoCbv1r3tZLCrBas -1+AfWknBynx0siGMbLFxtzR6hUkNz9URxt13FrzpUWMpAL8ZQGczOTSaWLrZA5l9 -xLzJ9ww8uM+C2Xej3/sANxi+kQE2GVMKurPS0TICwVWZxbdW/ytIkO67Rhse0q3t -vzjdawfCFRxv7XQB2ZJ6irDxbpHiJoojSWCHJadIyCG03iOiaqsSVvi4KnxtUck+ -udOEJUV5sxdzgeRrsDpeaN//KCWW9WjfsSkvOqP6S1gmWpNFdzF5XrzcgvqvSNqo -XejfakUTJqsIIEHO0zGuJFVzJNh2hQ/9dhjIspUORhtNKaljNvePiBrj2yqmd9PY -FlH1KMHe4H+YVIwPiyeNA87Pu+1yNo8gT7mXhGRfibgWjbt146WUJ7+l2StJMApn -eNSCartNaUNPnw96i2l5c9AsJ3SWC6XWpWzOLVj+9XceeA11lu/ogqEMHzx81NjH -2TePxwKTKxZnAvDmqryp++IgY2/OgIoIk3ZRdYu/dPijTOYWfCet/9/9kAFr9PeJ -KwARAQABiQIlBBgBAgAPBQJSXrwmAhsMBQkB4TOAAAoJEDfgrx/aSPNzJv0QAKkx -lCKEZ6ahAUuNWslsHnNWaHFHNawEO3NIEtQZGVFk2BYISupizvjZF6MnymO/9UFM -pzV6fp3xNdqaKWQBjScOgMgCASRixW2tMAKbJGHZKp3dBixpHgXxy2oOGMS+mQ5m -gWy07usq2YesoMD0K/SG6EnoRPHBvrJihArzMFVUY9hD3hk8bhiy8w9bCYFe+gkm -zpQl3/KN01kyt5LjzEBcIOw8qIBQe9Pk8PyOK75lPoNME714LatgOsyw2kaSQ9Sv -hziRGC5z/fV3PmH7XhSjENPKnCJU51GUMMLaL28t9o7Afh6Q8UV31/JO36vmQXQV -+b+0BoGqEmf3AKBASb2Cr2q4pZFjywwSUXHZ9hQyu1tpbE1dS6aI01kM0y270pk7 -W/ajuzuOxAVL1bJAanL/5+DWM03esZPVdEWhxpWEM40Z6Rhq+Xb2a5xfwCN9PmaQ -o9fez0I+yh53s7Ypv0tBj05FPe5L48+pDi6pz5nddN1B0FzF58jVfsBZUjBlY24+ -VwQeAaWkRXZrSEdtBS5ufsi80x/cNCSTJBWqtborKL1iGgf5MDPYRMSvmZXAeIld -pyL/0pbW7iokewyKzpFfo7KEbwLxB+flWaBZ867JpF4yyRj3b4qcvcyV8QnsoB7Z -KhxTl3gGwD/t0HUcu85zcfs4GkealYhIWfGaAso2 -=fF8P +mQINBFXQeMMBEACif4+9pTrC6uNmRng0ZbzLh7p3cazmbnp2YFgDQDJZ7ZNmebxy +ngRuRhjGuDcFAL/37BwJnrBpfZFK9ljoH4Fo5Jm9cOELaTy7AIcEiV9dKMyrKF1E +C76d8jHVuzuPbI92DkFdLZAdk+qjrrAy0x43PvUd+aaBGLcFs1ZMk7gOvElc2d95 +zWWSp5anjukmGbp+EsStnWJkF6VHj56qmklfYy5ioiVBOSpXo/RsACAcIlz8C8A1 +d4tNMiB2uF2OrUfrL8DD6m3nBqep+AYbIQrxMl9kUQH3I33e9kH/L+SHQyE6phS8 +Czq06WjV4TcJ9VWxm7hQCNLYSxhZYYr1AW45lS5+xmfBOq2qeLgvjbFxa8PPrsp6 +Bqgt8MjwUkXjU5IB7YulUBvFU2l0MJZWDBuNy0oNtCe1cU3JyIqLKjvzQQQ9eD5L +o3Ul704TLHz0z+67Rxh05Mi4JvyFMjnooSJkNH8/7yXoBN0ZGOh1/5zMU1gK5bmP +6hKgis2exSZNIS74mF6/PqGgcwk3PyI4T3keUQoNPj11M2EznLHxY19QZfQ5oMed +8xOlHKjpcm8PYMB4gduNXlV7gI9h7UxuC5GuPiP2lmM6wUyHu48divxDk5UYgPEC +xlPI2wHCNDsuy0EruCYIvrMSZfpYCCSrmXiOORBLO5qXkauILLkJarHqjQARAQAB +tCBBbGYgR2FpZGEgPGFnYWlkYUBzaWR1Y3Rpb24ub3JnPokCOAQTAQIAIgUCVdB4 +wwIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQQsnI069epeOT2xAAgSHf +41103cnElGf6TokPl4J6hdRPy2CUAjmBtMfr8eajYvGDGgnmsh9AGYGURjfFVCCf +Ag+8b6nF3xg03UmgsuSO8H78HGv9kKzF9aHmLt+SXq3jUX+LnIkFHErZWjFAKdJr +luu1j6ltxLe9PQljxZnugzMaUbW8eEPKvcriiDn3S4/DtikW/jpGA0MTY4ZWs9pZ +L/6iRRH99L2X/cWO4sCgDXCTt4oK0f5OvwiuCoVOM+PYoIm31JICCKOlqamkCn7d +2KH3nsy0v7tXgnrnb/zr8jVGsZLzUE51AFOzb5Ec74/2SAq8X4gbTppttLXEIooq +nbepitW/PePkPY5gpfwHtFbl88qFnir+ABMefqRZkzeh0tsxJVLVHGP1KZykXpv7 +96A6Q1h7Zo9Ny7WwN5Xl02g35LVCaPyzd3A8A4315uMuP3iziq57UktKqh9d5S3t +jfK7e9UfFQZBLfxn2sNPsjdYSNUQp/PXTTk/599h359WVuUIR866T8K7N7EEon3p +qLItZljQ9Nmr/yGwKi9iQgi2LtZj5KUcF1zBLzZKf95FvoqSZqBXdFSjm+eYGaCH +Q2IBnhyP92lEknSK9ystUJXmY69tQKBFqJxScwaS+7a/rfLKssQjSWxqk+SX4QeW +e9z9FUpo71bq0Zkc/M9aOCoEEmhg4Ob/JWy08oC5Ag0EVdB4wwEQAKZDCc/C41y0 +omLFCAJybvHiFScM+jOpyGpQvceoviEhIT7h1br/pnSEMkgPQEDPWJGtKueg1/94 +sXTH24uefr3Y6JdZoBtprxl4JXUoOndgq1QH1xuUsy3/9YWU8Qboy9j8a8w0oCDE +T8Z03KHCwqzD3K+44jhmhF+0eLoaaY8ohS8ziP+DcFKVHyatmS5yCCdjVrj6PxMp +uy/y5SXT1kmiPdVAIzQlM5DlN6o46TV+BH0pPvVYjtwf31o0FckJxy5S1v0koCNB +vX2b7tTDPKzn8G18eUVhGoUTZBUCp1gg36wJ0YY4xgZ9vI/xDCeHeAkyvGtaTAoy +qP4rHoUO5KVRSDh7frSlrdbLGWHaQwOhcqoKd4qP/164wHPGkgHL1vztdOc7l1wx +q3gMh2uwmJR0NRrw4WVuaIqL9lEbGBNijlmGsuqXfsMRhc/qoqgVDWvrcCtEoOwl +TONGobW3jpCCjpa9SeGNjxuY6IVLn0lfX4hItNVY9sFA+H+yj4uBQ7zsmMUXafxt +Yllm0f98yGNg5lnJg4bLOYu3IkpogUKNA3qkZ+6vRtwH70/bJGp7qdx/3G4W5dMX +asd/rJjdELW+R/NVULAmK1ETSklaa3Z6vbTu8bN8gvP8pmMJ8f/U8+qzkuAqc201 +Z4O+s7ZsQfTiz5mm7zPGIYTnppDSno/rABEBAAGJAh8EGAECAAkFAlXQeMMCGwwA +CgkQQsnI069epeMt0g/+JrwLhULD6NOxaLgxboh/KZkh/7ViU4cB+QPT8JIcWxkZ +zj8uk85TUitEUzKmjp/ItCrhQE5WNNWbz/FBnAuLtaQuHhcHMA3Vu95UUCGi1vyZ +ZRlS3YRM6S9BOzrjG7fGQJmO/RU3g6rb0TAwGFxDHj8t4JEDTc3zASG7wV/VTn06 +d8XIH9CZOw3kUuhkQ3OR/PEj1BCeCC+caC+tBjO0fgvDp8RV7NFQQ9kH8R3/xlWd +6KMPtILE6fUft6LubWRGd1P5JBuzXivELolASajewbYtL/s87CCji3ngq0aT9raK +m02wqFzNbX1iv+w2iqPQXq6pdRyxtJ8+Q8Z7zEBGJS5nkrYjsLTduZIjJHYHYH7f +3/ydVjQ3z12iqHKElgaRI7RUmpNiNxVIr+TtuxzeC6G+CF++XNkUtJODvCmRaoJS +waYsitz8+LSv3tawZJ0iQkKc9nerQMuBD+AzIr3i4NgXiEIN513esUtnKzeyIIsL +ntUcBjXKuLCj8OZrZtexjq7edWWbN57/3ikyS2Z7y0i3O30qk5jmccSaS6kA7xTY +WCDFzbN2v2y+vGu9KYn+2HtrP2BtNa8JTh3waNeLUTpn4GV4mMrsZjOy6vhhHb91 +1TKfI1gvjk7lE9xaWmcDjdI55dw3jIq8kK9SdgORGq9/S3g7KJNRjme+6GjqQfk= +=h7ww -----END PGP PUBLIC KEY BLOCK----- diff --git a/debian/watch b/debian/watch index 5fa3867..4637107 100644 --- a/debian/watch +++ b/debian/watch @@ -1,3 +1,3 @@ -version=3 +version=4 opts="pgpsigurlmangle=s/$/.asc/" \ https://github.com/lxde/libqtxdg/releases .*/libqtxdg-([\d\.]+)\.tar\.xz diff --git a/xdgiconloader/CMakeLists.txt b/xdgiconloader/CMakeLists.txt index 81a3fc0..f7405b3 100644 --- a/xdgiconloader/CMakeLists.txt +++ b/xdgiconloader/CMakeLists.txt @@ -54,6 +54,7 @@ target_include_directories(${QTXDGX_ICONLOADER_LIBRARY_NAME} target_link_libraries(${QTXDGX_ICONLOADER_LIBRARY_NAME} PUBLIC Qt5::Gui + Qt5::Svg ) set_target_properties(${QTXDGX_ICONLOADER_LIBRARY_NAME} diff --git a/xdgiconloader/xdgiconloader.cpp b/xdgiconloader/xdgiconloader.cpp index adc4ed7..cb084fa 100644 --- a/xdgiconloader/xdgiconloader.cpp +++ b/xdgiconloader/xdgiconloader.cpp @@ -42,12 +42,11 @@ #include #include #include -#include #include #include #include -#ifdef Q_WS_MAC +#ifdef Q_DEAD_CODE_FROM_QT4_MAC #include #endif @@ -74,9 +73,6 @@ XdgIconLoader::XdgIconLoader() : { } -// We lazily initialize the loader to make static icons -// work. Though we do not officially support this. - static inline QString systemThemeName() { if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { @@ -164,6 +160,141 @@ QStringList XdgIconLoader::themeSearchPaths() const return m_iconDirs; } +/*! + \class QIconCacheGtkReader + \internal + Helper class that reads and looks up into the icon-theme.cache generated with + gtk-update-icon-cache. If at any point we detect a corruption in the file + (because the offsets point at wrong locations for example), the reader + is marked as invalid. +*/ +class QIconCacheGtkReader +{ +public: + explicit QIconCacheGtkReader(const QString &themeDir); + QVector lookup(const QString &); + bool isValid() const { return m_isValid; } +private: + QFile m_file; + const unsigned char *m_data; + quint64 m_size; + bool m_isValid; + + quint16 read16(uint offset) + { + if (offset > m_size - 2 || (offset & 0x1)) { + m_isValid = false; + return 0; + } + return m_data[offset+1] | m_data[offset] << 8; + } + quint32 read32(uint offset) + { + if (offset > m_size - 4 || (offset & 0x3)) { + m_isValid = false; + return 0; + } + return m_data[offset+3] | m_data[offset+2] << 8 + | m_data[offset+1] << 16 | m_data[offset] << 24; + } +}; + + +QIconCacheGtkReader::QIconCacheGtkReader(const QString &dirName) + : m_isValid(false) +{ + QFileInfo info(dirName + QLatin1Literal("/icon-theme.cache")); + if (!info.exists() || info.lastModified() < QFileInfo(dirName).lastModified()) + return; + m_file.setFileName(info.absoluteFilePath()); + if (!m_file.open(QFile::ReadOnly)) + return; + m_size = m_file.size(); + m_data = m_file.map(0, m_size); + if (!m_data) + return; + if (read16(0) != 1) // VERSION_MAJOR + return; + + m_isValid = true; + + // Check that all the directories are older than the cache + auto lastModified = info.lastModified(); + quint32 dirListOffset = read32(8); + quint32 dirListLen = read32(dirListOffset); + for (uint i = 0; i < dirListLen; ++i) { + quint32 offset = read32(dirListOffset + 4 + 4 * i); + if (!m_isValid || offset >= m_size || lastModified < QFileInfo(dirName + QLatin1Char('/') + + QString::fromUtf8(reinterpret_cast(m_data + offset))).lastModified()) { + m_isValid = false; + return; + } + } +} + +static quint32 icon_name_hash(const char *p) +{ + quint32 h = static_cast(*p); + for (p += 1; *p != '\0'; p++) + h = (h << 5) - h + *p; + return h; +} + +/*! \internal + lookup the icon name and return the list of subdirectories in which an icon + with this name is present. The char* are pointers to the mapped data. + For example, this would return { "32x32/apps", "24x24/apps" , ... } + */ +QVector QIconCacheGtkReader::lookup(const QString &name) +{ + QVector ret; + if (!isValid()) + return ret; + + QByteArray nameUtf8 = name.toUtf8(); + quint32 hash = icon_name_hash(nameUtf8.data()); + + quint32 hashOffset = read32(4); + quint32 hashBucketCount = read32(hashOffset); + + if (!isValid() || hashBucketCount == 0) { + m_isValid = false; + return ret; + } + + quint32 bucketIndex = hash % hashBucketCount; + quint32 bucketOffset = read32(hashOffset + 4 + bucketIndex * 4); + while (bucketOffset > 0 && bucketOffset <= m_size - 12) { + quint32 nameOff = read32(bucketOffset + 4); + if (nameOff < m_size && strcmp(reinterpret_cast(m_data + nameOff), nameUtf8.constData()) == 0) { + quint32 dirListOffset = read32(8); + quint32 dirListLen = read32(dirListOffset); + + quint32 listOffset = read32(bucketOffset+8); + quint32 listLen = read32(listOffset); + + if (!m_isValid || listOffset + 4 + 8 * listLen > m_size) { + m_isValid = false; + return ret; + } + + ret.reserve(listLen); + for (uint j = 0; j < listLen && m_isValid; ++j) { + quint32 dirIndex = read16(listOffset + 4 + 8 * j); + quint32 o = read32(dirListOffset + 4 + dirIndex*4); + if (!m_isValid || dirIndex >= dirListLen || o >= m_size) { + m_isValid = false; + return ret; + } + ret.append(reinterpret_cast(m_data) + o); + } + return ret; + } + bucketOffset = read32(bucketOffset); + } + return ret; +} + QIconTheme::QIconTheme(const QString &themeName) : m_valid(false) { @@ -173,19 +304,17 @@ QIconTheme::QIconTheme(const QString &themeName) for ( int i = 0 ; i < iconDirs.size() ; ++i) { QDir iconDir(iconDirs[i]); QString themeDir = iconDir.path() + QLatin1Char('/') + themeName; - themeIndex.setFileName(themeDir + QLatin1String("/index.theme")); - if (themeIndex.exists()) { - m_contentDirs << themeDir; - m_valid = true; + QFileInfo themeDirInfo(themeDir); - QStringList themeSearchPaths = QIcon::themeSearchPaths(); - foreach (QString path, themeSearchPaths) - { - if (!path.startsWith(QLatin1Char(':')) && QFileInfo(path).isDir()) - m_contentDirs.append(path + QLatin1Char('/') + themeName); - } + if (themeDirInfo.isDir()) { + m_contentDirs << themeDir; + m_gtkCaches << QSharedPointer::create(themeDir); + } - break; + if (!m_valid) { + themeIndex.setFileName(themeDir + QLatin1String("/index.theme")); + if (themeIndex.exists()) + m_valid = true; } } #ifndef QT_NO_SETTINGS @@ -270,7 +399,6 @@ QThemeIconInfo XdgIconLoader::findIconHelper(const QString &themeName, } const QStringList contentDirs = theme.contentDirs(); - const QVector subDirs = theme.keyList(); const QString svgext(QLatin1String(".svg")); const QString pngext(QLatin1String(".png")); @@ -287,6 +415,29 @@ QThemeIconInfo XdgIconLoader::findIconHelper(const QString &themeName, // Add all relevant files for (int i = 0; i < contentDirs.size(); ++i) { + QVector subDirs = theme.keyList(); + + // Try to reduce the amount of subDirs by looking in the GTK+ cache in order to save + // a massive amount of file stat (especially if the icon is not there) + auto cache = theme.m_gtkCaches.at(i); + if (cache->isValid()) { + auto result = cache->lookup(iconNameFallback); + if (cache->isValid()) { + const QVector subDirsCopy = subDirs; + subDirs.clear(); + subDirs.reserve(result.count()); + foreach (const char *s, result) { + QString path = QString::fromUtf8(s); + auto it = std::find_if(subDirsCopy.cbegin(), subDirsCopy.cend(), + [&](const XdgIconDirInfo &info) { + return info.path == path; } ); + if (it != subDirsCopy.cend()) { + subDirs.append(*it); + } + } + } + } + QString contentDir = contentDirs.at(i) + QLatin1Char('/'); for (int j = 0; j < subDirs.size() ; ++j) { const XdgIconDirInfo &dirInfo = subDirs.at(j); @@ -487,7 +638,7 @@ void XdgIconLoaderEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) { QSize pixmapSize = rect.size(); -#if defined(Q_WS_MAC) +#if defined(Q_DEAD_CODE_FROM_QT4_MAC) pixmapSize *= qt_mac_get_scalefactor(); #endif painter->drawPixmap(rect, pixmap(pixmapSize, mode, state)); @@ -693,9 +844,16 @@ void XdgIconLoaderEngine::virtual_hook(int id, void *data) case QIconEngine::IconNameHook: { QString &name = *reinterpret_cast(data); - name = m_iconName; + name = m_info.iconName; + } + break; +#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) + case QIconEngine::IsNullHook: + { + *reinterpret_cast(data) = m_info.entries.isEmpty(); } break; +#endif default: QIconEngine::virtual_hook(id, data); } diff --git a/xdgiconloader/xdgiconloader_p.h b/xdgiconloader/xdgiconloader_p.h index 0511ab3..380a222 100644 --- a/xdgiconloader/xdgiconloader_p.h +++ b/xdgiconloader/xdgiconloader_p.h @@ -78,7 +78,7 @@ struct XdgIconDirInfo short maxSize; short minSize; short threshold; - Type type : 4; + Type type; }; class XdgIconLoaderEngineEntry @@ -141,6 +141,8 @@ private: friend class XdgIconLoader; }; +class QIconCacheGtkReader; + class QIconTheme { public: @@ -150,12 +152,13 @@ public: QVector keyList() { return m_keyList; } QStringList contentDirs() { return m_contentDirs; } bool isValid() { return m_valid; } - private: QStringList m_contentDirs; QVector m_keyList; QStringList m_parents; bool m_valid; +public: + QVector> m_gtkCaches; }; class XDGICONLOADER_EXPORT XdgIconLoader @@ -175,6 +178,7 @@ public: void updateSystemTheme(); void invalidateKey() { m_themeKey++; } void ensureInitialized(); + bool hasUserTheme() const { return !m_userTheme.isEmpty(); } private: QThemeIconInfo findIconHelper(const QString &themeName, From e236999695845234d984afc11db97bd0e73790c1 Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Fri, 30 Sep 2016 19:10:46 +0200 Subject: [PATCH 07/14] XdgIconLoader: Recommend gtk-update-icon-cache instead depend on it. Thanks Rohan Garg --- debian/changelog | 9 ++++++++- debian/control | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 78ff318..55fa035 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +libqtxdg (2.0.0-2) experimental; urgency=medium + + * XdgIconLoader: Recommend gtk-update-icon-cache instead depend on it. + Thanks Rohan Garg + + -- Alf Gaida Fri, 30 Sep 2016 19:10:36 +0200 + libqtxdg (2.0.0-1) experimental; urgency=medium * Cherry-picked new upstream release 2.0.0. @@ -17,7 +24,7 @@ libqtxdg (2.0.0-1) experimental; urgency=medium libqtxdg (1.3.1~50-g4fde773-4) experimental; urgency=medium * Added libfile-mimeinfo-perl as dependency, we really need this, a - recommendation is not enough. Thanks tsujan. + recommendation is not enough. Thanks tsujan. -- Alf Gaida Wed, 10 Aug 2016 22:48:40 +0200 diff --git a/debian/control b/debian/control index 4e16816..fc179ef 100644 --- a/debian/control +++ b/debian/control @@ -36,8 +36,8 @@ Package: libqt5xdgiconloader2 Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, - ${misc:Depends}, - gtk-update-icon-cache + ${misc:Depends} +Recommmends: gtk-update-icon-cache Pre-Depends: ${misc:Pre-Depends} Provides: libqt5xdgiconloader Description: Implementation of the XDG Iconloader for Qt (shared lib) From 6548865b944beba64b63efa37c09304674ca8975 Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Tue, 4 Oct 2016 21:21:16 +0200 Subject: [PATCH 08/14] Fixed typo Recommmends -> Recommends --- debian/changelog | 6 ++++++ debian/control | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 55fa035..64a10e1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +libqtxdg (2.0.0-3) experimental; urgency=medium + + * Fixed typo Recommmends -> Recommends + + -- Alf Gaida Tue, 04 Oct 2016 21:20:53 +0200 + libqtxdg (2.0.0-2) experimental; urgency=medium * XdgIconLoader: Recommend gtk-update-icon-cache instead depend on it. diff --git a/debian/control b/debian/control index fc179ef..e11484a 100644 --- a/debian/control +++ b/debian/control @@ -37,7 +37,7 @@ Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends} -Recommmends: gtk-update-icon-cache +Recommends: gtk-update-icon-cache Pre-Depends: ${misc:Pre-Depends} Provides: libqt5xdgiconloader Description: Implementation of the XDG Iconloader for Qt (shared lib) From 4c58fcb9c353be3fdf500c71729608c5fdd637ad Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Sat, 23 Sep 2017 00:35:24 +0200 Subject: [PATCH 09/14] Prepare libqtxdg 3.0.0 --- AUTHORS | 2 +- CMakeLists.txt | 35 +- cmake/compiler_settings.cmake | 72 ++- cmake/qt5xdg-config.cmake.in | 18 +- cmake/qt5xdgiconloader-config.cmake.in | 14 +- debian/.gitignore | 1 + debian/changelog | 91 ++-- debian/control | 26 +- debian/copyright | 2 +- debian/gbp.conf | 2 +- ...{libqt5xdg2.install => libqt5xdg3.install} | 0 ...{libqt5xdg2.symbols => libqt5xdg3.symbols} | 114 +++-- debian/libqt5xdgiconloader-dev.install | 2 + ...2.install => libqt5xdgiconloader3.install} | 0 ...2.symbols => libqt5xdgiconloader3.symbols} | 28 +- debian/qtxdg-dev-tools.install | 4 + debian/rules | 8 +- qtxdg/CMakeLists.txt | 32 +- qtxdg/xdgaction.h | 2 +- qtxdg/xdgautostart.cpp | 4 +- qtxdg/xdgdesktopfile.cpp | 52 +- qtxdg/xdgdirs.cpp | 12 +- qtxdg/xdgicon.cpp | 34 +- qtxdg/xdgicon.h | 15 +- qtxdg/xdgmenu.cpp | 19 +- qtxdg/xdgmenu.h | 2 +- qtxdg/xdgmenu_p.h | 4 +- qtxdg/xdgmenuapplinkprocessor.cpp | 12 +- qtxdg/xdgmenureader.cpp | 18 +- qtxdg/xdgmenureader.h | 4 +- qtxdg/xdgmenuwidget.cpp | 4 +- qtxdg/xdgmimetype.cpp | 2 +- qtxdg/xmlhelper.cpp | 2 +- release.sh | 28 -- test/CMakeLists.txt | 16 +- test/qtxdg_test.cpp | 6 +- test/qtxdg_test.h | 2 +- test/tst_xdgdesktopfile.cpp | 8 +- test/tst_xdgdesktopfile.h | 2 +- test/tst_xdgdirs.cpp | 2 +- util/CMakeLists.txt | 36 +- util/qtxdg-iconfinder.cpp | 74 +++ xdgiconloader/CMakeLists.txt | 32 +- xdgiconloader/plugin/CMakeLists.txt | 49 ++ xdgiconloader/plugin/xdgiconengineplugin.cpp | 35 ++ xdgiconloader/plugin/xdgiconengineplugin.h | 38 ++ xdgiconloader/plugin/xdgiconengineplugin.json | 1 + xdgiconloader/xdgiconloader.cpp | 444 +++++++++--------- xdgiconloader/xdgiconloader_p.h | 148 ++---- 49 files changed, 912 insertions(+), 646 deletions(-) rename debian/{libqt5xdg2.install => libqt5xdg3.install} (100%) rename debian/{libqt5xdg2.symbols => libqt5xdg3.symbols} (98%) rename debian/{libqt5xdgiconloader2.install => libqt5xdgiconloader3.install} (100%) rename debian/{libqt5xdgiconloader2.symbols => libqt5xdgiconloader3.symbols} (74%) create mode 100644 debian/qtxdg-dev-tools.install delete mode 100755 release.sh create mode 100644 util/qtxdg-iconfinder.cpp create mode 100644 xdgiconloader/plugin/CMakeLists.txt create mode 100644 xdgiconloader/plugin/xdgiconengineplugin.cpp create mode 100644 xdgiconloader/plugin/xdgiconengineplugin.h create mode 100644 xdgiconloader/plugin/xdgiconengineplugin.json diff --git a/AUTHORS b/AUTHORS index dd2061e..6ec1f48 100644 --- a/AUTHORS +++ b/AUTHORS @@ -4,7 +4,7 @@ Upstream Authors: Copyright: Copyright (c) 2010-2012 Razor team - Copyright (c) 2012-2016 LXQt team + Copyright (c) 2012-2017 LXQt team License: LGPL-2.1+ and LGPL-2.1-or-3-with-Digia-1.1-exception The full text of the LGPL-2.1+ license can be found in the 'COPYING' file. diff --git a/CMakeLists.txt b/CMakeLists.txt index 103d5ba..6af52bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,11 +25,13 @@ else() set(CMAKE_CXX_STANDARD 11) endif() -set(QTXDG_MAJOR_VERSION 2) +set(QTXDG_MAJOR_VERSION 3) set(QTXDG_MINOR_VERSION 0) set(QTXDG_PATCH_VERSION 0) set(QTXDG_VERSION_STRING ${QTXDG_MAJOR_VERSION}.${QTXDG_MINOR_VERSION}.${QTXDG_PATCH_VERSION}) +set(QT_MINIMUM_VERSION "5.6.1") + include(GNUInstallDirs) # Standard directories for installation include(CMakePackageConfigHelpers) include(GenerateExportHeader) @@ -37,13 +39,12 @@ include(create_portable_headers) include(create_pkgconfig_file) include(compiler_settings NO_POLICY_SCOPE) -find_package(Qt5Widgets REQUIRED QUIET) -find_package(Qt5Svg REQUIRED QUIET) -find_package(Qt5Xml REQUIRED QUIET) -find_package(Qt5DBus REQUIRED QUIET) +set(CMAKE_AUTOMOC ON) + +find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Widgets Svg Xml DBus) if (BUILD_TESTS) - find_package(Qt5Test REQUIRED QUIET) + find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Test) endif() @@ -52,12 +53,13 @@ set(QTXDGX_FILE_NAME "qt5xdg") set(QTXDGX_ICONLOADER_LIBRARY_NAME "Qt5XdgIconLoader") set(QTXDGX_ICONLOADER_FILE_NAME "qt5xdgiconloader") +set(QTXDGX_ICONENGINEPLUGIN_LIBRARY_NAME "Qt5XdgIconPlugin") set(QTXDGX_PKG_CONFIG_DESCRIPTION "Qt5Xdg, a Qt5 implementation of XDG standards") -set(QTXDGX_PKG_CONFIG_REQUIRES "Qt5Core, Qt5Xml, Qt5Widgets, Qt5DBus, Qt5XdgIconLoader") +set(QTXDGX_PKG_CONFIG_REQUIRES "Qt5Core >= ${QT_MINIMUM_VERSION}, Qt5Xml >= ${QT_MINIMUM_VERSION}, Qt5Widgets >= ${QT_MINIMUM_VERSION}, Qt5DBus >= ${QT_MINIMUM_VERSION}, Qt5XdgIconLoader = ${QTXDG_VERSION_STRING}") set(QTXDGX_ICONLOADER_PKG_CONFIG_DESCRIPTION "Qt5XdgIconLader, a Qt5 XDG Icon Loader") -set(QTXDGX_ICONLOADER_PKG_CONFIG_REQUIRES "Qt5Gui, Qt5Svg") +set(QTXDGX_ICONLOADER_PKG_CONFIG_REQUIRES "Qt5Gui >= ${QT_MINIMUM_VERSION}, Qt5Svg >= ${QT_MINIMUM_VERSION}") set(QTXDGX_INTREE_INCLUDEDIR "${CMAKE_CURRENT_BINARY_DIR}/InTreeBuild/include") @@ -65,7 +67,7 @@ if (NOT CMAKE_BUILD_TYPE) set ( CMAKE_BUILD_TYPE Release ) endif (NOT CMAKE_BUILD_TYPE) -message(STATUS "Building with Qt ${Qt5Core_VERSION_STRING}") +message(STATUS "Building ${PROJECT_NAME} with Qt ${Qt5Core_VERSION}") add_subdirectory(xdgiconloader) add_subdirectory(qtxdg) @@ -167,16 +169,5 @@ configure_file( "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) -add_custom_target(uninstall - COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") - - -# building tarball with CPack ------------------------------------------------- -include (InstallRequiredSystemLibraries) -set (CPACK_PACKAGE_VERSION_MAJOR ${QTXDG_MAJOR_VERSION}) -set (CPACK_PACKAGE_VERSION_MINOR ${QTXDG_MINOR_VERSION}) -set (CPACK_PACKAGE_VERSION_PATCH ${QTXDG_PATCH_VERSION}) -set (CPACK_GENERATOR TBZ2) -set (CPACK_SOURCE_GENERATOR TBZ2) -set (CPACK_SOURCE_IGNORE_FILES /build/;.gitignore;.*~;.git;.kdev4;temp) -include (CPack) +#add_custom_target(uninstall +# COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") diff --git a/cmake/compiler_settings.cmake b/cmake/compiler_settings.cmake index 044b36a..6e318d9 100644 --- a/cmake/compiler_settings.cmake +++ b/cmake/compiler_settings.cmake @@ -1,5 +1,6 @@ #============================================================================= # Copyright 2015 Luís Pereira +# Copyright 2013 Hong Jen Yee (PCMan) # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -65,6 +66,14 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") endif() +#----------------------------------------------------------------------------- +# Global definitions +#----------------------------------------------------------------------------- +if (CMAKE_BUILD_TYPE MATCHES "Debug") + add_definitions(-DQT_STRICT_ITERATORS) +endif() + + #----------------------------------------------------------------------------- # Set visibility to hidden to hide symbols, unless they're exported manually # in the code @@ -80,18 +89,25 @@ if (CMAKE_COMPILER_IS_GNUCXX OR QTXDG_COMPILER_IS_CLANGCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") endif() - #----------------------------------------------------------------------------- # Common warning flags #----------------------------------------------------------------------------- -set(QTXDG_COMMON_WARNING_FLAGS "-Wall") +set(QTXDG_COMMON_WARNING_FLAGS "-Wall -Wextra -Wchar-subscripts -Wno-long-long -Wpointer-arith -Wundef -Wformat-security") #----------------------------------------------------------------------------- # Warning flags #----------------------------------------------------------------------------- +if (CMAKE_COMPILER_IS_GNUCXX OR QTXDG_COMPILER_IS_CLANGCXX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${__QTXDG_COMMON_WARNING_FLAGS} -Wnon-virtual-dtor -Woverloaded-virtual -Wpedantic") +endif() + +if (QTXDG_COMPILER_IS_CLANGCXX) + # qCDebug(), qCWarning, etc trigger a very verbose warning, about.... nothing. Disable it. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-gnu-zero-variadic-macro-arguments") +endif() + list(APPEND QTXDG_WARNING_FLAGS ${QTXDG_COMMON_WARNING_FLAGS}) -add_definitions(${QTXDG_WARNING_FLAGS}) #----------------------------------------------------------------------------- # String conversion flags @@ -103,3 +119,53 @@ add_definitions( -DQT_NO_URL_CAST_FROM_STRING -DQT_NO_CAST_FROM_BYTEARRAY ) + +#----------------------------------------------------------------------------- +# Linker flags +# Do not allow undefined symbols +#----------------------------------------------------------------------------- +if (CMAKE_COMPILER_IS_GNUCXX OR QTXDG_COMPILER_IS_CLANGCXX) + # -Bsymbolic-functions: replace dynamic symbols used internally in + # shared libs with direct addresses. + set(SYMBOLIC_FLAGS + "-Wl,-Bsymbolic-functions -Wl,-Bsymbolic" + ) + set(CMAKE_SHARED_LINKER_FLAGS + "-Wl,--no-undefined ${SYMBOLIC_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" + ) + set(CMAKE_MODULE_LINKER_FLAGS + "-Wl,--no-undefined ${SYMBOLIC_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}" + ) + set(CMAKE_EXE_LINKER_FLAGS + "${SYMBOLIC_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" + ) + +endif() + +#----------------------------------------------------------------------------- +# Turn on more aggrassive optimizations not supported by CMake +# References: https://wiki.qt.io/Performance_Tip_Startup_Time +#----------------------------------------------------------------------------- +if (CMAKE_COMPILER_IS_GNUCXX OR QTXDG_COMPILER_IS_CLANGCXX) + # -flto: use link-time optimizations to generate more efficient code + if (CMAKE_COMPILER_IS_GNUCXX) + set(LTO_FLAGS "-flto -fuse-linker-plugin") + # When building static libraries with LTO in gcc >= 4.9, + # "gcc-ar" and "gcc-ranlib" should be used instead of "ar" and "ranlib". + # references: + # https://gcc.gnu.org/gcc-4.9/changes.html + # http://hubicka.blogspot.tw/2014/04/linktime-optimization-in-gcc-2-firefox.html + # https://github.com/monero-project/monero/pull/1065/commits/1855213c8fb8f8727f4107716aab8e7ba826462b + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9.0") # gcc >= 4.9 + set(CMAKE_AR "gcc-ar") + set(CMAKE_RANLIB "gcc-ranlib") + endif() + elseif (QTXDG_COMPILER_IS_CLANGCXX) + # The link-time optimization of clang++/llvm seems to be too aggrassive. + # After testing, it breaks the signal/slots of QObject sometimes. + # So disable it for now until there is a solution. + # set(LTO_FLAGS "-flto") + endif() + # apply these options to "Release" build type only + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${LTO_FLAGS}") +endif() diff --git a/cmake/qt5xdg-config.cmake.in b/cmake/qt5xdg-config.cmake.in index 045c920..ebcf150 100644 --- a/cmake/qt5xdg-config.cmake.in +++ b/cmake/qt5xdg-config.cmake.in @@ -1,13 +1,15 @@ @PACKAGE_INIT@ -include(CMakeFindDependencyMacro) +if (NOT TARGET @QTXDGX_LIBRARY_NAME@) + include(CMakeFindDependencyMacro) -find_dependency(Qt5Widgets) -find_dependency(Qt5Xml) -find_dependency(Qt5DBus) -find_dependency(Qt5XdgIconLoader) + find_dependency(Qt5Widgets @QT_MINIMUM_VERSION@) + find_dependency(Qt5Xml @QT_MINIMUM_VERSION@) + find_dependency(Qt5DBus @QT_MINIMUM_VERSION@) + find_dependency(Qt5XdgIconLoader @QTXDG_VERSION_STRING@ EXACT) -if (CMAKE_VERSION VERSION_GREATER 2.8.12) - cmake_policy(SET CMP0024 OLD) + if (CMAKE_VERSION VERSION_GREATER 2.8.12) + cmake_policy(SET CMP0024 NEW) + endif() + include("${CMAKE_CURRENT_LIST_DIR}/qt5xdg-targets.cmake") endif() -include("${CMAKE_CURRENT_LIST_DIR}/qt5xdg-targets.cmake") diff --git a/cmake/qt5xdgiconloader-config.cmake.in b/cmake/qt5xdgiconloader-config.cmake.in index f5ed0ac..765ef45 100644 --- a/cmake/qt5xdgiconloader-config.cmake.in +++ b/cmake/qt5xdgiconloader-config.cmake.in @@ -1,11 +1,13 @@ @PACKAGE_INIT@ -include(CMakeFindDependencyMacro) +if (NOT TARGET @QTXDGX_ICONLOADER_LIBRARY_NAME@) + include(CMakeFindDependencyMacro) -find_dependency(Qt5Gui) -find_dependency(Qt5Svg) + find_dependency(Qt5Gui @QT_MINIMUM_REQUIRED@) + find_dependency(Qt5Svg @QT_MINIMUM_REQUIRED@) -if (CMAKE_VERSION VERSION_GREATER 2.8.12) - cmake_policy(SET CMP0024 OLD) + if (CMAKE_VERSION VERSION_GREATER 2.8.12) + cmake_policy(SET CMP0024 NEW) + endif() + include("${CMAKE_CURRENT_LIST_DIR}/qt5xdgiconloader-targets.cmake") endif() -include("${CMAKE_CURRENT_LIST_DIR}/qt5xdgiconloader-targets.cmake") diff --git a/debian/.gitignore b/debian/.gitignore index 643c6a8..edc331a 100644 --- a/debian/.gitignore +++ b/debian/.gitignore @@ -9,4 +9,5 @@ /libqt5xdg-dev/ /libqt5xdgiconloader-dev/ /libqt5xdgiconloader2/ +/qtxdg-dev-tools/ /tmp diff --git a/debian/changelog b/debian/changelog index 64a10e1..2d5ff51 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,71 +1,70 @@ -libqtxdg (2.0.0-3) experimental; urgency=medium +libqtxdg (2.96.0-1) experimental; urgency=medium - * Fixed typo Recommmends -> Recommends + * New snapshot: 2.0.0-58-gbc64037 + * Switched to experimental + * Renamed packages to reflect the new soname + * Bumped standards to 4.0.0, no changes needed - -- Alf Gaida Tue, 04 Oct 2016 21:20:53 +0200 + -- Alf Gaida Tue, 25 Jul 2017 00:42:08 +0200 -libqtxdg (2.0.0-2) experimental; urgency=medium +libqtxdg (2.0.0-7) unstable; urgency=medium - * XdgIconLoader: Recommend gtk-update-icon-cache instead depend on it. - Thanks Rohan Garg + * Added qttranslations5-l10n to Recommends - without this packagage there are + no working shortcuts in localized LXQt desktops. So we want to make sure + that the package is at least recommended for qtxdg based packages. + + -- Alf Gaida Mon, 24 Jul 2017 21:54:16 +0200 + +libqtxdg (2.0.0-6) unstable; urgency=medium + + * Bump Standards to 4.0.0 - no changes needed + * Added Dependeny share-mime-info (Closes: #866744) + * Bumped year in copyrights + * Removed --parallel from rules, default in compat-leveld 10 - -- Alf Gaida Fri, 30 Sep 2016 19:10:36 +0200 + -- Alf Gaida Sat, 01 Jul 2017 14:15:07 +0200 -libqtxdg (2.0.0-1) experimental; urgency=medium +libqtxdg (2.0.0-5) unstable; urgency=medium + + * Rebuild with Qt 5.7.1~ + + -- Alf Gaida Fri, 04 Nov 2016 17:59:49 +0100 + +libqtxdg (2.0.0-4) unstable; urgency=medium * Cherry-picked new upstream release 2.0.0. * Added current signing key * Bumped compat to 10 - * Bumped debhelper to (>=10) + * Bumped debhelper to (>= 10) * Added build dependency libqt5svg5-dev * Renamed package libqt5xdg1 -> libqt5xdg2 (soname bump) - * Renamed package libqt5xdgiconloader1 -> libqt5xdgiconloader2 (soname bump) - * Added dependency gtk-update-icon-cache to libqt5xdgiconloader2 + * Added packages libqt5xdgiconloader2 and libqt5xdgiconloader-dev + * XdgIconLoader: Recommend gtk-update-icon-cache + Thanks Rohan Garg * Renamed install and symbols files * Fixed symbols * Fixed .gitignore + * Reworked descriptions in debian/control to prevent lintian whining + * Fixed copyright for xdgiconloader + * Added README.md to debian/docs + * Set CMAKE_BUILD_TYPE=RelWithDebInfo - -- Alf Gaida Sun, 18 Sep 2016 02:28:47 +0200 + -- Alf Gaida Sat, 09 Jul 2016 20:16:32 +0200 -libqtxdg (1.3.1~50-g4fde773-4) experimental; urgency=medium +libqtxdg (1.3.0-4) unstable; urgency=medium * Added libfile-mimeinfo-perl as dependency, we really need this, a - recommendation is not enough. Thanks tsujan. - - -- Alf Gaida Wed, 10 Aug 2016 22:48:40 +0200 - -libqtxdg (1.3.1~50-g4fde773-3) experimental; urgency=medium - - * Fixed typo in changelog - - -- Alf Gaida Sat, 23 Jul 2016 13:05:14 +0200 - -libqtxdg (1.3.1~50-g4fde773-2) experimental; urgency=medium - - * Added build dependencies gcc (>= 4:6), g++ (>= 4:6) - * Exported LC_ALL=C.UTF-8 - define language settings for - reproducible builds - - -- Alf Gaida Sat, 16 Jul 2016 20:26:26 +0200 - -libqtxdg (1.3.1~50-g4fde773-1) experimental; urgency=medium - - * New pre-release 1.3.1~50-g4fde773 - * Fixed libqt5xdgiconloader-dev.install - * Reworked descriptions in debian/control to prevent lintian whining - * Fixed symbols version - * Fixed copyright for xdgiconloader - * Fixed package descrioptions - * Introduced the new package libqt5xdgiconloader1 + recommendation is not enough. Thanks tsujan. * Bumped standards to 3.9.8, no changes needed - * Symbols sorted and unified - * Added missed Symbol * Bump years in copyright + * Added README to debian/docs * Added hardening=+all - * Added README.md to debian/docs - * set CMAKE_BUILD_TYPE=RelWithDebInfo - - -- Alf Gaida Sat, 09 Jul 2016 20:16:32 +0200 + * Exported LC_ALL=C.UTF-8 - define language settings for + reproducible builds + * Fixed VCS-fields, use https and plain /git/ + * Fixed copyrights Format field to https + + -- Alf Gaida Wed, 10 Aug 2016 23:06:12 +0200 libqtxdg (1.3.0-3) unstable; urgency=medium diff --git a/debian/control b/debian/control index e11484a..7a01260 100644 --- a/debian/control +++ b/debian/control @@ -13,17 +13,19 @@ Build-Depends: debhelper (>= 10), qtbase5-private-dev, qttools5-dev, qttools5-dev-tools -Standards-Version: 3.9.8 +Standards-Version: 4.1.0 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 -Package: libqt5xdg2 +Package: libqt5xdg3 Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends}, - libfile-mimeinfo-perl + libfile-mimeinfo-perl, + shared-mime-info +Recommends: qttranslations5-l10n Pre-Depends: ${misc:Pre-Depends} Provides: libqt5xdg Description: Implementation of the XDG Specifications for Qt (shared lib) @@ -32,7 +34,7 @@ Description: Implementation of the XDG Specifications for Qt (shared lib) . This package provides the shared library. -Package: libqt5xdgiconloader2 +Package: libqt5xdgiconloader3 Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, @@ -50,7 +52,7 @@ Package: libqt5xdg-dev Architecture: any Section: libdevel Depends: ${misc:Depends}, - libqt5xdg2 (= ${binary:Version}), + libqt5xdg3 (= ${binary:Version}), libqt5xdgiconloader-dev (= ${binary:Version}) Description: Development files for libqtxdg This library implements functions of the XDG Specifications in Qt. It is part @@ -61,10 +63,20 @@ Description: Development files for libqtxdg Package: libqt5xdgiconloader-dev Architecture: any Section: libdevel -Depends: ${misc:Depends}, - libqt5xdgiconloader2 (= ${binary:Version}) +Depends: ${shlibs:Depends}, + libqt5xdgiconloader3 (= ${binary:Version}) Description: Development files for libqtxdgiconloader This library implements the backend to load icons which are handled according to the XDG Icon Theme Specification in Qt. It is part of LXQt. . This package provides development files. + +Package: qtxdg-dev-tools +Architecture: any +Section: devel +Depends: ${shlibs:Depends}, + ${misc: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 afb3712..90c911c 100644 --- a/debian/copyright +++ b/debian/copyright @@ -15,7 +15,7 @@ License: LGPL-2.1-or-3-with-Digia-1.1-exception Files: debian/* Copyright: 2014-2016 ChangZhuo Chen (陳昌倬) - 2013-2016 Alf Gaida + 2013-2017 Alf Gaida 2015 Andrew Lee (李健秋) License: LGPL-2.1+ diff --git a/debian/gbp.conf b/debian/gbp.conf index 7a9f00a..ffe50a8 100644 --- a/debian/gbp.conf +++ b/debian/gbp.conf @@ -1,5 +1,5 @@ [DEFAULT] -debian-branch = debian/sid +debian-branch = debian/experimental upstream-branch = upstream/latest pristine-tar = True diff --git a/debian/libqt5xdg2.install b/debian/libqt5xdg3.install similarity index 100% rename from debian/libqt5xdg2.install rename to debian/libqt5xdg3.install diff --git a/debian/libqt5xdg2.symbols b/debian/libqt5xdg3.symbols similarity index 98% rename from debian/libqt5xdg2.symbols rename to debian/libqt5xdg3.symbols index f059df7..473ad97 100644 --- a/debian/libqt5xdg2.symbols +++ b/debian/libqt5xdg3.symbols @@ -1,9 +1,21 @@ -libQt5Xdg.so.2 libqt5xdg2 #MINVER# - (c++)"XdgAction::XdgAction(QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(QString const&, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(XdgAction const&, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(XdgDesktopFile const&, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(XdgDesktopFile const*, QObject*)@Base" 1.0.0 +libQt5Xdg.so.3 libqt5xdg3 #MINVER# + (c++)"non-virtual thunk to XdgMenuWidget::~XdgMenuWidget()@Base" 1.0.0 + (c++)"typeinfo for XdgAction@Base" 1.0.0 + (c++)"typeinfo for XdgDesktopFile@Base" 1.0.0 + (c++)"typeinfo for XdgIcon@Base" 1.0.0 + (c++)"typeinfo for XdgMenu@Base" 1.0.0 + (c++)"typeinfo for XdgMenuWidget@Base" 1.0.0 + (c++)"typeinfo name for XdgAction@Base" 1.0.0 + (c++)"typeinfo name for XdgDesktopFile@Base" 1.0.0 + (c++)"typeinfo name for XdgIcon@Base" 1.0.0 + (c++)"typeinfo name for XdgMenu@Base" 1.0.0 + (c++)"typeinfo name for XdgMenuWidget@Base" 1.0.0 + (c++)"vtable for XdgAction@Base" 1.0.0 + (c++)"vtable for XdgDesktopFile@Base" 1.0.0 + (c++)"vtable for XdgIcon@Base" 1.0.0 + (c++)"vtable for XdgMenu@Base" 1.0.0 + (c++)"vtable for XdgMenuWidget@Base" 1.0.0 + (c++)"XdgAction::isValid() const@Base" 1.0.0 (c++)"XdgAction::load(XdgDesktopFile const&)@Base" 1.0.0 (c++)"XdgAction::metaObject() const@Base" 1.0.0 @@ -14,18 +26,35 @@ libQt5Xdg.so.2 libqt5xdg2 #MINVER# (c++)"XdgAction::staticMetaObject@Base" 1.0.0 (c++)"XdgAction::updateIcon()@Base" 1.0.0 (c++)"XdgAction::~XdgAction()@Base" 1.0.0 - (c++)"XdgAutoStart::desktopFileList(QStringList, bool)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(QObject*)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(QString const&, QObject*)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(XdgAction const&, QObject*)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(XdgDesktopFile const*, QObject*)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(XdgDesktopFile const&, QObject*)@Base" 1.0.0 + (c++)"XdgAutoStart::desktopFileList(bool)@Base" 1.0.0 + (c++)"XdgAutoStart::desktopFileList(QStringList, bool)@Base" 1.0.0 (c++)"XdgAutoStart::localPath(XdgDesktopFile const&)@Base" 1.0.0 - (c++)"XdgDesktopFile::XdgDesktopFile()@Base" 1.0.0 - (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile const&)@Base" 1.0.0 - (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile::Type, QString const&, QString const&)@Base" 1.0.0 + + (c++)"XdgDesktopFileCache::desktopFileSettingsFormat()@Base" 1.0.0 + (c++)"XdgDesktopFileCache::getAllFiles()@Base" 1.0.0 + (c++)"XdgDesktopFileCache::getAppsOfCategory(QString const&)@Base" 1.2.0 + (c++)"XdgDesktopFileCache::getApps(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::getDefaultApp(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::getFile(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::initialize()@Base" 1.0.0 + (c++)"XdgDesktopFileCache::initialize(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::instance()@Base" 1.0.0 + (c++)"XdgDesktopFileCache::load(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::~XdgDesktopFileCache()@Base" 1.0.0 + (c++)"XdgDesktopFileCache::XdgDesktopFileCache()@Base" 1.0.0 + (c++)"XdgDesktopFile::categories() const@Base" 1.2.0 (c++)"XdgDesktopFile::contains(QString const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::expandExecString(QStringList const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::fileName() const@Base" 1.0.0 - (c++)"XdgDesktopFile::icon(QIcon const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::iconName() const@Base" 1.0.0 + (c++)"XdgDesktopFile::icon(QIcon const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::id(QString const&, bool)@Base" 2.0.0 (c++)"XdgDesktopFile::isShown(QString const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::isSuitable(bool, QString const&) const@Base" 1.0.0 @@ -47,18 +76,10 @@ libQt5Xdg.so.2 libqt5xdg2 #MINVER# (c++)"XdgDesktopFile::url() const@Base" 1.0.0 (c++)"XdgDesktopFile::value(QString const&, QVariant const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::~XdgDesktopFile()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::XdgDesktopFileCache()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::desktopFileSettingsFormat()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::getAllFiles()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::getApps(QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::getAppsOfCategory(QString const&)@Base" 1.2.0 - (c++)"XdgDesktopFileCache::getDefaultApp(QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::getFile(QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::initialize()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::initialize(QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::instance()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::load(QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::~XdgDesktopFileCache()@Base" 1.0.0 + (c++)"XdgDesktopFile::XdgDesktopFile()@Base" 1.0.0 + (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile const&)@Base" 1.0.0 + (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile::Type, QString const&, QString const&)@Base" 1.0.0 + (c++)"XdgDirs::autostartDirs(QString const&)@Base" 1.0.0 (c++)"XdgDirs::autostartHome(bool)@Base" 1.0.0 (c++)"XdgDirs::cacheHome(bool)@Base" 1.0.0 @@ -68,18 +89,19 @@ libQt5Xdg.so.2 libqt5xdg2 #MINVER# (c++)"XdgDirs::dataHome(bool)@Base" 1.0.0 (c++)"XdgDirs::runtimeDir()@Base" 1.0.0 (c++)"XdgDirs::setUserDir(XdgDirs::UserDirectory, QString const&, bool)@Base" 1.0.0 - (c++)"XdgDirs::userDir(XdgDirs::UserDirectory)@Base" 1.0.0 (c++)"XdgDirs::userDirDefault(XdgDirs::UserDirectory)@Base" 1.3.0 - (c++)"XdgIcon::XdgIcon()@Base" 1.0.0 + (c++)"XdgDirs::userDir(XdgDirs::UserDirectory)@Base" 1.0.0 + (c++)"XdgIcon::defaultApplicationIcon()@Base" 1.0.0 (c++)"XdgIcon::defaultApplicationIconName()@Base" 1.0.0 + (c++)"XdgIcon::followColorScheme()@Base" 2.0.1~ (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::setThemeName(QString const&)@Base" 1.0.0 - (c++)"XdgIcon::themeName()@Base" 1.0.0 + (c++)"XdgIcon::setFollowColorScheme(bool)@Base" 2.0.1~ (c++)"XdgIcon::~XdgIcon()@Base" 1.0.0 - (c++)"XdgMenu::XdgMenu(QObject*)@Base" 1.0.0 + (c++)"XdgIcon::XdgIcon()@Base" 1.0.0 + (c++)"XdgMenu::addWatchPath(QString const&)@Base" 1.0.0 (c++)"XdgMenu::changed()@Base" 1.0.0 (c++)"XdgMenu::environments()@Base" 1.0.0 @@ -98,11 +120,7 @@ libQt5Xdg.so.2 libqt5xdg2 #MINVER# (c++)"XdgMenu::setEnvironments(QStringList const&)@Base" 1.0.0 (c++)"XdgMenu::setLogDir(QString const&)@Base" 1.0.0 (c++)"XdgMenu::staticMetaObject@Base" 1.0.0 - (c++)"XdgMenu::xml() const@Base" 1.0.0 - (c++)"XdgMenu::~XdgMenu()@Base" 1.0.0 - (c++)"XdgMenuWidget::XdgMenuWidget(QDomElement const&, QWidget*)@Base" 1.0.0 - (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenu const&, QString const&, QWidget*)@Base" 1.0.0 - (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenuWidget const&, QWidget*)@Base" 1.0.0 + (c++)"XdgMenuWidget::event(QEvent*)@Base" 1.0.0 (c++)"XdgMenuWidget::metaObject() const@Base" 1.0.0 (c++)"XdgMenuWidget::operator=(XdgMenuWidget const&)@Base" 1.0.0 @@ -110,26 +128,18 @@ libQt5Xdg.so.2 libqt5xdg2 #MINVER# (c++)"XdgMenuWidget::qt_metacast(char const*)@Base" 1.0.0 (c++)"XdgMenuWidget::staticMetaObject@Base" 1.0.0 (c++)"XdgMenuWidget::~XdgMenuWidget()@Base" 1.0.0 - (c++)"XdgMimeType::XdgMimeType()@Base" 1.0.0 - (c++)"XdgMimeType::XdgMimeType(QMimeType const&)@Base" 1.0.0 - (c++)"XdgMimeType::XdgMimeType(XdgMimeType const&)@Base" 1.0.0 + (c++)"XdgMenuWidget::XdgMenuWidget(QDomElement const&, QWidget*)@Base" 1.0.0 + (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenu const&, QString const&, QWidget*)@Base" 1.0.0 + (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenuWidget const&, QWidget*)@Base" 1.0.0 + + (c++)"XdgMenu::~XdgMenu()@Base" 1.0.0 + (c++)"XdgMenu::XdgMenu(QObject*)@Base" 1.0.0 + (c++)"XdgMenu::xml() const@Base" 1.0.0 + (c++)"XdgMimeType::icon() const@Base" 1.0.0 (c++)"XdgMimeType::iconName() const@Base" 1.0.0 (c++)"XdgMimeType::operator=(XdgMimeType const&)@Base" 1.0.0 (c++)"XdgMimeType::~XdgMimeType()@Base" 1.0.0 - (c++)"non-virtual thunk to XdgMenuWidget::~XdgMenuWidget()@Base" 1.0.0 - (c++)"typeinfo for XdgAction@Base" 1.0.0 - (c++)"typeinfo for XdgDesktopFile@Base" 1.0.0 - (c++)"typeinfo for XdgIcon@Base" 1.0.0 - (c++)"typeinfo for XdgMenu@Base" 1.0.0 - (c++)"typeinfo for XdgMenuWidget@Base" 1.0.0 - (c++)"typeinfo name for XdgAction@Base" 1.0.0 - (c++)"typeinfo name for XdgDesktopFile@Base" 1.0.0 - (c++)"typeinfo name for XdgIcon@Base" 1.0.0 - (c++)"typeinfo name for XdgMenu@Base" 1.0.0 - (c++)"typeinfo name for XdgMenuWidget@Base" 1.0.0 - (c++)"vtable for XdgAction@Base" 1.0.0 - (c++)"vtable for XdgDesktopFile@Base" 1.0.0 - (c++)"vtable for XdgIcon@Base" 1.0.0 - (c++)"vtable for XdgMenu@Base" 1.0.0 - (c++)"vtable for XdgMenuWidget@Base" 1.0.0 + (c++)"XdgMimeType::XdgMimeType()@Base" 1.0.0 + (c++)"XdgMimeType::XdgMimeType(QMimeType const&)@Base" 1.0.0 + (c++)"XdgMimeType::XdgMimeType(XdgMimeType const&)@Base" 1.0.0 diff --git a/debian/libqt5xdgiconloader-dev.install b/debian/libqt5xdgiconloader-dev.install index b24b62b..1889cc9 100644 --- a/debian/libqt5xdgiconloader-dev.install +++ b/debian/libqt5xdgiconloader-dev.install @@ -3,6 +3,8 @@ usr/include/qt5xdgiconloader usr/lib/*/libQt5XdgIconLoader.so usr/lib/*/pkgconfig/Qt5XdgIconLoader.pc +usr/lib/*/qt5/plugins/iconengines/libQt5XdgIconPlugin.so + usr/share/cmake/qt5xdgiconloader/qt5xdgiconloader-config-version.cmake usr/share/cmake/qt5xdgiconloader/qt5xdgiconloader-config.cmake usr/share/cmake/qt5xdgiconloader/qt5xdgiconloader-targets.cmake diff --git a/debian/libqt5xdgiconloader2.install b/debian/libqt5xdgiconloader3.install similarity index 100% rename from debian/libqt5xdgiconloader2.install rename to debian/libqt5xdgiconloader3.install diff --git a/debian/libqt5xdgiconloader2.symbols b/debian/libqt5xdgiconloader3.symbols similarity index 74% rename from debian/libqt5xdgiconloader2.symbols rename to debian/libqt5xdgiconloader3.symbols index 7bf7093..4759958 100644 --- a/debian/libqt5xdgiconloader2.symbols +++ b/debian/libqt5xdgiconloader3.symbols @@ -1,15 +1,8 @@ -libQt5XdgIconLoader.so.2 libqt5xdgiconloader2 #MINVER# - (c++)"XdgIconLoader::XdgIconLoader()@Base" 2.0.0 - (c++)"XdgIconLoader::ensureInitialized()@Base" 2.0.0 - (c++)"XdgIconLoader::findIconHelper(QString const&, QString const&, QStringList&) const@Base" 2.0.0 - (c++)"XdgIconLoader::instance()@Base" 2.0.0 - (c++)"XdgIconLoader::loadIcon(QString const&) const@Base" 2.0.0 - (c++)"XdgIconLoader::setThemeName(QString const&)@Base" 2.0.0 - (c++)"XdgIconLoader::setThemeSearchPath(QStringList const&)@Base" 2.0.0 - (c++)"XdgIconLoader::themeSearchPaths() const@Base" 2.0.0 - (c++)"XdgIconLoader::updateSystemTheme()@Base" 2.0.0 - (c++)"XdgIconLoaderEngine::XdgIconLoaderEngine(QString const&)@Base" 2.0.0 - (c++)"XdgIconLoaderEngine::XdgIconLoaderEngine(XdgIconLoaderEngine const&)@Base" 2.0.0 +libQt5XdgIconLoader.so.3 libqt5xdgiconloader3 #MINVER# + (c++)"typeinfo for XdgIconLoaderEngine@Base" 2.0.0 + (c++)"typeinfo name for XdgIconLoaderEngine@Base" 2.0.0 + (c++)"vtable for XdgIconLoaderEngine@Base" 2.0.0 + (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 @@ -22,6 +15,11 @@ libQt5XdgIconLoader.so.2 libqt5xdgiconloader2 #MINVER# (c++)"XdgIconLoaderEngine::virtual_hook(int, void*)@Base" 2.0.0 (c++)"XdgIconLoaderEngine::write(QDataStream&) const@Base" 2.0.0 (c++)"XdgIconLoaderEngine::~XdgIconLoaderEngine()@Base" 2.0.0 - (c++)"typeinfo for XdgIconLoaderEngine@Base" 2.0.0 - (c++)"typeinfo name for XdgIconLoaderEngine@Base" 2.0.0 - (c++)"vtable for XdgIconLoaderEngine@Base" 2.0.0 + (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::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~ diff --git a/debian/qtxdg-dev-tools.install b/debian/qtxdg-dev-tools.install new file mode 100644 index 0000000..47a2743 --- /dev/null +++ b/debian/qtxdg-dev-tools.install @@ -0,0 +1,4 @@ +usr/bin/qtxdg-iconfinder +usr/bin/qtxdg-desktop-file-start + + diff --git a/debian/rules b/debian/rules index d310e6d..ea008d3 100755 --- a/debian/rules +++ b/debian/rules @@ -6,11 +6,13 @@ export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed export DEB_BUILD_MAINT_OPTIONS = hardening=+all %: - dh ${@} --buildsystem cmake \ - --parallel \ - --fail-missing + dh ${@} --buildsystem cmake + +override_dh_missing: + dh_missing --fail-missing override_dh_auto_configure: dh_auto_configure -- \ + -DBUILD_DEV_UTILS=YES \ -DCMAKE_BUILD_TYPE=RelWithDebInfo diff --git a/qtxdg/CMakeLists.txt b/qtxdg/CMakeLists.txt index 6eaea07..261849a 100644 --- a/qtxdg/CMakeLists.txt +++ b/qtxdg/CMakeLists.txt @@ -1,8 +1,5 @@ set(QTX_LIBRARIES Qt5::Widgets Qt5::Xml Qt5::DBus) -include_directories( - "${Qt5Gui_PRIVATE_INCLUDE_DIRS}" -) set(libqtxdg_PUBLIC_H_FILES xdgaction.h xdgdesktopfile.h @@ -63,14 +60,11 @@ set(libqtxdg_MOCS xdgmenuwidget.h ) -QT5_WRAP_CPP(libqtxdg_CXX_FILES ${libqtxdg_MOCS}) - add_library(${QTXDGX_LIBRARY_NAME} SHARED ${libqtxdg_PUBLIC_H_FILES} ${libqtxdg_PRIVATE_H_FILES} - ${libqtxdg_PRIVATE_H_FILES} ${libqtxdg_CPP_FILES} - ${libqtxdg_CXX_FILES} + ${libqtxdg_MOCS} ) target_link_libraries(${QTXDGX_LIBRARY_NAME} @@ -85,24 +79,22 @@ set_target_properties(${QTXDGX_LIBRARY_NAME} PROPERTIES ) target_compile_definitions(${QTXDGX_LIBRARY_NAME} - PRIVATE "QTXDG_COMPILATION=\"1\"" - PRIVATE "QTXDG_VERSION=\"${QTXDG_VERSION_STRING}\"" + PRIVATE + "QTXDG_COMPILATION=\"1\"" + "QTXDG_VERSION=\"${QTXDG_VERSION_STRING}\"" + "QT_NO_KEYWORDS" ) target_include_directories(${QTXDGX_LIBRARY_NAME} - INTERFACE "$" - INTERFACE "$" + INTERFACE + "$" + "$" + "$" + "$" + PRIVATE + ${Qt5Gui_PRIVATE_INCLUDE_DIRS} ) -# include directories and targets for the in tree build -target_include_directories(${QTXDGX_LIBRARY_NAME} - INTERFACE "$" - INTERFACE "$" -) - -export(TARGETS ${QTXDGX_LIBRARY_NAME} APPEND FILE "${CMAKE_BINARY_DIR}/${QTXDGX_FILE_NAME}-targets.cmake") -# end of in tree build stuff - # create the portble headers create_portable_headers(libqtxdg_PORTABLE_HEADERS HEADER_NAMES ${libqtxdg_PUBLIC_CLASSES} diff --git a/qtxdg/xdgaction.h b/qtxdg/xdgaction.h index 154a908..2991a39 100644 --- a/qtxdg/xdgaction.h +++ b/qtxdg/xdgaction.h @@ -71,7 +71,7 @@ public: const XdgDesktopFile& desktopFile() const { return mDesktopFile; } -private slots: +private Q_SLOTS: void runConmmand() const; void updateIcon(); diff --git a/qtxdg/xdgautostart.cpp b/qtxdg/xdgautostart.cpp index 402937e..55ca0de 100644 --- a/qtxdg/xdgautostart.cpp +++ b/qtxdg/xdgautostart.cpp @@ -57,14 +57,14 @@ XdgDesktopFileList XdgAutoStart::desktopFileList(QStringList dirs, bool excludeH QSet processed; XdgDesktopFileList ret; - foreach (const QString &dirName, dirs) + Q_FOREACH (const QString &dirName, dirs) { QDir dir(dirName); if (!dir.exists()) continue; const QFileInfoList files = dir.entryInfoList(QStringList(QLatin1String("*.desktop")), QDir::Files | QDir::Readable); - foreach (const QFileInfo &fi, files) + Q_FOREACH (const QFileInfo &fi, files) { if (processed.contains(fi.fileName())) continue; diff --git a/qtxdg/xdgdesktopfile.cpp b/qtxdg/xdgdesktopfile.cpp index 4972c37..b3d6c1b 100644 --- a/qtxdg/xdgdesktopfile.cpp +++ b/qtxdg/xdgdesktopfile.cpp @@ -409,9 +409,9 @@ bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const } bool nonDetach = false; - foreach(const QString &s, nonDetachExecs) + Q_FOREACH(const QString &s, nonDetachExecs) { - foreach(const QString &a, args) + Q_FOREACH(const QString &a, args) { if (a.contains(s)) { @@ -953,7 +953,7 @@ QString expandEnvVariables(const QString str) QStringList expandEnvVariables(const QStringList strs) { QStringList res; - foreach(const QString &s, strs) + Q_FOREACH(const QString &s, strs) res << expandEnvVariables(s); return res; @@ -971,7 +971,7 @@ QStringList XdgDesktopFile::expandExecString(const QStringList& urls) const unEscapeExec(execStr); QStringList tokens = parseCombinedArgString(execStr); - foreach (QString token, tokens) + Q_FOREACH (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")) { - foreach (const QString &s, urls) + Q_FOREACH (const QString &s, urls) { QUrl url(expandEnvVariables(s)); result << ((!url.toLocalFile().isEmpty()) ? url.toLocalFile() : QString::fromUtf8(url.toEncoded())); @@ -1081,7 +1081,7 @@ bool checkTryExec(const QString& progName) QStringList dirs = QFile::decodeName(qgetenv("PATH")).split(QLatin1Char(':')); - foreach (const QString &dir, dirs) + Q_FOREACH (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(); - foreach(const QString &d, dataDirs) { + Q_FOREACH(const QString &d, dataDirs) { if (id.startsWith(d)) { // remove only the first occurence id.replace(id.indexOf(d), d.size(), QString()); @@ -1211,7 +1211,7 @@ bool XdgDesktopFile::isSuitable(bool excludeHidden, const QString &environment) QString expandDynamicUrl(QString url) { - foreach(const QString &line, QProcess::systemEnvironment()) + Q_FOREACH(const QString &line, QProcess::systemEnvironment()) { QString name = line.section(QLatin1Char('='), 0, 0); QString val = line.section(QLatin1Char('='), 1); @@ -1253,7 +1253,7 @@ QString findDesktopFile(const QString& dirName, const QString& desktopName) // Working recursively ............ QFileInfoList dirs = dir.entryInfoList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot); - foreach (const QFileInfo &d, dirs) + Q_FOREACH (const QFileInfo &d, dirs) { QString cn = d.canonicalFilePath(); if (dirName != cn) @@ -1273,7 +1273,7 @@ QString findDesktopFile(const QString& desktopName) QStringList dataDirs = XdgDirs::dataDirs(); dataDirs.prepend(XdgDirs::dataHome(false)); - foreach (const QString &dirName, dataDirs) + Q_FOREACH (const QString &dirName, dataDirs) { QString f = findDesktopFile(dirName + QLatin1String("/applications"), desktopName); if (!f.isEmpty()) @@ -1415,14 +1415,14 @@ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map) QTextStream stream(&device); QString section; - foreach (const QString &key, map.keys()) + for (auto it = map.constBegin(); it != map.constEnd(); ++it) { - if (! map.value(key).canConvert()) + if (! it.value().canConvert()) { return false; } - QString thisSection = key.section(QLatin1Char('/'), 0, 0); + QString thisSection = it.key().section(QLatin1Char('/'), 0, 0); if (thisSection.isEmpty()) { qWarning() << "No section defined"; @@ -1435,7 +1435,7 @@ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map) section = thisSection; } - QString remainingKey = key.section(QLatin1Char('/'), 1, -1); + QString remainingKey = it.key().section(QLatin1Char('/'), 1, -1); if (remainingKey.isEmpty()) { @@ -1443,7 +1443,7 @@ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map) return false; } - stream << remainingKey << QLatin1Char('=') << map.value(key).toString() << QLatin1Char('\n'); + stream << remainingKey << QLatin1Char('=') << it.value().toString() << QLatin1Char('\n'); } @@ -1462,7 +1462,7 @@ void XdgDesktopFileCache::initialize(const QString& dirName) // Working recursively ............ QFileInfoList files = dir.entryInfoList(QStringList(), QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); - foreach (const QFileInfo &f, files) + Q_FOREACH (const QFileInfo &f, files) { if (f.isDir()) { @@ -1482,7 +1482,7 @@ void XdgDesktopFileCache::initialize(const QString& dirName) QStringList mimes = df->value(mimeTypeKey).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); - foreach (const QString &mime, mimes) + Q_FOREACH (const QString &mime, mimes) { int pref = df->value(initialPreferenceKey, 0).toInt(); // We move the desktopFile forward in the list for this mime, so that @@ -1522,8 +1522,8 @@ void loadMimeCacheDir(const QString& dirName, QHashvalue(mimeTypeKey).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); + const QStringList mimes = df->value(mimeTypeKey).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); - foreach (const QString &mime, mimes) + Q_FOREACH (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 +1582,7 @@ void XdgDesktopFileCache::initialize() QStringList dataDirs = XdgDirs::dataDirs(); dataDirs.prepend(XdgDirs::dataHome(false)); - foreach (const QString &dirname, dataDirs) + Q_FOREACH (const QString &dirname, dataDirs) { initialize(dirname + QLatin1String("/applications")); // loadMimeCacheDir(dirname + "/applications", m_defaultAppsCache); @@ -1593,7 +1593,7 @@ QList XdgDesktopFileCache::getAppsOfCategory(const QString& cat { QList list; const QString _category = category.toUpper(); - foreach (XdgDesktopFile *desktopFile, instance().m_fileCache.values()) + Q_FOREACH (XdgDesktopFile *desktopFile, instance().m_fileCache) { QStringList categories = desktopFile->value(categoriesKey).toString().toUpper().split(QLatin1Char(';')); if (!categories.isEmpty() && (categories.contains(_category) || categories.contains(QLatin1String("X-") + _category))) @@ -1614,10 +1614,10 @@ 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)); - foreach(const QString &dataDir, dataDirs) + Q_FOREACH(const QString &dataDir, dataDirs) { QString defaultsListPath = dataDir + QLatin1String("/applications/mimeapps.list"); - if (QFileInfo(defaultsListPath).exists()) + if (QFileInfo::exists(defaultsListPath)) { QSettings defaults(defaultsListPath, desktopFileSettingsFormat()); @@ -1628,7 +1628,7 @@ XdgDesktopFile* XdgDesktopFileCache::getDefaultApp(const QString& mimetype) QVariant value = defaults.value(mimetype); if (value.canConvert()) // A single string can also convert to a stringlist { - foreach (const QString &desktopFileName, value.toStringList()) + Q_FOREACH (const QString &desktopFileName, value.toStringList()) { XdgDesktopFile* desktopFile = XdgDesktopFileCache::getFile(desktopFileName); if (desktopFile) diff --git a/qtxdg/xdgdirs.cpp b/qtxdg/xdgdirs.cpp index 45d5367..c1f3b34 100644 --- a/qtxdg/xdgdirs.cpp +++ b/qtxdg/xdgdirs.cpp @@ -108,7 +108,7 @@ QString userDirFallback(XdgDirs::UserDirectory dir) if (home.isEmpty()) return QString::fromLatin1("/tmp"); else if (dir == XdgDirs::Desktop) - fallback = QString::fromLatin1("%1/%2").arg(home).arg(QLatin1String("Desktop")); + fallback = QString::fromLatin1("%1/%2").arg(home, QLatin1String("Desktop")); else fallback = home; @@ -178,10 +178,12 @@ bool XdgDirs::setUserDir(XdgDirs::UserDirectory dir, const QString& value, bool if (dir < XdgDirs::Desktop || dir > XdgDirs::Videos) return false; + const QString home = QFile::decodeName(qgetenv("HOME")); if (!(value.startsWith(QLatin1String("$HOME")) || value.startsWith(QLatin1String("~/")) - || value.startsWith(QFile::decodeName(qgetenv("HOME"))))) - return false; + || value.startsWith(home) + || value.startsWith(QDir(home).canonicalPath()))) + return false; QString folderName = userDirectoryString[dir]; @@ -215,7 +217,7 @@ bool XdgDirs::setUserDir(XdgDirs::UserDirectory dir, const QString& value, bool stream.reset(); configFile.resize(0); if (!foundVar) - stream << QString::fromLatin1("XDG_%1_DIR=\"%2\"\n").arg(folderName.toUpper()).arg(value); + stream << QString::fromLatin1("XDG_%1_DIR=\"%2\"\n").arg(folderName.toUpper(),(value)); for (QVector::iterator i = lines.begin(); i != lines.end(); ++i) stream << *i << QLatin1Char('\n'); @@ -334,7 +336,7 @@ QStringList XdgDirs::autostartDirs(const QString &postfix) { QStringList dirs; const QStringList s = configDirs(); - foreach(const QString &dir, s) + Q_FOREACH(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 bb1e153..d10aba9 100644 --- a/qtxdg/xdgicon.cpp +++ b/qtxdg/xdgicon.cpp @@ -50,7 +50,7 @@ struct QtIconCache: public IconCache } }; } -Q_GLOBAL_STATIC(IconCache, qtIconCache); +Q_GLOBAL_STATIC(IconCache, qtIconCache) static void qt_cleanup_icon_cache() { @@ -68,25 +68,6 @@ XdgIcon::~XdgIcon() } -/************************************************ - Returns the name of the current icon theme. - ************************************************/ -QString XdgIcon::themeName() -{ - return QIcon::themeName(); -} - - -/************************************************ - Sets the current icon theme to name. - ************************************************/ -void XdgIcon::setThemeName(const QString& themeName) -{ - QIcon::setThemeName(themeName); - XdgIconLoader::instance()->updateSystemTheme(); -} - - /************************************************ Returns the QIcon corresponding to name in the current icon theme. If no such icon is found in the current theme fallback is return instead. @@ -137,7 +118,7 @@ QIcon XdgIcon::fromTheme(const QString& iconName, const QIcon& fallback) ************************************************/ QIcon XdgIcon::fromTheme(const QStringList& iconNames, const QIcon& fallback) { - foreach (const QString &iconName, iconNames) + Q_FOREACH (const QString &iconName, iconNames) { QIcon icon = fromTheme(iconName); if (!icon.isNull()) @@ -164,6 +145,17 @@ QIcon XdgIcon::fromTheme(const QString &iconName, return fromTheme(icons); } +bool XdgIcon::followColorScheme() +{ + return XdgIconLoader::instance()->followColorScheme(); +} + + +void XdgIcon::setFollowColorScheme(bool enable) +{ + XdgIconLoader::instance()->setFollowColorScheme(enable); +} + QIcon XdgIcon::defaultApplicationIcon() { diff --git a/qtxdg/xdgicon.h b/qtxdg/xdgicon.h index 594415e..e3157cc 100644 --- a/qtxdg/xdgicon.h +++ b/qtxdg/xdgicon.h @@ -44,8 +44,19 @@ public: const QString &fallbackIcon4 = QString()); static QIcon fromTheme(const QStringList& iconNames, const QIcon& fallback = QIcon()); - static QString themeName(); - static void setThemeName(const QString& themeName); + /*! + * Flag if the "FollowsColorScheme" hint (the KDE extension to XDG + * themes) should be honored. If enabled and the icon theme supports + * this, the icon engine "colorizes" icons based on the application's + * palette. + * + * Default is true (use this extension). + */ + static bool followColorScheme(); + static void setFollowColorScheme(bool enable); + /* TODO: deprecate & remove all QIcon wrappers */ + static QString themeName() { return QIcon::themeName(); } + static void setThemeName(const QString& themeName) { QIcon::setThemeName(themeName); } static QIcon defaultApplicationIcon(); static QString defaultApplicationIconName(); diff --git a/qtxdg/xdgmenu.cpp b/qtxdg/xdgmenu.cpp index b59a001..6af58d4 100644 --- a/qtxdg/xdgmenu.cpp +++ b/qtxdg/xdgmenu.cpp @@ -205,8 +205,7 @@ void XdgMenu::save(const QString& fileName) if (!file.open(QFile::WriteOnly | QFile::Text)) { qWarning() << QString::fromLatin1("Cannot write file %1:\n%2.") - .arg(fileName) - .arg(file.errorString()); + .arg(fileName, file.errorString()); return; } @@ -225,7 +224,7 @@ void XdgMenuPrivate::load(const QString& fileName) QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { - qWarning() << QString::fromLatin1("%1 not loading: %2").arg(fileName).arg(file.errorString()); + qWarning() << QString::fromLatin1("%1 not loading: %2").arg(fileName, file.errorString()); return; } mXml.setContent(&file, true); @@ -413,7 +412,7 @@ QDomElement XdgMenu::findMenu(QDomElement& baseElement, const QString& path, boo const QStringList names = path.split(QLatin1Char('/'), QString::SkipEmptyParts); QDomElement el = baseElement; - foreach (const QString &name, names) + Q_FOREACH (const QString &name, names) { QDomElement p = el; el = d->mXml.createElement(QLatin1String("Menu")); @@ -538,12 +537,12 @@ void XdgMenuPrivate::processDirectoryEntries(QDomElement& element, const QString dirs << parentDirs; bool found = false; - foreach(const QString &file, files){ + Q_FOREACH(const QString &file, files){ if (file.startsWith(QLatin1Char('/'))) found = loadDirectoryFile(file, element); else { - foreach (const QString &dir, dirs) + Q_FOREACH (const QString &dir, dirs) { found = loadDirectoryFile(dir + QLatin1Char('/') + file, element); if (found) break; @@ -652,7 +651,7 @@ QString XdgMenu::getMenuFileName(const QString& baseName) const QStringList configDirs = XdgDirs::configDirs(); QString menuPrefix = QString::fromLocal8Bit(qgetenv("XDG_MENU_PREFIX")); - foreach(const QString &configDir, configDirs) + Q_FOREACH(const QString &configDir, configDirs) { QFileInfo file(QString::fromLatin1("%1/menus/%2%3").arg(configDir, menuPrefix, baseName)); if (file.exists()) @@ -670,9 +669,9 @@ QString XdgMenu::getMenuFileName(const QString& baseName) wellKnownFiles << QLatin1String("gnome-applications.menu"); wellKnownFiles << QLatin1String("lxde-applications.menu"); - foreach(const QString &configDir, configDirs) + Q_FOREACH(const QString &configDir, configDirs) { - foreach (const QString &f, wellKnownFiles) + Q_FOREACH (const QString &f, wellKnownFiles) { QFileInfo file(QString::fromLatin1("%1/menus/%2").arg(configDir, f)); if (file.exists()) @@ -715,7 +714,7 @@ void XdgMenuPrivate::rebuild() if (prevHash != mHash) { mOutDated = true; - emit changed(); + Q_EMIT changed(); } } diff --git a/qtxdg/xdgmenu.h b/qtxdg/xdgmenu.h index e18e0c3..0a2a3f6 100644 --- a/qtxdg/xdgmenu.h +++ b/qtxdg/xdgmenu.h @@ -112,7 +112,7 @@ public: bool isOutDated() const; -signals: +Q_SIGNALS: void changed(); protected: diff --git a/qtxdg/xdgmenu_p.h b/qtxdg/xdgmenu_p.h index 34443aa..c5d446c 100644 --- a/qtxdg/xdgmenu_p.h +++ b/qtxdg/xdgmenu_p.h @@ -73,10 +73,10 @@ public: QFileSystemWatcher mWatcher; bool mOutDated; -public slots: +public Q_SLOTS: void rebuild(); -signals: +Q_SIGNALS: void changed(); diff --git a/qtxdg/xdgmenuapplinkprocessor.cpp b/qtxdg/xdgmenuapplinkprocessor.cpp index f031940..73353e1 100644 --- a/qtxdg/xdgmenuapplinkprocessor.cpp +++ b/qtxdg/xdgmenuapplinkprocessor.cpp @@ -90,7 +90,7 @@ void XdgMenuApplinkProcessor::step1() } // Process childs menus ............................... - foreach (XdgMenuApplinkProcessor* child, mChilds) + Q_FOREACH (XdgMenuApplinkProcessor* child, mChilds) child->step1(); } @@ -100,7 +100,7 @@ void XdgMenuApplinkProcessor::step2() // Create AppLinks elements ........................... QDomDocument doc = mElement.ownerDocument(); - foreach (XdgMenuAppFileInfo* fileInfo, mSelected) + Q_FOREACH (XdgMenuAppFileInfo* fileInfo, mSelected) { if (mOnlyUnallocated && fileInfo->allocated()) continue; @@ -141,7 +141,7 @@ void XdgMenuApplinkProcessor::step2() // Process childs menus ............................... - foreach (XdgMenuApplinkProcessor* child, mChilds) + Q_FOREACH (XdgMenuApplinkProcessor* child, mChilds) child->step2(); } @@ -189,7 +189,7 @@ void XdgMenuApplinkProcessor::findDesktopFiles(const QString& dirName, const QSt mMenu->addWatchPath(dir.absolutePath()); const QFileInfoList files = dir.entryInfoList(QStringList(QLatin1String("*.desktop")), QDir::Files); - foreach (const QFileInfo &file, files) + Q_FOREACH (const QFileInfo &file, files) { XdgDesktopFile* f = XdgDesktopFileCache::getFile(file.canonicalFilePath()); if (f) @@ -199,7 +199,7 @@ void XdgMenuApplinkProcessor::findDesktopFiles(const QString& dirName, const QSt // Working recursively ............ const QFileInfoList dirs = dir.entryInfoList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot); - foreach (const QFileInfo &d, dirs) + Q_FOREACH (const QFileInfo &d, dirs) { QString dn = d.canonicalFilePath(); if (dn != dirName) @@ -242,7 +242,7 @@ bool XdgMenuApplinkProcessor::checkTryExec(const QString& progName) const QStringList dirs = QFile::decodeName(qgetenv("PATH")).split(QLatin1Char(':')); - foreach (const QString &dir, dirs) + Q_FOREACH (const QString &dir, dirs) { if (QFileInfo(QDir(dir), progName).isExecutable()) return true; diff --git a/qtxdg/xdgmenureader.cpp b/qtxdg/xdgmenureader.cpp index f4e4393..ef55a74 100644 --- a/qtxdg/xdgmenureader.cpp +++ b/qtxdg/xdgmenureader.cpp @@ -76,7 +76,7 @@ bool XdgMenuReader::load(const QString& fileName, const QString& baseDir) QFile file(mFileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { - mErrorStr = QString::fromLatin1("%1 not loading: %2").arg(fileName).arg(file.errorString()); + mErrorStr = QString::fromLatin1("%1 not loading: %2").arg(fileName, file.errorString()); return false; } //qDebug() << "Load file:" << mFileName; @@ -215,7 +215,7 @@ void XdgMenuReader::processMergeFileTag(QDomElement& element, QStringList* merge QString relativeName; QStringList configDirs = XdgDirs::configDirs(); - foreach (const QString &configDir, configDirs) + Q_FOREACH (const QString &configDir, configDirs) { if (mFileName.startsWith(configDir)) { @@ -236,9 +236,9 @@ void XdgMenuReader::processMergeFileTag(QDomElement& element, QStringList* merge if (relativeName.isEmpty()) return; - foreach (const QString &configDir, configDirs) + Q_FOREACH (const QString &configDir, configDirs) { - if (QFileInfo(configDir + relativeName).exists()) + if (QFileInfo::exists(configDir + relativeName)) { mergeFile(configDir + relativeName, element, mergedFiles); return; @@ -295,9 +295,9 @@ void XdgMenuReader::processDefaultMergeDirsTag(QDomElement& element, QStringList QStringList dirs = XdgDirs::configDirs(); dirs << XdgDirs::configHome(); - foreach (const QString &dir, dirs) + Q_FOREACH (const QString &dir, dirs) { - mergeDir(QString::fromLatin1("%1/menus/%2-merged").arg(dir).arg(menuBaseName), element, mergedFiles); + mergeDir(QString::fromLatin1("%1/menus/%2-merged").arg(dir, menuBaseName), element, mergedFiles); } if (menuBaseName == QLatin1String("applications")) @@ -329,7 +329,7 @@ void XdgMenuReader::processDefaultAppDirsTag(QDomElement& element) QStringList dirs = XdgDirs::dataDirs(); dirs.prepend(XdgDirs::dataHome(false)); - foreach (const QString &dir, dirs) + Q_FOREACH (const QString &dir, 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)); - foreach (const QString &dir, dirs) + Q_FOREACH (const QString &dir, dirs) addDirTag(element, QLatin1String("DirectoryDir"), dir + QLatin1String("/desktop-directories/")); } @@ -431,7 +431,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); - foreach (const QFileInfo &file, files) + Q_FOREACH (const QFileInfo &file, files) mergeFile(file.canonicalFilePath(), element, mergedFiles); } } diff --git a/qtxdg/xdgmenureader.h b/qtxdg/xdgmenureader.h index 27e1f5e..383021d 100644 --- a/qtxdg/xdgmenureader.h +++ b/qtxdg/xdgmenureader.h @@ -47,9 +47,9 @@ public: QString errorString() const { return mErrorStr; } QDomDocument& xml() { return mXml; } -signals: +Q_SIGNALS: -public slots: +public Q_SLOTS: protected: void processMergeTags(QDomElement& element); diff --git a/qtxdg/xdgmenuwidget.cpp b/qtxdg/xdgmenuwidget.cpp index acabb8f..56c8fde 100644 --- a/qtxdg/xdgmenuwidget.cpp +++ b/qtxdg/xdgmenuwidget.cpp @@ -44,7 +44,7 @@ class XdgMenuWidgetPrivate { private: XdgMenuWidget* const q_ptr; - Q_DECLARE_PUBLIC(XdgMenuWidget); + Q_DECLARE_PUBLIC(XdgMenuWidget) public: explicit XdgMenuWidgetPrivate(XdgMenuWidget* parent): @@ -186,7 +186,7 @@ void XdgMenuWidgetPrivate::buildMenu() QAction* first = 0; if (!q->actions().isEmpty()) - first = q->actions().last(); + first = q->actions().constLast(); DomElementIterator it(mXml, QString()); diff --git a/qtxdg/xdgmimetype.cpp b/qtxdg/xdgmimetype.cpp index ed9ab91..fa8d8d4 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()); - foreach (const QString &s, names) { + Q_FOREACH (const QString &s, names) { if (!XdgIcon::fromTheme(s).isNull()) { dx->iconName = s; break; diff --git a/qtxdg/xmlhelper.cpp b/qtxdg/xmlhelper.cpp index 6239ad4..a48baab 100644 --- a/qtxdg/xmlhelper.cpp +++ b/qtxdg/xmlhelper.cpp @@ -41,6 +41,6 @@ QDebug operator<<(QDebug dbg, const QDomElement &el) for (int i=0; i%3").arg(el.tagName()).arg(args).arg(el.text()); + dbg.nospace() << QString::fromLatin1("<%1%2>%3").arg(el.tagName(), args, el.text()); return dbg.space(); } diff --git a/release.sh b/release.sh deleted file mode 100755 index 29ca2c8..0000000 --- a/release.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -PROJECT="libqtxdg" -version="$1" -prefix=$PROJECT-$version -shift - -if [[ -z $version ]]; then - >&2 echo "USAGE: $0 " - exit 1 -fi - -mkdir -p "dist/$version" -echo "Creating $prefix.tar.gz" -git archive -9 --format tar.gz $version --prefix="$prefix/" > "dist/$version/$prefix.tar.gz" -gpg --armor --detach-sign "dist/$version/$prefix.tar.gz" -echo "Creating $prefix.tar.xz" -git archive -9 --format tar.xz $version --prefix="$prefix/" > "dist/$version/$prefix.tar.xz" -gpg --armor --detach-sign "dist/$version/$prefix.tar.xz" -cd "dist/$version" - -sha1sum --tag *.tar.gz *.tar.xz >> CHECKSUMS -sha256sum --tag *.tar.gz *.tar.xz >> CHECKSUMS - -cd .. -echo "Uploading to lxqt.org..." - -scp -r "$version" "downloads.lxqt.org:/srv/downloads.lxqt.org/$PROJECT/" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8d7b580..780c939 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,25 +1,25 @@ -set(PROJECT_NAME "qtxdg_test") - remove_definitions( -DQT_USE_QSTRINGBUILDER -DQT_NO_CAST_FROM_ASCII ) -set(CMAKE_AUTOMOC TRUE) +add_definitions( + -DQT_NO_KEYWORDS +) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) macro(qtxdg_add_test) foreach(_testname ${ARGN}) add_executable(${_testname} ${_testname}.cpp) target_link_libraries(${_testname} Qt5::Test ${QTXDGX_LIBRARY_NAME}) + target_include_directories(${_testname} + PRIVATE "${PROJECT_SOURCE_DIR}/qtxdg" + ) add_test(NAME ${_testname} COMMAND ${_testname}) endforeach() endmacro() -include_directories ( - "${CMAKE_SOURCE_DIR}/qtxdg" - ${CMAKE_CURRENT_BINARY_DIR} -) - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "QTXDG_BUILDING_TESTS=\"1\"" ) diff --git a/test/qtxdg_test.cpp b/test/qtxdg_test.cpp index 9270605..f9232e8 100644 --- a/test/qtxdg_test.cpp +++ b/test/qtxdg_test.cpp @@ -47,15 +47,15 @@ void QtXdgTest::testDefaultApp() { QStringList mimedirs = XdgDirs::dataDirs(); mimedirs.prepend(XdgDirs::dataHome(false)); - foreach (QString mimedir, mimedirs) + Q_FOREACH (QString mimedir, mimedirs) { QDir dir(mimedir + "/mime"); qDebug() << dir.path(); QStringList filters = (QStringList() << "*.xml"); - foreach(QFileInfo mediaDir, dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) + Q_FOREACH(QFileInfo mediaDir, dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) { qDebug() << " " << mediaDir.fileName(); - foreach (QString mimeXmlFileName, QDir(mediaDir.absoluteFilePath()).entryList(filters, QDir::Files)) + Q_FOREACH (QString mimeXmlFileName, QDir(mediaDir.absoluteFilePath()).entryList(filters, QDir::Files)) { QString mimetype = mediaDir.fileName() + "/" + mimeXmlFileName.left(mimeXmlFileName.length() - 4); QString xdg_utils_default = xdgUtilDefaultApp(mimetype); diff --git a/test/qtxdg_test.h b/test/qtxdg_test.h index 3d58c9f..014a406 100644 --- a/test/qtxdg_test.h +++ b/test/qtxdg_test.h @@ -39,7 +39,7 @@ class QtXdgTest : public QObject { Q_OBJECT -private slots: +private Q_SLOTS: void testCustomFormat(); private: diff --git a/test/tst_xdgdesktopfile.cpp b/test/tst_xdgdesktopfile.cpp index 63dd6a3..30db04e 100644 --- a/test/tst_xdgdesktopfile.cpp +++ b/test/tst_xdgdesktopfile.cpp @@ -27,20 +27,20 @@ class Language { public: Language (const QString& lang) - : mPreviousLang(QString::fromLocal8Bit(qgetenv("LANG"))) + : mPreviousLang(QString::fromLocal8Bit(qgetenv("LC_MESSAGES"))) { - qputenv("LANG", lang.toLocal8Bit()); + qputenv("LC_MESSAGES", lang.toLocal8Bit()); } ~Language() { - qputenv("LANG", mPreviousLang.toLocal8Bit()); + qputenv("LC_MESSAGES", mPreviousLang.toLocal8Bit()); } private: QString mPreviousLang; }; -QTEST_MAIN(tst_xdgdesktopfile); +QTEST_MAIN(tst_xdgdesktopfile) void tst_xdgdesktopfile::testRead() { diff --git a/test/tst_xdgdesktopfile.h b/test/tst_xdgdesktopfile.h index 337530c..6a001d2 100644 --- a/test/tst_xdgdesktopfile.h +++ b/test/tst_xdgdesktopfile.h @@ -25,7 +25,7 @@ class tst_xdgdesktopfile : public QObject { Q_OBJECT -private slots: +private Q_SLOTS: void testRead(); void testReadLocalized(); diff --git a/test/tst_xdgdirs.cpp b/test/tst_xdgdirs.cpp index 634fee5..e7ba103 100644 --- a/test/tst_xdgdirs.cpp +++ b/test/tst_xdgdirs.cpp @@ -36,7 +36,7 @@ class tst_xdgdirs : public QObject { Q_OBJECT -private slots: +private Q_SLOTS: void initTestCase(); void cleanupTestCase(); diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt index 7d871ae..05c6231 100644 --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -1,26 +1,52 @@ -include_directories ( - "${CMAKE_PROJECT_DIR}/qtxdg" - ${CMAKE_CURRENT_BINARY_DIR} -) +set(CMAKE_INCLUDE_CURRENT_DIR ON) set(QTXDG_DESKTOP_FILE_START_SRCS qtxdg-desktop-file-start.cpp ) +set(QTXDG_ICONFINDER_SRCS + qtxdg-iconfinder.cpp +) + add_executable(qtxdg-desktop-file-start ${QTXDG_DESKTOP_FILE_START_SRCS} ) +add_executable(qtxdg-iconfinder + ${QTXDG_ICONFINDER_SRCS} +) + +target_include_directories(qtxdg-desktop-file-start + PRIVATE "${PROJECT_SOURCE_DIR}/qtxdg" +) + +target_include_directories(qtxdg-iconfinder + PRIVATE "${Qt5Gui_PRIVATE_INCLUDE_DIRS}" +) + target_compile_definitions(qtxdg-desktop-file-start - PRIVATE "-DQTXDG_VERSION=\"${QTXDG_VERSION_STRING}\"" + PRIVATE + "-DQTXDG_VERSION=\"${QTXDG_VERSION_STRING}\"" + "QT_NO_KEYWORDS" +) + +target_compile_definitions(qtxdg-iconfinder + PRIVATE + "-DQTXDG_VERSION=\"${QTXDG_VERSION_STRING}\"" + "QT_NO_KEYWORDS" ) target_link_libraries(qtxdg-desktop-file-start ${QTXDGX_LIBRARY_NAME} ) +target_link_libraries(qtxdg-iconfinder + ${QTXDGX_ICONLOADER_LIBRARY_NAME} +) + install(TARGETS qtxdg-desktop-file-start + qtxdg-iconfinder RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT Runtime ) diff --git a/util/qtxdg-iconfinder.cpp b/util/qtxdg-iconfinder.cpp new file mode 100644 index 0000000..3b60d47 --- /dev/null +++ b/util/qtxdg-iconfinder.cpp @@ -0,0 +1,74 @@ +/* + * libqtxdg - An Qt implementation of freedesktop.org xdg specs + * Copyright (C) 2017 Luís Pereira + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include // XdgIconLoader needs a QGuiApplication +#include +#include +#include + + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + app.setApplicationName(QStringLiteral("qtxdg-iconfinder")); + app.setApplicationVersion(QStringLiteral(QTXDG_VERSION)); + + QCommandLineParser parser; + parser.setApplicationDescription(QStringLiteral("QtXdg icon finder")); + parser.addPositionalArgument(QStringLiteral("iconnames"), + QStringLiteral("The icon names to search for"), + QStringLiteral("[iconnames...]")); + parser.addVersionOption(); + parser.addHelpOption(); + parser.process(app); + + if (parser.positionalArguments().isEmpty()) + parser.showHelp(EXIT_FAILURE); + + qint64 totalElapsed = 0; + const auto icons = parser.positionalArguments(); + for (const QString& iconName : icons) { + QElapsedTimer t; + t.start(); + const auto info = XdgIconLoader::instance()->loadIcon(iconName); + qint64 elapsed = t.elapsed(); + const auto icon = info.iconName; + const auto entries = info.entries; + + std::cout << qPrintable(iconName) << + qPrintable(QString::fromLatin1(":")) << qPrintable(icon) << + qPrintable(QString::fromLatin1(":")) << + qPrintable(QString::number(elapsed)) << "\n"; + + for (const auto &i : entries) { + std::cout << "\t" << qPrintable(i->filename) << "\n"; + } + totalElapsed += elapsed; + } + + std::cout << qPrintable(QString::fromLatin1("Total loadIcon() time: ")) << + qPrintable(QString::number(totalElapsed)) << + qPrintable(QString::fromLatin1(" ms")) << "\n"; + + return EXIT_SUCCESS; +} diff --git a/xdgiconloader/CMakeLists.txt b/xdgiconloader/CMakeLists.txt index f7405b3..0e7466f 100644 --- a/xdgiconloader/CMakeLists.txt +++ b/xdgiconloader/CMakeLists.txt @@ -1,7 +1,3 @@ -include_directories( - "${Qt5Gui_PRIVATE_INCLUDE_DIRS}" -) - set(xdgiconloader_PUBLIC_H_FILES ) @@ -38,17 +34,22 @@ configure_file( COPYONLY ) -target_include_directories(${QTXDGX_ICONLOADER_LIBRARY_NAME} - INTERFACE "$" - INTERFACE "$" - INTERFACE "$" +target_compile_definitions(${QTXDGX_ICONLOADER_LIBRARY_NAME} + PRIVATE + "QT_NO_KEYWORDS" ) -# include directories and targets for the in tree build target_include_directories(${QTXDGX_ICONLOADER_LIBRARY_NAME} - PUBLIC "$" - PUBLIC "$" - PUBLIC "$" + INTERFACE + "$" + "$" + "$" + PUBLIC + "$" + "$" + "$" + PRIVATE + ${Qt5Gui_PRIVATE_INCLUDE_DIRS} ) target_link_libraries(${QTXDGX_ICONLOADER_LIBRARY_NAME} @@ -63,7 +64,7 @@ set_target_properties(${QTXDGX_ICONLOADER_LIBRARY_NAME} SOVERSION ${QTXDG_MAJOR_VERSION} ) -export(TARGETS ${QTXDGX_ICONLOADER_LIBRARY_NAME} FILE "${CMAKE_BINARY_DIR}/${QTXDGX_ICONLOADER_FILE_NAME}-targets.cmake") +add_subdirectory(plugin) install(TARGETS ${QTXDGX_ICONLOADER_LIBRARY_NAME} DESTINATION "${CMAKE_INSTALL_LIBDIR}" @@ -77,6 +78,11 @@ install(FILES COMPONENT Devel ) +file(COPY + ${xdgiconloader_PRIVATE_INSTALLABLE_H_FILES} + DESTINATION "${QTXDGX_INTREE_INCLUDEDIR}/${QTXDGX_ICONLOADER_FILE_NAME}/${QTXDG_VERSION_STRING}/private/xdgiconloader" +) + install(FILES "${QTXDGX_INTREE_INCLUDEDIR}/${QTXDGX_ICONLOADER_FILE_NAME}/${XDGICONLOADER_EXPORT_FILE}" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_ICONLOADER_FILE_NAME}" diff --git a/xdgiconloader/plugin/CMakeLists.txt b/xdgiconloader/plugin/CMakeLists.txt new file mode 100644 index 0000000..e5eb59c --- /dev/null +++ b/xdgiconloader/plugin/CMakeLists.txt @@ -0,0 +1,49 @@ +set(xdgiconengineplugin_CPP_FILES + xdgiconengineplugin.cpp +) + +add_library(${QTXDGX_ICONENGINEPLUGIN_LIBRARY_NAME} MODULE + ${xdgiconengineplugin_CPP_FILES} +) + +target_compile_definitions(${QTXDGX_ICONENGINEPLUGIN_LIBRARY_NAME} + PRIVATE + "QT_NO_KEYWORDS" +) +target_link_libraries(${QTXDGX_ICONENGINEPLUGIN_LIBRARY_NAME} + PUBLIC + Qt5::Gui + "${QTXDGX_ICONLOADER_LIBRARY_NAME}" +) + +target_include_directories("${QTXDGX_ICONENGINEPLUGIN_LIBRARY_NAME}" + PRIVATE + "${Qt5Gui_PRIVATE_INCLUDE_DIRS}" +) + +mark_as_advanced(QTXDGX_ICONENGINEPLUGIN_INSTALL_PATH) + +if (NOT DEFINED QTXDGX_ICONENGINEPLUGIN_INSTALL_PATH) + get_target_property(QT_QMAKE_EXECUTABLE ${Qt5Core_QMAKE_EXECUTABLE} IMPORTED_LOCATION) + if(NOT QT_QMAKE_EXECUTABLE) + message(FATAL_ERROR "qmake is not found.") + endif() + + # execute the command "qmake -query QT_INSTALL_PLUGINS" to get the path of plugins dir. + execute_process(COMMAND "${QT_QMAKE_EXECUTABLE}" -query QT_INSTALL_PLUGINS + OUTPUT_VARIABLE QT_PLUGINS_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if (NOT QT_PLUGINS_DIR) + message(FATAL_ERROR "Qt5 plugin directory cannot be detected.") + endif() + set(QTXDGX_ICONENGINEPLUGIN_INSTALL_PATH "${QT_PLUGINS_DIR}/iconengines") +endif() + +message(STATUS "XdgIconEnginePlugin will be installed into: ${QTXDGX_ICONENGINEPLUGIN_INSTALL_PATH}") + +install(TARGETS + "${QTXDGX_ICONENGINEPLUGIN_LIBRARY_NAME}" DESTINATION "${QTXDGX_ICONENGINEPLUGIN_INSTALL_PATH}" + COMPONENT Runtime +) + diff --git a/xdgiconloader/plugin/xdgiconengineplugin.cpp b/xdgiconloader/plugin/xdgiconengineplugin.cpp new file mode 100644 index 0000000..93e5001 --- /dev/null +++ b/xdgiconloader/plugin/xdgiconengineplugin.cpp @@ -0,0 +1,35 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight Qt based desktop + * http://lxqt.org + * + * Copyright: 2017 LXQt team + * Authors: + * Palo Kisa + * + * This program or library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#include "xdgiconengineplugin.h" +#include "../xdgiconloader_p.h" + +QIconEngine * XdgIconEnginePlugin::create(const QString & filename/* = QString{}*/) +{ + return new XdgIconLoaderEngine{filename}; +} + diff --git a/xdgiconloader/plugin/xdgiconengineplugin.h b/xdgiconloader/plugin/xdgiconengineplugin.h new file mode 100644 index 0000000..3f9276f --- /dev/null +++ b/xdgiconloader/plugin/xdgiconengineplugin.h @@ -0,0 +1,38 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight Qt based desktop + * http://lxqt.org + * + * Copyright: 2017 LXQt team + * Authors: + * Palo Kisa + * + * This program or library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#include + +class XdgIconEnginePlugin : public QIconEnginePlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QIconEngineFactoryInterface" FILE "xdgiconengineplugin.json") +public: + using QIconEnginePlugin::QIconEnginePlugin; + virtual QIconEngine * create(const QString & filename = QString{}) override; +}; + diff --git a/xdgiconloader/plugin/xdgiconengineplugin.json b/xdgiconloader/plugin/xdgiconengineplugin.json new file mode 100644 index 0000000..6943d22 --- /dev/null +++ b/xdgiconloader/plugin/xdgiconengineplugin.json @@ -0,0 +1 @@ +{"Keys": ["XdgIconLoaderEngine"]} diff --git a/xdgiconloader/xdgiconloader.cpp b/xdgiconloader/xdgiconloader.cpp index cb084fa..68a0cc7 100644 --- a/xdgiconloader/xdgiconloader.cpp +++ b/xdgiconloader/xdgiconloader.cpp @@ -45,6 +45,8 @@ #include #include #include +#include +#include #ifdef Q_DEAD_CODE_FROM_QT4_MAC #include @@ -62,104 +64,36 @@ static QString fallbackTheme() { if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { const QVariant themeHint = theme->themeHint(QPlatformTheme::SystemIconFallbackThemeName); - if (themeHint.isValid()) - return themeHint.toString(); - } - return QLatin1String("hicolor"); -} - -XdgIconLoader::XdgIconLoader() : - m_themeKey(1), m_supportsSvg(false), m_initialized(false) -{ -} - -static inline QString systemThemeName() -{ - if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { - const QVariant themeHint = theme->themeHint(QPlatformTheme::SystemIconThemeName); - if (themeHint.isValid()) - return themeHint.toString(); - } - return QIcon::themeName(); -} - -static inline QStringList systemIconSearchPaths() -{ - if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { - const QVariant themeHint = theme->themeHint(QPlatformTheme::IconThemeSearchPaths); - if (themeHint.isValid()) - return themeHint.toStringList(); + if (themeHint.isValid()) { + const QString theme = themeHint.toString(); + if (theme != QLatin1String("hicolor")) + return theme; + } } - return QIcon::themeSearchPaths(); + return QString(); } -#ifndef QT_NO_LIBRARY -//extern QFactoryLoader *qt_iconEngineFactoryLoader(); // qicon.cpp -#endif +#ifdef QT_NO_LIBRARY +static bool gSupportsSvg = false; +#else +static bool gSupportsSvg = true; +#endif //QT_NO_LIBRARY -void XdgIconLoader::ensureInitialized() +void XdgIconLoader::setFollowColorScheme(bool enable) { - if (!m_initialized) { - m_initialized = true; - - Q_ASSERT(qApp); - - m_systemTheme = systemThemeName(); - - if (m_systemTheme.isEmpty()) - m_systemTheme = fallbackTheme(); -#ifndef QT_NO_LIBRARY -// if (qt_iconEngineFactoryLoader()->keyMap().key(QLatin1String("svg"), -1) != -1) - m_supportsSvg = true; -#endif //QT_NO_LIBRARY + if (m_followColorScheme != enable) + { + QIconLoader::instance()->invalidateKey(); + m_followColorScheme = enable; } } XdgIconLoader *XdgIconLoader::instance() { - iconLoaderInstance()->ensureInitialized(); + QIconLoader::instance()->ensureInitialized(); return iconLoaderInstance(); } -// Queries the system theme and invalidates existing -// icons if the theme has changed. -void XdgIconLoader::updateSystemTheme() -{ - // Only change if this is not explicitly set by the user - if (m_userTheme.isEmpty()) { - QString theme = systemThemeName(); - if (theme.isEmpty()) - theme = fallbackTheme(); - if (theme != m_systemTheme) { - m_systemTheme = theme; - invalidateKey(); - } - } -} - -void XdgIconLoader::setThemeName(const QString &themeName) -{ - m_userTheme = themeName; - invalidateKey(); -} - -void XdgIconLoader::setThemeSearchPath(const QStringList &searchPaths) -{ - m_iconDirs = searchPaths; - themeList.clear(); - invalidateKey(); -} - -QStringList XdgIconLoader::themeSearchPaths() const -{ - if (m_iconDirs.isEmpty()) { - m_iconDirs = systemIconSearchPaths(); - // Always add resource directory as search path - m_iconDirs.append(QLatin1String(":/icons")); - } - return m_iconDirs; -} - /*! \class QIconCacheGtkReader \internal @@ -172,7 +106,7 @@ class QIconCacheGtkReader { public: explicit QIconCacheGtkReader(const QString &themeDir); - QVector lookup(const QString &); + QVector lookup(const QStringRef &); bool isValid() const { return m_isValid; } private: QFile m_file; @@ -203,7 +137,7 @@ private: QIconCacheGtkReader::QIconCacheGtkReader(const QString &dirName) : m_isValid(false) { - QFileInfo info(dirName + QLatin1Literal("/icon-theme.cache")); + QFileInfo info(dirName + QLatin1String("/icon-theme.cache")); if (!info.exists() || info.lastModified() < QFileInfo(dirName).lastModified()) return; m_file.setFileName(info.absoluteFilePath()); @@ -245,7 +179,7 @@ static quint32 icon_name_hash(const char *p) with this name is present. The char* are pointers to the mapped data. For example, this would return { "32x32/apps", "24x24/apps" , ... } */ -QVector QIconCacheGtkReader::lookup(const QString &name) +QVector QIconCacheGtkReader::lookup(const QStringRef &name) { QVector ret; if (!isValid()) @@ -295,12 +229,13 @@ QVector QIconCacheGtkReader::lookup(const QString &name) return ret; } -QIconTheme::QIconTheme(const QString &themeName) +XdgIconTheme::XdgIconTheme(const QString &themeName) : m_valid(false) + , m_followsColorScheme(false) { QFile themeIndex; - QStringList iconDirs = QIcon::themeSearchPaths(); + const QStringList iconDirs = QIcon::themeSearchPaths(); for ( int i = 0 ; i < iconDirs.size() ; ++i) { QDir iconDir(iconDirs[i]); QString themeDir = iconDir.path() + QLatin1Char('/') + themeName; @@ -320,27 +255,26 @@ QIconTheme::QIconTheme(const QString &themeName) #ifndef QT_NO_SETTINGS if (themeIndex.exists()) { const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat); - QStringListIterator keyIterator(indexReader.allKeys()); - while (keyIterator.hasNext()) { - - const QString key = keyIterator.next(); + m_followsColorScheme = indexReader.value(QStringLiteral("Icon Theme/FollowsColorScheme"), false).toBool(); + const QStringList keys = indexReader.allKeys(); + for (auto const &key : keys) { if (key.endsWith(QLatin1String("/Size"))) { // Note the QSettings ini-format does not accept // slashes in key names, hence we have to cheat if (int size = indexReader.value(key).toInt()) { QString directoryKey = key.left(key.size() - 5); - XdgIconDirInfo dirInfo(directoryKey); + QIconDirInfo dirInfo(directoryKey); dirInfo.size = size; QString type = indexReader.value(directoryKey + QLatin1String("/Type") ).toString(); if (type == QLatin1String("Fixed")) - dirInfo.type = XdgIconDirInfo::Fixed; + dirInfo.type = QIconDirInfo::Fixed; else if (type == QLatin1String("Scalable")) - dirInfo.type = XdgIconDirInfo::Scalable; + dirInfo.type = QIconDirInfo::Scalable; else - dirInfo.type = XdgIconDirInfo::Threshold; + dirInfo.type = QIconDirInfo::Threshold; dirInfo.threshold = indexReader.value(directoryKey + QLatin1String("/Threshold"), @@ -362,6 +296,7 @@ QIconTheme::QIconTheme(const QString &themeName) m_parents = indexReader.value( QLatin1String("Icon Theme/Inherits")).toStringList(); m_parents.removeAll(QString()); + m_parents.removeAll(QLatin1String("hicolor")); // Ensure a default platform fallback for all themes if (m_parents.isEmpty()) { @@ -369,33 +304,51 @@ QIconTheme::QIconTheme(const QString &themeName) if (!fallback.isEmpty()) m_parents.append(fallback); } - - // Ensure that all themes fall back to hicolor - if (!m_parents.contains(QLatin1String("hicolor"))) - m_parents.append(QLatin1String("hicolor")); } #endif //QT_NO_SETTINGS } +/* WARNING: + * + * https://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html + * + * + * The dash “-” character is used to separate levels of specificity in icon + * names, for all contexts other than MimeTypes. For instance, we use + * “input-mouse” as the generic item for all mouse devices, and we use + * “input-mouse-usb” for a USB mouse device. However, if the more specific + * item does not exist in the current theme, and does exist in a parent + * theme, the generic icon from the current theme is preferred, in order + * to keep consistent style. + * + * + * But we believe, that using the more specific icon (even from parents) + * is better for user experience. So we are violating the standard + * intentionally. + * + * Ref. + * https://github.com/lxde/lxqt/issues/1252 + * https://github.com/lxde/libqtxdg/pull/116 + */ QThemeIconInfo XdgIconLoader::findIconHelper(const QString &themeName, const QString &iconName, - QStringList &visited) const + QStringList &visited, + bool dashFallback) const { QThemeIconInfo info; Q_ASSERT(!themeName.isEmpty()); - QPixmap pixmap; - // Used to protect against potential recursions visited << themeName; - QIconTheme theme = themeList.value(themeName); + XdgIconTheme &theme = themeList[themeName]; if (!theme.isValid()) { - theme = QIconTheme(themeName); - if (!theme.isValid()) - theme = QIconTheme(fallbackTheme()); - - themeList.insert(themeName, theme); + theme = XdgIconTheme(themeName); + if (!theme.isValid()) { + const QString fallback = fallbackTheme(); + if (!fallback.isEmpty()) + theme = XdgIconTheme(fallback); + } } const QStringList contentDirs = theme.contentDirs(); @@ -405,7 +358,7 @@ QThemeIconInfo XdgIconLoader::findIconHelper(const QString &themeName, const QString xpmext(QLatin1String(".xpm")); - QString iconNameFallback = iconName; + QStringRef iconNameFallback(&iconName); // Iterate through all icon's fallbacks in current theme while (info.entries.isEmpty()) { @@ -415,21 +368,21 @@ QThemeIconInfo XdgIconLoader::findIconHelper(const QString &themeName, // Add all relevant files for (int i = 0; i < contentDirs.size(); ++i) { - QVector subDirs = theme.keyList(); + QVector subDirs = theme.keyList(); // Try to reduce the amount of subDirs by looking in the GTK+ cache in order to save // a massive amount of file stat (especially if the icon is not there) auto cache = theme.m_gtkCaches.at(i); if (cache->isValid()) { - auto result = cache->lookup(iconNameFallback); + const auto result = cache->lookup(iconNameFallback); if (cache->isValid()) { - const QVector subDirsCopy = subDirs; + const QVector subDirsCopy = subDirs; subDirs.clear(); subDirs.reserve(result.count()); - foreach (const char *s, result) { + for (const char *s : result) { QString path = QString::fromUtf8(s); auto it = std::find_if(subDirsCopy.cbegin(), subDirsCopy.cend(), - [&](const XdgIconDirInfo &info) { + [&](const QIconDirInfo &info) { return info.path == path; } ); if (it != subDirsCopy.cend()) { subDirs.append(*it); @@ -440,45 +393,41 @@ QThemeIconInfo XdgIconLoader::findIconHelper(const QString &themeName, QString contentDir = contentDirs.at(i) + QLatin1Char('/'); for (int j = 0; j < subDirs.size() ; ++j) { - const XdgIconDirInfo &dirInfo = subDirs.at(j); - QString subdir = dirInfo.path; - QDir currentDir(contentDir + subdir); - if (currentDir.exists(pngIconName)) { + const QIconDirInfo &dirInfo = subDirs.at(j); + const QString subDir = contentDir + dirInfo.path + QLatin1Char('/'); + const QString pngPath = subDir + pngIconName; + if (QFile::exists(pngPath)) { PixmapEntry *iconEntry = new PixmapEntry; iconEntry->dir = dirInfo; - iconEntry->filename = currentDir.filePath(pngIconName); + iconEntry->filename = pngPath; // Notice we ensure that pixmap entries always come before // scalable to preserve search order afterwards info.entries.prepend(iconEntry); - } else if (m_supportsSvg && - currentDir.exists(svgIconName)) { - ScalableEntry *iconEntry = new ScalableEntry; - iconEntry->dir = dirInfo; - iconEntry->filename = currentDir.filePath(svgIconName); - info.entries.append(iconEntry); - } else if(currentDir.exists(iconName + xpmext)) { + } else { + const QString svgPath = subDir + svgIconName; + if (gSupportsSvg && QFile::exists(svgPath)) { + ScalableEntry *iconEntry = (followColorScheme() && theme.followsColorScheme()) ? new ScalableFollowsColorEntry : new ScalableEntry; + iconEntry->dir = dirInfo; + iconEntry->filename = svgPath; + info.entries.append(iconEntry); + } + } + const QString xpmPath = subDir + xpmIconName; + if (QFile::exists(xpmPath)) { PixmapEntry *iconEntry = new PixmapEntry; iconEntry->dir = dirInfo; - iconEntry->filename = currentDir.filePath(iconName + xpmext); + iconEntry->filename = xpmPath; // Notice we ensure that pixmap entries always come before // scalable to preserve search order afterwards info.entries.append(iconEntry); - break; } } } - if (!info.entries.isEmpty()) { - info.iconName = iconNameFallback; - break; - } - - // If it's possible - find next fallback for the icon - const int indexOfDash = iconNameFallback.lastIndexOf(QLatin1Char('-')); - if (indexOfDash == -1) - break; + if (!info.entries.isEmpty()) + info.iconName = iconNameFallback.toString(); - iconNameFallback.truncate(indexOfDash); + break; } if (info.entries.isEmpty()) { @@ -496,83 +445,80 @@ QThemeIconInfo XdgIconLoader::findIconHelper(const QString &themeName, } } - if (info.entries.isEmpty()) { - // Search for unthemed icons in main dir of search paths - QStringList themeSearchPaths = QIcon::themeSearchPaths(); - foreach (QString contentDir, themeSearchPaths) { - QDir currentDir(contentDir); - - if (currentDir.exists(iconName + pngext)) { - PixmapEntry *iconEntry = new PixmapEntry; - iconEntry->filename = currentDir.filePath(iconName + pngext); - // Notice we ensure that pixmap entries always come before - // scalable to preserve search order afterwards - info.entries.prepend(iconEntry); - } else if (m_supportsSvg && - currentDir.exists(iconName + svgext)) { - ScalableEntry *iconEntry = new ScalableEntry; - iconEntry->filename = currentDir.filePath(iconName + svgext); - info.entries.append(iconEntry); - break; - } else if (currentDir.exists(iconName + xpmext)) { - PixmapEntry *iconEntry = new PixmapEntry; - iconEntry->filename = currentDir.filePath(iconName + xpmext); - // Notice we ensure that pixmap entries always come before - // scalable to preserve search order afterwards - info.entries.append(iconEntry); - break; - } + if (dashFallback && info.entries.isEmpty()) { + // If it's possible - find next fallback for the icon + const int indexOfDash = iconNameFallback.lastIndexOf(QLatin1Char('-')); + if (indexOfDash != -1) { + iconNameFallback.truncate(indexOfDash); + QStringList _visited; + info = findIconHelper(themeName, iconNameFallback.toString(), _visited, true); } } + return info; +} - /********************************************************************* - Author: Kaitlin Rupert - Date: Aug 12, 2010 - Description: Make it so that the QIcon loader honors /usr/share/pixmaps - directory. This is a valid directory per the Freedesktop.org - icon theme specification. - Bug: https://bugreports.qt.nokia.com/browse/QTBUG-12874 - *********************************************************************/ -#ifdef Q_OS_LINUX - /* Freedesktop standard says to look in /usr/share/pixmaps last */ - if (info.entries.isEmpty()) { - const QString pixmaps(QLatin1String("/usr/share/pixmaps")); +QThemeIconInfo XdgIconLoader::unthemedFallback(const QString &iconName, const QStringList &searchPaths) const +{ + QThemeIconInfo info; + + const QString svgext(QLatin1String(".svg")); + const QString pngext(QLatin1String(".png")); + const QString xpmext(QLatin1String(".xpm")); + + for (const auto &contentDir : searchPaths) { + QDir currentDir(contentDir); - const QDir currentDir(pixmaps); - const XdgIconDirInfo dirInfo(pixmaps); if (currentDir.exists(iconName + pngext)) { PixmapEntry *iconEntry = new PixmapEntry; - iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(iconName + pngext); // Notice we ensure that pixmap entries always come before // scalable to preserve search order afterwards info.entries.prepend(iconEntry); - } else if (m_supportsSvg && - currentDir.exists(iconName + svgext)) { + } else if (gSupportsSvg && + currentDir.exists(iconName + svgext)) { ScalableEntry *iconEntry = new ScalableEntry; - iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(iconName + svgext); info.entries.append(iconEntry); } else if (currentDir.exists(iconName + xpmext)) { PixmapEntry *iconEntry = new PixmapEntry; - iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(iconName + xpmext); // Notice we ensure that pixmap entries always come before // scalable to preserve search order afterwards info.entries.append(iconEntry); } } -#endif - return info; } QThemeIconInfo XdgIconLoader::loadIcon(const QString &name) const { - if (!themeName().isEmpty()) { + const QString theme_name = QIconLoader::instance()->themeName(); + if (!theme_name.isEmpty()) { QStringList visited; - return findIconHelper(themeName(), name, visited); + auto info = findIconHelper(theme_name, name, visited, true); + if (info.entries.isEmpty()) { + const auto hicolorInfo = findIconHelper(QLatin1String("hicolor"), name, visited, true); + if (hicolorInfo.entries.isEmpty()) { + const auto unthemedInfo = unthemedFallback(name, QIcon::themeSearchPaths()); + if (unthemedInfo.entries.isEmpty()) { + /* Freedesktop standard says to look in /usr/share/pixmaps last */ + const QStringList pixmapPath = (QStringList() << QString::fromLatin1("/usr/share/pixmaps")); + const auto pixmapInfo = unthemedFallback(name, pixmapPath); + if (pixmapInfo.entries.isEmpty()) { + return QThemeIconInfo(); + } else { + return pixmapInfo; + } + } else { + return unthemedInfo; + } + } else { + return hicolorInfo; + } + } else { + return info; + } } return QThemeIconInfo(); @@ -623,14 +569,14 @@ bool XdgIconLoaderEngine::hasIcon() const // Lazily load the icon void XdgIconLoaderEngine::ensureLoaded() { - if (!(XdgIconLoader::instance()->themeKey() == m_key)) { + if (!(QIconLoader::instance()->themeKey() == m_key)) { qDeleteAll(m_info.entries); m_info.entries.clear(); m_info.iconName.clear(); Q_ASSERT(m_info.entries.size() == 0); m_info = XdgIconLoader::instance()->loadIcon(m_iconName); - m_key = XdgIconLoader::instance()->themeKey(); + m_key = QIconLoader::instance()->themeKey(); } } @@ -648,16 +594,16 @@ 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 XdgIconDirInfo &dir, int iconsize) +static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize) { - if (dir.type == XdgIconDirInfo::Fixed) { + if (dir.type == QIconDirInfo::Fixed) { return dir.size == iconsize; - } else if (dir.type == XdgIconDirInfo::Scalable) { + } else if (dir.type == QIconDirInfo::Scalable) { return iconsize <= dir.maxSize && iconsize >= dir.minSize; - } else if (dir.type == XdgIconDirInfo::Threshold) { + } else if (dir.type == QIconDirInfo::Threshold) { return iconsize >= dir.size - dir.threshold && iconsize <= dir.size + dir.threshold; } @@ -670,12 +616,12 @@ static bool directoryMatchesSize(const XdgIconDirInfo &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 XdgIconDirInfo &dir, int iconsize) +static int directorySizeDistance(const QIconDirInfo &dir, int iconsize) { - if (dir.type == XdgIconDirInfo::Fixed) { + if (dir.type == QIconDirInfo::Fixed) { return qAbs(dir.size - iconsize); - } else if (dir.type == XdgIconDirInfo::Scalable) { + } else if (dir.type == QIconDirInfo::Scalable) { if (iconsize < dir.minSize) return dir.minSize - iconsize; else if (iconsize > dir.maxSize) @@ -683,7 +629,7 @@ static int directorySizeDistance(const XdgIconDirInfo &dir, int iconsize) else return 0; - } else if (dir.type == XdgIconDirInfo::Threshold) { + } else if (dir.type == QIconDirInfo::Threshold) { if (iconsize < dir.size - dir.threshold) return dir.minSize - iconsize; else if (iconsize > dir.size + dir.threshold) @@ -695,7 +641,7 @@ static int directorySizeDistance(const XdgIconDirInfo &dir, int iconsize) return INT_MAX; } -XdgIconLoaderEngineEntry *XdgIconLoaderEngine::entryForSize(const QSize &size) +QIconLoaderEngineEntry *XdgIconLoaderEngine::entryForSize(const QSize &size) { int iconsize = qMin(size.width(), size.height()); @@ -706,7 +652,7 @@ XdgIconLoaderEngineEntry *XdgIconLoaderEngine::entryForSize(const QSize &size) // Search for exact matches first for (int i = 0; i < numEntries; ++i) { - XdgIconLoaderEngineEntry *entry = m_info.entries.at(i); + QIconLoaderEngineEntry *entry = m_info.entries.at(i); if (directoryMatchesSize(entry->dir, iconsize)) { return entry; } @@ -714,9 +660,9 @@ XdgIconLoaderEngineEntry *XdgIconLoaderEngine::entryForSize(const QSize &size) // Find the minimum distance icon int minimalSize = INT_MAX; - XdgIconLoaderEngineEntry *closestMatch = 0; + QIconLoaderEngineEntry *closestMatch = 0; for (int i = 0; i < numEntries; ++i) { - XdgIconLoaderEngineEntry *entry = m_info.entries.at(i); + QIconLoaderEngineEntry *entry = m_info.entries.at(i); int distance = directorySizeDistance(entry->dir, iconsize); if (distance < minimalSize) { minimalSize = distance; @@ -737,10 +683,10 @@ QSize XdgIconLoaderEngine::actualSize(const QSize &size, QIcon::Mode mode, { ensureLoaded(); - XdgIconLoaderEngineEntry *entry = entryForSize(size); + QIconLoaderEngineEntry *entry = entryForSize(size); if (entry) { - const XdgIconDirInfo &dir = entry->dir; - if (dir.type == XdgIconDirInfo::Scalable || dynamic_cast(entry)) + const QIconDirInfo &dir = entry->dir; + if (dir.type == QIconDirInfo::Scalable || dynamic_cast(entry)) return size; else { int dir_size = dir.size; @@ -756,9 +702,10 @@ QSize XdgIconLoaderEngine::actualSize(const QSize &size, QIcon::Mode mode, return QSize(result, result); } } - return QIconEngine::actualSize(size, mode, state); + return {0, 0}; } +// XXX: duplicated from qiconloader.cpp, because this symbol isn't exported :( QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) { Q_UNUSED(state); @@ -794,6 +741,7 @@ QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State st return cachedPixmap; } +// XXX: duplicated from qiconloader.cpp, because this symbol isn't exported :( QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) { if (svgIcon.isNull()) @@ -803,12 +751,90 @@ QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State return svgIcon.pixmap(size, mode, state); } + +// XXX: duplicated from qicon.cpp, because the symbol qt_iconEngineFactoryLoader isn't exported :( +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, qt_iconEngineFactoryLoader, + (QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive)) +//extern QFactoryLoader *qt_iconEngineFactoryLoader(); // qicon.cpp + +QPixmap ScalableFollowsColorEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) +{ + QIcon & icon = QIcon::Selected == mode ? svgSelectedIcon : svgIcon; + if (icon.isNull()) + { + // The following lines are adapted and updated from KDE's "kiconloader.cpp" -> + // KIconLoaderPrivate::processSvg() and KIconLoaderPrivate::createIconImage(). + // They read the SVG color scheme of SVG icons and give images based on the icon mode. + QByteArray processedContents; + QFile device{filename};; + if (device.open(QIODevice::ReadOnly)) + { + const QPalette pal = qApp->palette(); + QString styleSheet = QStringLiteral(".ColorScheme-Text{color:%1;}") + .arg(mode == QIcon::Selected + ? pal.highlightedText().color().name() + : pal.windowText().color().name()); + QXmlStreamReader xmlReader(&device); + QXmlStreamWriter writer(&processedContents); + while (!xmlReader.atEnd()) + { + if (xmlReader.readNext() == QXmlStreamReader::StartElement + && xmlReader.qualifiedName() == QLatin1String("style") + && xmlReader.attributes().value(QLatin1String("id")) == QLatin1String("current-color-scheme")) + { + writer.writeStartElement(QLatin1String("style")); + writer.writeAttributes(xmlReader.attributes()); + writer.writeCharacters(styleSheet); + writer.writeEndElement(); + while (xmlReader.tokenType() != QXmlStreamReader::EndElement) + xmlReader.readNext(); + } + else if (xmlReader.tokenType() != QXmlStreamReader::Invalid) + writer.writeCurrentToken(xmlReader); + } + } + // use the QSvgIconEngine + // - assemble the content as it is done by the QSvgIconEngine::write() (operator <<) + // - create the QIcon with QSvgIconEngine initialized from the content + const int index = qt_iconEngineFactoryLoader()->indexOf(QStringLiteral("svg")); + if (index != -1) + { + if (QIconEnginePlugin * factory = qobject_cast(qt_iconEngineFactoryLoader()->instance(index))) + { + if (QIconEngine * engine = factory->create()) + { + QByteArray engine_arr; + QDataStream str{&engine_arr, QIODevice::WriteOnly}; + str.setVersion(QDataStream::Qt_4_4); + QHash filenames; + filenames[0] = filename; + QHash svg_buffers; + svg_buffers[0] = processedContents; + str << filenames << static_cast(0)/*isCompressed*/ << svg_buffers << static_cast(0)/*hasAddedPimaps*/; + + QDataStream str_read{&engine_arr, QIODevice::ReadOnly}; + str_read.setVersion(QDataStream::Qt_4_4); + + engine->read(str_read); + icon = QIcon{engine}; + } + } + } + + // load the icon directly from file, if still null + if (icon.isNull()) + icon = QIcon(filename); + } + + return icon.pixmap(size, mode, state); +} + QPixmap XdgIconLoaderEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) { ensureLoaded(); - XdgIconLoaderEngineEntry *entry = entryForSize(size); + QIconLoaderEngineEntry *entry = entryForSize(size); if (entry) return entry->pixmap(size, mode, state); diff --git a/xdgiconloader/xdgiconloader_p.h b/xdgiconloader/xdgiconloader_p.h index 380a222..f2e9960 100644 --- a/xdgiconloader/xdgiconloader_p.h +++ b/xdgiconloader/xdgiconloader_p.h @@ -31,8 +31,8 @@ ** ****************************************************************************/ -#ifndef QICONLOADER_P_H -#define QICONLOADER_P_H +#ifndef XDGICONLOADER_P_H +#define XDGICONLOADER_P_H #include @@ -52,65 +52,19 @@ #include #include -#include #include -#include +#include #include #include -#include //QT_BEGIN_NAMESPACE class XdgIconLoader; -struct XdgIconDirInfo -{ - enum Type { Fixed, Scalable, Threshold }; - XdgIconDirInfo(const QString &_path = QString()) : - path(_path), - size(0), - maxSize(0), - minSize(0), - threshold(0), - type(Threshold) {} - QString path; - short size; - short maxSize; - short minSize; - short threshold; - Type type; -}; - -class XdgIconLoaderEngineEntry - { -public: - virtual ~XdgIconLoaderEngineEntry() {} - virtual QPixmap pixmap(const QSize &size, - QIcon::Mode mode, - QIcon::State state) = 0; - QString filename; - XdgIconDirInfo dir; - static int count; -}; - -struct ScalableEntry : public XdgIconLoaderEngineEntry -{ - QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE; - QIcon svgIcon; -}; - -struct PixmapEntry : public XdgIconLoaderEngineEntry +struct ScalableFollowsColorEntry : public ScalableEntry { QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE; - QPixmap basePixmap; -}; - -typedef QList QThemeIconEntries; - -struct QThemeIconInfo -{ - QThemeIconEntries entries; - QString iconName; + QIcon svgSelectedIcon; }; //class QIconLoaderEngine : public QIconEngine @@ -120,19 +74,19 @@ public: XdgIconLoaderEngine(const QString& iconName = QString()); ~XdgIconLoaderEngine(); - void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state); - QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); - QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state); - QIconEngine *clone() const; - bool read(QDataStream &in); - bool write(QDataStream &out) const; + void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE; + QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE; + QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE; + QIconEngine *clone() const Q_DECL_OVERRIDE; + bool read(QDataStream &in) Q_DECL_OVERRIDE; + bool write(QDataStream &out) const Q_DECL_OVERRIDE; private: - QString key() const; + QString key() const Q_DECL_OVERRIDE; bool hasIcon() const; void ensureLoaded(); - void virtual_hook(int id, void *data); - XdgIconLoaderEngineEntry *entryForSize(const QSize &size); + void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; + QIconLoaderEngineEntry *entryForSize(const QSize &size); XdgIconLoaderEngine(const XdgIconLoaderEngine &other); QThemeIconInfo m_info; QString m_iconName; @@ -143,20 +97,24 @@ private: class QIconCacheGtkReader; -class QIconTheme +// Note: We can't simply reuse the QIconTheme from Qt > 5.7 because +// the QIconTheme constructor symbol isn't exported. +class XdgIconTheme { public: - QIconTheme(const QString &name); - QIconTheme() : m_valid(false) {} + XdgIconTheme(const QString &name); + XdgIconTheme() = default; QStringList parents() { return m_parents; } - QVector keyList() { return m_keyList; } + QVector keyList() { return m_keyList; } QStringList contentDirs() { return m_contentDirs; } - bool isValid() { return m_valid; } + bool isValid() const { return m_valid; } + bool followsColorScheme() const { return m_followsColorScheme; } private: QStringList m_contentDirs; - QVector m_keyList; + QVector m_keyList; QStringList m_parents; - bool m_valid; + bool m_valid = false; + bool m_followsColorScheme = false; public: QVector> m_gtkCaches; }; @@ -164,43 +122,39 @@ public: class XDGICONLOADER_EXPORT XdgIconLoader { public: - XdgIconLoader(); QThemeIconInfo loadIcon(const QString &iconName) const; - uint themeKey() const { return m_themeKey; } - - QString themeName() const { return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme; } - void setThemeName(const QString &themeName); - QIconTheme theme() { return themeList.value(themeName()); } - void setThemeSearchPath(const QStringList &searchPaths); - QStringList themeSearchPaths() const; - XdgIconDirInfo dirInfo(int dirindex); + + /* TODO: deprecate & remove all QIconLoader wrappers */ + inline uint themeKey() const { return QIconLoader::instance()->themeKey(); } + inline QString themeName() const { return QIconLoader::instance()->themeName(); } + inline void setThemeName(const QString &themeName) { QIconLoader::instance()->setThemeName(themeName); } + inline void setThemeSearchPath(const QStringList &searchPaths) { QIconLoader::instance()->setThemeSearchPath(searchPaths); } + inline QIconDirInfo dirInfo(int dirindex) { return QIconLoader::instance()->dirInfo(dirindex); } + inline QStringList themeSearchPaths() const { return QIconLoader::instance()->themeSearchPaths(); } + inline void updateSystemTheme() { QIconLoader::instance()->updateSystemTheme(); } + inline void invalidateKey() { QIconLoader::instance()->invalidateKey(); } + inline void ensureInitialized() { QIconLoader::instance()->ensureInitialized(); } + inline bool hasUserTheme() const { return QIconLoader::instance()->hasUserTheme(); } + /*! + * Flag if the "FollowsColorScheme" hint (the KDE extension to XDG + * themes) should be honored. + */ + inline bool followColorScheme() const { return m_followColorScheme; } + void setFollowColorScheme(bool enable); + + XdgIconTheme theme() { return themeList.value(QIconLoader::instance()->themeName()); } static XdgIconLoader *instance(); - void updateSystemTheme(); - void invalidateKey() { m_themeKey++; } - void ensureInitialized(); - bool hasUserTheme() const { return !m_userTheme.isEmpty(); } private: QThemeIconInfo findIconHelper(const QString &themeName, const QString &iconName, - QStringList &visited) const; - uint m_themeKey; - bool m_supportsSvg; - bool m_initialized; - - mutable QString m_userTheme; - mutable QString m_systemTheme; - mutable QStringList m_iconDirs; - mutable QHash themeList; + QStringList &visited, + bool dashFallback = false) const; + QThemeIconInfo unthemedFallback(const QString &iconName, const QStringList &searchPaths) const; + mutable QHash themeList; + bool m_followColorScheme = true; }; - -// Note: class template specialization of 'QTypeInfo' must occur at -// global scope -Q_DECLARE_TYPEINFO(XdgIconDirInfo, Q_MOVABLE_TYPE); - -//QT_END_NAMESPACE - #endif // QT_NO_ICON -#endif // QICONLOADER_P_H +#endif // XDGICONLOADER_P_H From ccc4eccbef589b85a3a6321fcef155a0ee012215 Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Sat, 23 Sep 2017 02:39:20 +0200 Subject: [PATCH 10/14] Imported new upstream release: 3.0.0 * Switched to experimental * Renamed packages to reflect the new soname * Bumped Standards to 4.1.0 * Added override_dh_missing * Added tools package * Fixed symbols --- .github/ISSUE_TEMPLATE.md | 34 ++++++++++ CHANGELOG | 65 +++++++++++++++++- debian/changelog | 13 ++-- debian/control | 5 +- debian/copyright | 100 +++++++++++++++++++++++++--- debian/libqt5xdg3.symbols | 4 +- debian/libqt5xdgiconloader3.symbols | 8 +-- qtxdg/xdgautostart.cpp | 4 +- qtxdg/xdgdesktopfile.cpp | 49 +++++++------- qtxdg/xdgdirs.cpp | 2 +- qtxdg/xdgicon.cpp | 2 +- qtxdg/xdgmenu.cpp | 12 ++-- qtxdg/xdgmenuapplinkprocessor.cpp | 13 ++-- qtxdg/xdgmenureader.cpp | 15 ++--- qtxdg/xdgmimetype.cpp | 2 +- test/qtxdg_test.cpp | 8 ++- xdgiconloader/xdgiconloader.cpp | 55 +++++++++++++-- xdgiconloader/xdgiconloader_p.h | 2 +- 18 files changed, 314 insertions(+), 79 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE.md 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; From 6858120f8c6f65be796cc22d1f9e4b0db0136958 Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Mon, 9 Oct 2017 18:02:06 +0200 Subject: [PATCH 11/14] Standards 4.1.1 removed some whitespaces --- debian/changelog | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/debian/changelog b/debian/changelog index b98220e..6a02ab4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,13 +4,13 @@ libqtxdg (3.0.0-1) experimental; urgency=medium * Switched to experimental * Renamed packages to reflect the new soname * Added dependency libqt5svg5-dev to QtXdgIconloader dev package. - * Bumped Standards to 4.1.0 - * Added override_dh_missing + * Bumped Standards to 4.1.1 + * Added override_dh_missing * Added tools package * Fixed symbols * Reworked copyright - -- Alf Gaida Fri, 06 Oct 2017 23:02:29 +0200 + -- Alf Gaida Mon, 09 Oct 2017 18:01:08 +0200 libqtxdg (2.0.0-7) unstable; urgency=medium @@ -59,16 +59,16 @@ libqtxdg (2.0.0-4) unstable; urgency=medium libqtxdg (1.3.0-4) unstable; urgency=medium * Added libfile-mimeinfo-perl as dependency, we really need this, a - recommendation is not enough. Thanks tsujan. + recommendation is not enough. Thanks tsujan. * Bumped standards to 3.9.8, no changes needed * Bump years in copyright * Added README to debian/docs * Added hardening=+all - * Exported LC_ALL=C.UTF-8 - define language settings for + * Exported LC_ALL=C.UTF-8 - define language settings for reproducible builds * Fixed VCS-fields, use https and plain /git/ * Fixed copyrights Format field to https - + -- Alf Gaida Wed, 10 Aug 2016 23:06:12 +0200 libqtxdg (1.3.0-3) unstable; urgency=medium From a533fea437cd547f42ccdf60b0f4b7f2bac1e4cc Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Sun, 22 Oct 2017 13:54:58 +0200 Subject: [PATCH 12/14] Cherry-picked new upstream-release 3.1.0 * Added lintian-overrides for tools package * Added new symbols for action handling --- .github/ISSUE_TEMPLATE.md | 34 ----- .gitignore | 8 -- CHANGELOG | 14 ++- CMakeLists.txt | 2 +- debian/changelog | 8 ++ debian/copyright | 2 +- debian/libqt5xdg3.symbols | 114 ++++++++--------- debian/libqt5xdgiconloader3.symbols | 23 ++-- debian/qtxdg-dev-tools.lintian-overrides | 5 + qtxdg/xdgdesktopfile.cpp | 153 ++++++++++++++++++----- qtxdg/xdgdesktopfile.h | 22 ++++ 11 files changed, 237 insertions(+), 148 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE.md delete mode 100644 .gitignore create mode 100644 debian/qtxdg-dev-tools.lintian-overrides diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 81cf0bb..0000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,34 +0,0 @@ - - - -##### 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/.gitignore b/.gitignore deleted file mode 100644 index 429cda3..0000000 --- a/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -build* -*.qm -*~ -*.autosave -*-swp -*.swp -CMakeLists.txt.user* -nbproject/ diff --git a/CHANGELOG b/CHANGELOG index 06c61f5..a70cca9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,19 @@ -libqtxdg-3.0.0 / 2017-09-22 +libqtxdg-3.1.0 / 2017-10-21 =========================== + * Bump version to 3.1.0 + * xdgdesktopfile: Add API for getting actions info + * xdgdesktopfile: Add support for activating actions + * xdgdesktopfile: Add getting actions + * Check $XDG_CONFIG_HOME and $XDG_CONFIG_DIRS for mimeapps.list first. + * Fix reading and writing mimeapps.list file. + * Don't export github templates + +3.0.0 / 2017-09-22 +================== + + * Release 3.0.0: Update changelog * Backport support for Scale directory key according to Icon Theme spec * Bump Major to 3 * test: Drop Q_FOREACH diff --git a/CMakeLists.txt b/CMakeLists.txt index 6af52bb..9145c34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ else() endif() set(QTXDG_MAJOR_VERSION 3) -set(QTXDG_MINOR_VERSION 0) +set(QTXDG_MINOR_VERSION 1) set(QTXDG_PATCH_VERSION 0) set(QTXDG_VERSION_STRING ${QTXDG_MAJOR_VERSION}.${QTXDG_MINOR_VERSION}.${QTXDG_PATCH_VERSION}) diff --git a/debian/changelog b/debian/changelog index 6a02ab4..d6cf8a2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +libqtxdg (3.1.0-1) experimental; urgency=medium + + * Cherry-picked new upstream-release 3.1.0 + * Added lintian-overrides for tools package + * Added new symbols for action handling + + -- Alf Gaida Sun, 22 Oct 2017 13:53:34 +0200 + libqtxdg (3.0.0-1) experimental; urgency=medium * Imported new upstream release: 3.0.0 diff --git a/debian/copyright b/debian/copyright index d485aef..489595e 100644 --- a/debian/copyright +++ b/debian/copyright @@ -3,7 +3,7 @@ Upstream-Name: libqtxdg Source: https://github.com/lxde/libqtxdg Files: * -Copyright: 2012-2016, LXQt team +Copyright: 2012-2017, LXQt team 2010-2012, Razor team License: LGPL-2.1+ diff --git a/debian/libqt5xdg3.symbols b/debian/libqt5xdg3.symbols index cc607ee..0062680 100644 --- a/debian/libqt5xdg3.symbols +++ b/debian/libqt5xdg3.symbols @@ -1,21 +1,9 @@ libQt5Xdg.so.3 libqt5xdg3 #MINVER# - (c++)"non-virtual thunk to XdgMenuWidget::~XdgMenuWidget()@Base" 1.0.0 - (c++)"typeinfo for XdgAction@Base" 1.0.0 - (c++)"typeinfo for XdgDesktopFile@Base" 1.0.0 - (c++)"typeinfo for XdgIcon@Base" 1.0.0 - (c++)"typeinfo for XdgMenu@Base" 1.0.0 - (c++)"typeinfo for XdgMenuWidget@Base" 1.0.0 - (c++)"typeinfo name for XdgAction@Base" 1.0.0 - (c++)"typeinfo name for XdgDesktopFile@Base" 1.0.0 - (c++)"typeinfo name for XdgIcon@Base" 1.0.0 - (c++)"typeinfo name for XdgMenu@Base" 1.0.0 - (c++)"typeinfo name for XdgMenuWidget@Base" 1.0.0 - (c++)"vtable for XdgAction@Base" 1.0.0 - (c++)"vtable for XdgDesktopFile@Base" 1.0.0 - (c++)"vtable for XdgIcon@Base" 1.0.0 - (c++)"vtable for XdgMenu@Base" 1.0.0 - (c++)"vtable for XdgMenuWidget@Base" 1.0.0 - + (c++)"XdgAction::XdgAction(QObject*)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(QString const&, QObject*)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(XdgAction const&, QObject*)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(XdgDesktopFile const&, QObject*)@Base" 1.0.0 + (c++)"XdgAction::XdgAction(XdgDesktopFile const*, QObject*)@Base" 1.0.0 (c++)"XdgAction::isValid() const@Base" 1.0.0 (c++)"XdgAction::load(XdgDesktopFile const&)@Base" 1.0.0 (c++)"XdgAction::metaObject() const@Base" 1.0.0 @@ -26,35 +14,23 @@ libQt5Xdg.so.3 libqt5xdg3 #MINVER# (c++)"XdgAction::staticMetaObject@Base" 1.0.0 (c++)"XdgAction::updateIcon()@Base" 1.0.0 (c++)"XdgAction::~XdgAction()@Base" 1.0.0 - (c++)"XdgAction::XdgAction(QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(QString const&, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(XdgAction const&, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(XdgDesktopFile const*, QObject*)@Base" 1.0.0 - (c++)"XdgAction::XdgAction(XdgDesktopFile const&, QObject*)@Base" 1.0.0 - - (c++)"XdgAutoStart::desktopFileList(bool)@Base" 1.0.0 (c++)"XdgAutoStart::desktopFileList(QStringList, bool)@Base" 1.0.0 + (c++)"XdgAutoStart::desktopFileList(bool)@Base" 1.0.0 (c++)"XdgAutoStart::localPath(XdgDesktopFile const&)@Base" 1.0.0 - - (c++)"XdgDesktopFileCache::desktopFileSettingsFormat()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::getAllFiles()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::getAppsOfCategory(QString const&)@Base" 1.2.0 - (c++)"XdgDesktopFileCache::getApps(QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::getDefaultApp(QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::getFile(QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::initialize()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::initialize(QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::instance()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::load(QString const&)@Base" 1.0.0 - (c++)"XdgDesktopFileCache::~XdgDesktopFileCache()@Base" 1.0.0 - (c++)"XdgDesktopFileCache::XdgDesktopFileCache()@Base" 1.0.0 - + (c++)"XdgDesktopFile::XdgDesktopFile()@Base" 1.0.0 + (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile const&)@Base" 1.0.0 + (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile::Type, QString const&, QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFile::actionActivate(QString const&, QStringList const&) const@Base" 3.1.0 + (c++)"XdgDesktopFile::actionIcon(QString const&, QIcon const&) const@Base" 3.1.0 + (c++)"XdgDesktopFile::actionIconName(QString const&) const@Base" 3.1.0 + (c++)"XdgDesktopFile::actionName(QString const&) const@Base" 3.1.0 + (c++)"XdgDesktopFile::actions() const@Base" 3.1.0 (c++)"XdgDesktopFile::categories() const@Base" 1.2.0 (c++)"XdgDesktopFile::contains(QString const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::expandExecString(QStringList const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::fileName() const@Base" 1.0.0 - (c++)"XdgDesktopFile::iconName() const@Base" 1.0.0 (c++)"XdgDesktopFile::icon(QIcon const&) const@Base" 1.0.0 + (c++)"XdgDesktopFile::iconName() const@Base" 1.0.0 (c++)"XdgDesktopFile::id(QString const&, bool)@Base" 2.0.0 (c++)"XdgDesktopFile::isShown(QString const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::isSuitable(bool, QString const&) const@Base" 1.0.0 @@ -76,10 +52,18 @@ libQt5Xdg.so.3 libqt5xdg3 #MINVER# (c++)"XdgDesktopFile::url() const@Base" 1.0.0 (c++)"XdgDesktopFile::value(QString const&, QVariant const&) const@Base" 1.0.0 (c++)"XdgDesktopFile::~XdgDesktopFile()@Base" 1.0.0 - (c++)"XdgDesktopFile::XdgDesktopFile()@Base" 1.0.0 - (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile const&)@Base" 1.0.0 - (c++)"XdgDesktopFile::XdgDesktopFile(XdgDesktopFile::Type, QString const&, QString const&)@Base" 1.0.0 - + (c++)"XdgDesktopFileCache::XdgDesktopFileCache()@Base" 1.0.0 + (c++)"XdgDesktopFileCache::desktopFileSettingsFormat()@Base" 1.0.0 + (c++)"XdgDesktopFileCache::getAllFiles()@Base" 1.0.0 + (c++)"XdgDesktopFileCache::getApps(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::getAppsOfCategory(QString const&)@Base" 1.2.0 + (c++)"XdgDesktopFileCache::getDefaultApp(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::getFile(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::initialize()@Base" 1.0.0 + (c++)"XdgDesktopFileCache::initialize(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::instance()@Base" 1.0.0 + (c++)"XdgDesktopFileCache::load(QString const&)@Base" 1.0.0 + (c++)"XdgDesktopFileCache::~XdgDesktopFileCache()@Base" 1.0.0 (c++)"XdgDirs::autostartDirs(QString const&)@Base" 1.0.0 (c++)"XdgDirs::autostartHome(bool)@Base" 1.0.0 (c++)"XdgDirs::cacheHome(bool)@Base" 1.0.0 @@ -89,9 +73,9 @@ libQt5Xdg.so.3 libqt5xdg3 #MINVER# (c++)"XdgDirs::dataHome(bool)@Base" 1.0.0 (c++)"XdgDirs::runtimeDir()@Base" 1.0.0 (c++)"XdgDirs::setUserDir(XdgDirs::UserDirectory, QString const&, bool)@Base" 1.0.0 - (c++)"XdgDirs::userDirDefault(XdgDirs::UserDirectory)@Base" 1.3.0 (c++)"XdgDirs::userDir(XdgDirs::UserDirectory)@Base" 1.0.0 - + (c++)"XdgDirs::userDirDefault(XdgDirs::UserDirectory)@Base" 1.3.0 + (c++)"XdgIcon::XdgIcon()@Base" 1.0.0 (c++)"XdgIcon::defaultApplicationIcon()@Base" 1.0.0 (c++)"XdgIcon::defaultApplicationIconName()@Base" 1.0.0 (c++)"XdgIcon::followColorScheme()@Base" 3.0.0 @@ -100,8 +84,7 @@ libQt5Xdg.so.3 libqt5xdg3 #MINVER# (c++)"XdgIcon::fromTheme(QStringList const&, QIcon const&)@Base" 1.0.0 (c++)"XdgIcon::setFollowColorScheme(bool)@Base" 3.0.0 (c++)"XdgIcon::~XdgIcon()@Base" 1.0.0 - (c++)"XdgIcon::XdgIcon()@Base" 1.0.0 - + (c++)"XdgMenu::XdgMenu(QObject*)@Base" 1.0.0 (c++)"XdgMenu::addWatchPath(QString const&)@Base" 1.0.0 (c++)"XdgMenu::changed()@Base" 1.0.0 (c++)"XdgMenu::environments()@Base" 1.0.0 @@ -120,7 +103,11 @@ libQt5Xdg.so.3 libqt5xdg3 #MINVER# (c++)"XdgMenu::setEnvironments(QStringList const&)@Base" 1.0.0 (c++)"XdgMenu::setLogDir(QString const&)@Base" 1.0.0 (c++)"XdgMenu::staticMetaObject@Base" 1.0.0 - + (c++)"XdgMenu::xml() const@Base" 1.0.0 + (c++)"XdgMenu::~XdgMenu()@Base" 1.0.0 + (c++)"XdgMenuWidget::XdgMenuWidget(QDomElement const&, QWidget*)@Base" 1.0.0 + (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenu const&, QString const&, QWidget*)@Base" 1.0.0 + (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenuWidget const&, QWidget*)@Base" 1.0.0 (c++)"XdgMenuWidget::event(QEvent*)@Base" 1.0.0 (c++)"XdgMenuWidget::metaObject() const@Base" 1.0.0 (c++)"XdgMenuWidget::operator=(XdgMenuWidget const&)@Base" 1.0.0 @@ -128,18 +115,27 @@ libQt5Xdg.so.3 libqt5xdg3 #MINVER# (c++)"XdgMenuWidget::qt_metacast(char const*)@Base" 1.0.0 (c++)"XdgMenuWidget::staticMetaObject@Base" 1.0.0 (c++)"XdgMenuWidget::~XdgMenuWidget()@Base" 1.0.0 - (c++)"XdgMenuWidget::XdgMenuWidget(QDomElement const&, QWidget*)@Base" 1.0.0 - (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenu const&, QString const&, QWidget*)@Base" 1.0.0 - (c++)"XdgMenuWidget::XdgMenuWidget(XdgMenuWidget const&, QWidget*)@Base" 1.0.0 - - (c++)"XdgMenu::~XdgMenu()@Base" 1.0.0 - (c++)"XdgMenu::XdgMenu(QObject*)@Base" 1.0.0 - (c++)"XdgMenu::xml() const@Base" 1.0.0 - + (c++)"XdgMimeType::XdgMimeType()@Base" 1.0.0 + (c++)"XdgMimeType::XdgMimeType(QMimeType const&)@Base" 1.0.0 + (c++)"XdgMimeType::XdgMimeType(XdgMimeType const&)@Base" 1.0.0 (c++)"XdgMimeType::icon() const@Base" 1.0.0 (c++)"XdgMimeType::iconName() const@Base" 1.0.0 (c++)"XdgMimeType::operator=(XdgMimeType const&)@Base" 1.0.0 (c++)"XdgMimeType::~XdgMimeType()@Base" 1.0.0 - (c++)"XdgMimeType::XdgMimeType()@Base" 1.0.0 - (c++)"XdgMimeType::XdgMimeType(QMimeType const&)@Base" 1.0.0 - (c++)"XdgMimeType::XdgMimeType(XdgMimeType const&)@Base" 1.0.0 + (c++)"non-virtual thunk to XdgMenuWidget::~XdgMenuWidget()@Base" 1.0.0 + (c++)"typeinfo for XdgAction@Base" 1.0.0 + (c++)"typeinfo for XdgDesktopFile@Base" 1.0.0 + (c++)"typeinfo for XdgIcon@Base" 1.0.0 + (c++)"typeinfo for XdgMenu@Base" 1.0.0 + (c++)"typeinfo for XdgMenuWidget@Base" 1.0.0 + (c++)"typeinfo name for XdgAction@Base" 1.0.0 + (c++)"typeinfo name for XdgDesktopFile@Base" 1.0.0 + (c++)"typeinfo name for XdgIcon@Base" 1.0.0 + (c++)"typeinfo name for XdgMenu@Base" 1.0.0 + (c++)"typeinfo name for XdgMenuWidget@Base" 1.0.0 + (c++)"vtable for XdgAction@Base" 1.0.0 + (c++)"vtable for XdgDesktopFile@Base" 1.0.0 + (c++)"vtable for XdgIcon@Base" 1.0.0 + (c++)"vtable for XdgMenu@Base" 1.0.0 + (c++)"vtable for XdgMenuWidget@Base" 1.0.0 +libQt5Xdg.so.3 libqt5xdg3 #MINVER# diff --git a/debian/libqt5xdgiconloader3.symbols b/debian/libqt5xdgiconloader3.symbols index f42690c..4002b51 100644 --- a/debian/libqt5xdgiconloader3.symbols +++ b/debian/libqt5xdgiconloader3.symbols @@ -1,8 +1,11 @@ libQt5XdgIconLoader.so.3 libqt5xdgiconloader3 #MINVER# - (c++)"typeinfo for XdgIconLoaderEngine@Base" 2.0.0 - (c++)"typeinfo name for XdgIconLoaderEngine@Base" 2.0.0 - (c++)"vtable for XdgIconLoaderEngine@Base" 2.0.0 - + (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" 3.0.0 + (c++)"XdgIconLoader::unthemedFallback(QString const&, QStringList const&) const@Base" 3.0.0 + (c++)"XdgIconLoaderEngine::XdgIconLoaderEngine(QString const&)@Base" 2.0.0 + (c++)"XdgIconLoaderEngine::XdgIconLoaderEngine(XdgIconLoaderEngine const&)@Base" 2.0.0 (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 @@ -15,11 +18,7 @@ libQt5XdgIconLoader.so.3 libqt5xdgiconloader3 #MINVER# (c++)"XdgIconLoaderEngine::virtual_hook(int, void*)@Base" 2.0.0 (c++)"XdgIconLoaderEngine::write(QDataStream&) const@Base" 2.0.0 (c++)"XdgIconLoaderEngine::~XdgIconLoaderEngine()@Base" 2.0.0 - (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" 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" 3.0.0 - (c++)"XdgIconLoader::unthemedFallback(QString const&, QStringList const&) const@Base" 3.0.0 + (c++)"typeinfo for XdgIconLoaderEngine@Base" 2.0.0 + (c++)"typeinfo name for XdgIconLoaderEngine@Base" 2.0.0 + (c++)"vtable for XdgIconLoaderEngine@Base" 2.0.0 +libQt5XdgIconLoader.so.3 libqt5xdgiconloader3 #MINVER# diff --git a/debian/qtxdg-dev-tools.lintian-overrides b/debian/qtxdg-dev-tools.lintian-overrides new file mode 100644 index 0000000..b432dec --- /dev/null +++ b/debian/qtxdg-dev-tools.lintian-overrides @@ -0,0 +1,5 @@ +# Yeah, we know + +qtxdg-dev-tools: binary-without-manpage usr/bin/qtxdg-desktop-file-start +qtxdg-dev-tools: binary-without-manpage usr/bin/qtxdg-iconfinder + diff --git a/qtxdg/xdgdesktopfile.cpp b/qtxdg/xdgdesktopfile.cpp index d21e2df..cde6388 100644 --- a/qtxdg/xdgdesktopfile.cpp +++ b/qtxdg/xdgdesktopfile.cpp @@ -66,6 +66,7 @@ static const QStringList nonDetachExecs = QStringList() static const QLatin1String onlyShowInKey("OnlyShowIn"); static const QLatin1String notShowInKey("NotShowIn"); static const QLatin1String categoriesKey("Categories"); +static const QLatin1String actionsKey("Actions"); static const QLatin1String extendPrefixKey("X-"); static const QLatin1String mimeTypeKey("MimeType"); static const QLatin1String applicationsStr("applications"); @@ -274,14 +275,37 @@ QString &unEscapeExec(QString& str) return doUnEscape(str, repl); } +namespace +{ + /*! + * Helper class for getting the keys for "Additional applications actions" + * ([Desktop Action %s] sections) + */ + class XdgDesktopAction : public XdgDesktopFile + { + public: + XdgDesktopAction(const XdgDesktopFile & parent, const QString & action) + : XdgDesktopFile(parent) + , m_prefix(QString{QLatin1String("Desktop Action %1")}.arg(action)) + {} + + protected: + virtual QString prefix() const { return m_prefix; } + + private: + const QString m_prefix; + }; +} + class XdgDesktopFileData: public QSharedData { public: XdgDesktopFileData(); bool read(const QString &prefix); XdgDesktopFile::Type detectType(XdgDesktopFile *q) const; - bool startApplicationDetached(const XdgDesktopFile *q, const QStringList& urls) const; + bool startApplicationDetached(const XdgDesktopFile *q, const QString & action, const QStringList& urls) const; bool startLinkDetached(const XdgDesktopFile *q) const; - bool startByDBus(const QStringList& urls) const; + bool startByDBus(const QString & action, const QStringList& urls) const; + QStringList getListValue(const XdgDesktopFile * q, const QString & key, bool tryExtendPrefix) const; QString mFileName; bool mIsValid; @@ -365,7 +389,7 @@ XdgDesktopFile::Type XdgDesktopFileData::detectType(XdgDesktopFile *q) const return XdgDesktopFile::UnknownType; } -bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const QStringList& urls) const +bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const QString & action, const QStringList& urls) const { //DBusActivatable handling if (q->value(QLatin1String("DBusActivatable"), false).toBool()) { @@ -390,10 +414,12 @@ bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const * We consider that this violation is more acceptable than an failure * in launching an application. */ - if (startByDBus(urls)) + if (startByDBus(action, urls)) return true; } - QStringList args = q->expandExecString(urls); + QStringList args = action.isEmpty() + ? q->expandExecString(urls) + : XdgDesktopAction{*q, action}.expandExecString(urls); if (args.isEmpty()) return false; @@ -481,8 +507,7 @@ bool XdgDesktopFileData::startLinkDetached(const XdgDesktopFile *q) const return false; } -// TODO: Handle ActivateAction -bool XdgDesktopFileData::startByDBus(const QStringList& urls) const +bool XdgDesktopFileData::startByDBus(const QString & action, const QStringList& urls) const { QFileInfo f(mFileName); QString path(f.completeBaseName()); @@ -509,7 +534,13 @@ bool XdgDesktopFileData::startByDBus(const QStringList& urls) const << ", but trying to continue..."; } QDBusMessage reply; - if (urls.isEmpty()) + if (!action.isEmpty()) + { + QList v_urls; + for (const auto & url : urls) + v_urls.append(url); + reply = app.call(QLatin1String("ActivateAction"), action, v_urls, platformData); + } else if (urls.isEmpty()) reply = app.call(QLatin1String("Activate"), platformData); else reply = app.call(QLatin1String("Open"), urls, platformData); @@ -517,6 +548,19 @@ bool XdgDesktopFileData::startByDBus(const QStringList& urls) const return QDBusMessage::ErrorMessage != reply.type(); } +QStringList XdgDesktopFileData::getListValue(const XdgDesktopFile * q, const QString & key, bool tryExtendPrefix) const +{ + QString used_key = key; + if (!q->contains(used_key) && tryExtendPrefix) + { + used_key = extendPrefixKey + key; + if (!q->contains(used_key)) + return QStringList(); + } + + return q->value(key).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); +} + XdgDesktopFile::XdgDesktopFile(): d(new XdgDesktopFileData) @@ -750,22 +794,13 @@ QVariant XdgDesktopFile::localizedValue(const QString& key, const QVariant& defa QStringList XdgDesktopFile::categories() const { - QString key; - if (contains(categoriesKey)) - { - key = categoriesKey; - } - else - { - key = extendPrefixKey + categoriesKey; - if (!contains(key)) - return QStringList(); - } - - QStringList cats = value(key).toString().split(QLatin1Char(';')); - return cats; + return d->getListValue(this, categoriesKey, true); } +QStringList XdgDesktopFile::actions() const +{ + return d->getListValue(this, actionsKey, false); +} void XdgDesktopFile::removeEntry(const QString& key) { @@ -806,18 +841,41 @@ QIcon const XdgDesktopFile::icon(const QIcon& fallback) const } +QIcon const XdgDesktopFile::actionIcon(const QString & action, const QIcon& fallback) const +{ + return d->mType == ApplicationType + ? XdgDesktopAction{*this, action}.icon(icon(fallback)) + : fallback; +} + + QString const XdgDesktopFile::iconName() const { return value(iconKey).toString(); } +QString const XdgDesktopFile::actionIconName(const QString & action) const +{ + return d->mType == ApplicationType + ? XdgDesktopAction{*this, action}.iconName() + : QString{}; +} + + QStringList XdgDesktopFile::mimeTypes() const { return value(mimeTypeKey).toString().split(QLatin1Char(';'), QString::SkipEmptyParts); } +QString XdgDesktopFile::actionName(const QString & action) const +{ + return d->mType == ApplicationType + ? XdgDesktopAction{*this, action}.name() + : QString{}; +} + XdgDesktopFile::Type XdgDesktopFile::type() const { return d->mType; @@ -839,7 +897,7 @@ bool XdgDesktopFile::startDetached(const QStringList& urls) const switch(d->mType) { case ApplicationType: - return d->startApplicationDetached(this, urls); + return d->startApplicationDetached(this, QString{}, urls); break; case LinkType: @@ -851,6 +909,11 @@ bool XdgDesktopFile::startDetached(const QStringList& urls) const } } +bool XdgDesktopFile::actionActivate(const QString & action, const QStringList& urls) const +{ + return d->mType == ApplicationType ? d->startApplicationDetached(this, action, urls) : false; +} + /************************************************ This is an overloaded function. @@ -1396,7 +1459,7 @@ bool readDesktopFile(QIODevice & device, QSettings::SettingsMap & map) if (value.contains(QLatin1Char(';'))) { - map.insert(key, value.split(QLatin1Char(';'))); + map.insert(key, value.split(QLatin1Char(';'), QString::SkipEmptyParts)); } else { @@ -1418,7 +1481,10 @@ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map) for (auto it = map.constBegin(); it != map.constEnd(); ++it) { - if (! it.value().canConvert()) + bool isString = it.value().canConvert(); + bool isStringList = (it.value().type() == QVariant::StringList); + + if ((! isString) && (! isStringList)) { return false; } @@ -1444,7 +1510,21 @@ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map) return false; } - stream << remainingKey << QLatin1Char('=') << it.value().toString() << QLatin1Char('\n'); + stream << remainingKey << QLatin1Char('='); + + if (isString) + { + stream << it.value().toString() << QLatin1Char(';'); + } + else /* if (isStringList) */ + { + for (const QString &value: it.value().toStringList()) + { + stream << value << QLatin1Char(';'); + } + } + + stream << QLatin1Char('\n'); } @@ -1612,13 +1692,22 @@ QList XdgDesktopFileCache::getApps(const QString& mimetype) XdgDesktopFile* XdgDesktopFileCache::getDefaultApp(const QString& mimetype) { - // First, we look in ~/.local/share/applications/mimeapps.list, /usr/local/share/applications/mimeapps.list and - // /usr/share/applications/mimeapps.list (in that order) for a default. - QStringList dataDirs = XdgDirs::dataDirs(); - dataDirs.prepend(XdgDirs::dataHome(false)); - for (const QString &dataDir : const_cast(dataDirs)) + // First, we look in following places for a default in specified order: + // ~/.config/mimeapps.list + // /etc/xdg/mimeapps.list + // ~/.local/share/applications/mimeapps.list + // /usr/local/share/applications/mimeapps.list + // /usr/share/applications/mimeapps.list + QStringList mimeDirsList; + + mimeDirsList.append(XdgDirs::configHome(false)); + mimeDirsList.append(XdgDirs::configDirs()); + mimeDirsList.append(XdgDirs::dataHome(false) + QLatin1String("/applications")); + mimeDirsList.append(XdgDirs::dataDirs(QLatin1String("/applications"))); + + for (const QString &mimeDir : const_cast(mimeDirsList)) { - QString defaultsListPath = dataDir + QLatin1String("/applications/mimeapps.list"); + QString defaultsListPath = mimeDir + QLatin1String("/mimeapps.list"); if (QFileInfo::exists(defaultsListPath)) { QSettings defaults(defaultsListPath, desktopFileSettingsFormat()); diff --git a/qtxdg/xdgdesktopfile.h b/qtxdg/xdgdesktopfile.h index 63c0994..a1d7533 100644 --- a/qtxdg/xdgdesktopfile.h +++ b/qtxdg/xdgdesktopfile.h @@ -130,6 +130,9 @@ public: //! Returns the entry Categories. It supports X-Categories extensions. QStringList categories() const; + //! Returns list of values in entry Actions. + QStringList actions() const; + //! Returns true if there exists a setting called key; returns false otherwise. bool contains(const QString& key) const; @@ -142,9 +145,13 @@ public: //! Returns an icon specified in this file. QIcon const icon(const QIcon& fallback = QIcon()) const; + //! Returns an icon for application action \param action. + QIcon const actionIcon(const QString & action, const QIcon& fallback = QIcon()) const; //! Returns an icon name specified in this file. QString const iconName() const; + //! Returns an icon name for application action \param action. + QString const actionIconName(const QString & action) const; //! Returns an list of mimetypes specified in this file. /*! @return Returns a list of the "MimeType=" entries. @@ -155,6 +162,8 @@ public: //! This function is provided for convenience. It's equivalent to calling localizedValue("Name").toString(). QString name() const { return localizedValue(QLatin1String("Name")).toString(); } + //! Returns an (localized) name for application action \param action. + QString actionName(const QString & action) const; //! This function is provided for convenience. It's equivalent to calling localizedValue("Comment").toString(). QString comment() const { return localizedValue(QLatin1String("Comment")).toString(); } @@ -175,6 +184,19 @@ public: //! This function is provided for convenience. It's equivalent to calling startDetached(QStringList(url)). bool startDetached(const QString& url = QString()) const; + /*! For file with Application type. Activates action defined by the \param action. Action is activated + * either with the [Desktop Action %s]/Exec or by the D-Bus if the [Desktop Entry]/DBusActivatable is set. + * \note Starting is done the same way as \sa startDetached() + * + * \return true on success; otherwise returns false. + * \param urls - A list of files or URLS. Each file is passed as a separate argument to the executable program. + * + * For file with Link type, do nothing. + * + * For file with Directory type, do nothing. + */ + bool actionActivate(const QString & action, const QStringList & urls) const; + /*! A Exec value consists of an executable program optionally followed by one or more arguments. This function expands this arguments and returns command line string parts. Note this method make sense only for Application type. From 57af3ec7f03d63f835e7eb0d46cc3e424a05f642 Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Fri, 27 Oct 2017 19:13:12 +0200 Subject: [PATCH 13/14] Pick up Qt 5.9.2 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index d6cf8a2..2b3c874 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +libqtxdg (3.1.0-2) experimental; urgency=medium + + * Pick up Qt 5.9.2 + + -- Alf Gaida Fri, 27 Oct 2017 19:11:33 +0200 + libqtxdg (3.1.0-1) experimental; urgency=medium * Cherry-picked new upstream-release 3.1.0 From 79ea5ca2dd89263603e0c8ea1f974b0d1f1e7e60 Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Thu, 30 Nov 2017 21:26:52 +0100 Subject: [PATCH 14/14] Some cleanup * Removed superfluous line from symbols * Removed trailing whitespaces from changelog --- debian/changelog | 11 +++++++++-- debian/libqt5xdgiconloader3.symbols | 1 - 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 2b3c874..d57866b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,13 @@ +libqtxdg (3.1.0-3) experimental; urgency=medium + + * Removed superfluous line from symbols + * Removed trailing whitespaces from changelog + + -- Alf Gaida Thu, 30 Nov 2017 21:26:44 +0100 + libqtxdg (3.1.0-2) experimental; urgency=medium - * Pick up Qt 5.9.2 + * Pick up Qt 5.9.2 -- Alf Gaida Fri, 27 Oct 2017 19:11:33 +0200 @@ -8,7 +15,7 @@ libqtxdg (3.1.0-1) experimental; urgency=medium * Cherry-picked new upstream-release 3.1.0 * Added lintian-overrides for tools package - * Added new symbols for action handling + * Added new symbols for action handling -- Alf Gaida Sun, 22 Oct 2017 13:53:34 +0200 diff --git a/debian/libqt5xdgiconloader3.symbols b/debian/libqt5xdgiconloader3.symbols index 4002b51..1581f1c 100644 --- a/debian/libqt5xdgiconloader3.symbols +++ b/debian/libqt5xdgiconloader3.symbols @@ -21,4 +21,3 @@ libQt5XdgIconLoader.so.3 libqt5xdgiconloader3 #MINVER# (c++)"typeinfo for XdgIconLoaderEngine@Base" 2.0.0 (c++)"typeinfo name for XdgIconLoaderEngine@Base" 2.0.0 (c++)"vtable for XdgIconLoaderEngine@Base" 2.0.0 -libQt5XdgIconLoader.so.3 libqt5xdgiconloader3 #MINVER#