Merging upstream version 1.2.0+20150807.

ubuntu/cosmic
Andrew Lee (李健秋) 9 years ago
parent e1f045ac33
commit 4865e7f1d7

@ -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 "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_FILE_NAME}>"
INTERFACE "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
INTERFACE "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${QTXDGX_FILE_NAME}/${QTXDG_VERSION_STRING}>"
)
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 "$<BUILD_INTERFACE:${QTXDGX_INTREE_INCLUDEDIR}/${QTXDGX_FILE_NAME}>"
INTERFACE "$<BUILD_INTERFACE:${QTXDGX_INTREE_INCLUDEDIR}>"
INTERFACE "$<BUILD_INTERFACE:${QTXDGX_INTREE_INCLUDEDIR}/${QTXDGX_FILE_NAME}/${QTXDG_VERSION_STRING}>"
)
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)

@ -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 ..

@ -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)

@ -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=<value> (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)

@ -0,0 +1,94 @@
#=============================================================================
# Copyright 2015 Luís Pereira <luis.artur.pereira@gmail.com>
#
# 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 ``<LANG>_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})

@ -1,36 +1,245 @@
#=============================================================================
# Copyright 2015 Luís Pereira <luis.artur.pereira@gmail.com>
#
# 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 <package_name>
# VERSION <version>
# [PREFIX <path>]
# [EXEC_PREFIX <path>]
# [INCLUDEDIR_PREFIX <path>]
# [INCLUDEDIRS <path1> <path2> ... <path3>]
# [LIBDIR_PREFIX <path>]
# [DESCRIPTIVE_NAME <name>]
# [DESCRIPTION <description>]
# [URL <url>]
# [REQUIRES <dep1> <dep2> ... <dep3>]
# [REQUIRES_PRIVATE <dep1> <dep2> ... <dep3>]
# [LIB_INSTALLDIR <dir>]
# [CFLAGS <cflags>]
# [PATH <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()

@ -1,8 +1,51 @@
#=============================================================================
# Copyright 2015 Luís Pereira <luis.artur.pereira@gmail.com>
#
# 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(<portable_headers>
# HEADER_NAMES <CamelCaseName> [<CamelCaseName1> [...]]
# [OUTPUT_DIR <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)

@ -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")

@ -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}")

@ -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)

@ -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()

@ -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 <luis.artur.pereira@gmail.com>
*
* 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 <QtCore/QByteArray>

@ -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)

@ -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 ..

@ -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<QIconDirInfo> 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 <kaitlin.rupert@intel.com>
@ -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<QIconEngine::AvailableSizesArgument*>(data);
const int N = m_entries.size();
const int N = m_info.entries.size();
QList<QSize> 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

@ -107,6 +107,12 @@ struct PixmapEntry : public QIconLoaderEngineEntry
typedef QList<QIconLoaderEngineEntry*> 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 <QIconDirInfo> 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 <QIconDirInfo> 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;

@ -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 <QtGui/QIcon>
#include <QtGui/QIconEngine>
#include <QtGui/QPixmapCache>
//#include "qt/qicon_p.h"
//#include "qt/qfactoryloader_p.h"
#include <QHash>
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<QIconLoaderEngineEntry*> 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 <QIconDirInfo> 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 <QIconDirInfo> 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 <QString, QIconTheme> themeList;
};
} // QtXdg
#endif // QDESKTOPICON_P_H
#endif //QT_NO_ICON

@ -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 <qt/qicon_p.h>
//#include <qt/qguiplatformplugin_p.h>
#include <QtGui/QIconEnginePlugin>
#include <QtGui/QPixmapCache>
#include <QtGui/QIconEngine>
#include <QStyleOption>
#include <QList>
#include <QHash>
#include <QDir>
#include <QSettings>
#include <QtGui/QPainter>
#include <QApplication>
#include <QLatin1Literal>
//#ifdef Q_WS_MAC
//#include <private/qt_cocoa_helpers_mac_p.h>
//#endif
//#ifdef Q_WS_X11
//#include "qt/qt_x11_p.h"
//#endif
#include <QDebug>
#if QT_VERSION < 0x040700
#include <limits.h>
#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 <QIconDirInfo> 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<QIconDirInfo> 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 <kaitlin.rupert@intel.com>
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<int>(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<QIconEngineV2::AvailableSizesArgument*>(data);
#else
QIconEngine::AvailableSizesArgument &arg
= *reinterpret_cast<QIconEngine::AvailableSizesArgument*>(data);
#endif
const QList<QIconDirInfo> 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<QString*>(data);
name = m_iconName;
}
break;
#elif QT_VERSION > QT_VERSION_CHECK(5,0,0)
case QIconEngine::IconNameHook:
{
QString &name = *reinterpret_cast<QString*>(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

@ -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
)

@ -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 <christian@surlykke.dk>
* Jerome Leclanche <jerome@leclan.ch>
* Luís Pereira <luis.artur.pereira@gmail.com>
*
* 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"

@ -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 <christian@surlykke.dk>
* Luís Pereira <luis.artur.pereira@gmail.com>
* Jerome Leclanche <jerome@leclan.ch>
*
* 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

@ -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 <luis.artur.pereira@gmail.com>
*
* 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 <QObject>
#include "xdgdirs.h"
#include <QtTest>
#include <QTemporaryDir>
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"

@ -32,18 +32,12 @@
#include <QCoreApplication>
/************************************************
************************************************/
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());

@ -36,12 +36,8 @@
#include "xdgdesktopfile.h"
#include "xdgdesktopfile_p.h"
#ifdef HAVE_QTMIMETYPES
#include <QMimeDatabase>
#include <QMimeType>
#else
#include "xdgmime.h"
#endif
#include "xdgicon.h"
#include "xdgdirs.h"
@ -58,10 +54,7 @@
#include <QUrl>
#include <QDesktopServices>
#include <QStringBuilder> // for the % operator
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
#else
#include <QStandardPaths>
#endif
#include <QList>
#include <QtAlgorithms>
@ -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<QString, QList<XdgDesktopFile*> > & cache);
/************************************************
************************************************/
QString &doEscape(QString& str, const QHash<QChar,QChar> &repl)
{
// First we replace slash.
@ -166,10 +158,6 @@ QString &escapeExec(QString& str)
}
/************************************************
************************************************/
QString &doUnEscape(QString& str, const QHash<QChar,QChar> &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<QProcess> 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<QString, QList<XdgDesktopFile*> > & cache)
{
QDir dir(dirName);
@ -1643,7 +1496,7 @@ void loadMimeCacheDir(const QString& dirName, QHash<QString, QList<XdgDesktopFil
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 = 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<XdgDesktopFile*> 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;
}

@ -33,7 +33,6 @@
#include "xdgmacros.h"
#include <QSharedDataPointer>
//#include <QObject>
#include <QString>
#include <QVariant>
#include <QStringList>
@ -41,7 +40,7 @@
#include <QSettings>
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<QString, QList<XdgDesktopFile*> > m_defaultAppsCache;

@ -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 <luis.artur.pereira@gmail.com>
*
* 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

@ -25,15 +25,12 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#include "xdgdirs.h"
#include <stdlib.h>
#include <QDir>
#include <QStringBuilder> // for the % operator
#include <QDebug>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QStandardPaths>
#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<QString> 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<QString> 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;

@ -25,8 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef QTXDG_XDGDIRS_H
#define QTXDG_XDGDIRS_H

@ -25,8 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#include "xdgicon.h"
#include <QString>
@ -35,18 +33,11 @@
#include <QStringList>
#include <QFileInfo>
#include <QCache>
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
#include "qiconfix/qiconloader_p_qt4.h"
#else
#include "qiconfix/qiconloader_p.h"
#endif
#include <QCoreApplication>
#define DEFAULT_APP_ICON "application-x-executable"
/************************************************
************************************************/
static void qt_cleanup_icon_cache();
typedef QCache<QString, QIcon> 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;

@ -25,8 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef QTXDG_XDGICON_H
#define QTXDG_XDGICON_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

@ -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<QString, QDomElement> 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;

@ -25,8 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef QTXDG_XDGMENU_H
#define QTXDG_XDGMENU_H
@ -36,7 +34,6 @@
#include <QStringList>
#include <QtXml/QDomDocument>
class QDomDocument;
class QDomElement;
class XdgMenuPrivate;

@ -25,7 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#include "xdgmenu.h"
#include <QObject>
#include <QFileSystemWatcher>
@ -85,4 +84,3 @@ private:
XdgMenu* const q_ptr;
Q_DECLARE_PUBLIC(XdgMenu)
};

@ -25,7 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#include "xdgmenu.h"
#include "xdgmenuapplinkprocessor.h"
#include "xmlhelper.h"
@ -34,9 +33,6 @@
#include <QDir>
/************************************************
************************************************/
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());

@ -25,7 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef QTXDG_XDGMENUAPPLINKPROCESSOR_H
#define QTXDG_XDGMENUAPPLINKPROCESSOR_H
@ -45,6 +44,7 @@ typedef QLinkedList<XdgMenuAppFileInfo*> XdgMenuAppFileInfoList;
typedef QHash<QString, XdgMenuAppFileInfo*> XdgMenuAppFileInfoHash;
typedef QHashIterator<QString, XdgMenuAppFileInfo*> XdgMenuAppFileInfoHashIterator;
class XdgMenuApplinkProcessor : public QObject
{
Q_OBJECT
@ -98,5 +98,4 @@ private:
QString mId;
};
#endif // QTXDG_XDGMENUAPPLINKPROCESSOR_H

@ -25,7 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#include "xdgmenulayoutprocessor.h"
#include "xmlhelper.h"
#include <QDebug>
@ -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);
}

@ -25,7 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef QTXDG_XDGMENULAYOUTPROCESSOR_H
#define QTXDG_XDGMENULAYOUTPROCESSOR_H

@ -25,7 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#include "xdgmenureader.h"
#include "xdgmenu.h"
#include "xdgdirs.h"
@ -41,10 +40,6 @@
#include <QtXml/QDomNode>
/************************************************
************************************************/
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);
}
}

@ -25,7 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef QTXDG_XDGMENUREADER_H
#define QTXDG_XDGMENUREADER_H
@ -34,6 +33,7 @@
#include <QStringList>
#include <QtXml/QDomDocument>
#include <QtXml/QDomElement>
class XdgMenu;
class XdgMenuReader : public QObject
{

@ -25,7 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
/*********************************************************************
See: http://standards.freedesktop.org/desktop-entry-spec
@ -38,10 +37,6 @@
#include <QDebug>
/************************************************
************************************************/
XdgMenuRule::XdgMenuRule(const QDomElement& element, QObject* parent) :
QObject(parent)
{
@ -49,17 +44,11 @@ XdgMenuRule::XdgMenuRule(const QDomElement& element, QObject* parent) :
}
/************************************************
************************************************/
XdgMenuRule::~XdgMenuRule()
{
}
/************************************************
The <Or> element contains a list of matching rules. If any of the matching rules
inside the <Or> element match a desktop entry, then the entire <Or> rule matches
@ -100,9 +89,6 @@ XdgMenuRuleOr::XdgMenuRuleOr(const QDomElement& element, QObject* parent) :
}
/************************************************
************************************************/
bool XdgMenuRuleOr::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile)
{
for (QLinkedList<XdgMenuRule*>::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<XdgMenuRule*>::Iterator i=mChilds.begin(); i!=mChilds.end(); ++i)
@ -136,7 +119,6 @@ bool XdgMenuRuleAnd::check(const QString& desktopFileId, const XdgDesktopFile& d
}
/************************************************
The <Not> element contains a list of matching rules. If any of the matching rules
inside the <Not> element matches a desktop entry, then the entire <Not> 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 <Filename> 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 <Category> 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<XdgMenuRule*>::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<XdgMenuRule*>::Iterator i=mExcludeRules.begin(); i!=mExcludeRules.end(); ++i)
@ -285,5 +233,3 @@ bool XdgMenuRules::checkExclude(const QString& desktopFileId, const XdgDesktopFi
return false;
}

@ -40,6 +40,7 @@
#include "xdgdesktopfile.h"
class XdgMenuRule : public QObject
{
Q_OBJECT

@ -25,7 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#include "xdgmenuwidget.h"
#include "xdgicon.h"
#include "xmlhelper.h"
@ -35,14 +34,12 @@
#include <QEvent>
#include <QDebug>
#include <QUrl>
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
#else
#include <QMimeData>
#endif
#include <QtGui/QDrag>
#include <QtGui/QMouseEvent>
#include <QApplication>
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("&", "&&");
}

@ -25,7 +25,6 @@
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef QTXDG_XDGMENUWIDGET_H
#define QTXDG_XDGMENUWIDGET_H

@ -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 <sokoloff.a@gmail.com>
*
* 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 <QFileInfo>
#include <magic.h>
#include <QDebug>
#include <QStringList>
#include <QMap>
#include <QDir>
#include <QFileInfo>
#include <QFile>
#include <QDomDocument>
#include <QDomElement>
#include <QSharedData>
struct XdgMimeData
{
public:
XdgMimeData(QString media, QString subtype);
bool readXml(QIODevice* xml);
QString mMedia;
QString mSubtype;
bool mDbLoaded;
QString mComment;
QMap<QString, QString> 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<QString> 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<QString, QMap<QString, XdgMimeInfo*> > & 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<QString, QMap<QString, XdgMimeInfo*> > & XdgMimeInfoCache::cache()
{
static QMap<QString, QMap<QString, XdgMimeInfo*> > _cache;
static bool cache_loaded = false;
if (! cache_loaded)
{
loadMimeInfoCache(_cache);
cache_loaded = true;
}
return _cache;
}

@ -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 <sokoloff.a@gmail.com>
*
* 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 <QString>
#include <QFileInfo>
#include <QtGui/QIcon>
#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<QString, QMap<QString, XdgMimeInfo*> > & cache();
};
#endif // QTXDG_XDGMIME_H

@ -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()));

@ -121,9 +121,6 @@ protected:
};
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
#else
Q_DECLARE_SHARED(XdgMimeType)
#endif
#endif // QTXDG_MIMETYPE_H

Loading…
Cancel
Save