summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSlávek Banko <slavek.banko@axis.cz>2018-11-25 01:55:01 +0100
committerSlávek Banko <slavek.banko@axis.cz>2018-11-25 01:55:01 +0100
commitf87cec4baae8c7bc02850edef84ac1d219df82b6 (patch)
tree8fb55e6baa1995147ea38a9487a998fd830339a9
parente5692c8bdbde55e425a1ec60601680d1114b909d (diff)
downloadtde-cmake-f87cec4baae8c7bc02850edef84ac1d219df82b6.tar.gz
tde-cmake-f87cec4baae8c7bc02850edef84ac1d219df82b6.zip
Add TDEL10n module
Signed-off-by: Slávek Banko <slavek.banko@axis.cz>
-rw-r--r--modules/TDEL10n.cmake353
1 files changed, 353 insertions, 0 deletions
diff --git a/modules/TDEL10n.cmake b/modules/TDEL10n.cmake
new file mode 100644
index 0000000..166ab00
--- /dev/null
+++ b/modules/TDEL10n.cmake
@@ -0,0 +1,353 @@
+#################################################
+#
+# (C) 2018 Slávek Banko
+# slavek (DOT) banko (AT) axis.cz
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+
+##### include essential TDE macros ##############
+
+if( NOT DEFINED MASTER_SOURCE_DIR )
+ set( MASTER_SOURCE_DIR "${CMAKE_SOURCE_DIR}" )
+ include( TDEMacros )
+endif( )
+
+
+##### verify required programs ##################
+
+if( NOT DEFINED TDE_PREFIX AND IS_DIRECTORY /opt/trinity )
+ set( TDE_PREFIX "/opt/trinity" )
+else( )
+ set( TDE_PREFIX "/usr" )
+endif( )
+
+if( NOT DEFINED KDE_XGETTEXT_EXECUTABLE )
+ find_program( KDE_XGETTEXT_EXECUTABLE
+ NAMES kde-xgettext
+ HINTS "${TDE_PREFIX}/bin"
+ )
+ if( NOT KDE_XGETTEXT_EXECUTABLE )
+ tde_message_fatal( "kde-xgettext is required but not found" )
+ endif( )
+endif( )
+
+if( NOT DEFINED EXTRACTRC_EXECUTABLE )
+ find_program( EXTRACTRC_EXECUTABLE
+ NAMES extractrc
+ HINTS "${TDE_PREFIX}/bin"
+ )
+ if( NOT EXTRACTRC_EXECUTABLE )
+ tde_message_fatal( "extractrc is required but not found" )
+ endif( )
+endif( )
+
+if( NOT DEFINED XGETTEXT_EXECUTABLE )
+ find_program( XGETTEXT_EXECUTABLE
+ NAMES xgettext
+ HINTS "${TDE_PREFIX}/bin"
+ )
+ if( NOT XGETTEXT_EXECUTABLE )
+ tde_message_fatal( "xgettext is required but not found" )
+ endif( )
+ execute_process(
+ COMMAND ${XGETTEXT_EXECUTABLE} --version
+ OUTPUT_VARIABLE _xgettext_version
+ ERROR_VARIABLE _xgettext_version
+ )
+ string( REGEX REPLACE "^xgettext[^\n]* ([^ ]*)\n.*" "\\1" _xgettext_version ${_xgettext_version} )
+ if( "${_xgettext_version}" VERSION_LESS "0.19" )
+ tde_message_fatal( "xgettext version >= 0.19 is required but found only ${_xgettext_version}" )
+ endif( )
+endif( )
+
+if( NOT DEFINED MSGUNIQ_EXECUTABLE )
+ find_program( MSGUNIQ_EXECUTABLE
+ NAMES msguniq
+ HINTS "${TDE_PREFIX}/bin"
+ )
+ if( NOT MSGUNIQ_EXECUTABLE )
+ tde_message_fatal( "msguniq is required but not found" )
+ endif( )
+endif( )
+
+
+#################################################
+#####
+##### tde_add_l10n_subdirectory
+#####
+##### The function simulates the add_subdirectory() behavior, but
+##### the CMakeL10n.txt file is used instead of CMakeLists.txt.
+#####
+
+function( tde_add_l10n_subdirectory _dir )
+ set( CMAKE_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${_dir}" )
+ set( CMAKE_CURRENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/${_dir}" )
+ include( ${CMAKE_CURRENT_SOURCE_DIR}/CMakeL10n.txt )
+endfunction( )
+
+
+#################################################
+#####
+##### tde_auto_add_l10n_subdirectories
+
+function( tde_auto_add_l10n_subdirectories )
+ file( GLOB _dirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/*" )
+ foreach( _dir ${_dirs} )
+ if( IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_dir}
+ AND NOT ${_dir} STREQUAL ".svn"
+ AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_dir}/CMakeL10n.txt )
+ tde_add_l10n_subdirectory( ${_dir} )
+ endif( )
+ endforeach( )
+endfunction( )
+
+
+#################################################
+#####
+##### tde_create_l10n_template
+
+macro( tde_create_l10n_template )
+
+ unset( _catalog )
+ unset( _sources )
+ unset( _files )
+ unset( _rcs )
+ unset( _desktops )
+ unset( _dest )
+ unset( _keywords )
+ unset( _directive )
+ unset( _var )
+ unset( _pot )
+
+ foreach( _arg ${ARGN} )
+
+ # found directive "CATALOG"
+ if( "+${_arg}" STREQUAL "+CATALOG" )
+ unset( _catalog )
+ set( _var _catalog )
+ set( _directive 1 )
+ endif( )
+
+ # found directive "SOURCES"
+ if( "+${_arg}" STREQUAL "+SOURCES" )
+ unset( _sources )
+ set( _var _sources )
+ set( _directive 1 )
+ endif( )
+
+ # found directive "DESTINATION"
+ if( "+${_arg}" STREQUAL "+DESTINATION" )
+ unset( _dest )
+ set( _var _dest )
+ set( _directive 1 )
+ endif( )
+
+ # found directive "KEYWORDS"
+ if( "+${_arg}" STREQUAL "+KEYWORDS" )
+ unset( _keywords )
+ set( _var _keywords )
+ set( _directive 1 )
+ endif( )
+
+ # collect data
+ if( _directive )
+ unset( _directive )
+ elseif( _var )
+ list( APPEND ${_var} ${_arg} )
+ endif( )
+
+ endforeach( )
+
+ # verify catalog
+ if( NOT _catalog )
+ tde_message_fatal( "the name of the translation catalog is not defined" )
+ endif( )
+ if( ${_dest} MATCHES "[^/]$" )
+ set( _dest "${_dest}/" )
+ endif( )
+
+ get_filename_component( _potFilename "${CMAKE_CURRENT_SOURCE_DIR}/${_dest}${_catalog}.pot" ABSOLUTE )
+ file( RELATIVE_PATH _potFilename ${CMAKE_SOURCE_DIR} ${_potFilename} )
+ message( STATUS "Create translation template ${_potFilename}" )
+
+ # verify sources
+ if( NOT _sources )
+ # add current directory
+ list( APPEND _sources "." )
+ endif( )
+ foreach( _src ${_sources} )
+
+ # add all source files from directory
+ if( IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_src} )
+ if( ${_src} STREQUAL "." )
+ set( _dir "${CMAKE_CURRENT_SOURCE_DIR}" )
+ else( )
+ set( _dir "${CMAKE_CURRENT_SOURCE_DIR}/${_src}" )
+ endif( )
+ file( GLOB_RECURSE _add_files
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ ${_dir}/*.c
+ ${_dir}/*.cc
+ ${_dir}/*.cpp
+ ${_dir}/*.h
+ ${_dir}/*.kcfg
+ ${_dir}/*.rc
+ ${_dir}/*.ui
+ )
+ list( SORT _add_files )
+ list( APPEND _files ${_add_files} )
+
+ # add files by the specified mask
+ elseif( ${_src} MATCHES "(\\*|\\?)" )
+ file( GLOB_RECURSE _add_files
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/${_src}
+ )
+ list( SORT _add_files )
+ list( APPEND _files ${_add_files} )
+
+ # add a single file
+ elseif( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_src} )
+ list( APPEND _files ${_src} )
+ endif( )
+
+ endforeach( )
+ if( NOT _files )
+ tde_message_fatal( "no source files found" )
+ endif( )
+
+ # prepare additional keywords
+ unset( _add_keywords )
+ foreach( _keyword ${_keywords} )
+ list( APPEND _add_keywords "-k${_keyword}" )
+ endforeach( )
+
+ # pick resource files *.kcfg, *.rc and *.ui
+ foreach( _src ${_files} )
+ if( ${_src} MATCHES "\\.(kcfg|rc|ui)(\\.cmake)?$" )
+ list( APPEND _rcs ${_src} )
+ list( REMOVE_ITEM _files ${_src} )
+ endif( )
+ endforeach( )
+
+ # process resource files
+ if( _rcs )
+ execute_process(
+ COMMAND ${EXTRACTRC_EXECUTABLE} ${_rcs}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ OUTPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/extracted-rc.cpp
+ )
+ list( APPEND _files extracted-rc.cpp )
+ endif( )
+
+ # pick desktop files *.desktop and *.protocol
+ foreach( _src ${_files} )
+ if( ${_src} MATCHES "\\.(desktop|protocol)(\\.cmake)?$" )
+ list( APPEND _desktops ${_src} )
+ list( REMOVE_ITEM _files ${_src} )
+ endif( )
+ endforeach( )
+
+ # create translation template
+ if( _files )
+ execute_process(
+ COMMAND ${KDE_XGETTEXT_EXECUTABLE} --foreign-user -C
+ -ki18n -ki18n:1,2 -ktr2i18n -ktr2i18n:1,2
+ -kI18N_NOOP -kI18N_NOOP2 ${_add_keywords}
+ -o - ${_files}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ OUTPUT_VARIABLE _pot
+ )
+
+ # set charset and encoding headers
+ if( _pot )
+ string( REPLACE "Content-Type: text/plain charset=CHARSET" "Content-Type: text/plain charset=UTF-8" _pot ${_pot} )
+ string( REPLACE "Content-Transfer-Encoding: ENCODING" "Content-Transfer-Encoding: 8bit" _pot ${_pot} )
+ endif( )
+ endif( )
+
+ # process desktop files
+ if( _desktops )
+ # create translation template for desktop files
+ if( _pot )
+ set( _withPotHeader "--omit-header" )
+ else( )
+ set( _withPotHeader "--foreign-user" )
+ endif( )
+ execute_process(
+ COMMAND ${XGETTEXT_EXECUTABLE} ${_withPotHeader} -L Desktop
+ -kDescription -kExtraNames -kX-TDE-Submenu ${_add_keywords}
+ -o - ${_desktops}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ OUTPUT_VARIABLE _potDesktop
+ )
+
+ # merge translation templates
+ if( _potDesktop )
+ if( _pot )
+ file( WRITE ${CMAKE_CURRENT_SOURCE_DIR}/extracted-pot.tmp ${_pot} )
+ file( APPEND ${CMAKE_CURRENT_SOURCE_DIR}/extracted-pot.tmp ${_potDesktop} )
+ execute_process(
+ COMMAND ${MSGUNIQ_EXECUTABLE}
+ INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/extracted-pot.tmp
+ OUTPUT_VARIABLE _pot
+ )
+ file( REMOVE ${CMAKE_CURRENT_SOURCE_DIR}/extracted-pot.tmp )
+ else( )
+ set( _pot ${_potDesktop} )
+
+ # set charset and encoding headers
+ string( REPLACE "Content-Type: text/plain charset=CHARSET" "Content-Type: text/plain charset=UTF-8" _pot ${_pot} )
+ string( REPLACE "Content-Transfer-Encoding: ENCODING" "Content-Transfer-Encoding: 8bit" _pot ${_pot} )
+ endif( )
+ endif( )
+ endif( )
+
+ # finalize translation template
+ if( _pot )
+
+ # update references for resources to original files and line numbers
+ if( _rcs )
+ file( STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/extracted-rc.cpp" _extractedRC )
+ list( LENGTH _extractedRC _extractedRC_len )
+ set( _rcPos 0 )
+ while( _rcPos LESS ${_extractedRC_len} )
+ list( GET _extractedRC ${_rcPos} _rcLine )
+ math( EXPR _rcPos "${_rcPos}+1" )
+ if( "${_rcLine}" MATCHES "^//i18n: file .* line [0-9]*$" )
+ string( REGEX REPLACE "^//i18n: file (.*) line ([0-9]*)$" "\\1:\\2" _rcOrig ${_rcLine} )
+ endif( )
+ if( "${_rcLine}" MATCHES "^i18n\\(" AND _rcOrig )
+ string( REGEX REPLACE "(^|\n)(#:.*) extracted-rc.cpp:${_rcPos}( |\n)" "\\1\\2 ${_rcOrig}\\3" _pot ${_pot} )
+ unset( _rcOrig )
+ endif( )
+ endwhile( )
+ endif( )
+
+ # save translation template
+ if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_dest}${_catalog}.pot" )
+ file( READ "${CMAKE_CURRENT_SOURCE_DIR}/${_dest}${_catalog}.pot" _potOrig )
+ else( )
+ unset( _potOrig )
+ endif( )
+ if( _potOrig )
+ string( REGEX REPLACE "\n\"POT-Creation-Date: [^\"]*\"\n" "" _potOrig ${_potOrig} )
+ string( REGEX REPLACE "\n\"POT-Creation-Date: [^\"]*\"\n" "" _potNew ${_pot} )
+ endif( )
+ if( NOT _potOrig OR NOT "${_potNew}" STREQUAL "${_potOrig}" )
+ file( WRITE "${CMAKE_CURRENT_SOURCE_DIR}/${_dest}${_catalog}.pot" ${_pot} )
+ endif( )
+
+ endif( _pot )
+
+ # cleanup
+ if( _rcs )
+ file( REMOVE ${CMAKE_CURRENT_SOURCE_DIR}/extracted-rc.cpp )
+ endif( )
+
+endmacro( )