From 4865e7f1d799ce331c0a6ea6c1d2faa03018ecb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrew=20Lee=20=28=E6=9D=8E=E5=81=A5=E7=A7=8B=29?= Date: Fri, 14 Aug 2015 04:07:03 +0800 Subject: [PATCH] Merging upstream version 1.2.0+20150807. --- CMakeLists.txt | 364 +++++--------- README | 28 +- cmake/FindLibMagic.cmake | 23 - cmake/FindLibSuffix.cmake | 26 - cmake/compiler_settings.cmake | 94 ++++ cmake/create_pkgconfig_file.cmake | 271 ++++++++-- cmake/create_portable_headers.cmake | 76 ++- cmake/qt5xdg-config.cmake.in | 60 +-- cmake/qt5xdg_use.cmake | 23 - cmake/qtxdg-config.cmake.in | 53 -- cmake/qtxdg_use.cmake | 42 -- desktopenvironment_p.cpp | 27 + examples/use-qtxdg/CMakeLists.txt | 18 +- examples/use-qtxdg/README | 11 +- qiconfix/qiconloader.cpp | 181 ++++--- qiconfix/qiconloader_p.h | 18 +- qiconfix/qiconloader_p_qt4.h | 216 -------- qiconfix/qiconloader_qt4.cpp | 737 ---------------------------- test/CMakeLists.txt | 59 +-- test/qtxdg_test.cpp | 30 ++ test/qtxdg_test.h | 30 ++ test/tst_xdgdirs.cpp | 227 +++++++++ xdgaction.cpp | 33 -- xdgdesktopfile.cpp | 201 +------- xdgdesktopfile.h | 5 +- xdgdesktopfile_p.h | 28 ++ xdgdirs.cpp | 142 +----- xdgdirs.h | 2 - xdgicon.cpp | 24 - xdgicon.h | 2 - xdgmacros.h | 8 +- xdgmenu.cpp | 100 +--- xdgmenu.h | 3 - xdgmenu_p.h | 2 - xdgmenuapplinkprocessor.cpp | 22 - xdgmenuapplinkprocessor.h | 3 +- xdgmenulayoutprocessor.cpp | 19 - xdgmenulayoutprocessor.h | 1 - xdgmenureader.cpp | 18 - xdgmenureader.h | 2 +- xdgmenurules.cpp | 54 -- xdgmenurules.h | 1 + xdgmenuwidget.cpp | 36 +- xdgmenuwidget.h | 1 - xdgmime.cpp | 366 -------------- xdgmime.h | 99 ---- xdgmimetype.cpp | 10 + xdgmimetype.h | 3 - 48 files changed, 1093 insertions(+), 2706 deletions(-) delete mode 100644 cmake/FindLibMagic.cmake delete mode 100644 cmake/FindLibSuffix.cmake create mode 100644 cmake/compiler_settings.cmake delete mode 100644 cmake/qt5xdg_use.cmake delete mode 100644 cmake/qtxdg-config.cmake.in delete mode 100644 cmake/qtxdg_use.cmake delete mode 100644 qiconfix/qiconloader_p_qt4.h delete mode 100644 qiconfix/qiconloader_qt4.cpp create mode 100644 test/tst_xdgdirs.cpp delete mode 100644 xdgmime.cpp delete mode 100644 xdgmime.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 95266aa..7422650 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,113 +1,48 @@ -cmake_minimum_required( VERSION 2.8.5 ) - +cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) project(libqtxdg) -# Support different versions of Qt -option(USE_QT4 "Build with Qt4." $ENV{USE_QT4}) option(BUILD_TESTS "Builds tests" OFF) -if (USE_QT4) - set(USE_QT5 FALSE) -else() - set(USE_QT5 TRUE) -endif() - -# The Qt4 version can be compiled with libmagic or with QtMimeTypes -# QtMimeTypes is the preferred way and also the default. libmagic will be -# dropped in future releases. -if (NOT USE_QT5) - option(USE_QTMIMETYPES "Use QtMimeTypes library" ON) -endif() - -# Standard directories for installation -include(GNUInstallDirs) - # additional cmake files set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -set (MAJOR_VERSION 1) -set (MINOR_VERSION 2) -set (PATCH_VERSION 0) -set(QTXDG_VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}) - -add_definitions(-Wall -DQTXDG_COMPILATION=1) +set(QTXDG_MAJOR_VERSION 1) +set(QTXDG_MINOR_VERSION 2) +set(QTXDG_PATCH_VERSION 0) +set(QTXDG_VERSION_STRING ${QTXDG_MAJOR_VERSION}.${QTXDG_MINOR_VERSION}.${QTXDG_PATCH_VERSION}) -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(QTXDG_COMPILER_IS_CLANGCXX 1) -endif() +include(GNUInstallDirs) # Standard directories for installation +include(CMakePackageConfigHelpers) +include(create_portable_headers) +include(create_pkgconfig_file) +include(compiler_settings NO_POLICY_SCOPE) -if (CMAKE_COMPILER_IS_GNUCXX OR QTXDG_COMPILER_IS_CLANGCXX) - # set visibility to hidden to hide symbols, unless they're exported manually in the code - set(CMAKE_CXX_FLAGS "-fvisibility=hidden -fvisibility-inlines-hidden -fno-exceptions ${CMAKE_CXX_FLAGS}") +find_package(Qt5Widgets REQUIRED QUIET) +find_package(Qt5Xml REQUIRED QUIET) +find_package(Qt5DBus REQUIRED QUIET) +if (BUILD_TESTS) + find_package(Qt5Test REQUIRED QUIET) endif() -find_package(PkgConfig) -if (USE_QT5) - cmake_minimum_required(VERSION 2.8.11) - find_package(Qt5Widgets REQUIRED QUIET) - find_package(Qt5Xml REQUIRED QUIET) - find_package(Qt5DBus REQUIRED QUIET) - if (BUILD_TESTS) - find_package(Qt5Test REQUIRED QUIET) - endif() +set(QTXDGX_LIBRARY_NAME "Qt5Xdg") +set(QTXDGX_FILE_NAME "qt5xdg") - # if both Qt4 and Qt5 are installed we must check what version was found - if (NOT ${Qt5Core_VERSION_MAJOR} EQUAL 5) - message(FATAL_ERROR "Qt was found, but NOT Qt5.") - endif() +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_LIBRARY_NAME "Qt5Xdg") - set(QTXDGX_FILE_NAME "qt5xdg") +include_directories( + "${Qt5Gui_PRIVATE_INCLUDE_DIRS}" +) - set(QTXDGX_PKG_CONFIG_DESCRIPTION "Qt5Xdg, a Qt5 implementation of XDG standards") - set(QTXDGX_PKG_CONFIG_REQUIRES "Qt5Core, Qt5Xml, Qt5Widgets, Qt5DBus") +set(QTX_LIBRARIES Qt5::Widgets Qt5::Xml Qt5::DBus) - include_directories( - "${Qt5Widgets_INCLUDE_DIRS}" - "${Qt5Gui_PRIVATE_INCLUDE_DIRS}" - "${Qt5Xml_INCLUDE_DIRS}" - ) - add_definitions(${Qt5Core_DEFINITIONS}) -# set(CMAKE_CXX_FLAGS -# "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}" -# ) - - # QMimeDatabase and QMimeType are part of Qt5Core - # We just use that as an mimetype provider. - # An empty MIMETYPES_PROVIDER_LIBRARY means we are using Qt internal - # mimetypes support - set(MIMETYPES_PROVIDER_LIBRARY "") - add_definitions("-DHAVE_QTMIMETYPES") - - set(QTX_LIBRARIES ${Qt5Widgets_LIBRARIES} ${Qt5Xml_LIBRARIES} ${Qt5DBus_LIBRARIES}) - message(STATUS "Building with Qt ${Qt5Core_VERSION_STRING}") -else() - find_package(Qt4 REQUIRED QtCore QtGui QtXml QtDBus QUIET) - if (BUILD_TESTS) - find_package(Qt4 REQUIRED QtTest QUIET) - endif() - - # if both Qt4 and Qt5 are installed we must check what version was found - if (NOT ${QT_VERSION_MAJOR} EQUAL 4) - message(FATAL_ERROR "Qt was found, but NOT Qt4") - endif() - - set(QTXDGX_LIBRARY_NAME "qtxdg") - set(QTXDGX_FILE_NAME "qtxdg") - - set(QTXDGX_PKG_CONFIG_DESCRIPTION "QtXdg, a Qt4 implementation of XDG standards") - - include(${QT_USE_FILE}) - set(QTX_LIBRARIES - ${QT_QTCORE_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${QT_QTXML_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ) - message(STATUS "Building with Qt ${QTVERSION}") -endif() +if (NOT CMAKE_BUILD_TYPE) + set ( CMAKE_BUILD_TYPE Release ) +endif (NOT CMAKE_BUILD_TYPE) +message(STATUS "Building with Qt ${Qt5Core_VERSION_STRING}") set(libqtxdg_PUBLIC_H_FILES xdgaction.h @@ -119,6 +54,7 @@ set(libqtxdg_PUBLIC_H_FILES xmlhelper.h xdgautostart.h xdgmacros.h + xdgmimetype.h ) set(libqtxdg_PUBLIC_CLASSES @@ -130,6 +66,7 @@ set(libqtxdg_PUBLIC_CLASSES XdgMenuWidget XmlHelper XdgAutoStart + XdgMimeType ) set(libqtxdg_PRIVATE_H_FILES @@ -154,6 +91,8 @@ set(libqtxdg_CPP_FILES xdgmenuwidget.cpp xmlhelper.cpp xdgautostart.cpp + xdgmimetype.cpp + qiconfix/qiconloader.cpp ) set(libqtxdg_MOCS @@ -166,114 +105,11 @@ set(libqtxdg_MOCS xdgmenuwidget.h ) -if (USE_QT5) - list(APPEND libqtxdg_PRIVATE_INSTALLABLE_H_FILES qiconfix/qiconloader_p.h) - list(APPEND libqtxdg_CPP_FILES qiconfix/qiconloader.cpp) -else() - list(APPEND libqtxdg_PRIVATE_H_FILES qiconfix/qiconloader_p_qt4.h) - list(APPEND libqtxdg_CPP_FILES qiconfix/qiconloader_qt4.cpp) -endif() - -if (NOT USE_QT5) - if (USE_QTMIMETYPES) - # Using QtMimeTypes to provide a better mimetype support on Qt4 - # Project repo: https://qt.gitorious.org/qtplayground/mimetypes - pkg_check_modules(QTMIMETYPES REQUIRED - QtMimeTypes - ) - include_directories("${QTMIMETYPES_INCLUDE_DIRS}") - set(QTXDGX_PKG_CONFIG_REQUIRES "QtCore, QtXml, QtDbus, QtMimeTypes") - set(MIMETYPES_PROVIDER_LIBRARY ${QTMIMETYPES_LIBRARIES}) - link_directories("${QTMIMETYPES_LIBRARY_DIRS}") - add_definitions("-DHAVE_QTMIMETYPES") - else() - # Use libmagic - find_package(LibMagic REQUIRED QUIET) - set(MIMETYPES_PROVIDER_LIBRARY ${LIBMAGIC_LIBRARY}) - set(QTXDGX_PKG_CONFIG_REQUIRES "QtCore, QtXml, QtDBus") - - list(APPEND libqtxdg_PUBLIC_H_FILES xdgmime.h) - list(APPEND libqtxdg_PUBLIC_CLASSES XdgMime) - list(APPEND libqtxdg_CPP_FILES xdgmime.cpp) - endif() -endif() - -if (USE_QTMIMETYPES OR USE_QT5) - list(APPEND libqtxdg_PUBLIC_H_FILES xdgmimetype.h) - list(APPEND libqtxdg_PUBLIC_CLASSES XdgMimeType) - list(APPEND libqtxdg_CPP_FILES xdgmimetype.cpp) -endif() - - -set(APP_SHARE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/lib${QTXDGX_FILE_NAME}") -add_definitions(-DTRANSLATIONS_DIR=\"${APP_SHARE_DIR}\") - - -#************************************************ -# Build 2 config.cmake files -# One for in-tree build and second for normal one. -#************************************************ -set(QTXDG_MAJOR_VERSION ${MAJOR_VERSION}) -set(QTXDG_MINOR_VERSION ${MINOR_VERSION}) -set(QTXDG_PATCH_VERSION ${PATCH_VERSION}) - -# In tree compilation ...................... -set(QTXDG_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_BINARY_DIR}") - -if (USE_QT5) - set(QTXDG_PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/qiconfix") - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/qt5xdg-config.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake/${QTXDGX_FILE_NAME}-config.cmake" - @ONLY - ) -else() - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/qtxdg-config.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake/${QTXDGX_FILE_NAME}-config.cmake" - @ONLY - ) -endif() - -configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/${QTXDGX_FILE_NAME}_use.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/cmake/${QTXDGX_FILE_NAME}_use.cmake" - @ONLY +set(libqtxdg_PRIVATE_INSTALLABLE_H_FILES + qiconfix/qiconloader_p.h ) -# Instalable ............................... -set(QTXDG_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_FILE_NAME}") - -if (USE_QT5) - set(QTXDG_PRIVATE_INCLUDE_DIR "${QTXDG_INCLUDE_DIR}/${QTXDG_VERSION_STRING}") - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/qt5xdg-config.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/${QTXDGX_FILE_NAME}-config.cmake" - @ONLY - ) -else() - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/qtxdg-config.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/${QTXDGX_FILE_NAME}-config.cmake" - @ONLY - ) -endif() - -#********************************************************** - -include(FindLibSuffix) - -if(USE_QT5) - QT5_WRAP_CPP(libqtxdg_CXX_FILES ${libqtxdg_MOCS}) -else() - QT4_WRAP_CPP(libqtxdg_CXX_FILES ${libqtxdg_MOCS}) -endif() - - -if (NOT CMAKE_BUILD_TYPE) - set ( CMAKE_BUILD_TYPE Release ) -endif (NOT CMAKE_BUILD_TYPE) - +QT5_WRAP_CPP(libqtxdg_CXX_FILES ${libqtxdg_MOCS}) add_library(${QTXDGX_LIBRARY_NAME} SHARED ${libqtxdg_PUBLIC_H_FILES} @@ -286,46 +122,118 @@ add_library(${QTXDGX_LIBRARY_NAME} SHARED target_link_libraries(${QTXDGX_LIBRARY_NAME} - ${QTX_LIBRARIES} - ${MIMETYPES_PROVIDER_LIBRARY} + PUBLIC + ${QTX_LIBRARIES} ) set_target_properties(${QTXDGX_LIBRARY_NAME} PROPERTIES - VERSION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION} - SOVERSION ${MAJOR_VERSION} + VERSION ${QTXDG_VERSION_STRING} + SOVERSION ${QTXDG_MAJOR_VERSION} ) -# create the portable headers -include(create_portable_headers) -create_portable_headers(libqtxdg_PORTABLE_HEADERS ${libqtxdg_PUBLIC_CLASSES}) +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}" +) -install(TARGETS ${QTXDGX_LIBRARY_NAME} DESTINATION "${CMAKE_INSTALL_LIBDIR}") -install(FILES ${libqtxdg_PUBLIC_H_FILES} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_FILE_NAME}") +write_basic_package_version_file( + "${CMAKE_BINARY_DIR}/${QTXDGX_FILE_NAME}-config-version.cmake" + VERSION ${QTXDG_VERSION_STRING} + COMPATIBILITY AnyNewerVersion +) -if (USE_QT5) - install(FILES - ${libqtxdg_PRIVATE_INSTALLABLE_H_FILES} - DESTINATION - "${QTXDG_PRIVATE_INCLUDE_DIR}/private/qtxdg" - ) -endif() +create_pkgconfig_file( + PACKAGE_NAME ${QTXDGX_LIBRARY_NAME} + DESCRIPTIVE_NAME ${QTXDGX_LIBRARY_NAME} + DESCRIPTION ${QTXDGX_PKG_CONFIG_DESCRIPTION} + INCLUDEDIRS ${QTXDGX_FILE_NAME} + LIBS ${QTXDGX_LIBRARY_NAME} + REQUIRES ${QTXDGX_PKG_CONFIG_REQUIRES} + VERSION ${QTXDG_VERSION_STRING} + INSTALL +) + +target_compile_definitions(${QTXDGX_LIBRARY_NAME} + PRIVATE "QTXDG_COMPILATION=\"1\"" +) -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${QTXDGX_FILE_NAME}-config.cmake" DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTXDGX_FILE_NAME}") -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/${QTXDGX_FILE_NAME}_use.cmake" DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTXDGX_FILE_NAME}") -install(FILES ${libqtxdg_PORTABLE_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_FILE_NAME}") +target_include_directories(${QTXDGX_LIBRARY_NAME} + INTERFACE "$" + INTERFACE "$" + INTERFACE "$" +) -include(create_pkgconfig_file) -create_pkgconfig_file(${QTXDGX_LIBRARY_NAME} - ${QTXDGX_PKG_CONFIG_DESCRIPTION} - ${QTXDGX_PKG_CONFIG_REQUIRES} - ${QTXDGX_FILE_NAME} - ${QTXDG_VERSION_STRING} +# 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 ) +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 + "${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_PORTABLE_HEADERS} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_FILE_NAME}" + COMPONENT Devel +) if(BUILD_TESTS) enable_testing() - add_definitions(-DQTXDG_TESTS=1) + target_compile_definitions(${QTXDGX_LIBRARY_NAME} + PRIVATE "QTXDG_TESTS=\"1\"" + ) add_subdirectory(test) else() message(STATUS "") @@ -345,9 +253,9 @@ add_custom_target(uninstall # building tarball with CPack ------------------------------------------------- include (InstallRequiredSystemLibraries) -set (CPACK_PACKAGE_VERSION_MAJOR ${MAJOR_VERSION}) -set (CPACK_PACKAGE_VERSION_MINOR ${MINOR_VERSION}) -set (CPACK_PACKAGE_VERSION_PATCH ${PATCH_VERSION}) +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) diff --git a/README b/README index 9302686..4abf265 100644 --- a/README +++ b/README @@ -1,20 +1,11 @@ Overview ======== libqtxdg is An Qt implementation of freedesktop.org xdg specifications. -It can be built with Qt4 and Qt5 +It's built with Qt5. Dependencies ============ -Qt4 build: - Qt4 - libmagic OR QtMimeTypes - -QtMimeTypes the preffered. libmagic is deprecated and may be dropped in future -releases. -QtMimeTypes can be found at: https://qt.gitorious.org/qtplayground/mimetypes - -Qt5 build: Qt5 @@ -24,20 +15,11 @@ libqtxdg uses the CMake build system. Everything that applies to CMake also applies here. Configuration options: - USE_QT5 Builds with Qt5, defaults to then environment variable - with the same name. - - USE_QTMIMETYPES It only affects the Qt4 build. Builds using QtMimeTypes. - Defaults to On. If set to OFF libmagic will be used. - BUILD_TESTS Builds tests, defaults to OFF Configuration Examples: - Build with Qt5 and build self tests: - cmake -DUSE_QT5=ON -DBUILD_TESTS=ON .. - - Build with Qt4 and no tests using QtMimeTypes - cmake -DUSE_QT5=OFF .. + Build library and build self tests: + cmake -DBUILD_TESTS=ON .. - Build with Qt4, no tests and using libmagic - cmake -DUSE_QT5=OFF -DUSE_QTMIMETYPES=OFF .. + Build the library without building self tests + cmake .. diff --git a/cmake/FindLibMagic.cmake b/cmake/FindLibMagic.cmake deleted file mode 100644 index 929226f..0000000 --- a/cmake/FindLibMagic.cmake +++ /dev/null @@ -1,23 +0,0 @@ -FIND_PATH(LIBMAGIC_INCLUDE_DIR magic.h) - -FIND_LIBRARY(LIBMAGIC_LIBRARY NAMES magic) - -IF (LIBMAGIC_INCLUDE_DIR AND LIBMAGIC_LIBRARY) - SET(LIBMAGIC_FOUND TRUE) -ENDIF (LIBMAGIC_INCLUDE_DIR AND LIBMAGIC_LIBRARY) - -IF (LIBMAGIC_FOUND) - IF (NOT LibMagic_FIND_QUIETLY) - MESSAGE(STATUS "Found libmagic: ${LIBMAGIC_LIBRARY}") - MESSAGE(STATUS " includes: ${LIBMAGIC_INCLUDE_DIR}") - ENDIF (NOT LibMagic_FIND_QUIETLY) -ELSE (LIBMAGIC_FOUND) - IF (LibMagic_FIND_REQUIRED) - MESSAGE(STATUS "") - MESSAGE(STATUS "libmagic development package cannot be found. Install it, please") - MESSAGE(STATUS "For example in (open)SUSE it's file-devel package") - MESSAGE(STATUS "") - MESSAGE(FATAL_ERROR "Could not find libmagic") - ENDIF (LibMagic_FIND_REQUIRED) -ENDIF (LIBMAGIC_FOUND) - diff --git a/cmake/FindLibSuffix.cmake b/cmake/FindLibSuffix.cmake deleted file mode 100644 index f7a8c3b..0000000 --- a/cmake/FindLibSuffix.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# some system (rpm builds) setup LIB_SUFFIX for cmake. If there is no set, try to get it from system -IF(NOT DEFINED LIB_SUFFIX AND LIB_SUFFIX_ALREADY_SET) - MESSAGE(STATUS "*********************************************************************") - MESSAGE(STATUS "LIB_SUFFIX variable is not defined. It will be autodetected now") - MESSAGE(STATUS "You can set it manually with -DLIB_SUFFIX= (64 for example)") - - # All 32bit system have empty lib suffix - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - # If there is lib64 dir, set suffix to 64 - if(IS_DIRECTORY "${CMAKE_INSTALL_PREFIX}/lib64") - set(LIB_SUFFIX 64) - elseif(IS_DIRECTORY "${CMAKE_INSTALL_PREFIX}/lib") - set(LIB_SUFFIX "") - else() - message(WARNING "LIB_SUFFIX cannot be autodetected. No \"${CMAKE_INSTALL_PREFIX}/lib\" neither \"${CMAKE_INSTALL_PREFIX}/lib64\" found.") - set(LIB_SUFFIX "") - endif() - else() - set(LIB_SUFFIX "") - endif() - - set(LIB_SUFFIX_ALREADY_SET 1) - - message(STATUS "LIB_SUFFIX autodetected as '${LIB_SUFFIX}', libraries will be installed into \"${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}\"") - MESSAGE(STATUS "*********************************************************************") -ENDIF(NOT DEFINED LIB_SUFFIX AND LIB_SUFFIX_ALREADY_SET) diff --git a/cmake/compiler_settings.cmake b/cmake/compiler_settings.cmake new file mode 100644 index 0000000..da31e77 --- /dev/null +++ b/cmake/compiler_settings.cmake @@ -0,0 +1,94 @@ +#============================================================================= +# Copyright 2015 Luís Pereira +# +# 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 copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +#============================================================================= + +#----------------------------------------------------------------------------- +# Honor visibility properties for all target types. +# +# The ``_VISIBILITY_PRESET`` and +# ``VISIBILITY_INLINES_HIDDEN`` target properties affect visibility +# of symbols during dynamic linking. When first introduced these properties +# affected compilation of sources only in shared libraries, module libraries, +# and executables with the ``ENABLE_EXPORTS`` property set. This +# was sufficient for the basic use cases of shared libraries and executables +# with plugins. However, some sources may be compiled as part of static +# libraries or object libraries and then linked into a shared library later. +# CMake 3.3 and above prefer to honor these properties for sources compiled +# in all target types. This policy preserves compatibility for projects +# expecting the properties to work only for some target types. +# +# The ``OLD`` behavior for this policy is to ignore the visibility properties +# for static libraries, object libraries, and executables without exports. +# The ``NEW`` behavior for this policy is to honor the visibility properties +# for all target types. +# +# This policy was introduced in CMake version 3.3. CMake version +# 3.3.0 warns when the policy is not set and uses ``OLD`` behavior. Use +# the ``cmake_policy()`` command to set it to ``OLD`` or ``NEW`` +# explicitly. +#----------------------------------------------------------------------------- +if(COMMAND CMAKE_POLICY) + if (POLICY CMP0063) + cmake_policy(SET CMP0063 NEW) + endif() +endif() + + +#----------------------------------------------------------------------------- +# Detect Clang compiler +#----------------------------------------------------------------------------- +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set(QTXDG_COMPILER_IS_CLANGCXX 1) +endif() + + +#----------------------------------------------------------------------------- +# Set visibility to hidden to hide symbols, unless they're exported manually +# in the code +#----------------------------------------------------------------------------- +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) + + +#----------------------------------------------------------------------------- +# Disable exceptions +#----------------------------------------------------------------------------- +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") + + +#----------------------------------------------------------------------------- +# Warning flags +#----------------------------------------------------------------------------- +list(APPEND QTXDG_WARNING_FLAGS ${QTXDG_COMMON_WARNING_FLAGS}) +add_definitions(${QTXDG_WARNING_FLAGS}) diff --git a/cmake/create_pkgconfig_file.cmake b/cmake/create_pkgconfig_file.cmake index 92592af..b218cef 100644 --- a/cmake/create_pkgconfig_file.cmake +++ b/cmake/create_pkgconfig_file.cmake @@ -1,36 +1,245 @@ +#============================================================================= +# Copyright 2015 Luís Pereira # -# Write a pkg-config pc file for given "name" with "decription" -# Arguments: -# name: a library name (withoud "lib" prefix and "so" suffixes -# desc: a desription string -# requires: required libraries -# include_rel_dir: include directory, relative to includedir -# version: package version +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: # -macro (create_pkgconfig_file name desc requires include_rel_dir version) - set(_pkgfname "${CMAKE_CURRENT_BINARY_DIR}/${name}.pc") - message(STATUS "${name}: writing pkgconfig file ${_pkgfname}") - - file(WRITE "${_pkgfname}" - "# file generated by razor-qt cmake build\n" - "prefix=${CMAKE_INSTALL_PREFIX}\n" - "libdir=\${prefix}/${CMAKE_INSTALL_LIBDIR}\n" - "includedir=\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}\n" - "\n" - "Name: ${name}\n" - "Description: ${desc}\n" - "Version: ${version}\n" - "Requires: ${requires}\n" - "Libs: -L\${libdir} -l${name}\n" - "Cflags: -I\${includedir} -I\${includedir}/${include_rel_dir}\n" - "\n" - ) +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +#=============================================================================# + +# create_pkgconfig_file(PACKAGE_NAME +# VERSION +# [PREFIX ] +# [EXEC_PREFIX ] +# [INCLUDEDIR_PREFIX ] +# [INCLUDEDIRS ... ] +# [LIBDIR_PREFIX ] +# [DESCRIPTIVE_NAME ] +# [DESCRIPTION ] +# [URL ] +# [REQUIRES ... ] +# [REQUIRES_PRIVATE ... ] +# [LIB_INSTALLDIR ] +# [CFLAGS ] +# [PATH ] +# [INSTALL]) +# +# +# PACKAGE_NAME and VERSION are mandatory. Everything else is optional + +include(CMakeParseArguments) +include(GNUInstallDirs) + +function(create_pkgconfig_file) + set(options INSTALL) + set(oneValueArgs + PACKAGE_NAME + PREFIX + EXEC_PREFIX + INCLUDEDIR_PREFIX + LIBDIR_PREFIX + DESCRIPTIVE_NAME + DESCRIPTION + URL + VERSION + PATH + ) + set(multiValueArgs + INCLUDEDIRS + REQUIRES + REQUIRES_PRIVATE + CONFLICTS + CFLAGS + LIBS + LIBS_PRIVATE + ) + + cmake_parse_arguments(USER "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (USER_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown keywords given to create_pkgconfig_file(): \"${USER_UNPARSED_ARGUMENTS}\"") + endif() - # FreeBSD loves to install files to different locations - # http://www.freebsd.org/doc/handbook/dirstructure.html - if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") - install(FILES ${_pkgfname} DESTINATION libdata/pkgconfig) + # Check for mandatory args. Abort if not set + if (NOT DEFINED USER_PACKAGE_NAME) + message(FATAL_ERROR "Required argument PACKAGE_NAME missing in generate_pkgconfig_file() call") else() - install(FILES ${_pkgfname} DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + set(_PKGCONFIG_PACKAGE_NAME "${USER_PACKAGE_NAME}") + endif() + + if (NOT DEFINED USER_VERSION) + message(FATAL_ERROR "Required argument VERSION missing in generate_pkgconfig_file() call") + else() + set(_PKGCONFIG_VERSION "${USER_VERSION}") + endif() + + + # Optional args + if (NOT DEFINED USER_PREFIX) + set(_PKGCONFIG_PREFIX "${CMAKE_INSTALL_PREFIX}") + endif() + + if (NOT DEFINED USER_EXEC_PREFIX) + set(_PKGCONFIG_EXEC_PREFIX "\${prefix}") + endif() + + if (NOT DEFINED USER_INCLUDEDIR_PREFIX) + set(_PKGCONFIG_INCLUDEDIR_PREFIX "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") + endif() + + if (NOT DEFINED USER_LIBDIR_PREFIX) + set(_PKGCONFIG_LIBDIR_PREFIX "\${prefix}/${CMAKE_INSTALL_LIBDIR}") + endif() + + if (NOT DEFINED USER_DESCRIPTIVE_NAME) + set(_PKGCONFIG_DESCRIPTIVE_NAME "") + else() + set(_PKGCONFIG_DESCRIPTIVE_NAME "${USER_DESCRIPTIVE_NAME}") + endif() + + if (DEFINED USER_INCLUDEDIRS) + set(tmp "") + foreach(dir ${USER_INCLUDEDIRS}) + if (NOT IS_ABSOLUTE "${dir}") + list(APPEND tmp "-I\${includedir}/${dir}") + endif() + endforeach() + string(REPLACE ";" " " _INCLUDEDIRS "${tmp}") + endif() + + if (DEFINED USER_REQUIRES) + string(REPLACE ";" ", " _PKGCONFIG_REQUIRES "${USER_REQUIRES}") + endif() + + if (DEFINED USER_REQUIRES_PRIVATE) + string(REPLACE ";" ", " _PKGCONFIG_REQUIRES_PRIVATE "${USER_REQUIRES_PRIVATE}") + else() + set(_PKGCONFIG_REQUIRES_PRIVATE "") + endif() + + if (NOT DEFINED USER_CFLAGS) + set(_PKGCONFIG_CFLAGS "-I\${includedir} ${_INCLUDEDIRS}") + endif() + + if (NOT DEFINED USER_LIBS) + set(_PKGCONFIG_LIBS "-L\${libdir}") + else() + set(tmp "-L\${libdir}") + set(_libs "${USER_LIBS}") + foreach(lib ${_libs}) + list(APPEND tmp "-l${lib}") + endforeach() + string(REPLACE ";" " " _PKGCONFIG_LIBS "${tmp}") + endif() + + if (NOT DEFINED USER_LIBS_PRIVATE) + set(PKGCONFIG_LIBS "-L\${libdir}") + else() + set(tmp "") + set(_libs "${USER_LIBS_PRIVATE}") + foreach(lib ${_libs}) + list(APPEND tmp "-l${lib}") + endforeach() + string(REPLACE ";" " " _PKGCONFIG_LIBS_PRIVATE "${tmp}") + endif() + + if (DEFINED USER_DESCRIPTION) + set(_PKGCONFIG_DESCRIPTION "${USER_DESCRIPTION}") + else() + set(_PKGCONFIG_DESCRIPTION "") + endif() + + if (DEFINED USER_URL) + set(_PKFCONFIG_URL "${USER_URL}") + else() + set(_PKGCONFIG_URL "") + endif() + + if (NOT DEFINED USER_PATH) + set(_PKGCONFIG_FILE "${PROJECT_BINARY_DIR}/${_PKGCONFIG_PACKAGE_NAME}.pc") + else() + if (IS_ABSOLUTE "${USER_PATH}") + set(_PKGCONFIG_FILE "${USER_PATH}/${_PKGCONFIG_PACKAGE_NAME}.pc") + else() + set(_PKGCONFIG_FILE "${PROJECT_BINARY_DIR}/${USER_PATH}/${_PKGCONFIG_PACKAGE_NAME}.pc") + endif() + endif() + + # Write the .pc file + FILE(WRITE "${_PKGCONFIG_FILE}" + "# file generated by create_pkgconfig_file()\n" + "prefix=${_PKGCONFIG_PREFIX}\n" + "exec_prefix=${_PKGCONFIG_EXEC_PREFIX}\n" + "libdir=${_PKGCONFIG_LIBDIR_PREFIX}\n" + "includedir=${_PKGCONFIG_INCLUDEDIR_PREFIX}\n" + "\n" + "Name: ${_PKGCONFIG_DESCRIPTIVE_NAME}\n" + ) + + if (NOT "${_PKGCONFIG_DESCRIPTION}" STREQUAL "") + FILE(APPEND ${_PKGCONFIG_FILE} + "Description: ${_PKGCONFIG_DESCRIPTION}\n" + ) + endif() + + if (NOT "${_PKGCONFIG_URL}" STREQUAL "") + FILE(APPEND ${_PKGCONFIG_FILE} "URL: ${_PKGCONFIG_URL}\n") + endif() + + FILE(APPEND ${_PKGCONFIG_FILE} "Version: ${_PKGCONFIG_VERSION}\n") + + if (NOT "${_PKGCONFIG_REQUIRES}" STREQUAL "") + FILE(APPEND ${_PKGCONFIG_FILE} "Requires: ${_PKGCONFIG_REQUIRES}\n") + endif() + + if (NOT "${_PKGCONFIG_REQUIRES_PRIVATE}" STREQUAL "") + FILE(APPEND ${_PKGCONFIG_FILE} + "Requires.private: ${_PKGCONFIG_REQUIRES_PRIVATE}\n" + ) + endif() + + + FILE(APPEND ${_PKGCONFIG_FILE} + "Cflags: ${_PKGCONFIG_CFLAGS}\n" + "Libs: ${_PKGCONFIG_LIBS}\n" + ) + + if (NOT "${_PKGCONFIG_LIBS_PRIVATE}" STREQUAL "") + FILE(APPEND ${_PKGCONFIG_FILE} + "Libs.private: ${_PKGCONFIG_REQUIRES_PRIVATE}\n" + ) + endif() + + if (DEFINED USER_INSTALL) + # FreeBSD loves to install files to different locations + # http://www.freebsd.org/doc/handbook/dirstructure.html + if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") + set(_PKGCONFIG_INSTALL_DESTINATION "libdata/pkgconfig") + else() + set(_PKGCONFIG_INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + endif() + + # Make the COMPONENT an parameter ? + install(FILES "${_PKGCONFIG_FILE}" + DESTINATION "${_PKGCONFIG_INSTALL_DESTINATION}" + COMPONENT Devel) endif() -endmacro() +endfunction() diff --git a/cmake/create_portable_headers.cmake b/cmake/create_portable_headers.cmake index ac29c84..60a10ef 100644 --- a/cmake/create_portable_headers.cmake +++ b/cmake/create_portable_headers.cmake @@ -1,8 +1,51 @@ +#============================================================================= +# Copyright 2015 Luís Pereira +# +# 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 copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +#============================================================================= + +# create_portable_headers( +# HEADER_NAMES [ [...]] +# [OUTPUT_DIR ] +# ) +# # Creates portable headers; e.g.: # Creates XdgAction from xdgaction.h # XdgAction contents: # #include "xdgaction.h" # +# Output: +# portable_headers File locations of the created headers +# +# Input: +# HEADER_NAMES Header CamelCaseNames. An CamelCaseName header will be created +# that includes camelcasename.h file +# +# OUTPUT_DIR Specifies where the files will be created. Defaults to +# ``${CMAKE_CURRENT_BINARY_DIR}``. If the value is an relative path, it +# will be appended to ``${CMAKE_CURRENT_BINARY_DIR}``. +# # Use: # set(PUBLIC_CLASSES MyClass YourClass) # create_portable_headers(PORTABLE_HEADERS ${PUBLIC_CLASSES}) @@ -11,18 +54,39 @@ function(create_portable_headers outfiles) set(options) - set(oneValueArgs) - set(multiValueArgs) + set(oneValueArgs OUTPUT_DIR) + set(multiValueArgs HEADER_NAMES) + + cmake_parse_arguments(USER "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (USER_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown keywords given to create_portable_headers(): \"${USER_UNPARSED_ARGUMENTS}\"") + endif() + + if (NOT DEFINED USER_HEADER_NAMES) + message(FATAL_ERROR "Required argument HEADER_NAMES missing in create_portable_headers() call") + else() + set(_HEADER_NAMES "${USER_HEADER_NAMES}") + endif() + + if (NOT DEFINED USER_OUTPUT_DIR) + set(_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}") + else() + if (IS_ABSOLUTE "${USER_OUTPUT_DIR}") + set(_OUTPUT_DIR "${USER_OUTPUT_DIR}") + else() + set(_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${USER_OUTPUT_DIR}") + endif() + endif() - cmake_parse_arguments(_CREATE_PORTABLE_HEADERS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - set(class_list ${_CREATE_PORTABLE_HEADERS_UNPARSED_ARGUMENTS}) + set(class_list ${_HEADER_NAMES}) foreach(f ${class_list}) string(TOLOWER "${f}.h" _filename) - file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${f}" + file(WRITE "${_OUTPUT_DIR}/${f}" "#include \"${_filename}\"") - list(APPEND ${outfiles} "${CMAKE_CURRENT_BINARY_DIR}/${f}") + list(APPEND ${outfiles} "${_OUTPUT_DIR}/${f}") endforeach() set(${outfiles} ${${outfiles}} PARENT_SCOPE) diff --git a/cmake/qt5xdg-config.cmake.in b/cmake/qt5xdg-config.cmake.in index 1a338f5..dc312d7 100644 --- a/cmake/qt5xdg-config.cmake.in +++ b/cmake/qt5xdg-config.cmake.in @@ -1,54 +1,12 @@ -# - Find the QtXdg include and library dirs and define a some macros -# -# The module defines the following variables -# QTXDG_FOUND - Set to TRUE if all of the above has been found -# -# QTXDG_INCLUDE_DIR - The QtXdg include directory -# -# QTXDG_INCLUDE_DIRS - The QtXdg lib and it's dependencies include directories -# -# QTXDG_LIBRARY_DIRS - The QtXdg lib and it's dependencies linker search paths -# -# QTXDG_LIBRARY - The QtXdg library itself -# QTXDG_LIBRARIES - The QtXdg library and all it's dependencies -# -# QTXDG_USE_FILE - The variable QTXDG_USE_FILE is set which is the path -# to a CMake file that can be included to compile qtxdg -# applications and libraries. It sets up the compilation -# environment for include directories and populates a -# QTXDG_LIBRARIES variable. -# -# QTXDG_QT_LIBRARIES - The QtXdg Qt dependencies libraries -# -# Typical usage: -# option(USE_QT5 "Build using Qt5. Default off" OFF) -# if (USE_QT5) -# find_package(QT5XDG) -# else() -# find_package(QTXDG) -# endif() -# -# include(${QTXDG_USE_FILE}) -# add_executable(use-qtxdg main.cpp) -# target_link_libraries(use-qtxdg ${QTXDG_LIBRARIES}) +@PACKAGE_INIT@ -set(QTXDG_INCLUDE_DIR "@QTXDG_INCLUDE_DIR@") -set(QTXDG_LIBRARY @QTXDGX_LIBRARY_NAME@) -set(QTXDG_PRIVATE_INCLUDE_DIR "@QTXDG_PRIVATE_INCLUDE_DIR@" CACHE PATH "Qt5Xdg private include dir") +include(CMakeFindDependencyMacro) -set(QTXDG_LIBRARIES ${QTXDG_LIBRARY}) -set(QTXDG_INCLUDE_DIRS "${QTXDG_INCLUDE_DIR}") -set(QTXDG_PRIVATE_INCLUDE_DIRS "${QTXDG_PRIVATE_INCLUDE_DIR}") +find_dependency(Qt5Widgets) +find_dependency(Qt5Xml) +find_dependency(Qt5DBus) -set(QTXDG_LIBRARY_DIRS "@CMAKE_INSTALL_FULL_LIBDIR@") - -set(QTXDG_USE_FILE "${CMAKE_CURRENT_LIST_DIR}/@QTXDGX_FILE_NAME@_use.cmake") -set(QTXDG_FOUND 1) -set(QTXDG_QTMIMETYPES @USE_QTMIMETYPES@) - -set(QTXDG_MAJOR_VERSION @QTXDG_MAJOR_VERSION@) -set(QTXDG_MINOR_VERSION @QTXDG_MINOR_VERSION@) -set(QTXDG_PATCH_VERSION @QTXDG_PATCH_VERSION@) -set(QTXDG_VERSION @QTXDG_MAJOR_VERSION@.@QTXDG_MINOR_VERSION@.@QTXDG_PATCH_VERSION@) - -mark_as_advanced(QTXDG_LIBRARY QTXDG_INCLUDE_DIR QTXDG_PRIVATE_INCLUDE_DIR) +if (CMAKE_VERSION VERSION_GREATER 2.8.12) + cmake_policy(SET CMP0024 OLD) +endif() +include("${CMAKE_CURRENT_LIST_DIR}/qt5xdg-targets.cmake") diff --git a/cmake/qt5xdg_use.cmake b/cmake/qt5xdg_use.cmake deleted file mode 100644 index 1cdb58e..0000000 --- a/cmake/qt5xdg_use.cmake +++ /dev/null @@ -1,23 +0,0 @@ -find_package(Qt5Widgets REQUIRED) -find_package(Qt5Xml REQUIRED) -find_package(Qt5DBus REQUIRED) - -if (QTXDG_QTMIMETYPES) - add_definitions("-DQT_MIMETYPES") -endif() - -add_definitions(${Qt5Core_DEFINITIONS}) -set(CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}" -) -set(QTXDG_QT_LIBRARIES ${Qt5Widgets_LIBRARIES} ${Qt5Xml_LIBRARIES} ${Qt5DBus_LIBRARIES}) -set(QTXDG_LIBRARIES ${QTXDG_LIBRARIES} ${QTXDG_QT_LIBRARIES}) -set(QTXDG_INCLUDE_DIRS - "${QTXDG_INCLUDE_DIRS}" - "${Qt5Widgets_INCLUDE_DIRS}" - "${Qt5Xml_INCLUDE_DIRS}" - "${Qt5DBus_INCLUDE_DIRS}" -) - -link_directories("${QTXDG_LIBRARY_DIRS}") -include_directories("${QTXDG_INCLUDE_DIRS}") diff --git a/cmake/qtxdg-config.cmake.in b/cmake/qtxdg-config.cmake.in deleted file mode 100644 index 33fa866..0000000 --- a/cmake/qtxdg-config.cmake.in +++ /dev/null @@ -1,53 +0,0 @@ -# - Find the QtXdg include and library dirs and define a some macros -# -# The module defines the following variables -# QTXDG_FOUND - Set to TRUE if all of the above has been found -# -# QTXDG_INCLUDE_DIR - The QtXdg include directory -# -# QTXDG_INCLUDE_DIRS - The QtXdg lib and it's dependencies include directories -# -# QTXDG_LIBRARY_DIRS - The QtXdg lib and it's dependencies linker search paths -# -# QTXDG_LIBRARY - The QtXdg library itself -# QTXDG_LIBRARIES - The QtXdg library and all it's dependencies -# -# QTXDG_USE_FILE - The variable QTXDG_USE_FILE is set which is the path -# to a CMake file that can be included to compile qtxdg -# applications and libraries. It sets up the compilation -# environment for include directories and populates a -# QTXDG_LIBRARIES variable. -# -# QTXDG_QT_LIBRARIES - The QtXdg Qt dependencies libraries -# -# Typical usage: -# option(USE_QT5 "Build using Qt5. Default off" OFF) -# if (USE_QT5) -# find_package(QT5XDG) -# else() -# find_package(QTXDG) -# endif() -# -# include(${QTXDG_USE_FILE}) -# add_executable(use-qtxdg main.cpp) -# target_link_libraries(use-qtxdg ${QTXDG_LIBRARIES}) - -set(QTXDG_INCLUDE_DIR "@QTXDG_INCLUDE_DIR@") -set(QTXDG_PRIVATE_INCLUDE_DIR "@QTXDG_PRIVATE_INCLUDE_DIR@") -set(QTXDG_LIBRARY @QTXDGX_LIBRARY_NAME@) - -set(QTXDG_LIBRARIES ${QTXDG_LIBRARY}) -set(QTXDG_INCLUDE_DIRS "${QTXDG_INCLUDE_DIR}") - -set(QTXDG_LIBRARY_DIRS "@CMAKE_INSTALL_FULL_LIBDIR@") - -set(QTXDG_USE_FILE "${CMAKE_CURRENT_LIST_DIR}/@QTXDGX_FILE_NAME@_use.cmake") -set(QTXDG_FOUND 1) -set(QTXDG_QTMIMETYPES @USE_QTMIMETYPES@) - -set(QTXDG_MAJOR_VERSION @QTXDG_MAJOR_VERSION@) -set(QTXDG_MINOR_VERSION @QTXDG_MINOR_VERSION@) -set(QTXDG_PATCH_VERSION @QTXDG_PATCH_VERSION@) -set(QTXDG_VERSION @QTXDG_MAJOR_VERSION@.@QTXDG_MINOR_VERSION@.@QTXDG_PATCH_VERSION@) - -mark_as_advanced(QTXDG_LIBRARY QTXDG_INCLUDE_DIR) diff --git a/cmake/qtxdg_use.cmake b/cmake/qtxdg_use.cmake deleted file mode 100644 index 16d4a6a..0000000 --- a/cmake/qtxdg_use.cmake +++ /dev/null @@ -1,42 +0,0 @@ -# - Find the Razor-qt include and library dirs and define a some macros -# - - -find_package(Qt4 REQUIRED QtCore QtGui QtXml QtDBus QUIET) -include(${QT_USE_FILE}) - -set(QTXDG_QT_LIBRARIES - ${QT_QTCORE_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${QT_QTXML_LIBRARY} - ${QT_DBUS_LIBRARY} -) - -set(QTXDG_LIBRARIES ${QTXDG_LIBRARY} ${QTXDG_QT_LIBRARIES}) - -set(QTXDG_INCLUDE_DIRS - ${QTXDG_INCLUDE_DIRS} - ${QT_QTCORE_INCLUDE_DIR} - ${QT_QTGUI_INCLUDE_DIR} - ${QT_QTXML_INCLUDE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} -) - -set(QTXDG_DEFINITIONS ${QT_DEFINITIONS}) - -if (QTXDG_QTMIMETYPES) - find_package(PkgConfig) - pkg_check_modules(QTMIMETYPES REQUIRED - QtMimeTypes - ) - - set(QTXDG_LIBRARIES ${QTXDG_LIBRARY} ${QTMIMETYPES_LIBRARIES}) - set(QTXDG_LIBRARY_DIRS ${QTXDG_LIBRARY_DIRS} ${QTMIMETYPES_LIBRARY_DIRS}) - set(QTXDG_DEFINITIONS ${QTXDG_DEFINITIONS} "-DQT_MIMETYPES") - include_directories(${QTXDG_INCLUDE_DIR} ${QTMIMETYPES_INCLUDE_DIRS}) - link_directories(${QTXDG_LIBRARY_DIRS}) - add_definitions("-DQT_MIMETYPES") -else() - include_directories(${QTXDG_INCLUDE_DIR} ${QTMIMETYPES_INCLUDE_DIRS}) - link_directories(${QTXDG_LIBRARY_DIRS}) -endif() diff --git a/desktopenvironment_p.cpp b/desktopenvironment_p.cpp index 215560f..38056c0 100644 --- a/desktopenvironment_p.cpp +++ b/desktopenvironment_p.cpp @@ -1,3 +1,30 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * http://lxqt.org + * + * Copyright: 2014 LXQt team + * Authors: + * Luís Pereira + * + * 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 diff --git a/examples/use-qtxdg/CMakeLists.txt b/examples/use-qtxdg/CMakeLists.txt index 0674766..b569ac9 100644 --- a/examples/use-qtxdg/CMakeLists.txt +++ b/examples/use-qtxdg/CMakeLists.txt @@ -1,18 +1,6 @@ project(use-qtxdg) -cmake_minimum_required(VERSION 2.6) - -option(USE_QT5 "Build using Qt5. Default off" OFF) - -if (USE_QT5) - find_package(QT5XDG) -else() - find_package(QTXDG) -endif() - -include(${QTXDG_USE_FILE}) +cmake_minimum_required(VERSION 2.8.12) +find_package(QT5XDG) add_executable(use-qtxdg main.cpp) - -# The QTXDG_QT_LIBRARIES variable contains the needed Qt libraries. They are -# set taking in account the choosed Qt version. -target_link_libraries(use-qtxdg ${QTXDG_QT_LIBRARIES} ${QTXDG_LIBRARIES}) +target_link_libraries(use-qtxdg Qt5Xdg) diff --git a/examples/use-qtxdg/README b/examples/use-qtxdg/README index 9f9d687..dada0aa 100644 --- a/examples/use-qtxdg/README +++ b/examples/use-qtxdg/README @@ -1,9 +1,4 @@ -An example of how to write an CMakeLists.txt to use libqtxdg in a portable -way. +An example of how to write an CMakeLists.txt to use libqtxdg. -Building with Qt4 is the default. Ex: -cmake.. - -To build with Qt5 just pass to set the USE_QT5 to Yes. Ex: - -cmake -DUSE_QT5=On .. +To build this example just use: + cmake .. diff --git a/qiconfix/qiconloader.cpp b/qiconfix/qiconloader.cpp index 5a868c9..8d8fe7e 100644 --- a/qiconfix/qiconloader.cpp +++ b/qiconfix/qiconloader.cpp @@ -176,7 +176,7 @@ QIconTheme::QIconTheme(const QString &themeName) QString themeDir = iconDir.path() + QLatin1Char('/') + themeName; themeIndex.setFileName(themeDir + QLatin1String("/index.theme")); if (themeIndex.exists()) { - m_contentDir = themeDir; + m_contentDirs << themeDir; m_valid = true; QStringList themeSearchPaths = QIcon::themeSearchPaths(); @@ -249,11 +249,11 @@ QIconTheme::QIconTheme(const QString &themeName) #endif //QT_NO_SETTINGS } -QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, +QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName, const QString &iconName, QStringList &visited) const { - QThemeIconEntries entries; + QThemeIconInfo info; Q_ASSERT(!themeName.isEmpty()); QPixmap pixmap; @@ -270,61 +270,111 @@ QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, themeList.insert(themeName, theme); } - QStringList contentDirs = theme.contentDirs(); + const QStringList contentDirs = theme.contentDirs(); const QVector subDirs = theme.keyList(); const QString svgext(QLatin1String(".svg")); const QString pngext(QLatin1String(".png")); const QString xpmext(QLatin1String(".xpm")); - // Add all relevant files - for (int i = 0; i < subDirs.size() ; ++i) { - const QIconDirInfo &dirInfo = subDirs.at(i); - QString subdir = dirInfo.path; - foreach (QString contentDir, contentDirs) { - QDir currentDir(contentDir + '/' + subdir); + QString iconNameFallback = iconName; + + // Iterate through all icon's fallbacks in current theme + while (info.entries.isEmpty()) { + const QString svgIconName = iconNameFallback + svgext; + const QString pngIconName = iconNameFallback + pngext; + const QString xpmIconName = iconNameFallback + xpmext; + + // Add all relevant files + 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); + QString subdir = dirInfo.path; + QDir currentDir(contentDir + subdir); + if (currentDir.exists(pngIconName)) { + PixmapEntry *iconEntry = new PixmapEntry; + iconEntry->dir = dirInfo; + iconEntry->filename = currentDir.filePath(pngIconName); + // 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)) { + 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); + 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; + + iconNameFallback.truncate(indexOfDash); + } + + if (info.entries.isEmpty()) { + const QStringList parents = theme.parents(); + // Search recursively through inherited themes + for (int i = 0 ; i < parents.size() ; ++i) { + + const QString parentTheme = parents.at(i).trimmed(); + + if (!visited.contains(parentTheme)) // guard against recursion + info = findIconHelper(parentTheme, iconName, visited); + + if (!info.entries.isEmpty()) // success + break; + } + } + + 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->dir = dirInfo; iconEntry->filename = currentDir.filePath(iconName + pngext); // Notice we ensure that pixmap entries always come before // scalable to preserve search order afterwards - entries.prepend(iconEntry); + info.entries.prepend(iconEntry); } else if (m_supportsSvg && currentDir.exists(iconName + svgext)) { ScalableEntry *iconEntry = new ScalableEntry; - iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(iconName + svgext); - entries.append(iconEntry); + info.entries.append(iconEntry); break; } 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 - entries.append(iconEntry); + info.entries.append(iconEntry); break; } } } - if (entries.isEmpty()) { - const QStringList parents = theme.parents(); - // Search recursively through inherited themes - for (int i = 0 ; i < parents.size() ; ++i) { - - const QString parentTheme = parents.at(i).trimmed(); - - if (!visited.contains(parentTheme)) // guard against recursion - entries = findIconHelper(parentTheme, iconName, visited); - - if (!entries.isEmpty()) // success - break; - } - } /********************************************************************* Author: Kaitlin Rupert @@ -336,75 +386,46 @@ QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, *********************************************************************/ #ifdef Q_OS_LINUX /* Freedesktop standard says to look in /usr/share/pixmaps last */ - if (entries.isEmpty()) { + if (info.entries.isEmpty()) { const QString pixmaps(QLatin1String("/usr/share/pixmaps")); - QDir currentDir(pixmaps); - QIconDirInfo dirInfo(pixmaps); + const QDir currentDir(pixmaps); + const QIconDirInfo 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 - entries.prepend(iconEntry); + info.entries.prepend(iconEntry); } else if (m_supportsSvg && currentDir.exists(iconName + svgext)) { ScalableEntry *iconEntry = new ScalableEntry; iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(iconName + svgext); - entries.append(iconEntry); + 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 - entries.append(iconEntry); + info.entries.append(iconEntry); } - } #endif - if (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 - entries.prepend(iconEntry); - } else if (m_supportsSvg && - currentDir.exists(iconName + svgext)) { - ScalableEntry *iconEntry = new ScalableEntry; - iconEntry->filename = currentDir.filePath(iconName + svgext); - 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 - entries.append(iconEntry); - break; - } - } - } - return entries; + return info; } -QThemeIconEntries QIconLoader::loadIcon(const QString &name) const +QThemeIconInfo QIconLoader::loadIcon(const QString &name) const { if (!themeName().isEmpty()) { QStringList visited; return findIconHelper(themeName(), name, visited); } - return QThemeIconEntries(); + return QThemeIconInfo(); } @@ -418,7 +439,7 @@ QIconLoaderEngineFixed::QIconLoaderEngineFixed(const QString& iconName) QIconLoaderEngineFixed::~QIconLoaderEngineFixed() { - qDeleteAll(m_entries); + qDeleteAll(m_info.entries); } QIconLoaderEngineFixed::QIconLoaderEngineFixed(const QIconLoaderEngineFixed &other) @@ -446,17 +467,19 @@ bool QIconLoaderEngineFixed::write(QDataStream &out) const bool QIconLoaderEngineFixed::hasIcon() const { - return !(m_entries.isEmpty()); + return !(m_info.entries.isEmpty()); } // Lazily load the icon void QIconLoaderEngineFixed::ensureLoaded() { if (!(QIconLoader::instance()->themeKey() == m_key)) { + qDeleteAll(m_info.entries); + m_info.entries.clear(); + m_info.iconName.clear(); - qDeleteAll(m_entries); - - m_entries = QIconLoader::instance()->loadIcon(m_iconName); + Q_ASSERT(m_info.entries.size() == 0); + m_info = QIconLoader::instance()->loadIcon(m_iconName); m_key = QIconLoader::instance()->themeKey(); } } @@ -526,14 +549,14 @@ QIconLoaderEngineEntry *QIconLoaderEngineFixed::entryForSize(const QSize &size) { int iconsize = qMin(size.width(), size.height()); - // Note that m_entries are sorted so that png-files + // Note that m_info.entries are sorted so that png-files // come first - const int numEntries = m_entries.size(); + const int numEntries = m_info.entries.size(); // Search for exact matches first for (int i = 0; i < numEntries; ++i) { - QIconLoaderEngineEntry *entry = m_entries.at(i); + QIconLoaderEngineEntry *entry = m_info.entries.at(i); if (directoryMatchesSize(entry->dir, iconsize)) { return entry; } @@ -543,7 +566,7 @@ QIconLoaderEngineEntry *QIconLoaderEngineFixed::entryForSize(const QSize &size) int minimalSize = INT_MAX; QIconLoaderEngineEntry *closestMatch = 0; for (int i = 0; i < numEntries; ++i) { - QIconLoaderEngineEntry *entry = m_entries.at(i); + QIconLoaderEngineEntry *entry = m_info.entries.at(i); int distance = directorySizeDistance(entry->dir, iconsize); if (distance < minimalSize) { minimalSize = distance; @@ -647,13 +670,13 @@ void QIconLoaderEngineFixed::virtual_hook(int id, void *data) { QIconEngine::AvailableSizesArgument &arg = *reinterpret_cast(data); - const int N = m_entries.size(); + const int N = m_info.entries.size(); QList sizes; sizes.reserve(N); // Gets all sizes from the DirectoryInfo entries for (int i = 0; i < N; ++i) { - int size = m_entries.at(i)->dir.size; + int size = m_info.entries.at(i)->dir.size; sizes.append(QSize(size, size)); } arg.sizes.swap(sizes); // commit diff --git a/qiconfix/qiconloader_p.h b/qiconfix/qiconloader_p.h index 6610ed4..f3abbb9 100644 --- a/qiconfix/qiconloader_p.h +++ b/qiconfix/qiconloader_p.h @@ -107,6 +107,12 @@ struct PixmapEntry : public QIconLoaderEngineEntry typedef QList QThemeIconEntries; +struct QThemeIconInfo +{ + QThemeIconEntries entries; + QString iconName; +}; + //class QIconLoaderEngine : public QIconEngine class QIconLoaderEngineFixed : public QIconEngine { @@ -128,7 +134,7 @@ private: void virtual_hook(int id, void *data); QIconLoaderEngineEntry *entryForSize(const QSize &size); QIconLoaderEngineFixed(const QIconLoaderEngineFixed &other); - QThemeIconEntries m_entries; + QThemeIconInfo m_info; QString m_iconName; uint m_key; @@ -142,12 +148,10 @@ public: QIconTheme() : m_valid(false) {} QStringList parents() { return m_parents; } QVector keyList() { return m_keyList; } - QString contentDir() { return m_contentDir; } QStringList contentDirs() { return m_contentDirs; } bool isValid() { return m_valid; } private: - QString m_contentDir; QStringList m_contentDirs; QVector m_keyList; QStringList m_parents; @@ -158,7 +162,7 @@ class Q_GUI_EXPORT QIconLoader { public: QIconLoader(); - QThemeIconEntries loadIcon(const QString &iconName) const; + QThemeIconInfo loadIcon(const QString &iconName) const; uint themeKey() const { return m_themeKey; } QString themeName() const { return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme; } @@ -173,9 +177,9 @@ public: void ensureInitialized(); private: - QThemeIconEntries findIconHelper(const QString &themeName, - const QString &iconName, - QStringList &visited) const; + QThemeIconInfo findIconHelper(const QString &themeName, + const QString &iconName, + QStringList &visited) const; uint m_themeKey; bool m_supportsSvg; bool m_initialized; diff --git a/qiconfix/qiconloader_p_qt4.h b/qiconfix/qiconloader_p_qt4.h deleted file mode 100644 index 6147af3..0000000 --- a/qiconfix/qiconloader_p_qt4.h +++ /dev/null @@ -1,216 +0,0 @@ -/* BEGIN_COMMON_COPYRIGHT_HEADER - * (c)LGPL2 - */ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//END_COMMON_COPYRIGHT_HEADER - -/************************************************************************* - It's fixes the following bugs: - * QIcon::fromTheme returns pixmaps that are bigger than requested - https://bugreports.qt.nokia.com/browse/QTBUG-17953 - - * Qt should honor /usr/share/pixmaps as a valid icon directory on Linux - https://bugreports.qt.nokia.com/browse/QTBUG-12874 - - *************************************************************************/ - -#ifndef QDESKTOPICON_P_H -#define QDESKTOPICON_P_H - -#ifndef QT_NO_ICON -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -//#include "qt/qicon_p.h" -//#include "qt/qfactoryloader_p.h" -#include - -namespace QtXdg { - -class QIconLoader; - -struct QIconDirInfo -{ - enum Type { Fixed, Scalable, Threshold }; - QIconDirInfo(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 : 4; -}; - -class QIconLoaderEngineEntry - { -public: - virtual ~QIconLoaderEngineEntry() {} - virtual QPixmap pixmap(const QSize &size, - QIcon::Mode mode, - QIcon::State state) = 0; - QString filename; - QIconDirInfo dir; - static int count; -}; - -struct ScalableEntry : public QIconLoaderEngineEntry -{ - QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); - QIcon svgIcon; -}; - -struct PixmapEntry : public QIconLoaderEngineEntry -{ - QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); - QPixmap basePixmap; -}; - -typedef QList QThemeIconEntries; - -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) -class QIconLoaderEngineFixed : public QIconEngineV2 -#else -class QIconLoaderEngineFixed : public QIconEngine -#endif -{ -public: - QIconLoaderEngineFixed(const QString& iconName = QString()); - ~QIconLoaderEngineFixed(); - - 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); -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - QIconEngineV2 *clone() const; -#else - QIconEngine *clone() const; -#endif - bool read(QDataStream &in); - bool write(QDataStream &out) const; - -private: - QString key() const; - bool hasIcon() const; - void ensureLoaded(); - void virtual_hook(int id, void *data); - QIconLoaderEngineEntry *entryForSize(const QSize &size); - QIconLoaderEngineFixed(const QIconLoaderEngineFixed &other); - QThemeIconEntries m_entries; - QString m_iconName; - uint m_key; - - friend class QIconLoader; -}; - -class QIconTheme -{ -public: - QIconTheme(const QString &name); - QIconTheme() : m_valid(false) {} - QStringList parents() { return m_parents; } - QList keyList() { return m_keyList; } - QString contentDir() { return m_contentDir; } - QStringList contentDirs() { return m_contentDirs; } - bool isValid() { return m_valid; } - -private: - QString m_contentDir; - QStringList m_contentDirs; - QList m_keyList; - QStringList m_parents; - bool m_valid; -}; - -class QIconLoader : public QObject -{ -public: - QIconLoader(); - QThemeIconEntries 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; - QIconDirInfo dirInfo(int dirindex); - static QIconLoader *instance(); - void updateSystemTheme(); - void invalidateKey() { m_themeKey++; } - void ensureInitialized(); - -private: - QThemeIconEntries 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; -}; - -} // QtXdg - -#endif // QDESKTOPICON_P_H - -#endif //QT_NO_ICON diff --git a/qiconfix/qiconloader_qt4.cpp b/qiconfix/qiconloader_qt4.cpp deleted file mode 100644 index b508e5f..0000000 --- a/qiconfix/qiconloader_qt4.cpp +++ /dev/null @@ -1,737 +0,0 @@ -/* BEGIN_COMMON_COPYRIGHT_HEADER - * (c)LGPL2 - */ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//END_COMMON_COPYRIGHT_HEADER - -#ifndef QT_NO_ICON -#include "qiconloader_p_qt4.h" - -//#include "qt/qapplication_p.h" -//#include -//#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#ifdef Q_WS_MAC -//#include -//#endif - -//#ifdef Q_WS_X11 -//#include "qt/qt_x11_p.h" -//#endif -#include - -#if QT_VERSION < 0x040700 -#include -#endif - -namespace QtXdg { - -Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance) - -/* Theme to use in last resort, if the theme does not have the icon, neither the parents */ -/*static QString fallbackTheme() -{ -#ifdef Q_WS_X11 - if (X11->desktopEnvironment == DE_GNOME) { - return QLatin1String("gnome"); - } else if (X11->desktopEnvironment == DE_KDE) { - return X11->desktopVersion >= 4 - ? QString::fromLatin1("oxygen") - : QString::fromLatin1("crystalsvg"); - } else { - return QLatin1String("hicolor"); - } -#endif - return QString(); -} -*/ -QIconLoader::QIconLoader() : - m_themeKey(1), m_supportsSvg(false), m_initialized(false) -{ -} - -// We lazily initialize the loader to make static icons -// work. Though we do not officially support this. -void QIconLoader::ensureInitialized() -{ - if (!m_initialized) { - m_initialized = true; - - Q_ASSERT(qApp); - - m_systemTheme = QIcon::themeName(); - -#ifndef QT_NO_LIBRARY -// QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterfaceV2_iid, -// QLatin1String("/iconengines"), -// Qt::CaseInsensitive); -// if (iconFactoryLoader.keys().contains(QLatin1String("svg"))) - m_supportsSvg = true; -#endif //QT_NO_LIBRARY - } -} - -QIconLoader *QIconLoader::instance() -{ - return iconLoaderInstance(); -} - -// Queries the system theme and invalidates existing -// icons if the theme has changed. -void QIconLoader::updateSystemTheme() -{ - // Only change if this is not explicitly set by the user - if (m_userTheme.isEmpty()) { - QString theme = QIcon::themeName();//qt_guiPlatformPlugin()->systemIconThemeName(); - //if (theme.isEmpty()) - // theme = fallbackTheme(); - if (theme != m_systemTheme) { - m_systemTheme = theme; - invalidateKey(); - } - } -} - -void QIconLoader::setThemeName(const QString &themeName) -{ - m_userTheme = themeName; - invalidateKey(); -} - -void QIconLoader::setThemeSearchPath(const QStringList &searchPaths) -{ - m_iconDirs = searchPaths; - themeList.clear(); - invalidateKey(); -} - -QStringList QIconLoader::themeSearchPaths() const -{ - if (m_iconDirs.isEmpty()) - { - m_iconDirs = QIcon::themeSearchPaths();//qt_guiPlatformPlugin()->iconThemeSearchPaths(); - // Always add resource directory as search path - m_iconDirs.append(QLatin1String(":/icons")); - } - return m_iconDirs; -} - - -QIconTheme::QIconTheme(const QString &themeName) - : m_valid(false) -{ - - QFile themeIndex; - - QList keyList; - QStringList iconDirs = QIcon::themeSearchPaths(); - 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_contentDir = themeDir; - m_valid = true; - - QStringList themeSearchPaths = QIcon::themeSearchPaths(); - foreach (QString path, themeSearchPaths) - { - if (!path.startsWith(':') && QFileInfo(path).isDir()) - m_contentDirs.append(path + QLatin1Char('/') + themeName); - } - - break; - } - } - - -#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(); - 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); - QIconDirInfo dirInfo(directoryKey); - dirInfo.size = size; - QString type = indexReader.value(directoryKey + - QLatin1String("/Type") - ).toString(); - - if (type == QLatin1String("Fixed")) - dirInfo.type = QIconDirInfo::Fixed; - else if (type == QLatin1String("Scalable")) - dirInfo.type = QIconDirInfo::Scalable; - else - dirInfo.type = QIconDirInfo::Threshold; - - dirInfo.threshold = indexReader.value(directoryKey + - QLatin1String("/Threshold"), - 2).toInt(); - - dirInfo.minSize = indexReader.value(directoryKey + - QLatin1String("/MinSize"), - size).toInt(); - - dirInfo.maxSize = indexReader.value(directoryKey + - QLatin1String("/MaxSize"), - size).toInt(); - m_keyList.append(dirInfo); - } - } - } - - // Parent themes provide fallbacks for missing icons - m_parents = indexReader.value( - QLatin1String("Icon Theme/Inherits")).toStringList(); - - // Ensure a default platform fallback for all themes - if (m_parents.isEmpty()) - m_parents.append(QIcon::themeName());//fallbackTheme()); - - // Ensure that all themes fall back to hicolor - if (!m_parents.contains(QLatin1String("hicolor"))) - m_parents.append(QLatin1String("hicolor")); - } -#endif //QT_NO_SETTINGS -} - - -QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, - const QString &iconName, - QStringList &visited) const -{ - QThemeIconEntries entries; - Q_ASSERT(!themeName.isEmpty()); - - QPixmap pixmap; - - // Used to protect against potential recursions - visited << themeName; - - QIconTheme theme = themeList.value(themeName); - if (!theme.isValid()) { - theme = QIconTheme(themeName); - if (!theme.isValid()) - theme = QIconTheme(QIcon::themeName());//fallbackTheme()); - - themeList.insert(themeName, theme); - } - - QStringList contentDirs = theme.contentDirs(); - QList subDirs = theme.keyList(); - - const QString svgext(QLatin1String(".svg")); - const QString pngext(QLatin1String(".png")); - const QString xpmext(QLatin1String(".xpm")); - - // Add all relevant files - for (int i = 0; i < subDirs.size() ; ++i) - { - const QIconDirInfo &dirInfo = subDirs.at(i); - QString subdir = dirInfo.path; - - foreach (QString contentDir, contentDirs) - { - QDir currentDir(contentDir + '/' + subdir); - - 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 - entries.prepend(iconEntry); - break; - } - else if (m_supportsSvg && - currentDir.exists(iconName + svgext)) - { - ScalableEntry *iconEntry = new ScalableEntry; - iconEntry->dir = dirInfo; - iconEntry->filename = currentDir.filePath(iconName + svgext); - entries.append(iconEntry); - break; - } - 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 - entries.append(iconEntry); - break; - } - } - } - - if (entries.isEmpty()) { - const QStringList parents = theme.parents(); - // Search recursively through inherited themes - for (int i = 0 ; i < parents.size() ; ++i) { - - const QString parentTheme = parents.at(i).trimmed(); - - if (!visited.contains(parentTheme)) // guard against recursion - entries = findIconHelper(parentTheme, iconName, visited); - - if (!entries.isEmpty()) // success - break; - } - } - - /********************************************************************* - 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 (entries.isEmpty()) { - const QString pixmaps(QLatin1String("/usr/share/pixmaps")); - - QDir currentDir(pixmaps); - QIconDirInfo 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 - entries.prepend(iconEntry); - } else if (m_supportsSvg && - currentDir.exists(iconName + svgext)) { - ScalableEntry *iconEntry = new ScalableEntry; - iconEntry->dir = dirInfo; - iconEntry->filename = currentDir.filePath(iconName + svgext); - 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 - entries.append(iconEntry); - } - - } -#endif - - if (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 - entries.prepend(iconEntry); - } else if (m_supportsSvg && - currentDir.exists(iconName + svgext)) { - ScalableEntry *iconEntry = new ScalableEntry; - iconEntry->filename = currentDir.filePath(iconName + svgext); - 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 - entries.append(iconEntry); - break; - } - } - } - return entries; -} - -QThemeIconEntries QIconLoader::loadIcon(const QString &name) const -{ - if (!themeName().isEmpty()) { - QStringList visited; - return findIconHelper(themeName(), name, visited); - } - - return QThemeIconEntries(); -} - - -// -------- Icon Loader Engine -------- // - - -QIconLoaderEngineFixed::QIconLoaderEngineFixed(const QString& iconName) - : m_iconName(iconName), m_key(0) -{ -} - -QIconLoaderEngineFixed::~QIconLoaderEngineFixed() -{ - while (!m_entries.isEmpty()) - delete m_entries.takeLast(); - Q_ASSERT(m_entries.size() == 0); -} - -QIconLoaderEngineFixed::QIconLoaderEngineFixed(const QIconLoaderEngineFixed &other) -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - : QIconEngineV2(other), -#else - : QIconEngine(other), -#endif - m_iconName(other.m_iconName), - m_key(0) -{ -} - - -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) -QIconEngineV2 *QIconLoaderEngineFixed::clone() const -#else -QIconEngine *QIconLoaderEngineFixed::clone() const -#endif -{ - return new QIconLoaderEngineFixed(*this); -} - -bool QIconLoaderEngineFixed::read(QDataStream &in) { - in >> m_iconName; - return true; -} - -bool QIconLoaderEngineFixed::write(QDataStream &out) const -{ - out << m_iconName; - return true; -} - -bool QIconLoaderEngineFixed::hasIcon() const -{ - return !(m_entries.isEmpty()); -} - -// Lazily load the icon -void QIconLoaderEngineFixed::ensureLoaded() -{ - - iconLoaderInstance()->ensureInitialized(); - - if (!(iconLoaderInstance()->themeKey() == m_key)) { - - while (!m_entries.isEmpty()) - delete m_entries.takeLast(); - - Q_ASSERT(m_entries.size() == 0); - m_entries = iconLoaderInstance()->loadIcon(m_iconName); - m_key = iconLoaderInstance()->themeKey(); - } -} - -void QIconLoaderEngineFixed::paint(QPainter *painter, const QRect &rect, - QIcon::Mode mode, QIcon::State state) -{ - QSize pixmapSize = rect.size(); -#if defined(Q_WS_MAC) - pixmapSize *= qt_mac_get_scalefactor(); -#endif - painter->drawPixmap(rect, pixmap(pixmapSize, mode, state)); -} - -/* - * 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) -{ - if (dir.type == QIconDirInfo::Fixed) { - return dir.size == iconsize; - - } else if (dir.type == QIconDirInfo::Scalable) { - return dir.size <= dir.maxSize && - iconsize >= dir.minSize; - - } else if (dir.type == QIconDirInfo::Threshold) { - return iconsize >= dir.size - dir.threshold && - iconsize <= dir.size + dir.threshold; - } - - Q_ASSERT(1); // Not a valid value - return false; -} - -/* - * 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) -{ - if (dir.type == QIconDirInfo::Fixed) { - return qAbs(dir.size - iconsize); - - } else if (dir.type == QIconDirInfo::Scalable) { - if (iconsize < dir.minSize) - return dir.minSize - iconsize; - else if (iconsize > dir.maxSize) - return iconsize - dir.maxSize; - else - return 0; - - } else if (dir.type == QIconDirInfo::Threshold) { - if (iconsize < dir.size - dir.threshold) - return dir.minSize - iconsize; - else if (iconsize > dir.size + dir.threshold) - return iconsize - dir.maxSize; - else return 0; - } - - Q_ASSERT(1); // Not a valid value - return INT_MAX; -} - -QIconLoaderEngineEntry *QIconLoaderEngineFixed::entryForSize(const QSize &size) -{ - int iconsize = qMin(size.width(), size.height()); - - // Note that m_entries are sorted so that png-files - // come first - - // Search for exact matches first - for (int i = 0; i < m_entries.count(); ++i) { - QIconLoaderEngineEntry *entry = m_entries.at(i); - if (directoryMatchesSize(entry->dir, iconsize)) { - return entry; - } - } - - // Find the minimum distance icon - int minimalSize = INT_MAX; - QIconLoaderEngineEntry *closestMatch = 0; - for (int i = 0; i < m_entries.count(); ++i) { - QIconLoaderEngineEntry *entry = m_entries.at(i); - int distance = directorySizeDistance(entry->dir, iconsize); - if (distance < minimalSize) { - minimalSize = distance; - closestMatch = entry; - } - } - return closestMatch; -} - -/* - * Returns the actual icon size. For scalable svg's this is equivalent - * to the requested size. Otherwise the closest match is returned but - * we can never return a bigger size than the requested size. - * - */ -QSize QIconLoaderEngineFixed::actualSize(const QSize &size, QIcon::Mode mode, - QIcon::State state) -{ - ensureLoaded(); - QIconLoaderEngineEntry *entry = entryForSize(size); - if (entry) { - const QIconDirInfo &dir = entry->dir; - if (dir.type == QIconDirInfo::Scalable) - { - return size; - } - else { - if (dir.size == 0) - { - entry->dir.size = QPixmap(entry->filename).size().width(); - entry->dir.minSize = dir.size; - entry->dir.maxSize = dir.size; - } - int result = qMin(dir.size, qMin(size.width(), size.height())); - - return QSize(result, result); - } - } -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - return QIconEngineV2::actualSize(size, mode, state); -#else - return QIconEngine::actualSize(size, mode, state); -#endif -} - -QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) -{ - Q_UNUSED(state); - - // Ensure that basePixmap is lazily initialized before generating the - // key, otherwise the cache key is not unique - if (basePixmap.isNull()) - basePixmap.load(filename); - - QSize actualSize = basePixmap.size(); - if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height())) - actualSize.scale(size, Qt::KeepAspectRatio); - - - QString key = QString("$qt_theme_%1%2%3%4%5") - .arg(basePixmap.cacheKey(), 16, 16, QChar('0')) - .arg(mode, 8, 16, QChar('0')) - .arg(qApp->palette().cacheKey(),16, 16, QChar('0')) - .arg(actualSize.width(), 8, 16, QChar('0')) - .arg(actualSize.height(), 8, 16, QChar('0')); - - QPixmap cachedPixmap; - if (QPixmapCache::find(key, &cachedPixmap)) { - return cachedPixmap; - } else { - if (basePixmap.size() != actualSize) - basePixmap = basePixmap.scaled(actualSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - - QStyleOption opt(0); - opt.palette = qApp->palette(); - cachedPixmap = qApp->style()->generatedIconPixmap(mode, basePixmap, &opt); - QPixmapCache::insert(key, cachedPixmap); - } - return cachedPixmap; -} - -QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) -{ - if (svgIcon.isNull()) - svgIcon = QIcon(filename); - - // Simply reuse svg icon engine - return svgIcon.pixmap(size, mode, state); -} - -QPixmap QIconLoaderEngineFixed::pixmap(const QSize &size, QIcon::Mode mode, - QIcon::State state) -{ - - ensureLoaded(); - - QIconLoaderEngineEntry *entry = entryForSize(size); - - if (entry) - return entry->pixmap(size, mode, state); - - return QPixmap(); -} - -QString QIconLoaderEngineFixed::key() const -{ - return QLatin1String("QIconLoaderEngineFixed"); -} - -void QIconLoaderEngineFixed::virtual_hook(int id, void *data) -{ - ensureLoaded(); - - switch (id) { -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - case QIconEngineV2::AvailableSizesHook: -#else - case QIconEngine::AvailableSizesHook: -#endif - { -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - QIconEngineV2::AvailableSizesArgument &arg - = *reinterpret_cast(data); -#else - QIconEngine::AvailableSizesArgument &arg - = *reinterpret_cast(data); -#endif - const QList directoryKey = iconLoaderInstance()->theme().keyList(); - arg.sizes.clear(); - - // Gets all sizes from the DirectoryInfo entries - for (int i = 0 ; i < m_entries.size() ; ++i) { - int size = m_entries.at(i)->dir.size; - arg.sizes.append(QSize(size, size)); - } - } - break; -#if (QT_VERSION >= 0x040700) && (QT_VERSION < 0x050000) - case QIconEngineV2::IconNameHook: - { - QString &name = *reinterpret_cast(data); - name = m_iconName; - } - break; -#elif QT_VERSION > QT_VERSION_CHECK(5,0,0) - case QIconEngine::IconNameHook: - { - QString &name = *reinterpret_cast(data); - name = m_iconName; - } - break; -#else// QT_VERSION > QT_VERSION_CHECK(5,0,0) -#warning QIconEngineV2::IconNameHook is ignored due Qt version. Upgrade to 4.7.x -#endif - default: -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - QIconEngineV2::virtual_hook(id, data); -#else - QIconEngine::virtual_hook(id, data); -#endif - } -} - -} // QtXdg - -#endif //QT_NO_ICON diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b5792b5..19b0df6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,52 +1,25 @@ set(PROJECT_NAME "qtxdg_test") -set(${PROJECT_NAME}_SRCS - qtxdg_test.cpp -) - -set(${PROJECT_NAME}_MOCS - qtxdg_test.h -) - -set(LIBRARIES - ${QTXDGX_LIBRARY_NAME} -) - +set(CMAKE_AUTOMOC TRUE) -if (BUILD_TESTS) - add_definitions(-DQTXDG_BUILDING_TESTS=1) -endif() - -if (USE_QT5) - qt5_wrap_cpp(MOCS ${${PROJECT_NAME}_MOCS}) -else() - qt4_wrap_cpp(MOCS ${${PROJECT_NAME}_MOCS}) -endif() +macro(qtxdg_add_test) + foreach(_testname ${ARGN}) + add_executable(${_testname} ${_testname}.cpp) + target_link_libraries(${_testname} Qt5::Test ${QTXDGX_LIBRARY_NAME}) + add_test(NAME ${_testname} COMMAND ${_testname}) + endforeach() +endmacro() include_directories ( ${CMAKE_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} ) -if (USE_QT5) - add_definitions(${Qt5Test_DEFINITINS}) - include_directories ( - ${Qt5Test_INCLUDE_DIRS} - ) - set(CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} ${Qt5Test_EXECUTABLE_COMPILE_FLAGS}" - ) -else() - include_directories ( - ${QT_QTCORE_INCLUDE_DIR} - ) -endif() - -add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_SRCS} ${UIS} ${RSCS} ${TRS} ${MOCS} ) - -if (USE_QT5) - target_link_libraries ( ${PROJECT_NAME} ${Qt5Test_LIBRARIES} ${LIBRARIES} ) -else() - target_link_libraries ( ${PROJECT_NAME} ${QT_LIBRARIES} ${LIBRARIES} ) -endif() +set_property(DIRECTORY APPEND + PROPERTY COMPILE_DEFINITIONS "QTXDG_BUILDING_TESTS=\"1\"" +) -add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) +qtxdg_add_test( + qtxdg_test + tst_xdgdirs +) diff --git a/test/qtxdg_test.cpp b/test/qtxdg_test.cpp index 8b20d44..9270605 100644 --- a/test/qtxdg_test.cpp +++ b/test/qtxdg_test.cpp @@ -1,3 +1,33 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * http://lxqt.org + * + * Copyright: 2013~2015 LXQt team + * Authors: + * Christian Surlykke + * Jerome Leclanche + * Luís Pereira + * + * 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 "qtxdg_test.h" #include "xdgdesktopfile.h" diff --git a/test/qtxdg_test.h b/test/qtxdg_test.h index 480b6e6..3d58c9f 100644 --- a/test/qtxdg_test.h +++ b/test/qtxdg_test.h @@ -1,3 +1,33 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * http://lxqt.org + * + * Copyright: 2013~2014 LXQt team + * Authors: + * Christian Surlykke + * Luís Pereira + * Jerome Leclanche + * + * 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 */ + + #ifndef QTXDG_TEST_H #define QTXDG_TEST_H diff --git a/test/tst_xdgdirs.cpp b/test/tst_xdgdirs.cpp new file mode 100644 index 0000000..634fee5 --- /dev/null +++ b/test/tst_xdgdirs.cpp @@ -0,0 +1,227 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * http://lxqt.org + * + * Copyright: 2015 LXQt team + * Authors: + * Luís Pereira + * + * 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 + +#include "xdgdirs.h" + +#include +#include + +class tst_xdgdirs : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void testDataHome(); + void testConfigHome(); + void testDataDirs(); + void testConfigDirs(); + void testCacheHome(); + void testAutostartHome(); + void testAutostartDirs(); + +private: + void setDefaultLocations(); + void setCustomLocations(); + + QString m_configHome; + QTemporaryDir m_configHomeTemp; + QString m_configDirs; + QTemporaryDir m_configDirsTemp; + QString m_dataHome; + QTemporaryDir m_dataHomeTemp; + QString m_dataDirs; + QTemporaryDir m_dataDirsTemp; + QString m_cacheHome; + QTemporaryDir m_cacheHomeTemp; +}; + +void tst_xdgdirs::initTestCase() +{ + QCoreApplication::instance()->setOrganizationName("QtXdg"); + QCoreApplication::instance()->setApplicationName("tst_xdgdirs"); +} + +void tst_xdgdirs::cleanupTestCase() +{ + QCoreApplication::instance()->setOrganizationName(QString()); + QCoreApplication::instance()->setApplicationName(QString()); +} + +void tst_xdgdirs::setDefaultLocations() +{ + qputenv("XDG_CONFIG_HOME", QByteArray()); + qputenv("XDG_CONFIG_DIRS", QByteArray()); + qputenv("XDG_DATA_HOME", QByteArray()); + qputenv("XDG_DATA_DIRS", QByteArray()); + qputenv("XDG_CACHE_HOME", QByteArray()); +} + +void tst_xdgdirs::setCustomLocations() +{ + m_configHome = m_configHomeTemp.path(); + m_configDirs = m_configDirsTemp.path(); + m_dataHome = m_dataHomeTemp.path(); + m_dataDirs = m_dataDirsTemp.path(); + m_cacheHome = m_cacheHomeTemp.path(); + qputenv("XDG_CONFIG_HOME", QFile::encodeName(m_configHome)); + qputenv("XDG_CONFIG_DIRS", QFile::encodeName(m_configDirs)); + qputenv("XDG_DATA_HOME", QFile::encodeName(m_dataHome)); + qputenv("XDG_DATA_DIRS", QFile::encodeName(m_dataDirs)); + qputenv("XDG_CACHE_HOME", QFile::encodeName(m_cacheHome)); + +} + +void tst_xdgdirs::testDataHome() +{ + setDefaultLocations(); + const QString expectedDataHome = QDir::homePath() + QString::fromLatin1("/.local/share"); + QCOMPARE(XdgDirs::dataHome(), expectedDataHome); + QCOMPARE(XdgDirs::dataHome(false), expectedDataHome); + + setCustomLocations(); + QCOMPARE(XdgDirs::dataHome(), m_dataHome); + QCOMPARE(XdgDirs::dataHome(false), m_dataHome); +} + +void tst_xdgdirs::testConfigHome() +{ + setDefaultLocations(); + const QString expectedConfigHome = QDir::homePath() + QString::fromLatin1("/.config"); + QCOMPARE(XdgDirs::configHome(), expectedConfigHome); + QCOMPARE(XdgDirs::configHome(false), expectedConfigHome); + + setCustomLocations(); + QCOMPARE(XdgDirs::configHome(), m_configHome); + QCOMPARE(XdgDirs::configHome(false), m_configHome); +} + +void tst_xdgdirs::testDataDirs() +{ + const QString postfix = QString::fromLatin1("/") + QCoreApplication::applicationName(); + + setDefaultLocations(); + const QStringList dataDirs = XdgDirs::dataDirs(); + QCOMPARE(dataDirs.count(), 2); + QCOMPARE(dataDirs.at(0), QString::fromLatin1("/usr/local/share")); + QCOMPARE(dataDirs.at(1), QString::fromLatin1("/usr/share")); + + const QStringList dataDirsWithPostfix = XdgDirs::dataDirs(postfix); + QCOMPARE(dataDirsWithPostfix.count(), 2); + QCOMPARE(dataDirsWithPostfix.at(0), QString::fromLatin1("/usr/local/share") + postfix); + QCOMPARE(dataDirsWithPostfix.at(1), QString::fromLatin1("/usr/share") + postfix); + + setCustomLocations(); + const QStringList dataDirsCustom = XdgDirs::dataDirs(); + QCOMPARE(dataDirsCustom.count(), 1); + QCOMPARE(dataDirsCustom.at(0), m_dataDirs); + + const QStringList dataDirsCustomWithPostfix = XdgDirs::dataDirs(postfix); + QCOMPARE(dataDirsCustomWithPostfix.count(), 1); + QCOMPARE(dataDirsCustomWithPostfix.at(0), m_dataDirs + postfix); +} + +void tst_xdgdirs::testConfigDirs() +{ + const QString postfix = QString::fromLatin1("/") + QCoreApplication::applicationName(); + setDefaultLocations(); + + const QStringList configDirs = XdgDirs::configDirs(); + QCOMPARE(configDirs.count(), 1); + QCOMPARE(configDirs.at(0), QString::fromLatin1("/etc/xdg")); + + const QStringList configDirsWithPostfix = XdgDirs::configDirs(postfix); + QCOMPARE(configDirsWithPostfix.count(), 1); + QCOMPARE(configDirsWithPostfix.at(0), QString::fromLatin1("/etc/xdg") + postfix); + + setCustomLocations(); + const QStringList configDirsCustom = XdgDirs::configDirs(); + QCOMPARE(configDirsCustom.count(), 1); + QCOMPARE(configDirsCustom.at(0), m_configDirs); + + const QStringList configDirsCustomWithPostfix = XdgDirs::configDirs(postfix); + QCOMPARE(configDirsCustomWithPostfix.count(), 1); + QCOMPARE(configDirsCustomWithPostfix.at(0), m_configDirs + postfix); +} + +void tst_xdgdirs::testCacheHome() +{ + setDefaultLocations(); + const QString expectedCacheHome = QDir::homePath() + QString("/.cache"); + QCOMPARE(XdgDirs::cacheHome(), expectedCacheHome); + QCOMPARE(XdgDirs::cacheHome(false), expectedCacheHome); + + setCustomLocations(); + const QString expectedCacheHomeCustom = XdgDirs::cacheHome(); + QCOMPARE(XdgDirs::cacheHome(), expectedCacheHomeCustom); + QCOMPARE(XdgDirs::cacheHome(false), expectedCacheHomeCustom); + +} + +void tst_xdgdirs::testAutostartHome() +{ + setDefaultLocations(); + const QString expectedAutoStartHome = QDir::homePath() + QString::fromLatin1("/.config/autostart"); + QCOMPARE(XdgDirs::autostartHome(), expectedAutoStartHome); + QCOMPARE(XdgDirs::autostartHome(false), expectedAutoStartHome); + + setCustomLocations(); + const QString expectedAutostartHomeCustom = XdgDirs::configHome() + QString::fromLatin1("/autostart"); + QCOMPARE(XdgDirs::autostartHome(), expectedAutostartHomeCustom); + QCOMPARE(XdgDirs::autostartHome(false), expectedAutostartHomeCustom); +} + +void tst_xdgdirs::testAutostartDirs() +{ + const QString postfix = QString::fromLatin1("/") + QCoreApplication::applicationName(); + + setDefaultLocations(); + const QStringList autostartDirs = XdgDirs::autostartDirs(); + QCOMPARE(autostartDirs.count(), 1); + QCOMPARE(autostartDirs.at(0), QString::fromLatin1("/etc/xdg/autostart")); + + const QStringList autostartDirsWithPostfix = XdgDirs::autostartDirs(postfix); + QCOMPARE(autostartDirsWithPostfix.count(), 1); + QCOMPARE(autostartDirsWithPostfix.at(0), QString::fromLatin1("/etc/xdg/autostart") + postfix); + + + setCustomLocations(); + const QStringList autostartDirsCustom = XdgDirs::autostartDirs(); + QCOMPARE(autostartDirsCustom.count(), 1); + QCOMPARE(autostartDirsCustom.at(0), m_configDirs + QString::fromLatin1("/autostart")); + + const QStringList autostartDirsCustomWithPostfix = XdgDirs::autostartDirs(postfix); + QCOMPARE(autostartDirsCustomWithPostfix.count(), 1); + QCOMPARE(autostartDirsCustomWithPostfix.at(0), m_configDirs + QString::fromLatin1("/autostart") + postfix); +} + +QTEST_APPLESS_MAIN(tst_xdgdirs) +#include "tst_xdgdirs.moc" diff --git a/xdgaction.cpp b/xdgaction.cpp index 29c1712..9fd24fe 100644 --- a/xdgaction.cpp +++ b/xdgaction.cpp @@ -32,18 +32,12 @@ #include -/************************************************ - - ************************************************/ XdgAction::XdgAction(QObject *parent): QAction(parent) { } -/************************************************ - - ************************************************/ XdgAction::XdgAction(const XdgDesktopFile& desktopFile, QObject *parent): QAction(parent) { @@ -51,9 +45,6 @@ XdgAction::XdgAction(const XdgDesktopFile& desktopFile, QObject *parent): } -/************************************************ - - ************************************************/ XdgAction::XdgAction(const XdgDesktopFile* desktopFile, QObject *parent): QAction(parent) { @@ -61,9 +52,6 @@ XdgAction::XdgAction(const XdgDesktopFile* desktopFile, QObject *parent): } -/************************************************ - - ************************************************/ XdgAction::XdgAction(const QString& desktopFileName, QObject *parent): QAction(parent) { @@ -73,9 +61,6 @@ XdgAction::XdgAction(const QString& desktopFileName, QObject *parent): } -/************************************************ - - ************************************************/ XdgAction::XdgAction(const XdgAction& other, QObject *parent): QAction(parent) { @@ -83,17 +68,11 @@ XdgAction::XdgAction(const XdgAction& other, QObject *parent): } -/************************************************ - - ************************************************/ XdgAction::~XdgAction() { } -/************************************************ - - ************************************************/ XdgAction& XdgAction::operator=(const XdgAction& other) { load(other.mDesktopFile); @@ -101,18 +80,12 @@ XdgAction& XdgAction::operator=(const XdgAction& other) } -/************************************************ - - ************************************************/ bool XdgAction::isValid() const { return mDesktopFile.isValid(); } -/************************************************ - - ************************************************/ void XdgAction::load(const XdgDesktopFile& desktopFile) { mDesktopFile = desktopFile; @@ -134,9 +107,6 @@ void XdgAction::load(const XdgDesktopFile& desktopFile) } -/************************************************ - - ************************************************/ void XdgAction::runConmmand() const { if (mDesktopFile.isValid()) @@ -144,9 +114,6 @@ void XdgAction::runConmmand() const } -/************************************************ - - ************************************************/ void XdgAction::updateIcon() { setIcon(mDesktopFile.icon()); diff --git a/xdgdesktopfile.cpp b/xdgdesktopfile.cpp index d92a872..9aac1a0 100644 --- a/xdgdesktopfile.cpp +++ b/xdgdesktopfile.cpp @@ -36,12 +36,8 @@ #include "xdgdesktopfile.h" #include "xdgdesktopfile_p.h" -#ifdef HAVE_QTMIMETYPES #include #include -#else -#include "xdgmime.h" -#endif #include "xdgicon.h" #include "xdgdirs.h" @@ -58,10 +54,7 @@ #include #include #include // for the % operator -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) -#else #include -#endif #include #include @@ -98,9 +91,8 @@ void replaceVar(QString &str, const QString &varName, const QString &after); QString &unEscape(QString& str); QString &unEscapeExec(QString& str); void loadMimeCacheDir(const QString& dirName, QHash > & cache); -/************************************************ - ************************************************/ + QString &doEscape(QString& str, const QHash &repl) { // First we replace slash. @@ -166,10 +158,6 @@ QString &escapeExec(QString& str) } - -/************************************************ - - ************************************************/ QString &doUnEscape(QString& str, const QHash &repl) { int n = 0; @@ -209,7 +197,6 @@ QString &unEscape(QString& str) } - /************************************************ Quoting must be done by enclosing the argument between double quotes and escaping the @@ -299,9 +286,6 @@ public: }; -/************************************************ - - ************************************************/ XdgDesktopFileData::XdgDesktopFileData(): mIsValid(false), mValidIsChecked(false) @@ -309,9 +293,6 @@ XdgDesktopFileData::XdgDesktopFileData(): } -/************************************************ - - ************************************************/ bool XdgDesktopFileData::read(const QString &prefix) { QFile file(mFileName); @@ -355,9 +336,6 @@ bool XdgDesktopFileData::read(const QString &prefix) return mIsValid; } -/************************************************ - - ************************************************/ XdgDesktopFile::Type XdgDesktopFileData::detectType(XdgDesktopFile *q) const { QString typeStr = q->value("Type").toString(); @@ -377,9 +355,6 @@ XdgDesktopFile::Type XdgDesktopFileData::detectType(XdgDesktopFile *q) const } -/************************************************ - - ************************************************/ bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const QStringList& urls) const { //DBusActivatable handling @@ -418,11 +393,7 @@ bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const if (nonDetach) { QScopedPointer p(new QProcess); -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) p->setStandardInputFile(QProcess::nullDevice()); -#else - p->setStandardInputFile(QLatin1String("/dev/null")); -#endif p->setProcessChannelMode(QProcess::ForwardedChannels); p->start(cmd, args); bool started = p->waitForStarted(); @@ -440,9 +411,6 @@ bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const } -/************************************************ - - ************************************************/ bool XdgDesktopFileData::startLinkDetached(const XdgDesktopFile *q) const { QString url = q->url(); @@ -460,14 +428,9 @@ bool XdgDesktopFileData::startLinkDetached(const XdgDesktopFile *q) const // Local file QFileInfo fi(url); -#ifdef HAVE_QTMIMETYPES QMimeDatabase db; QMimeType mimeInfo = db.mimeTypeForFile(fi); XdgDesktopFile* desktopFile = XdgDesktopFileCache::getDefaultApp(mimeInfo.name()); -#else - XdgMimeInfo mimeInfo(fi); - XdgDesktopFile* desktopFile = XdgDesktopFileCache::getDefaultApp(mimeInfo.mimeType()); -#endif if (desktopFile) return desktopFile->startDetached(url); @@ -502,27 +465,18 @@ bool XdgDesktopFileData::startByDBus(const QStringList& urls) const } - -/************************************************ - - ************************************************/ XdgDesktopFile::XdgDesktopFile(): d(new XdgDesktopFileData) { } -/************************************************ - - ************************************************/ XdgDesktopFile::XdgDesktopFile(const XdgDesktopFile& other): d(other.d) { } -/************************************************ - ************************************************/ XdgDesktopFile::XdgDesktopFile(Type type, const QString& name, const QString &value): d(new XdgDesktopFileData) { @@ -548,17 +502,11 @@ XdgDesktopFile::XdgDesktopFile(Type type, const QString& name, const QString &va } -/************************************************ - - ************************************************/ XdgDesktopFile::~XdgDesktopFile() { } -/************************************************ - - ************************************************/ XdgDesktopFile& XdgDesktopFile::operator=(const XdgDesktopFile& other) { d = other.d; @@ -566,18 +514,12 @@ XdgDesktopFile& XdgDesktopFile::operator=(const XdgDesktopFile& other) } -/************************************************ - - ************************************************/ bool XdgDesktopFile::operator==(const XdgDesktopFile &other) const { return d->mItems == other.d->mItems; } -/************************************************ - - ************************************************/ bool XdgDesktopFile::load(const QString& fileName) { if (fileName.startsWith(QDir::separator())) { // absolute path @@ -596,9 +538,6 @@ bool XdgDesktopFile::load(const QString& fileName) } -/************************************************ - - ************************************************/ bool XdgDesktopFile::save(QIODevice *device) const { QTextStream stream(device); @@ -622,9 +561,6 @@ bool XdgDesktopFile::save(QIODevice *device) const } -/************************************************ - - ************************************************/ bool XdgDesktopFile::save(const QString &fileName) const { QFile file(fileName); @@ -635,9 +571,6 @@ bool XdgDesktopFile::save(const QString &fileName) const } -/************************************************ - - ************************************************/ QVariant XdgDesktopFile::value(const QString& key, const QVariant& defaultValue) const { QString path = (!prefix().isEmpty()) ? prefix() + "/" + key : key; @@ -652,9 +585,6 @@ 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; @@ -679,9 +609,6 @@ void XdgDesktopFile::setValue(const QString &key, const QVariant &value) } -/************************************************ - - ************************************************/ void XdgDesktopFile::setLocalizedValue(const QString &key, const QVariant &value) { setValue(localizedKey(key), value); @@ -763,9 +690,7 @@ QString XdgDesktopFile::localizedKey(const QString& key) const return key; } -/************************************************ - ************************************************/ QVariant XdgDesktopFile::localizedValue(const QString& key, const QVariant& defaultValue) const { return value(localizedKey(key), defaultValue); @@ -790,9 +715,7 @@ QStringList XdgDesktopFile::categories() const return cats; } -/************************************************ - ************************************************/ void XdgDesktopFile::removeEntry(const QString& key) { QString path = (!prefix().isEmpty()) ? prefix() + "/" + key : key; @@ -800,9 +723,6 @@ void XdgDesktopFile::removeEntry(const QString& key) } -/************************************************ - - ************************************************/ bool XdgDesktopFile::contains(const QString& key) const { QString path = (!prefix().isEmpty()) ? prefix() + "/" + key : key; @@ -810,27 +730,18 @@ bool XdgDesktopFile::contains(const QString& key) const } -/************************************************ - - ************************************************/ bool XdgDesktopFile::isValid() const { return d->mIsValid; } -/************************************************ - - ************************************************/ QString XdgDesktopFile::fileName() const { return d->mFileName; } -/************************************************ - - ************************************************/ QIcon const XdgDesktopFile::icon(const QIcon& fallback) const { QIcon result = XdgIcon::fromTheme(value("Icon").toString(), fallback); @@ -844,18 +755,12 @@ QIcon const XdgDesktopFile::icon(const QIcon& fallback) const } -/************************************************ - - ************************************************/ QString const XdgDesktopFile::iconName() const { return value("Icon").toString(); } -/************************************************ - - ************************************************/ XdgDesktopFile::Type XdgDesktopFile::type() const { return d->mType; @@ -900,9 +805,6 @@ bool XdgDesktopFile::startDetached(const QString& url) const } -/************************************************ - - ************************************************/ static QStringList parseCombinedArgString(const QString &program) { QStringList args; @@ -944,9 +846,6 @@ 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); @@ -954,9 +853,6 @@ void replaceVar(QString &str, const QString &varName, const QString &after) } -/************************************************ - - ************************************************/ QString expandEnvVariables(const QString str) { QString scheme = QUrl(str).scheme(); @@ -981,16 +877,6 @@ QString expandEnvVariables(const QString str) replaceVar(res, "HOME", getenv("HOME")); replaceVar(res, "USER", getenv("USER")); -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - replaceVar(res, "XDG_DESKTOP_DIR", QDesktopServices::storageLocation(QDesktopServices::DesktopLocation)); - replaceVar(res, "XDG_TEMPLATES_DIR", QDesktopServices::storageLocation(QDesktopServices::TempLocation)); - replaceVar(res, "XDG_DOCUMENTS_DIR", QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation)); - replaceVar(res, "XDG_MUSIC_DIR", QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); - replaceVar(res, "XDG_PICTURES_DIR", QDesktopServices::storageLocation(QDesktopServices::PicturesLocation)); - replaceVar(res, "XDG_VIDEOS_DIR", QDesktopServices::storageLocation(QDesktopServices::MoviesLocation)); - replaceVar(res, "XDG_PHOTOS_DIR", QDesktopServices::storageLocation(QDesktopServices::PicturesLocation)); - replaceVar(res, "XDG_MOVIES_DIR", QDesktopServices::storageLocation(QDesktopServices::MoviesLocation)); -#else 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)); @@ -999,15 +885,11 @@ QString expandEnvVariables(const QString str) replaceVar(res, "XDG_VIDEOS_DIR", QStandardPaths::writableLocation(QStandardPaths::MoviesLocation)); replaceVar(res, "XDG_PHOTOS_DIR", QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)); replaceVar(res, "XDG_MOVIES_DIR", QStandardPaths::writableLocation(QStandardPaths::MoviesLocation)); -#endif // QT_VERSION < QT_VERSION_CHECK(5,0,0) return res; } -/************************************************ - - ************************************************/ QStringList expandEnvVariables(const QStringList strs) { QStringList res; @@ -1018,9 +900,6 @@ QStringList expandEnvVariables(const QStringList strs) } -/************************************************ - - ************************************************/ QStringList XdgDesktopFile::expandExecString(const QStringList& urls) const { if (d->mType != ApplicationType) @@ -1135,10 +1014,6 @@ QStringList XdgDesktopFile::expandExecString(const QStringList& urls) const } - -/************************************************ - Check if the program is actually installed. - ************************************************/ bool checkTryExec(const QString& progName) { if (progName.startsWith(QDir::separator())) @@ -1156,9 +1031,6 @@ bool checkTryExec(const QString& progName) } -/************************************************ - - ************************************************/ bool XdgDesktopFile::isShow(const QString& environment) const { const QString env = environment.toUpper(); @@ -1180,6 +1052,7 @@ bool XdgDesktopFile::isShow(const QString& environment) const return true; } + bool XdgDesktopFile::isShown(const QString &environment) const { const QString env = environment.toUpper(); @@ -1202,9 +1075,6 @@ 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 @@ -1238,6 +1108,7 @@ bool XdgDesktopFile::isApplicable(bool excludeHidden, const QString& environment return true; } + bool XdgDesktopFile::isSuitable(bool excludeHidden, const QString &environment) const { // Hidden should have been called Deleted. It means the user deleted @@ -1291,7 +1162,7 @@ bool XdgDesktopFile::isSuitable(bool excludeHidden, const QString &environment) if (keyFound) { QStringList s = value(key).toString().toUpper().split(QLatin1Char(';')); - if (!s.contains(env)) + if (s.contains(env)) return false; } @@ -1303,9 +1174,7 @@ bool XdgDesktopFile::isSuitable(bool excludeHidden, const QString &environment) return true; } -/************************************************ - ************************************************/ QString expandDynamicUrl(QString url) { foreach(QString line, QProcess::systemEnvironment()) @@ -1320,9 +1189,6 @@ QString expandDynamicUrl(QString url) } -/************************************************ - - ************************************************/ QString XdgDesktopFile::url() const { if (type() != LinkType) @@ -1343,10 +1209,6 @@ QString XdgDesktopFile::url() const } - -/************************************************ - - ************************************************/ QString findDesktopFile(const QString& dirName, const QString& desktopName) { QDir dir(dirName); @@ -1372,9 +1234,6 @@ QString findDesktopFile(const QString& dirName, const QString& desktopName) } -/************************************************ - - ************************************************/ QString findDesktopFile(const QString& desktopName) { QStringList dataDirs = XdgDirs::dataDirs(); @@ -1391,18 +1250,13 @@ QString findDesktopFile(const QString& desktopName) } - - -/************************************************ - - ************************************************/ XdgDesktopFile* XdgDesktopFileCache::getFile(const QString& fileName) { if (instance().m_fileCache.contains(fileName)) { return instance().m_fileCache.value(fileName); } - + if (fileName.startsWith(QDir::separator())) { // Absolute path ........................ @@ -1451,7 +1305,7 @@ XdgDesktopFileCache & XdgDesktopFileCache::instance() static XdgDesktopFileCache cache; if (!cache.m_IsInitialized) { - cache.initialize(); + cache.initialize(); cache.m_IsInitialized = true; } @@ -1459,8 +1313,7 @@ XdgDesktopFileCache & XdgDesktopFileCache::instance() } - -/*! +/*! * Handles files with a syntax similar to desktopfiles as QSettings files. * The differences between ini-files and desktopfiles are: * desktopfiles uses '#' as comment marker, and ';' as list-separator. @@ -1470,7 +1323,7 @@ bool readDesktopFile(QIODevice & device, QSettings::SettingsMap & map) { QString section; QTextStream stream(&device); - + while (!stream.atEnd()) { QString line = stream.readLine().trimmed(); @@ -1490,7 +1343,7 @@ bool readDesktopFile(QIODevice & device, QSettings::SettingsMap & map) if (key.isEmpty()) continue; - + if (section.isEmpty()) { qWarning() << "key=value outside section"; @@ -1500,7 +1353,7 @@ bool readDesktopFile(QIODevice & device, QSettings::SettingsMap & map) key.prepend("/"); key.prepend(section); - if (value.contains(";")) + if (value.contains(";")) { map.insert(key, value.split(";")); } @@ -1510,16 +1363,17 @@ bool readDesktopFile(QIODevice & device, QSettings::SettingsMap & map) } } - + return true; } + /*! See readDesktopFile */ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map) { QTextStream stream(&device); - QString section; + QString section; foreach (QString key, map.keys()) { @@ -1542,7 +1396,7 @@ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map) } QString remainingKey = key.section("/", 1, -1); - + if (remainingKey.isEmpty()) { qWarning() << "Only one level in key..." ; @@ -1552,14 +1406,11 @@ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map) stream << remainingKey << "=" << map.value(key).toString() << "\n"; } - + return true; } -/************************************************ - - ************************************************/ void XdgDesktopFileCache::initialize(const QString& dirName) { QDir dir(dirName); @@ -1588,13 +1439,13 @@ 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("MimeType").toString().split(';', QString::SkipEmptyParts); foreach (QString mime, mimes) { int pref = df->value("InitialPreference", 0).toInt(); - // We move the desktopFile forward in the list for this mime, so that + // 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) @@ -1607,6 +1458,7 @@ void XdgDesktopFileCache::initialize(const QString& dirName) } + XdgDesktopFile* XdgDesktopFileCache::load(const QString& fileName) { XdgDesktopFile* desktopFile = new XdgDesktopFile(); @@ -1614,6 +1466,7 @@ XdgDesktopFile* XdgDesktopFileCache::load(const QString& fileName) return desktopFile; } + void loadMimeCacheDir(const QString& dirName, QHash > & cache) { QDir dir(dirName); @@ -1643,7 +1496,7 @@ void loadMimeCacheDir(const QString& dirName, QHashvalue("InitialPreference", 0).toInt(); - // We move the desktopFile forward in the list for this mime, so that + // 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) @@ -1676,18 +1529,18 @@ XdgDesktopFileCache::XdgDesktopFileCache() : { } + XdgDesktopFileCache::~XdgDesktopFileCache() { } - 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"); // loadMimeCacheDir(dirname + "/applications", m_defaultAppsCache); @@ -1713,9 +1566,6 @@ 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 @@ -1728,7 +1578,7 @@ XdgDesktopFile* XdgDesktopFileCache::getDefaultApp(const QString& mimetype) if (QFileInfo(defaultsListPath).exists()) { QSettings defaults(defaultsListPath, desktopFileSettingsFormat()); - + defaults.beginGroup("Default Applications"); if (defaults.contains(mimetype)) @@ -1743,7 +1593,7 @@ XdgDesktopFile* XdgDesktopFileCache::getDefaultApp(const QString& mimetype) { return desktopFile; } - else + else { qWarning() << desktopFileName << "not a valid desktopfile"; } @@ -1760,4 +1610,3 @@ XdgDesktopFile* XdgDesktopFileCache::getDefaultApp(const QString& mimetype) XdgDesktopFile* desktopFile = apps.isEmpty() ? 0 : apps[0]; return desktopFile; } - diff --git a/xdgdesktopfile.h b/xdgdesktopfile.h index 0712ca6..cad9147 100644 --- a/xdgdesktopfile.h +++ b/xdgdesktopfile.h @@ -33,7 +33,6 @@ #include "xdgmacros.h" #include -//#include #include #include #include @@ -41,7 +40,7 @@ #include class XdgDesktopFileData; - + /** \brief Desktop files handling. XdgDesktopFile class gives the interface for reading the values from the XDG .desktop file. @@ -249,7 +248,7 @@ private: XdgDesktopFileCache(); ~XdgDesktopFileCache(); - void initialize(); + void initialize(); void initialize(const QString & dirName); bool m_IsInitialized; QHash > m_defaultAppsCache; diff --git a/xdgdesktopfile_p.h b/xdgdesktopfile_p.h index b28ec33..e0e9754 100644 --- a/xdgdesktopfile_p.h +++ b/xdgdesktopfile_p.h @@ -1,3 +1,31 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * http://lxqt.org + * + * Copyright: 2015 LXQt team + * Authors: + * Luís Pereira + * + * 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 */ + + #ifndef XDGDESKTOPFILE_P_H #define XDGDESKTOPFILE_P_H diff --git a/xdgdirs.cpp b/xdgdirs.cpp index 2671ae2..8b93e37 100644 --- a/xdgdirs.cpp +++ b/xdgdirs.cpp @@ -25,15 +25,12 @@ * * END_COMMON_COPYRIGHT_HEADER */ - #include "xdgdirs.h" #include #include #include // for the % operator #include -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) #include -#endif static const QString userDirectoryString[8] = { @@ -52,14 +49,8 @@ void fixBashShortcuts(QString &s); void removeEndingSlash(QString &s); QString createDirectory(const QString &dir); -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) void cleanAndAddPostfix(QStringList &dirs, const QString& postfix); -#endif -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) -QString xdgSingleDir(const QString &envVar, const QString &def, bool createDir); -QStringList xdgDirList(const QString &envVar, const QString &postfix); -#endif /************************************************ Helper func. @@ -70,6 +61,7 @@ void fixBashShortcuts(QString &s) s = QString(getenv("HOME")) + (s).mid(1); } + void removeEndingSlash(QString &s) { // We don't check for empty strings. Caller must check it. @@ -79,6 +71,7 @@ void removeEndingSlash(QString &s) s.chop(1); } + QString createDirectory(const QString &dir) { QDir d(dir); @@ -94,6 +87,7 @@ QString createDirectory(const QString &dir) return r; } + void cleanAndAddPostfix(QStringList &dirs, const QString& postfix) { const int N = dirs.count(); @@ -105,53 +99,7 @@ void cleanAndAddPostfix(QStringList &dirs, const QString& postfix) } } -/************************************************ - Helper func. - ************************************************/ -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) -QString xdgSingleDir(const QString &envVar, const QString &def, bool createDir) -{ - QString s(getenv(envVar.toAscii())); - - if (!s.isEmpty()) - fixBashShortcuts(s); - else - s = QString("%1/%2").arg(getenv("HOME"), def); - - if (createDir) - return createDirectory(s); - - removeEndingSlash(s); - return s; -} -#endif - -/************************************************ - Helper func. - ************************************************/ -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) -QStringList xdgDirList(const QString &envVar, const QString &postfix) -{ - QStringList dirs = QString(getenv(envVar.toAscii())).split(':', QString::SkipEmptyParts); - - QMutableStringListIterator i(dirs); - while(i.hasNext()) { - i.next(); - QString s = i.value(); - if (s.isEmpty()) { - i.remove(); - } else { - fixBashShortcuts(s); - removeEndingSlash(s); - i.setValue(s % postfix); - } - } - return dirs; -} -#endif -/************************************************ - ************************************************/ QString XdgDirs::userDir(XdgDirs::UserDirectory dir) { // possible values for UserDirectory @@ -199,9 +147,6 @@ QString XdgDirs::userDir(XdgDirs::UserDirectory dir) } -/************************************************ - - ************************************************/ bool XdgDirs::setUserDir(XdgDirs::UserDirectory dir, const QString& value, bool createDir) { // possible values for UserDirectory @@ -262,31 +207,20 @@ bool XdgDirs::setUserDir(XdgDirs::UserDirectory dir, const QString& value, bool } -/************************************************ - - ************************************************/ QString XdgDirs::dataHome(bool createDir) { -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - QString s = QStandardPaths::writableLocation(QStandardPaths::DataLocation); + QString s = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); fixBashShortcuts(s); if (createDir) return createDirectory(s); removeEndingSlash(s); return s; -#else - return xdgSingleDir("XDG_DATA_HOME", QLatin1String(".local/share"), createDir); -#endif } -/************************************************ - - ************************************************/ QString XdgDirs::configHome(bool createDir) { -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) QString s = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); fixBashShortcuts(s); if (createDir) @@ -294,51 +228,35 @@ QString XdgDirs::configHome(bool createDir) removeEndingSlash(s); return s; -#else - return xdgSingleDir("XDG_CONFIG_HOME", QLatin1String(".config"), createDir); -#endif } -/************************************************ - - ************************************************/ QStringList XdgDirs::dataDirs(const QString &postfix) { -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) QString d = QFile::decodeName(qgetenv("XDG_DATA_DIRS")); QStringList dirs = d.split(QLatin1Char(':'), QString::SkipEmptyParts); - QMutableListIterator it(dirs); - while (it.hasNext()) { - const QString dir = it.next(); - if (!dir.startsWith(QLatin1Char('/'))) - it.remove(); + if (dirs.isEmpty()) { + dirs.append(QString::fromLatin1("/usr/local/share")); + dirs.append(QString::fromLatin1("/usr/share")); + } else { + QMutableListIterator it(dirs); + while (it.hasNext()) { + const QString dir = it.next(); + if (!dir.startsWith(QLatin1Char('/'))) + it.remove(); + } } dirs.removeDuplicates(); cleanAndAddPostfix(dirs, postfix); return dirs; -#else - QStringList dirs = xdgDirList("XDG_DATA_DIRS", postfix); - if (dirs.isEmpty()) - { - dirs << QLatin1String("/usr/local/share") % postfix; - dirs << QLatin1String("/usr/share") % postfix; - } - - return dirs; -#endif } -/************************************************ - - ************************************************/ QStringList XdgDirs::configDirs(const QString &postfix) { -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) QStringList dirs; const QString env = QFile::decodeName(qgetenv("XDG_CONFIG_DIRS")); if (env.isEmpty()) @@ -348,24 +266,11 @@ QStringList XdgDirs::configDirs(const QString &postfix) cleanAndAddPostfix(dirs, postfix); return dirs; -#else - QStringList dirs = xdgDirList("XDG_CONFIG_DIRS", postfix); - if (dirs.isEmpty()) - { - dirs << QLatin1String("/etc/xdg") % postfix; - } - - return dirs; -#endif } -/************************************************ - - ************************************************/ QString XdgDirs::cacheHome(bool createDir) { -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) QString s = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation); fixBashShortcuts(s); if (createDir) @@ -373,34 +278,18 @@ QString XdgDirs::cacheHome(bool createDir) removeEndingSlash(s); return s; -#else - return xdgSingleDir("XDG_CACHE_HOME", QLatin1String(".cache"), createDir); -#endif - } -/************************************************ - - ************************************************/ QString XdgDirs::runtimeDir() { -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) QString result = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); fixBashShortcuts(result); removeEndingSlash(result); return result; -#else - QString result(getenv("XDG_RUNTIME_DIR")); - fixBashShortcuts(result); - return result; -#endif } -/************************************************ - - ************************************************/ QString XdgDirs::autostartHome(bool createDir) { QString s = QString("%1/autostart").arg(configHome(createDir)); @@ -416,9 +305,6 @@ QString XdgDirs::autostartHome(bool createDir) } -/************************************************ - - ************************************************/ QStringList XdgDirs::autostartDirs(const QString &postfix) { QStringList dirs; diff --git a/xdgdirs.h b/xdgdirs.h index 0ac1298..fb333d2 100644 --- a/xdgdirs.h +++ b/xdgdirs.h @@ -25,8 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - - #ifndef QTXDG_XDGDIRS_H #define QTXDG_XDGDIRS_H diff --git a/xdgicon.cpp b/xdgicon.cpp index d32e5e9..231a3d5 100644 --- a/xdgicon.cpp +++ b/xdgicon.cpp @@ -25,8 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - - #include "xdgicon.h" #include @@ -35,18 +33,11 @@ #include #include #include -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) -#include "qiconfix/qiconloader_p_qt4.h" -#else #include "qiconfix/qiconloader_p.h" -#endif #include #define DEFAULT_APP_ICON "application-x-executable" -/************************************************ - - ************************************************/ static void qt_cleanup_icon_cache(); typedef QCache IconCache; @@ -67,18 +58,11 @@ static void qt_cleanup_icon_cache() } - -/************************************************ - - ************************************************/ XdgIcon::XdgIcon() { } -/************************************************ - - ************************************************/ XdgIcon::~XdgIcon() { } @@ -163,9 +147,6 @@ QIcon XdgIcon::fromTheme(const QStringList& iconNames, const QIcon& fallback) } -/************************************************ - - ************************************************/ QIcon XdgIcon::fromTheme(const QString &iconName, const QString &fallbackIcon1, const QString &fallbackIcon2, @@ -182,18 +163,13 @@ QIcon XdgIcon::fromTheme(const QString &iconName, return fromTheme(icons); } -/************************************************ - ************************************************/ QIcon XdgIcon::defaultApplicationIcon() { return fromTheme(DEFAULT_APP_ICON); } -/************************************************ - - ************************************************/ QString XdgIcon::defaultApplicationIconName() { return DEFAULT_APP_ICON; diff --git a/xdgicon.h b/xdgicon.h index 63fe6ea..594415e 100644 --- a/xdgicon.h +++ b/xdgicon.h @@ -25,8 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - - #ifndef QTXDG_XDGICON_H #define QTXDG_XDGICON_H diff --git a/xdgmacros.h b/xdgmacros.h index 4c7fe1c..bda6aee 100644 --- a/xdgmacros.h +++ b/xdgmacros.h @@ -34,12 +34,12 @@ #define QTXDG_API Q_DECL_IMPORT #endif -#if defined(QTXDG_COMPILATION) && defined(QTXDG_BUILDING_TESTS) +#if defined(QTXDG_COMPILATION) && defined(QTXDG_TESTS) +# define QTXDG_AUTOTEST Q_DECL_EXPORT /* Build library,tests enabled */ +#elif defined(QTXDG_BUILDING_TESTS) /* Build the tests */ # define QTXDG_AUTOTEST Q_DECL_IMPORT -#elif defined(QTXDG_COMPILATION) && defined(QTXDG_TESTS) -# define QTXDG_AUTOTEST Q_DECL_EXPORT #else -# define QTXDG_AUTOTEST +# define QTXDG_AUTOTEST /* Building library, tests disabled */ #endif #endif // QTXDG_MACROS_H diff --git a/xdgmenu.cpp b/xdgmenu.cpp index 9e538e8..ba0e698 100644 --- a/xdgmenu.cpp +++ b/xdgmenu.cpp @@ -26,7 +26,6 @@ * END_COMMON_COPYRIGHT_HEADER */ - #include "xdgmenu.h" #include "xdgmenu_p.h" #include "xdgmenureader.h" @@ -55,36 +54,14 @@ void installTranslation(const QString &name); bool isParent(const QDomElement& parent, const QDomElement& child); -void installTranslation(const QString &name) -{ - static bool alreadyLoaded = false; - - if (alreadyLoaded) - return; - - QString locale = QLocale::system().name(); - QTranslator *translator = new QTranslator(qApp); - translator->load(QString("%1/%2_%3.qm").arg(TRANSLATIONS_DIR, name, locale)); - - QCoreApplication::installTranslator(translator); - alreadyLoaded = true; -} - - -/************************************************ - ************************************************/ XdgMenu::XdgMenu(QObject *parent) : QObject(parent), d_ptr(new XdgMenuPrivate(this)) { - installTranslation("libqtxdg"); } -/************************************************ - - ************************************************/ XdgMenu::~XdgMenu() { Q_D(XdgMenu); @@ -92,9 +69,6 @@ XdgMenu::~XdgMenu() } -/************************************************ - - ************************************************/ XdgMenuPrivate::XdgMenuPrivate(XdgMenu *parent): mOutDated(true), q_ptr(parent) @@ -111,9 +85,6 @@ XdgMenuPrivate::XdgMenuPrivate(XdgMenu *parent): } -/************************************************ - - ************************************************/ const QString XdgMenu::logDir() const { Q_D(const XdgMenu); @@ -121,9 +92,6 @@ const QString XdgMenu::logDir() const } -/************************************************ - - ************************************************/ void XdgMenu::setLogDir(const QString& directory) { Q_D(XdgMenu); @@ -131,9 +99,6 @@ void XdgMenu::setLogDir(const QString& directory) } -/************************************************ - - ************************************************/ const QDomDocument XdgMenu::xml() const { Q_D(const XdgMenu); @@ -141,9 +106,6 @@ const QDomDocument XdgMenu::xml() const } -/************************************************ - - ************************************************/ QString XdgMenu::menuFileName() const { Q_D(const XdgMenu); @@ -151,28 +113,26 @@ QString XdgMenu::menuFileName() const } -/************************************************ - - ************************************************/ QStringList XdgMenu::environments() { Q_D(XdgMenu); return d->mEnvironments; } + void XdgMenu::setEnvironments(const QStringList &envs) { Q_D(XdgMenu); d->mEnvironments = envs; } + + void XdgMenu::setEnvironments(const QString &env) { setEnvironments(QStringList() << env); } -/************************************************ - ************************************************/ const QString XdgMenu::errorString() const { Q_D(const XdgMenu); @@ -180,9 +140,6 @@ const QString XdgMenu::errorString() const } -/************************************************ - - ************************************************/ bool XdgMenu::read(const QString& menuFileName) { Q_D(XdgMenu); @@ -241,9 +198,6 @@ bool XdgMenu::read(const QString& menuFileName) } -/************************************************ - - ************************************************/ void XdgMenu::save(const QString& fileName) { Q_D(const XdgMenu); @@ -279,9 +233,6 @@ void XdgMenuPrivate::load(const QString& fileName) } -/************************************************ - - ************************************************/ void XdgMenuPrivate::saveLog(const QString& logFileName) { Q_Q(XdgMenu); @@ -290,9 +241,6 @@ void XdgMenuPrivate::saveLog(const QString& logFileName) } -/************************************************ - - ************************************************/ void XdgMenuPrivate::mergeMenus(QDomElement& element) { QHash menus; @@ -333,9 +281,6 @@ void XdgMenuPrivate::mergeMenus(QDomElement& element) } -/************************************************ - - ************************************************/ void XdgMenuPrivate::simplify(QDomElement& element) { MutableDomElementIterator it(element); @@ -393,9 +338,6 @@ void XdgMenuPrivate::simplify(QDomElement& element) } -/************************************************ - - ************************************************/ void XdgMenuPrivate::prependChilds(QDomElement& srcElement, QDomElement& destElement) { MutableDomElementIterator it(srcElement); @@ -419,9 +361,6 @@ void XdgMenuPrivate::prependChilds(QDomElement& srcElement, QDomElement& destEle } -/************************************************ - - ************************************************/ void XdgMenuPrivate::appendChilds(QDomElement& srcElement, QDomElement& destElement) { MutableDomElementIterator it(srcElement); @@ -487,9 +426,6 @@ QDomElement XdgMenu::findMenu(QDomElement& baseElement, const QString& path, boo } -/************************************************ - - ************************************************/ bool isParent(const QDomElement& parent, const QDomElement& child) { QDomNode n = child; @@ -574,9 +510,6 @@ void XdgMenuPrivate::deleteDeletedMenus(QDomElement& element) } -/************************************************ - - ************************************************/ void XdgMenuPrivate::processDirectoryEntries(QDomElement& element, const QStringList& parentDirs) { QStringList dirs; @@ -631,9 +564,6 @@ void XdgMenuPrivate::processDirectoryEntries(QDomElement& element, const QString } -/************************************************ - - ************************************************/ bool XdgMenuPrivate::loadDirectoryFile(const QString& fileName, QDomElement& element) { XdgDesktopFile file; @@ -653,9 +583,6 @@ bool XdgMenuPrivate::loadDirectoryFile(const QString& fileName, QDomElement& ele } -/************************************************ - - ************************************************/ void XdgMenuPrivate::processApps(QDomElement& element) { Q_Q(XdgMenu); @@ -664,9 +591,6 @@ void XdgMenuPrivate::processApps(QDomElement& element) } -/************************************************ - - ************************************************/ void XdgMenuPrivate::deleteEmpty(QDomElement& element) { MutableDomElementIterator it(element, "Menu"); @@ -686,9 +610,6 @@ void XdgMenuPrivate::deleteEmpty(QDomElement& element) } -/************************************************ - - ************************************************/ void XdgMenuPrivate::processLayouts(QDomElement& element) { XdgMenuLayoutProcessor proc(element); @@ -696,9 +617,6 @@ void XdgMenuPrivate::processLayouts(QDomElement& element) } -/************************************************ - - ************************************************/ void XdgMenuPrivate::fixSeparators(QDomElement& element) { @@ -768,9 +686,6 @@ QString XdgMenu::getMenuFileName(const QString& baseName) } -/************************************************ - - ************************************************/ void XdgMenu::addWatchPath(const QString &path) { Q_D(XdgMenu); @@ -785,9 +700,6 @@ void XdgMenu::addWatchPath(const QString &path) } -/************************************************ - - ************************************************/ bool XdgMenu::isOutDated() const { Q_D(const XdgMenu); @@ -795,9 +707,6 @@ bool XdgMenu::isOutDated() const } -/************************************************ - - ************************************************/ void XdgMenuPrivate::rebuild() { Q_Q(XdgMenu); @@ -812,9 +721,6 @@ void XdgMenuPrivate::rebuild() } -/************************************************ - - ************************************************/ void XdgMenuPrivate::clearWatcher() { QStringList sl; diff --git a/xdgmenu.h b/xdgmenu.h index 54357ea..a88aa64 100644 --- a/xdgmenu.h +++ b/xdgmenu.h @@ -25,8 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - - #ifndef QTXDG_XDGMENU_H #define QTXDG_XDGMENU_H @@ -36,7 +34,6 @@ #include #include - class QDomDocument; class QDomElement; class XdgMenuPrivate; diff --git a/xdgmenu_p.h b/xdgmenu_p.h index fb2c936..34443aa 100644 --- a/xdgmenu_p.h +++ b/xdgmenu_p.h @@ -25,7 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - #include "xdgmenu.h" #include #include @@ -85,4 +84,3 @@ private: XdgMenu* const q_ptr; Q_DECLARE_PUBLIC(XdgMenu) }; - diff --git a/xdgmenuapplinkprocessor.cpp b/xdgmenuapplinkprocessor.cpp index c7ceedc..02265d6 100644 --- a/xdgmenuapplinkprocessor.cpp +++ b/xdgmenuapplinkprocessor.cpp @@ -25,7 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - #include "xdgmenu.h" #include "xdgmenuapplinkprocessor.h" #include "xmlhelper.h" @@ -34,9 +33,6 @@ #include -/************************************************ - - ************************************************/ XdgMenuApplinkProcessor::XdgMenuApplinkProcessor(QDomElement& element, XdgMenu* menu, XdgMenuApplinkProcessor *parent) : QObject(parent) { @@ -56,17 +52,11 @@ XdgMenuApplinkProcessor::XdgMenuApplinkProcessor(QDomElement& element, XdgMenu* } -/************************************************ - - ************************************************/ XdgMenuApplinkProcessor::~XdgMenuApplinkProcessor() { } -/************************************************ - - ************************************************/ void XdgMenuApplinkProcessor::run() { step1(); @@ -74,9 +64,6 @@ void XdgMenuApplinkProcessor::run() } -/************************************************ - - ************************************************/ void XdgMenuApplinkProcessor::step1() { fillAppFileInfoList(); @@ -108,9 +95,6 @@ void XdgMenuApplinkProcessor::step1() } -/************************************************ - - ************************************************/ void XdgMenuApplinkProcessor::step2() { // Create AppLinks elements ........................... @@ -199,9 +183,6 @@ void XdgMenuApplinkProcessor::fillAppFileInfoList() } -/************************************************ - - ************************************************/ void XdgMenuApplinkProcessor::findDesktopFiles(const QString& dirName, const QString& prefix) { QDir dir(dirName); @@ -229,9 +210,6 @@ void XdgMenuApplinkProcessor::findDesktopFiles(const QString& dirName, const QSt } -/************************************************ - Create rules - ************************************************/ void XdgMenuApplinkProcessor::createRules() { MutableDomElementIterator i(mElement, QString()); diff --git a/xdgmenuapplinkprocessor.h b/xdgmenuapplinkprocessor.h index 6b85331..0bd0cb5 100644 --- a/xdgmenuapplinkprocessor.h +++ b/xdgmenuapplinkprocessor.h @@ -25,7 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - #ifndef QTXDG_XDGMENUAPPLINKPROCESSOR_H #define QTXDG_XDGMENUAPPLINKPROCESSOR_H @@ -45,6 +44,7 @@ typedef QLinkedList XdgMenuAppFileInfoList; typedef QHash XdgMenuAppFileInfoHash; typedef QHashIterator XdgMenuAppFileInfoHashIterator; + class XdgMenuApplinkProcessor : public QObject { Q_OBJECT @@ -98,5 +98,4 @@ private: QString mId; }; - #endif // QTXDG_XDGMENUAPPLINKPROCESSOR_H diff --git a/xdgmenulayoutprocessor.cpp b/xdgmenulayoutprocessor.cpp index f4aa414..75089c2 100644 --- a/xdgmenulayoutprocessor.cpp +++ b/xdgmenulayoutprocessor.cpp @@ -25,7 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - #include "xdgmenulayoutprocessor.h" #include "xmlhelper.h" #include @@ -36,9 +35,7 @@ QDomElement findLastElementByTag(const QDomElement element, const QString tagName); int childsCount(const QDomElement& element); -/************************************************ - ************************************************/ QDomElement findLastElementByTag(const QDomElement element, const QString tagName) { QDomNodeList l = element.elementsByTagName(tagName); @@ -100,9 +97,6 @@ XdgMenuLayoutProcessor::XdgMenuLayoutProcessor(QDomElement& element): } -/************************************************ - - ************************************************/ XdgMenuLayoutProcessor::XdgMenuLayoutProcessor(QDomElement& element, XdgMenuLayoutProcessor *parent): mElement(element) { @@ -127,9 +121,6 @@ XdgMenuLayoutProcessor::XdgMenuLayoutProcessor(QDomElement& element, XdgMenuLayo } -/************************************************ - - ************************************************/ void XdgMenuLayoutProcessor::setParams(QDomElement defaultLayout, LayoutParams *result) { if (defaultLayout.hasAttribute("show_empty")) @@ -149,9 +140,6 @@ void XdgMenuLayoutProcessor::setParams(QDomElement defaultLayout, LayoutParams * } -/************************************************ - - ************************************************/ QDomElement XdgMenuLayoutProcessor::searchElement(const QString &tagName, const QString &attributeName, const QString &attributeValue) const { DomElementIterator it(mElement, tagName); @@ -168,9 +156,6 @@ QDomElement XdgMenuLayoutProcessor::searchElement(const QString &tagName, const } -/************************************************ - - ************************************************/ int childsCount(const QDomElement& element) { int count = 0; @@ -186,9 +171,6 @@ int childsCount(const QDomElement& element) } -/************************************************ - - ************************************************/ void XdgMenuLayoutProcessor::run() { QDomDocument doc = mLayout.ownerDocument(); @@ -427,4 +409,3 @@ void XdgMenuLayoutProcessor::processMergeTag(const QDomElement &element) mResult.removeChild(element); } - diff --git a/xdgmenulayoutprocessor.h b/xdgmenulayoutprocessor.h index d67c61b..c07dfd6 100644 --- a/xdgmenulayoutprocessor.h +++ b/xdgmenulayoutprocessor.h @@ -25,7 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - #ifndef QTXDG_XDGMENULAYOUTPROCESSOR_H #define QTXDG_XDGMENULAYOUTPROCESSOR_H diff --git a/xdgmenureader.cpp b/xdgmenureader.cpp index 9e6b14b..6207eb9 100644 --- a/xdgmenureader.cpp +++ b/xdgmenureader.cpp @@ -25,7 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - #include "xdgmenureader.h" #include "xdgmenu.h" #include "xdgdirs.h" @@ -41,10 +40,6 @@ #include - -/************************************************ - - ************************************************/ XdgMenuReader::XdgMenuReader(XdgMenu* menu, XdgMenuReader* parentReader, QObject *parent) : QObject(parent), mMenu(menu) @@ -55,18 +50,12 @@ XdgMenuReader::XdgMenuReader(XdgMenu* menu, XdgMenuReader* parentReader, QObjec } -/************************************************ - - ************************************************/ XdgMenuReader::~XdgMenuReader() { } -/************************************************ - - ************************************************/ bool XdgMenuReader::load(const QString& fileName, const QString& baseDir) { if (fileName.isEmpty()) @@ -433,9 +422,6 @@ void XdgMenuReader::mergeFile(const QString& fileName, QDomElement& element, QSt } -/************************************************ - - ************************************************/ void XdgMenuReader::mergeDir(const QString& dirName, QDomElement& element, QStringList* mergedFiles) { QFileInfo dirInfo(mDirName, dirName); @@ -450,7 +436,3 @@ void XdgMenuReader::mergeDir(const QString& dirName, QDomElement& element, QStri mergeFile(file.canonicalFilePath(), element, mergedFiles); } } - - - - diff --git a/xdgmenureader.h b/xdgmenureader.h index 1962cfb..27e1f5e 100644 --- a/xdgmenureader.h +++ b/xdgmenureader.h @@ -25,7 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - #ifndef QTXDG_XDGMENUREADER_H #define QTXDG_XDGMENUREADER_H @@ -34,6 +33,7 @@ #include #include #include + class XdgMenu; class XdgMenuReader : public QObject { diff --git a/xdgmenurules.cpp b/xdgmenurules.cpp index eca7dd1..eab1da7 100644 --- a/xdgmenurules.cpp +++ b/xdgmenurules.cpp @@ -25,7 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - /********************************************************************* See: http://standards.freedesktop.org/desktop-entry-spec @@ -38,10 +37,6 @@ #include - -/************************************************ - - ************************************************/ XdgMenuRule::XdgMenuRule(const QDomElement& element, QObject* parent) : QObject(parent) { @@ -49,17 +44,11 @@ XdgMenuRule::XdgMenuRule(const QDomElement& element, QObject* parent) : } -/************************************************ - - ************************************************/ XdgMenuRule::~XdgMenuRule() { } - - - /************************************************ The element contains a list of matching rules. If any of the matching rules inside the element match a desktop entry, then the entire rule matches @@ -100,9 +89,6 @@ XdgMenuRuleOr::XdgMenuRuleOr(const QDomElement& element, QObject* parent) : } -/************************************************ - - ************************************************/ bool XdgMenuRuleOr::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile) { for (QLinkedList::Iterator i=mChilds.begin(); i!=mChilds.end(); ++i) @@ -124,9 +110,6 @@ XdgMenuRuleAnd::XdgMenuRuleAnd(const QDomElement& element, QObject *parent) : } -/************************************************ - - ************************************************/ bool XdgMenuRuleAnd::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile) { for (QLinkedList::Iterator i=mChilds.begin(); i!=mChilds.end(); ++i) @@ -136,7 +119,6 @@ bool XdgMenuRuleAnd::check(const QString& desktopFileId, const XdgDesktopFile& d } - /************************************************ The element contains a list of matching rules. If any of the matching rules inside the element matches a desktop entry, then the entire rule does @@ -150,16 +132,12 @@ XdgMenuRuleNot::XdgMenuRuleNot(const QDomElement& element, QObject *parent) : } -/************************************************ - - ************************************************/ bool XdgMenuRuleNot::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile) { return ! XdgMenuRuleOr::check(desktopFileId, desktopFile); } - /************************************************ The element is the most basic matching rule. It matches a desktop entry if the desktop entry has the given desktop-file id. See Desktop-File Id. @@ -172,9 +150,6 @@ XdgMenuRuleFileName::XdgMenuRuleFileName(const QDomElement& element, QObject *pa } -/************************************************ - - ************************************************/ bool XdgMenuRuleFileName::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile) { Q_UNUSED(desktopFile) @@ -183,7 +158,6 @@ bool XdgMenuRuleFileName::check(const QString& desktopFileId, const XdgDesktopFi } - /************************************************ The element is another basic matching predicate. It matches a desktop entry if the desktop entry has the given category in its Categories field. @@ -195,9 +169,6 @@ XdgMenuRuleCategory::XdgMenuRuleCategory(const QDomElement& element, QObject *pa } -/************************************************ - - ************************************************/ bool XdgMenuRuleCategory::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile) { Q_UNUSED(desktopFileId) @@ -215,9 +186,6 @@ XdgMenuRuleAll::XdgMenuRuleAll(const QDomElement& element, QObject *parent) : } -/************************************************ - - ************************************************/ bool XdgMenuRuleAll::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile) { Q_UNUSED(desktopFileId) @@ -226,46 +194,29 @@ bool XdgMenuRuleAll::check(const QString& desktopFileId, const XdgDesktopFile& d } - - -/************************************************ - - ************************************************/ XdgMenuRules::XdgMenuRules(QObject* parent) : QObject(parent) { } -/************************************************ - - ************************************************/ XdgMenuRules::~XdgMenuRules() { } -/************************************************ - - ************************************************/ void XdgMenuRules::addInclude(const QDomElement& element) { mIncludeRules.append(new XdgMenuRuleOr(element, this)); } -/************************************************ - - ************************************************/ void XdgMenuRules::addExclude(const QDomElement& element) { mExcludeRules.append(new XdgMenuRuleOr(element, this)); } -/************************************************ - - ************************************************/ bool XdgMenuRules::checkInclude(const QString& desktopFileId, const XdgDesktopFile& desktopFile) { for (QLinkedList::Iterator i=mIncludeRules.begin(); i!=mIncludeRules.end(); ++i) @@ -275,9 +226,6 @@ bool XdgMenuRules::checkInclude(const QString& desktopFileId, const XdgDesktopFi } -/************************************************ - - ************************************************/ bool XdgMenuRules::checkExclude(const QString& desktopFileId, const XdgDesktopFile& desktopFile) { for (QLinkedList::Iterator i=mExcludeRules.begin(); i!=mExcludeRules.end(); ++i) @@ -285,5 +233,3 @@ bool XdgMenuRules::checkExclude(const QString& desktopFileId, const XdgDesktopFi return false; } - - diff --git a/xdgmenurules.h b/xdgmenurules.h index 9ce558f..422a33f 100644 --- a/xdgmenurules.h +++ b/xdgmenurules.h @@ -40,6 +40,7 @@ #include "xdgdesktopfile.h" + class XdgMenuRule : public QObject { Q_OBJECT diff --git a/xdgmenuwidget.cpp b/xdgmenuwidget.cpp index 1f12605..d2e6c79 100644 --- a/xdgmenuwidget.cpp +++ b/xdgmenuwidget.cpp @@ -25,7 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - #include "xdgmenuwidget.h" #include "xdgicon.h" #include "xmlhelper.h" @@ -35,14 +34,12 @@ #include #include #include -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) -#else #include -#endif #include #include #include + class XdgMenuWidgetPrivate { private: @@ -69,10 +66,6 @@ private: }; - -/************************************************ - - ************************************************/ XdgMenuWidget::XdgMenuWidget(const XdgMenu& xdgMenu, const QString& title, QWidget* parent): QMenu(parent), d_ptr(new XdgMenuWidgetPrivate(this)) @@ -81,9 +74,7 @@ XdgMenuWidget::XdgMenuWidget(const XdgMenu& xdgMenu, const QString& title, QWidg setTitle(XdgMenuWidgetPrivate::escape(title)); } -/************************************************ - ************************************************/ XdgMenuWidget::XdgMenuWidget(const QDomElement& menuElement, QWidget* parent): QMenu(parent), d_ptr(new XdgMenuWidgetPrivate(this)) @@ -92,9 +83,6 @@ XdgMenuWidget::XdgMenuWidget(const QDomElement& menuElement, QWidget* parent): } -/************************************************ - - ************************************************/ XdgMenuWidget::XdgMenuWidget(const XdgMenuWidget& other, QWidget* parent): QMenu(parent), d_ptr(new XdgMenuWidgetPrivate(this)) @@ -103,9 +91,6 @@ XdgMenuWidget::XdgMenuWidget(const XdgMenuWidget& other, QWidget* parent): } -/************************************************ - - ************************************************/ void XdgMenuWidgetPrivate::init(const QDomElement& xml) { Q_Q(XdgMenuWidget); @@ -134,18 +119,12 @@ void XdgMenuWidgetPrivate::init(const QDomElement& xml) } -/************************************************ - - ************************************************/ XdgMenuWidget::~XdgMenuWidget() { delete d_ptr; } -/************************************************ - - ************************************************/ XdgMenuWidget& XdgMenuWidget::operator=(const XdgMenuWidget& other) { Q_D(XdgMenuWidget); @@ -155,9 +134,6 @@ XdgMenuWidget& XdgMenuWidget::operator=(const XdgMenuWidget& other) } -/************************************************ - - ************************************************/ bool XdgMenuWidget::event(QEvent* event) { Q_D(XdgMenuWidget); @@ -179,9 +155,6 @@ bool XdgMenuWidget::event(QEvent* event) } -/************************************************ - - ************************************************/ void XdgMenuWidgetPrivate::mouseMoveEvent(QMouseEvent *event) { if (!(event->buttons() & Qt::LeftButton)) @@ -207,9 +180,6 @@ void XdgMenuWidgetPrivate::mouseMoveEvent(QMouseEvent *event) } -/************************************************ - - ************************************************/ void XdgMenuWidgetPrivate::buildMenu() { Q_Q(XdgMenuWidget); @@ -240,9 +210,6 @@ void XdgMenuWidgetPrivate::buildMenu() } -/************************************************ - - ************************************************/ XdgAction* XdgMenuWidgetPrivate::createAction(const QDomElement& xml) { Q_Q(XdgMenuWidget); @@ -272,4 +239,3 @@ QString XdgMenuWidgetPrivate::escape(QString string) { return string.replace("&", "&&"); } - diff --git a/xdgmenuwidget.h b/xdgmenuwidget.h index 53e24e6..4b73412 100644 --- a/xdgmenuwidget.h +++ b/xdgmenuwidget.h @@ -25,7 +25,6 @@ * * END_COMMON_COPYRIGHT_HEADER */ - #ifndef QTXDG_XDGMENUWIDGET_H #define QTXDG_XDGMENUWIDGET_H diff --git a/xdgmime.cpp b/xdgmime.cpp deleted file mode 100644 index 520a20c..0000000 --- a/xdgmime.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/* BEGIN_COMMON_COPYRIGHT_HEADER - * (c)LGPL2+ - * - * Razor - a lightweight, Qt based, desktop toolset - * http://razor-qt.org - * - * Copyright: 2010-2011 Razor team - * Authors: - * Alexander Sokoloff - * - * 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 "xdgmime.h" -#include "xdgicon.h" -#include "xdgdirs.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -struct XdgMimeData -{ -public: - XdgMimeData(QString media, QString subtype); - bool readXml(QIODevice* xml); - - QString mMedia; - QString mSubtype; - - bool mDbLoaded; - QString mComment; - QMap mLocalizedComments; - QStringList mPatterns; - QString mSubClassOf; -}; - - - -/************************************************ - - ************************************************/ -XdgMimeInfo::XdgMimeInfo(const QString& mimeType) -{ - QString media = mimeType.section('/', 0, 0); - QString subtype = mimeType.section('/', 1); - mData = new XdgMimeData(media, subtype); -} - -XdgMimeInfo::~XdgMimeInfo() -{ - delete mData; - mData = 0; -} - -/************************************************ - - ************************************************/ -QString getFileMimeType(const QFileInfo& fileInfo, bool followSymLinks) -{ - - QString result("application/octet-stream"); - - magic_t magicMimePredictor; - magicMimePredictor = magic_open(MAGIC_MIME_TYPE); // Open predictor - if (!magicMimePredictor) { - qWarning() << "libmagic: Unable to initialize magic library"; - return result; - } - - - if (magic_load(magicMimePredictor, 0)) { // if not 0 - error - qWarning() << QString("libmagic: Can't load magic database - %1").arg(magic_error(magicMimePredictor)); - magic_close(magicMimePredictor); // Close predictor - return result; - } - - QByteArray ar = fileInfo.absoluteFilePath().toLocal8Bit(); - if (followSymLinks && fileInfo.isSymLink()) - { - ar = fileInfo.symLinkTarget().toLocal8Bit(); - } - char *file = ar.data(); - - // getting mime-type ........................ - const char *mime; - mime = magic_file(magicMimePredictor, file); - result = QString(mime); - - // Close predictor .......................... - magic_close(magicMimePredictor); - - return result; -} - - -/************************************************ - - ************************************************/ -XdgMimeInfo::XdgMimeInfo(const QFileInfo& file, bool followSymLinks) -{ - QString mimeType = getFileMimeType(file, followSymLinks); - QString media = mimeType.section('/', 0, 0); - QString subtype = mimeType.section('/', 1); - mData = new XdgMimeData(media, subtype); -} - - -/************************************************ - - ************************************************/ -QString XdgMimeInfo::mimeType() const -{ - return mData->mMedia + "/" + mData->mSubtype; -} - - -QString XdgMimeInfo::mediaType() const -{ - return mData->mMedia; -} - - -QString XdgMimeInfo::subType() const -{ - return mData->mSubtype; -} - -QString XdgMimeInfo::comment() const -{ - return mData->mComment; -} - -QString XdgMimeInfo::localizedComment() const -{ - // FIXME - return mData->mComment; -} - -QStringList XdgMimeInfo::patterns() const -{ - return mData->mPatterns; -} - -/************************************************ - - ************************************************/ -QString XdgMimeInfo::iconName() const -{ - QStringList names; - names << QString("%1-x-%2").arg(mData->mMedia, mData->mSubtype); - names << QString("%1-%2").arg(mData->mMedia, mData->mSubtype); - names << QString("%1-x-generic").arg(mData->mMedia); - names << QString("%1-generic").arg(mData->mMedia); - - foreach (QString s, names) - { - if (!XdgIcon::fromTheme(s).isNull()) - return s; - } - - return "unknown"; -} - -/************************************************ - - ************************************************/ -QIcon XdgMimeInfo::icon() const -{ - return XdgIcon::fromTheme(iconName()); -} - - -QString XdgMimeInfo::subClassOf() const -{ - return mData->mSubClassOf; -} - - -bool XdgMimeInfo::loadFromDb(QIODevice* xml) -{ - return mData->readXml(xml); -} - - - -XdgMimeData::XdgMimeData(QString media, QString subtype): - mMedia(media), - mSubtype(subtype), - mDbLoaded(false) -{ -} - -bool XdgMimeData::readXml(QIODevice* xml) -{ - QDomDocument domDocument; - if (! domDocument.setContent(xml, false)) - { - return false; - } - - QDomElement rootElement = domDocument.documentElement(); - if (rootElement.nodeName() != "mime-type") - { - return false; - } - - if (rootElement.attribute("type") != mMedia + "/" + mSubtype) - { - return false; - } - - QDomNodeList commentNodes = rootElement.elementsByTagName("comment"); - for(int i = 0; i < commentNodes.size(); i++) - { - if (! commentNodes.item(i).isElement()) - { - continue; - } - - QDomElement commentElement = commentNodes.item(i).toElement(); - - if (commentElement.hasAttribute("xml:lang")) - { - mLocalizedComments[commentElement.attribute("xml:lang")] = commentElement.text(); - } - else - { - mComment = commentElement.text(); - } - } - - QSet collectedPatterns; - QDomNodeList globNodes = rootElement.elementsByTagName("glob"); - for(int i = 0; i < globNodes.size(); i++) - { - if (globNodes.item(i).isElement() && globNodes.item(i).toElement().hasAttribute("pattern")) - { - collectedPatterns << globNodes.item(i).toElement().attribute("pattern"); - } - } - - mPatterns = collectedPatterns.toList(); - mPatterns.sort(); - - QDomNodeList subClassOfElements = rootElement.elementsByTagName("sub-class-of"); - if (subClassOfElements.size() > 0) - { - mSubClassOf = subClassOfElements.at(0).toElement().attribute("type"); - } - - return true; -} - - -QStringList XdgMimeInfoCache::mediatypes() -{ - return cache().keys(); -} - -QStringList XdgMimeInfoCache::subtypes(const QString& media) -{ - return cache().value(media).keys(); -} - -XdgMimeInfo* XdgMimeInfoCache::xdgMimeInfo(const QString & media, const QString & subtype) -{ - return cache().value(media).value(subtype); -} - -XdgMimeInfo* XdgMimeInfoCache::xdgMimeInfo(const QString& mimetype) -{ - QString media = mimetype.section("/", 0, 0); - QString subtype = mimetype.section("/", 1, 1); - return xdgMimeInfo(media, subtype); -} - - -void loadMimeInfoCache(QMap > & cache) -{ - qDebug() << "loadMimeInfoCache"; - QStringList datadirs = XdgDirs::dataDirs(); - datadirs.prepend(XdgDirs::dataHome(false)); - const QStringList filters = (QStringList() << "*.xml"); - - foreach (const QString datadir, datadirs) - { - QDir mimedir(datadir + "/mime"); - - if (! mimedir.exists()) - { - continue; - } - - - foreach (QFileInfo mediadirInfo, mimedir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) - { - QString media = mediadirInfo.fileName(); - - QDir mediadir(mediadirInfo.absoluteFilePath()); - foreach (QFileInfo subtypefileInfo, mediadir.entryInfoList(filters, QDir::Files)) - { - QString subtype = subtypefileInfo.fileName().left(subtypefileInfo.fileName().length() - 4); - //qDebug() << "subtype:" << subtype; - QFile subtypefile(subtypefileInfo.absoluteFilePath()); - XdgMimeInfo* mimeInfo = new XdgMimeInfo(media + "/" + subtype); - if (subtypefile.open(QIODevice::ReadOnly) && mimeInfo->loadFromDb(&subtypefile)) - { - cache[media][subtype] = mimeInfo; - } - else - { - delete mimeInfo; - } - - } - } - } - - // TESTING - XdgMimeData data("application", "msword"); - QFile mswordxml("/usr/share/mime/application/msword.xml"); - mswordxml.open(QIODevice::ReadOnly); - data.readXml(&mswordxml); - qDebug() << "================================================================================="; - qDebug() << "data:" << data.mMedia << data.mSubtype << data.mComment << data.mLocalizedComments << data.mPatterns; - qDebug() << "================================================================================="; -} - -QMap > & XdgMimeInfoCache::cache() -{ - static QMap > _cache; - static bool cache_loaded = false; - - if (! cache_loaded) - { - loadMimeInfoCache(_cache); - cache_loaded = true; - } - - return _cache; -} diff --git a/xdgmime.h b/xdgmime.h deleted file mode 100644 index 7c4a201..0000000 --- a/xdgmime.h +++ /dev/null @@ -1,99 +0,0 @@ -/* BEGIN_COMMON_COPYRIGHT_HEADER - * (c)LGPL2+ - * - * Razor - a lightweight, Qt based, desktop toolset - * http://razor-qt.org - * - * Copyright: 2010-2011 Razor team - * Authors: - * Alexander Sokoloff - * - * 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 */ - - -#ifndef QTXDG_XDGMIME_H -#define QTXDG_XDGMIME_H - -#include -#include -#include - -#include "xdgmacros.h" - -struct XdgMimeData; - -/*! @brief The XdgMimeInfo class provides mime information about file. - */ -class QTXDG_DEPRECATED QTXDG_API XdgMimeInfo -{ -public: - /// Constructs a XdgMimeInfo with the mimeType type. - explicit XdgMimeInfo(const QString& mimeType); - - /** - Constructs a new XdgMimeInfo that gives mime information about the given file. - If file is symlink and followSymLinks is true function gives information for the - file the link references rather than for the link itself. - **/ - explicit XdgMimeInfo(const QFileInfo& file, bool followSymLinks=true); - - ~XdgMimeInfo(); - - /// Returns the name of the mime type. - QString mimeType() const; - - /// Returns the media type, eg. 'application' for mimetype 'application/pdf' - QString mediaType() const; - - /// Returns the subtype, e.g. 'pdf' for 'application/pdf' - QString subType() const; - - QString comment() const; - - QString localizedComment() const; - - QStringList patterns() const; - - /// Returns an icon associated with the mime type. - QIcon icon() const; - - /// Returns an icon associated with the mime type. - QString iconName() const; - - QString subClassOf() const; - - bool loadFromDb(QIODevice* xml); - -private: - XdgMimeData *mData; -}; - - -class QTXDG_DEPRECATED QTXDG_API XdgMimeInfoCache -{ -public: - static QStringList mediatypes(); - static QStringList subtypes(const QString & media); - static XdgMimeInfo* xdgMimeInfo(const QString & media, const QString & subtype); - static XdgMimeInfo* xdgMimeInfo(const QString & mimetype); - -private: - static QMap > & cache(); -}; - -#endif // QTXDG_XDGMIME_H diff --git a/xdgmimetype.cpp b/xdgmimetype.cpp index 7059e5c..7bb8987 100644 --- a/xdgmimetype.cpp +++ b/xdgmimetype.cpp @@ -22,6 +22,7 @@ #include "xdgicon.h" + class XdgMimeTypePrivate : public QSharedData { public: XdgMimeTypePrivate(); @@ -33,35 +34,41 @@ public: bool computed; }; + XdgMimeTypePrivate::XdgMimeTypePrivate() : computed(false) { } + XdgMimeTypePrivate::XdgMimeTypePrivate(const XdgMimeType& other) : iconName(other.dx->iconName), computed(other.dx->computed) { } + XdgMimeType::XdgMimeType() : QMimeType(), dx(new XdgMimeTypePrivate()) { } + XdgMimeType::XdgMimeType(const QMimeType& mime) : QMimeType(mime), dx(new XdgMimeTypePrivate()) { } + XdgMimeType::XdgMimeType(const XdgMimeType& mime) : QMimeType(mime), dx(mime.dx) { } + XdgMimeType &XdgMimeType::operator=(const XdgMimeType &other) { QMimeType::operator =(other); @@ -72,10 +79,12 @@ XdgMimeType &XdgMimeType::operator=(const XdgMimeType &other) return *this; } + XdgMimeType::~XdgMimeType() { } + QString XdgMimeType::iconName() const { if (dx->computed) { @@ -98,6 +107,7 @@ QString XdgMimeType::iconName() const } } + QIcon XdgMimeType::icon() const { return XdgIcon::fromTheme((iconName())); diff --git a/xdgmimetype.h b/xdgmimetype.h index a654834..0edf085 100644 --- a/xdgmimetype.h +++ b/xdgmimetype.h @@ -121,9 +121,6 @@ protected: }; -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) -#else Q_DECLARE_SHARED(XdgMimeType) -#endif #endif // QTXDG_MIMETYPE_H