diff --git a/BSD-3-Clause b/BSD-3-Clause new file mode 100644 index 0000000..887371d --- /dev/null +++ b/BSD-3-Clause @@ -0,0 +1,25 @@ +License: BSD-3-Clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/CMakeLists.txt b/CMakeLists.txt index d75ec85..8525086 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,13 +12,22 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + +include(Config.cmake) + +# QtCreator doesn't use the system locale and I see no way to prefix with LANG=XYZ.UTF-8 the command, +# so enabling these 2 settings we can test any language, see initLocale() in main.cpp. +set(PROJECT_TRANSLATION_TEST_ENABLED 0 CACHE STRING "Whether to enable translation testing [default: 0]") +set(PROJECT_TRANSLATION_TEST_LANGUAGE "en" CACHE STRING "Country code of language to test in IDE [default: en]") set(PROJECT_QT_VERSION 6 CACHE STRING "Qt version to use [Default: 6]") +option(PROJECT_TRANSLATIONS_UPDATE "Update source translations [default: OFF]" OFF) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize=undefined") #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize=undefined") find_package(QT NAMES Qt${PROJECT_QT_VERSION}) -find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools) find_package(PkgConfig REQUIRED) pkg_search_module(GLIB REQUIRED glib-2.0) find_package(LibXml2 REQUIRED) @@ -37,10 +46,56 @@ set(PROJECT_SOURCES keyboard-layouts.c keyboard-layouts.h ) -source_group("" FILES ${PROJECT_SOURCES}) +set(PROJECT_OTHER_FILES + .github/workflows/build.yml + README.md +) +file(GLOB PROJECT_TRANSLATION_SOURCES "${PROJECT_TRANSLATIONS_DIR}/*") +source_group("" FILES + ${PROJECT_SOURCES} + ${PROJECT_TRANSLATION_SOURCES} +) +#=================================================================================================== +# Translations +#=================================================================================================== +include(GNUInstallDirs) +include(LXQtTranslate) +lxqt_translate_ts(PROJECT_QM_FILES + SOURCES ${PROJECT_SOURCES} + TEMPLATE ${PROJECT_ID} + TRANSLATION_DIR "${PROJECT_TRANSLATIONS_DIR}" + UPDATE_TRANSLATIONS ${PROJECT_TRANSLATIONS_UPDATE} + INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/${PROJECT_ID}/translations" +) +lxqt_translate_desktop(PROJECT_DESKTOP_FILES + SOURCES "${CMAKE_BINARY_DIR}/${PROJECT_APPSTREAM_ID}.desktop.in" + TRANSLATION_DIR "${PROJECT_TRANSLATIONS_DIR}" + USE_YAML +) +#=================================================================================================== +# Application +#=================================================================================================== qt_add_executable(${PROJECT_NAME} MANUAL_FINALIZATION ${PROJECT_SOURCES} + ${PROJECT_DESKTOP_FILES} + ${PROJECT_OTHER_FILES} + ${PROJECT_QM_FILES} + ${PROJECT_TRANSLATION_SOURCES} +) +set(PROJECT_ICON_SYSTEM_PATH "${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/scalable/apps") +file(COPY_FILE "${CMAKE_SOURCE_DIR}/data/${PROJECT_APPSTREAM_ID}.svg" + "${CMAKE_BINARY_DIR}/${PROJECT_APPSTREAM_ID}.svg" +) +target_compile_definitions(${PROJECT_NAME} PRIVATE + APPLICATION_NAME="${PROJECT_NAME}" + APPLICATION_VERSION="${PROJECT_VERSION}" + PROJECT_ID="${PROJECT_ID}" + PROJECT_APPSTREAM_ID="${PROJECT_APPSTREAM_ID}" + PROJECT_DATA_DIR="${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}" + PROJECT_ICON_SYSTEM_PATH="${PROJECT_ICON_SYSTEM_PATH}" + PROJECT_TRANSLATION_TEST_ENABLED=${PROJECT_TRANSLATION_TEST_ENABLED} + PROJECT_TRANSLATION_TEST_LANGUAGE="${PROJECT_TRANSLATION_TEST_LANGUAGE}" ) target_include_directories(${PROJECT_NAME} PRIVATE ${GLIB_INCLUDE_DIRS}) target_include_directories(${PROJECT_NAME} PRIVATE ${LIBXML2_INCLUDE_DIR}) @@ -51,11 +106,39 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBXML2_LIBRARIES} ) #target_link_options(${PROJECT_NAME} BEFORE PUBLIC -fsanitize=undefined PUBLIC -fsanitize=address) - -include(GNUInstallDirs) +#=================================================================================================== +# Installation +#=================================================================================================== +configure_file("${CMAKE_SOURCE_DIR}/data/${PROJECT_APPSTREAM_ID}.desktop.in" + "${CMAKE_BINARY_DIR}/${PROJECT_APPSTREAM_ID}.desktop.in" @ONLY +) +configure_file("${CMAKE_SOURCE_DIR}/data/${PROJECT_APPSTREAM_ID}.appdata.xml.in" + "${CMAKE_BINARY_DIR}/${PROJECT_APPSTREAM_ID}.appdata.xml" @ONLY +) install(TARGETS ${PROJECT_NAME} BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_APPSTREAM_ID}.appdata.xml" + DESTINATION "${CMAKE_INSTALL_DATADIR}/metainfo" +) +install(FILES "${PROJECT_DESKTOP_FILES}" + DESTINATION "${CMAKE_INSTALL_DATADIR}/applications" +) +install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_APPSTREAM_ID}.svg" + # Don't use PROJECT_ICON_SYSTEM_PATH here which is absolute and doesn't take prefixes into account + DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps" +) qt_finalize_executable(${PROJECT_NAME}) +#=================================================================================================== +# Configuration report +#=================================================================================================== +message(STATUS " +Project name: ${PROJECT_NAME} +Version: ${PROJECT_VERSION} +Qt version: ${QT_VERSION} +Build type: ${CMAKE_BUILD_TYPE} +Install prefix: ${CMAKE_INSTALL_PREFIX} +Update translations before build: ${PROJECT_TRANSLATIONS_UPDATE} +") diff --git a/Config.cmake b/Config.cmake new file mode 100644 index 0000000..164f6ec --- /dev/null +++ b/Config.cmake @@ -0,0 +1,31 @@ +#=============================================================================== +# Editable project configuration +# +# Essential, non translatable application information (except DESCRIPTION). +# Translatable strings are passed via code. +#=============================================================================== +set(PROJECT_ID "labwc-tweaks") +list(APPEND PROJECT_CATEGORIES "Settings;System") # Freedesktop menu categories +list(APPEND PROJECT_KEYWORDS "labwc;wayland;compositor") +set(PROJECT_AUTHOR_NAME "Labwc Team") +set(PROJECT_COPYRIGHT_YEAR "2024") # TODO: from git +set(PROJECT_DESCRIPTION "Labwc Wayland compositor settings") +set(PROJECT_ORGANIZATION_NAME "labwc") +set(PROJECT_ORGANIZATION_URL "${PROJECT_ORGANIZATION_NAME}.github.io") +set(PROJECT_ORGANIZATION_ID "io.github.${PROJECT_ORGANIZATION_NAME}") +set(PROJECT_REPOSITORY_URL "https://github.com/${PROJECT_ORGANIZATION_NAME}/${PROJECT_ID}") +set(PROJECT_REPOSITORY_BRANCH "master") +set(PROJECT_HOMEPAGE_URL ${PROJECT_REPOSITORY_URL}) # TODO: "https://${PROJECT_ORGANIZATION_URL}/${PROJECT_ID}" +set(PROJECT_SPDX_ID "GPL-2.0-only") +set(PROJECT_TRANSLATIONS_DIR "${CMAKE_SOURCE_DIR}/data/translations") +set(PROJECT_SCREENSHOT_URL "https://github-production-user-asset-6210df.s3.amazonaws.com/1019119/294060534-84ef3747-f336-444e-9e2c-9a417ebe67e5.png") +#=============================================================================== +# Appstream +#=============================================================================== +set(PROJECT_APPSTREAM_SPDX_ID "CC0-1.0") +set(PROJECT_APPSTREAM_ID "labwc_tweaks") +#=============================================================================== +# Adapt to CMake variables +#=============================================================================== +set(${PROJECT_NAME}_DESCRIPTION "${PROJECT_DESCRIPTION}") +set(${PROJECT_NAME}_HOMEPAGE_URL "${PROJECT_HOMEPAGE_URL}") diff --git a/bin/lxqt-transupdate b/bin/lxqt-transupdate new file mode 100755 index 0000000..795df49 --- /dev/null +++ b/bin/lxqt-transupdate @@ -0,0 +1,50 @@ +#!/bin/sh + +#============================================================================= +# Copyright 2018 Alf Gaida +# +# 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. +#============================================================================= + +# lxqt-transupdate +# Update LXQt translation files. + +# just to be sure - for distributions that user qtchooser +# Debian and derivatives, Fedora, FreeBSD, Mageia, OpenMandriva, PCLinuxOS +export QT_SELECT=6 + +TEMPLATES=$(find . -name \*.ts | grep -v '_') +for i in $TEMPLATES; do + echo "\n\n==== $i ====\n" + TRANSDIR=$(dirname $i) + SOURCEDIR=$(dirname $TRANSDIR) + # template-update + echo "== Template Update ==" + echo "lupdate $SOURCEDIR -ts $i -locations absolute -no-obsolete\n" + lupdate $SOURCEDIR -ts $i -locations absolute -no-obsolete + echo + echo "== Language updates ==" + echo "lupdate $SOURCEDIR -ts $TRANSDIR/*_*.ts -locations absolute -no-obsolete\n" + lupdate $SOURCEDIR -ts $TRANSDIR/*_*.ts -locations absolute -no-obsolete +done diff --git a/cmake/LXQtTranslate.cmake b/cmake/LXQtTranslate.cmake new file mode 100644 index 0000000..e3c32c6 --- /dev/null +++ b/cmake/LXQtTranslate.cmake @@ -0,0 +1,223 @@ +#============================================================================= +# Copyright 2014 Luís Pereira +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= +# +# funtion lxqt_translate_ts(qmFiles +# [UPDATE_TRANSLATIONS [Yes | No]] +# SOURCES +# [UPDATE_OPTIONS] update_options +# [TEMPLATE] translation_template +# [TRANSLATION_DIR] translation_directory +# [INSTALL_DIR] install_directory +# [COMPONENT] component +# ) +# Output: +# qmFiles The generated compiled translations (.qm) files +# +# UPDATE_TRANSLATIONS Optional flag. Setting it to Yes, extracts and +# compiles the translations. Setting it No, only +# compiles them. +# +# UPDATE_OPTIONS Optional options to lupdate when UPDATE_TRANSLATIONS +# is True. +# +# TEMPLATE Optional translations files base name. Defaults to +# ${PROJECT_NAME}. An .ts extensions is added. +# +# TRANSLATION_DIR Optional path to the directory with the .ts files, +# relative to the CMakeList.txt. Defaults to +# "translations". +# +# INSTALL_DIR Optional destination of the file compiled files (qmFiles). +# If not present no installation is performed +# +# COMPONENT Optional install component. Only effective if INSTALL_DIR +# present. Defaults to "Runtime". +# +function(lxqt_translate_ts qmFiles) + set(oneValueArgs + UPDATE_TRANSLATIONS + TEMPLATE + TRANSLATION_DIR + INSTALL_DIR + COMPONENT + ) + set(multiValueArgs SOURCES UPDATE_OPTIONS) + cmake_parse_arguments(TR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (NOT DEFINED TR_UPDATE_TRANSLATIONS) + set(TR_UPDATE_TRANSLATIONS "No") + endif() + + if (NOT DEFINED TR_UPDATE_OPTIONS) + set(TR_UPDATE_OPTIONS "") + endif() + + + if(NOT DEFINED TR_TEMPLATE) + set(TR_TEMPLATE "${PROJECT_NAME}") + endif() + + if (NOT DEFINED TR_TRANSLATION_DIR) + set(TR_TRANSLATION_DIR "translations") + endif() + get_filename_component(TR_TRANSLATION_DIR "${TR_TRANSLATION_DIR}" ABSOLUTE) + + if (EXISTS "${TR_TRANSLATION_DIR}") + file(GLOB tsFiles "${TR_TRANSLATION_DIR}/${TR_TEMPLATE}_*.ts") + set(templateFile "${TR_TRANSLATION_DIR}/${TR_TEMPLATE}.ts") + endif () + + if (TR_UPDATE_TRANSLATIONS) + qt6_create_translation(QMS + ${TR_SOURCES} + ${templateFile} + OPTIONS ${TR_UPDATE_OPTIONS} + ) + qt6_create_translation(QM + ${TR_SOURCES} + ${tsFiles} + OPTIONS ${TR_UPDATE_OPTIONS} + ) + else() + qt6_add_translation(QM ${tsFiles}) + endif() + + if(TR_UPDATE_TRANSLATIONS) + add_custom_target("update_${TR_TEMPLATE}_ts" ALL DEPENDS ${QMS}) + endif() + + if(DEFINED TR_INSTALL_DIR) + if(NOT DEFINED TR_COMPONENT) + set(TR_COMPONENT "Runtime") + endif() + + install(FILES ${QM} + DESTINATION "${TR_INSTALL_DIR}" + COMPONENT "${TR_COMPONENT}" + ) + endif() + + set(${qmFiles} ${QM} PARENT_SCOPE) +endfunction() +#============================================================================= +# The lxqt_translate_desktop() function was copied from the +# LXQt LXQtTranslate.cmake +# +# Original Author: Alexander Sokolov +# +# funtion lxqt_translate_desktop(_RESULT +# SOURCES +# [TRANSLATION_DIR] translation_directory +# [USE_YAML] +# ) +# Output: +# _RESULT The generated .desktop (.desktop) files +# +# Input: +# +# SOURCES List of input desktop files (.destktop.in) to be translated +# (merged), relative to the CMakeList.txt. +# +# TRANSLATION_DIR Optional path to the directory with the .ts files, +# relative to the CMakeList.txt. Defaults to +# "translations". +# +# USE_YAML Flag if *.desktop.yaml translation should be used. +#============================================================================= +find_package(Perl REQUIRED) + +function(lxqt_translate_desktop _RESULT) + # Parse arguments *************************************** + set(options USE_YAML) + set(oneValueArgs TRANSLATION_DIR) + set(multiValueArgs SOURCES) + + cmake_parse_arguments(_ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # check for unknown arguments + set(_UNPARSED_ARGS ${_ARGS_UNPARSED_ARGUMENTS}) + if (NOT ${_UNPARSED_ARGS} STREQUAL "") + MESSAGE(FATAL_ERROR + "Unknown arguments '${_UNPARSED_ARGS}'.\n" + "See lxqt_translate_desktop() documentation for more information.\n" + ) + endif() + + if (NOT DEFINED _ARGS_SOURCES) + set(${_RESULT} "" PARENT_SCOPE) + return() + else() + set(_sources ${_ARGS_SOURCES}) + endif() + + if (NOT DEFINED _ARGS_TRANSLATION_DIR) + set(_translationDir "translations") + else() + set(_translationDir ${_ARGS_TRANSLATION_DIR}) + endif() + + get_filename_component (_translationDir ${_translationDir} ABSOLUTE) + + foreach (_inFile ${_sources}) + get_filename_component(_inFile ${_inFile} ABSOLUTE) + get_filename_component(_fileName ${_inFile} NAME_WE) + #Extract the real extension ............ + get_filename_component(_fileExt ${_inFile} EXT) + string(REPLACE ".in" "" _fileExt ${_fileExt}) + string(REGEX REPLACE "^\\.([^.].*)$" "\\1" _fileExt ${_fileExt}) + #....................................... + set(_outFile "${CMAKE_CURRENT_BINARY_DIR}/${_fileName}.${_fileExt}") + + if (_ARGS_USE_YAML) + add_custom_command(OUTPUT ${_outFile} + COMMAND ${PERL_EXECUTABLE} ${CMAKE_SOURCE_DIR}/cmake/LXQtTranslateDesktopYaml.pl ${_inFile} ${_fileName} ${_translationDir}/${_fileName}[_.]*${_fileExt}.yaml >> ${_outFile} + VERBATIM + COMMENT "Generating ${_fileName}.${_fileExt}" + ) + else () + file(GLOB _translations + ${_translationDir}/${_fileName}[_.]*${_fileExt} + ) + list(SORT _translations) + add_custom_command(OUTPUT ${_outFile} + COMMAND grep -v -a "#TRANSLATIONS_DIR=" ${_inFile} > ${_outFile} + VERBATIM + COMMENT "Generating ${_fileName}.${_fileExt}" + ) + if (_translations) + add_custom_command(OUTPUT ${_outFile} + COMMAND grep -h -a "\\[.*]\\s*=" ${_translations} >> ${_outFile} + VERBATIM APPEND + ) + endif () + endif () + + set(__result ${__result} ${_outFile}) + endforeach() + + set(${_RESULT} ${__result} PARENT_SCOPE) +endfunction(lxqt_translate_desktop) diff --git a/cmake/LXQtTranslateDesktopYaml.pl b/cmake/LXQtTranslateDesktopYaml.pl new file mode 100644 index 0000000..412a3eb --- /dev/null +++ b/cmake/LXQtTranslateDesktopYaml.pl @@ -0,0 +1,50 @@ +use strict; + +binmode(STDOUT, ":encoding(utf8)"); +binmode(STDERR, ":encoding(utf8)"); + +my $desktop_in = $ARGV[0]; +my $filename_base = $ARGV[1]; +my @translation_files = glob($ARGV[2]); + +my $section_re = qr/^\[([^\]]+)]/o; +my $lang_re = qr/^.*${filename_base}_([^.]+)\..+$/o; +my $strip_re = qr/#TRANSLATIONS_DIR=/o; + +sub flush_translations { + my ($curr_section) = @_; + if (defined $curr_section) { + my $transl_yaml_re = qr/^${curr_section}\/([^: ]+) ?: *([^ ].*)$/; + foreach my $file (@translation_files) { + my $language = ($file =~ $lang_re ? "[$1]" : ''); + open(my $trans_fh, '<:encoding(UTF-8)', $file) or next; + while (my $trans_l = <$trans_fh>) { + if ($trans_l =~ $transl_yaml_re) + { + my ($key, $value) = ($1, $2); + $value =~ s/^\s+|\s+$//; $value =~ s/^['"]//; $value =~ s/['"]$//; + if (length($value)) + { + # Don't flush empty (untranslated) strings + print(STDOUT "$key$language=$value\n"); + } + } + } + close($trans_fh); + } + } +} + + +open(my $fh, '<:encoding(UTF-8)', $desktop_in) or die "Could not open file '$desktop_in' $!"; +my $curr_section = undef; +while (my $line = <$fh>) { + if ($line =~ $section_re) { + flush_translations($curr_section); + $curr_section = $1; + } + $line =~ $strip_re or print(STDOUT $line); +} +flush_translations($curr_section); + +close($fh); diff --git a/data/labwc-tweaks.desktop b/data/labwc-tweaks.desktop deleted file mode 100644 index cb4bdcd..0000000 --- a/data/labwc-tweaks.desktop +++ /dev/null @@ -1,8 +0,0 @@ -[Desktop Entry] -Name=Labwc Config -GenericName=Labwc Configuration -Comment=Configure settings for Labwc -Exec=labwc-tweaks -Icon=labwc-tweaks -Type=Application -Categories=Settings;System; diff --git a/data/labwc_tweaks.appdata.xml.in b/data/labwc_tweaks.appdata.xml.in new file mode 100644 index 0000000..9a3aebe --- /dev/null +++ b/data/labwc_tweaks.appdata.xml.in @@ -0,0 +1,27 @@ + + + @PROJECT_APPSTREAM_ID@ + @PROJECT_APPSTREAM_SPDX_ID@ + @PROJECT_SPDX_ID@ + @PROJECT_NAME@ + @PROJECT_DESCRIPTION@ + +@PROJECT_DESCRIPTION_HTML@ + @PROJECT_ORGANIZATION_NAME@ + + @PROJECT_AUTHOR_NAME@ + + @PROJECT_HOMEPAGE_URL@ + + + Screenshot + @PROJECT_SCREENSHOT_URL@ + + + + @PROJECT_ID@ + + @PROJECT_APPSTREAM_ID@.desktop +@PROJECT_KEYWORDS_HTML@ +@PROJECT_RELEASES_HTML@ + diff --git a/data/labwc_tweaks.desktop.in b/data/labwc_tweaks.desktop.in new file mode 100644 index 0000000..d9fcc2d --- /dev/null +++ b/data/labwc_tweaks.desktop.in @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Application +Exec=@PROJECT_ID@ +Icon=@PROJECT_APPSTREAM_ID@ +Categories=@PROJECT_CATEGORIES@; + diff --git a/data/labwc-tweaks.svg b/data/labwc_tweaks.svg similarity index 100% rename from data/labwc-tweaks.svg rename to data/labwc_tweaks.svg diff --git a/data/translations/labwc-tweaks.ts b/data/translations/labwc-tweaks.ts new file mode 100644 index 0000000..45f2878 --- /dev/null +++ b/data/translations/labwc-tweaks.ts @@ -0,0 +1,52 @@ + + + + + MainDialog + + + Appearance + + + + + Corner Radius + + + + + Openbox Theme + + + + + Mouse & Touchpad + + + + + Cursor Theme + + + + + Cursor Size + + + + + Natural Scroll + + + + + Language & Region + + + + + Keyboard Layout + + + + diff --git a/data/translations/labwc-tweaks_it.ts b/data/translations/labwc-tweaks_it.ts new file mode 100644 index 0000000..f161951 --- /dev/null +++ b/data/translations/labwc-tweaks_it.ts @@ -0,0 +1,52 @@ + + + + + MainDialog + + + Appearance + Aspetto + + + + Corner Radius + Raggio Angolo + + + + Openbox Theme + Tema Openbox + + + + Mouse & Touchpad + Mouse e Touchpad + + + + Cursor Theme + Tema Puntatore + + + + Cursor Size + Grandezza Puntatore + + + + Natural Scroll + Scorrimento Naturale + + + + Language & Region + Lingua e Paese + + + + Keyboard Layout + Mappatura Tastiera + + + diff --git a/data/translations/labwc_tweaks.desktop.yaml b/data/translations/labwc_tweaks.desktop.yaml new file mode 100644 index 0000000..f5274df --- /dev/null +++ b/data/translations/labwc_tweaks.desktop.yaml @@ -0,0 +1,3 @@ +Desktop Entry/Name: "labwc-tweaks" +Desktop Entry/GenericName: "Compositor Settings" +Desktop Entry/Comment: "Labwc Wayland compositor settings" diff --git a/data/translations/labwc_tweaks_it.desktop.yaml b/data/translations/labwc_tweaks_it.desktop.yaml new file mode 100644 index 0000000..650579d --- /dev/null +++ b/data/translations/labwc_tweaks_it.desktop.yaml @@ -0,0 +1,3 @@ +Desktop Entry/Name: "labwc-tweaks" +Desktop Entry/GenericName: "Impostazioni Gestore Finestre" +Desktop Entry/Comment: "Impostazioni di Labwc, gestore delle finestre in Wayland" diff --git a/tweaks-qt/main.cpp b/tweaks-qt/main.cpp index d422134..a59c436 100644 --- a/tweaks-qt/main.cpp +++ b/tweaks-qt/main.cpp @@ -1,14 +1,61 @@ #include "maindialog.h" #include +#include +#include + +static void initLocale(QTranslator* qtTranslator, QTranslator* translator) +{ + QApplication* app = qApp; +#if PROJECT_TRANSLATION_TEST_ENABLED + QLocale locale(QLocale(PROJECT_TRANSLATION_TEST_LANGUAGE)); + QLocale::setDefault(locale); +#else + QLocale locale = QLocale::system(); +#endif + // Qt translations (buttons text and the like) + QString translationsPath = QLibraryInfo::path(QLibraryInfo::TranslationsPath); + QString translationsFileName = QStringLiteral("qt_") + locale.name(); + + if (qtTranslator->load(translationsFileName, translationsPath)) + app->installTranslator(qtTranslator); + + translationsFileName = QString(PROJECT_ID) + '_' + locale.name(); // E.g. "_en" + + // Try first in the same binary directory, in case we are building, + // otherwise read from system data + translationsPath = QCoreApplication::applicationDirPath(); + + bool isLoaded = translator->load(translationsFileName, translationsPath); + if (!isLoaded) { + // "/usr/share//translations + isLoaded = translator->load(translationsFileName, + QStringLiteral(PROJECT_DATA_DIR) + QStringLiteral("/translations")); + } + app->installTranslator(translator); +} int main(int argc, char *argv[]) { QApplication app(argc, argv); - app.setApplicationName(QStringLiteral("labwc-tweaks")); + app.setApplicationName(PROJECT_ID); + + QTranslator qtTranslator, translator; + initLocale(&qtTranslator, &translator); MainDialog w; w.show(); + // Make work the window icon also when the application is not (yet) installed + QString iconSuffix = QString("%1%2%3").arg("/", PROJECT_APPSTREAM_ID, QStringLiteral(".svg")); + QString icoLocalPath = QCoreApplication::applicationDirPath() + iconSuffix; + QString icoSysPath = QStringLiteral(PROJECT_ICON_SYSTEM_PATH) + iconSuffix; + + QIcon appIcon = QIcon(icoLocalPath); + if (appIcon.isNull()) + appIcon = QIcon(icoSysPath); + + w.setWindowIcon(appIcon); + return app.exec(); }