# SPDX-FileCopyrightText: 2014 Alex Merry # SPDX-FileCopyrightText: 2013 David Edmundson # SPDX-FileCopyrightText: 2008 Chusslove Illich # SPDX-FileCopyrightText: 2006 Alex Neundorf # # SPDX-License-Identifier: BSD-3-Clause #[=======================================================================[.rst: ECMInstallIcons --------------- Installs icons, sorting them into the correct directories according to the FreeDesktop.org icon naming specification. :: ecm_install_icons(ICONS [ [...]] DESTINATION [LANG ] [THEME ]) The given icons, whose names must match the pattern:: --. will be installed to the appropriate subdirectory of ``DESTINATION`` according to the FreeDesktop.org icon naming scheme. By default, they are installed to the "hicolor" theme, but this can be changed using the ``THEME`` argument. If the icons are localized, the LANG argument can be used to install them in a locale-specific directory. ```` is a numeric pixel size (typically 16, 22, 32, 48, 64, 128 or 256) or ``sc`` for scalable (SVG) files, ```` is one of the standard FreeDesktop.org icon groups (actions, animations, apps, categories, devices, emblems, emotes, intl, mimetypes, places, status) and ```` is one of ``.png``, ``.mng`` or ``.svgz``. The typical installation directory is ``share/icons``. .. code-block:: cmake ecm_install_icons(ICONS 22-actions-menu_new.png DESTINATION share/icons) The above code will install the file ``22-actions-menu_new.png`` as ``${CMAKE_INSTALL_PREFIX}/share/icons//22x22/actions/menu_new.png`` Users of the :kde-module:`KDEInstallDirs` module would normally use ``${KDE_INSTALL_ICONDIR}`` as the DESTINATION, while users of the GNUInstallDirs module should use ``${CMAKE_INSTALL_DATAROOTDIR}/icons``. An old form of arguments will also be accepted:: ecm_install_icons( []) This matches files named like:: --. where ```` is one of * ``hi`` for hicolor * ``lo`` for locolor * ``cr`` for the Crystal icon theme * ``ox`` for the Oxygen icon theme * ``br`` for the Breeze icon theme With this syntax, the file ``hi22-actions-menu_new.png`` would be installed into ``/hicolor/22x22/actions/menu_new.png`` Since pre-1.0.0. #]=======================================================================] # A "map" of short type names to the directories. # Unknown names produce a warning. set(_ECM_ICON_GROUP_mimetypes "mimetypes") set(_ECM_ICON_GROUP_places "places") set(_ECM_ICON_GROUP_devices "devices") set(_ECM_ICON_GROUP_apps "apps") set(_ECM_ICON_GROUP_actions "actions") set(_ECM_ICON_GROUP_categories "categories") set(_ECM_ICON_GROUP_status "status") set(_ECM_ICON_GROUP_emblems "emblems") set(_ECM_ICON_GROUP_emotes "emotes") set(_ECM_ICON_GROUP_animations "animations") set(_ECM_ICON_GROUP_intl "intl") # For the "compatibility" syntax: a "map" of short theme names to the theme # directory set(_ECM_ICON_THEME_br "breeze") set(_ECM_ICON_THEME_ox "oxygen") set(_ECM_ICON_THEME_cr "crystalsvg") set(_ECM_ICON_THEME_lo "locolor") set(_ECM_ICON_THEME_hi "hicolor") macro(_ecm_install_icons_v1 _defaultpath) # the l10n-subdir if language given as second argument (localized icon) set(_lang ${ARGV1}) if(_lang) set(_l10n_SUBDIR l10n/${_lang}) else() set(_l10n_SUBDIR ".") endif() set(_themes) # first the png icons file(GLOB _icons *.png) foreach (_current_ICON ${_icons} ) # since CMake 2.6 regex matches are stored in special variables CMAKE_MATCH_x, if it didn't match, they are empty string(REGEX MATCH "^.*/([a-zA-Z]+)([0-9]+)\\-([a-z]+)\\-(.+\\.png)$" _dummy "${_current_ICON}") set(_type "${CMAKE_MATCH_1}") set(_size "${CMAKE_MATCH_2}") set(_group "${CMAKE_MATCH_3}") set(_name "${CMAKE_MATCH_4}") set(_theme_GROUP ${_ECM_ICON_THEME_${_type}}) if( _theme_GROUP) list(APPEND _themes "${_theme_GROUP}") _ECM_ADD_ICON_INSTALL_RULE(${CMAKE_CURRENT_BINARY_DIR}/install_icons.cmake ${_defaultpath}/${_theme_GROUP}/${_size}x${_size} ${_group} ${_current_ICON} ${_name} ${_l10n_SUBDIR}) endif() endforeach (_current_ICON) # mng icons file(GLOB _icons *.mng) foreach (_current_ICON ${_icons} ) # since CMake 2.6 regex matches are stored in special variables CMAKE_MATCH_x, if it didn't match, they are empty string(REGEX MATCH "^.*/([a-zA-Z]+)([0-9]+)\\-([a-z]+)\\-(.+\\.mng)$" _dummy "${_current_ICON}") set(_type "${CMAKE_MATCH_1}") set(_size "${CMAKE_MATCH_2}") set(_group "${CMAKE_MATCH_3}") set(_name "${CMAKE_MATCH_4}") set(_theme_GROUP ${_ECM_ICON_THEME_${_type}}) if( _theme_GROUP) list(APPEND _themes "${_theme_GROUP}") _ECM_ADD_ICON_INSTALL_RULE(${CMAKE_CURRENT_BINARY_DIR}/install_icons.cmake ${_defaultpath}/${_theme_GROUP}/${_size}x${_size} ${_group} ${_current_ICON} ${_name} ${_l10n_SUBDIR}) endif() endforeach (_current_ICON) # and now the svg icons file(GLOB _icons *.svgz) foreach (_current_ICON ${_icons} ) # since CMake 2.6 regex matches are stored in special variables CMAKE_MATCH_x, if it didn't match, they are empty string(REGEX MATCH "^.*/([a-zA-Z]+)sc\\-([a-z]+)\\-(.+\\.svgz)$" _dummy "${_current_ICON}") set(_type "${CMAKE_MATCH_1}") set(_group "${CMAKE_MATCH_2}") set(_name "${CMAKE_MATCH_3}") set(_theme_GROUP ${_ECM_ICON_THEME_${_type}}) if( _theme_GROUP) list(APPEND _themes "${_theme_GROUP}") _ECM_ADD_ICON_INSTALL_RULE(${CMAKE_CURRENT_BINARY_DIR}/install_icons.cmake ${_defaultpath}/${_theme_GROUP}/scalable ${_group} ${_current_ICON} ${_name} ${_l10n_SUBDIR}) endif() endforeach (_current_ICON) if (_themes) list(REMOVE_DUPLICATES _themes) foreach(_theme ${_themes}) _ecm_update_iconcache("${_defaultpath}" "${_theme}") endforeach() else() message(AUTHOR_WARNING "No suitably-named icons found") endif() endmacro() # only used internally by _ecm_install_icons_v1 macro(_ecm_add_icon_install_rule _install_SCRIPT _install_PATH _group _orig_NAME _install_NAME _l10n_SUBDIR) # if the string doesn't match the pattern, the result is the full string, so all three have the same content if (NOT ${_group} STREQUAL ${_install_NAME} ) set(_icon_GROUP ${_ECM_ICON_GROUP_${_group}}) if(NOT _icon_GROUP) message(WARNING "Icon ${_install_NAME} uses invalid category ${_group}, setting to 'actions'") set(_icon_GROUP "actions") endif() # message(STATUS "icon: ${_current_ICON} size: ${_size} group: ${_group} name: ${_name} l10n: ${_l10n_SUBDIR}") install(FILES ${_orig_NAME} DESTINATION ${_install_PATH}/${_icon_GROUP}/${_l10n_SUBDIR}/ RENAME ${_install_NAME} ) endif (NOT ${_group} STREQUAL ${_install_NAME} ) endmacro() # Updates the mtime of the icon theme directory, so caches that # watch for changes to the directory will know to update. # If present, this also runs gtk-update-icon-cache (which despite the name is also used by Qt). function(_ecm_update_iconcache installdir theme) find_program(GTK_UPDATE_ICON_CACHE_EXECUTABLE NAMES gtk-update-icon-cache) # We don't always have touch command (e.g. on Windows), so instead # create and delete a temporary file in the theme dir. install(CODE " set(DESTDIR_VALUE \"\$ENV{DESTDIR}\") if (NOT DESTDIR_VALUE) execute_process(COMMAND \"${CMAKE_COMMAND}\" -E touch \"${CMAKE_INSTALL_PREFIX}/${installdir}/${theme}\") set(HAVE_GTK_UPDATE_ICON_CACHE_EXEC ${GTK_UPDATE_ICON_CACHE_EXECUTABLE}) if (HAVE_GTK_UPDATE_ICON_CACHE_EXEC) execute_process(COMMAND ${GTK_UPDATE_ICON_CACHE_EXECUTABLE} -q -t -i . WORKING_DIRECTORY \"${CMAKE_INSTALL_PREFIX}/${installdir}/${theme}\") endif () endif (NOT DESTDIR_VALUE) ") endfunction() function(ecm_install_icons) set(options) set(oneValueArgs DESTINATION LANG THEME) set(multiValueArgs ICONS) cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(NOT ARG_ICONS AND NOT ARG_DESTINATION) message(AUTHOR_WARNING "ecm_install_icons() with no ICONS argument is deprecated") _ecm_install_icons_v1(${ARGN}) return() endif() if(ARG_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unexpected arguments to ecm_install_icons: ${ARG_UNPARSED_ARGUMENTS}") endif() if(NOT ARG_DESTINATION) message(FATAL_ERROR "No DESTINATION argument given to ecm_install_icons") endif() if(NOT ARG_THEME) set(ARG_THEME "hicolor") endif() if(ARG_LANG) set(l10n_subdir "l10n/${ARG_LANG}/") endif() foreach(icon ${ARG_ICONS}) get_filename_component(filename "${icon}" NAME) string(REGEX MATCH "([0-9sc]+)\\-([a-z]+)\\-([^/]+)\\.([a-z]+)$" complete_match "${filename}") set(size "${CMAKE_MATCH_1}") set(group "${CMAKE_MATCH_2}") set(name "${CMAKE_MATCH_3}") set(ext "${CMAKE_MATCH_4}") if(NOT size OR NOT group OR NOT name OR NOT ext) message(WARNING "${icon} is not named correctly for ecm_install_icons - ignoring") elseif(NOT size STREQUAL "sc" AND NOT size GREATER 0) message(WARNING "${icon} size (${size}) is invalid - ignoring") else() if (NOT complete_match STREQUAL filename) # We can't stop accepting filenames with leading characters, # because that would break existing projects, so just warn # about them instead. message(AUTHOR_WARNING "\"${icon}\" has characters before the size; it should be renamed to \"${size}-${group}-${name}.${ext}\"") endif() if(NOT _ECM_ICON_GROUP_${group}) message(WARNING "${icon} group (${group}) is not recognized") endif() if(size STREQUAL "sc") if(NOT ext STREQUAL "svg" AND NOT ext STREQUAL "svgz") message(WARNING "Scalable icon ${icon} is not SVG or SVGZ") endif() set(size_dir "scalable") else() if(NOT ext STREQUAL "png" AND NOT ext STREQUAL "mng" AND NOT ext STREQUAL "svg" AND NOT ext STREQUAL "svgz") message(WARNING "Fixed-size icon ${icon} is not PNG/MNG/SVG/SVGZ") endif() set(size_dir "${size}x${size}") endif() install( FILES "${icon}" DESTINATION "${ARG_DESTINATION}/${ARG_THEME}/${size_dir}/${group}/${l10n_subdir}" RENAME "${name}.${ext}" ) endif() endforeach() _ecm_update_iconcache("${ARG_DESTINATION}" "${ARG_THEME}") endfunction()