diff --git a/win-linux/extras/update-daemon/UpdateDaemon.pro b/win-linux/extras/update-daemon/UpdateDaemon.pro index 936837d9b..a442bcc8c 100644 --- a/win-linux/extras/update-daemon/UpdateDaemon.pro +++ b/win-linux/extras/update-daemon/UpdateDaemon.pro @@ -4,3 +4,10 @@ include(common.pri) DEFINES += COPYRIGHT_YEAR=$${CURRENT_YEAR} DEFINES += APP_ICON_PATH=\"./icons/desktopeditors.ico\" +DEFINES += APP_LANG_PATH=\"./langs/langs.iss\" + +core_linux { + SOURCES += $$PWD/res/gresource.c +} + +OTHER_FILES += $$PWD/res/langs/langs.iss diff --git a/win-linux/extras/update-daemon/common.pri b/win-linux/extras/update-daemon/common.pri index 22e26d609..43b6a475b 100644 --- a/win-linux/extras/update-daemon/common.pri +++ b/win-linux/extras/update-daemon/common.pri @@ -17,10 +17,12 @@ INCLUDEPATH += $$PWD/../../src/prop HEADERS += $$PWD/src/version.h \ $$PWD/src/classes/csocket.h \ - $$PWD/src/classes/csvcmanager.h + $$PWD/src/classes/csvcmanager.h \ + $$PWD/src/classes/translator.h SOURCES += $$PWD/src/classes/csocket.cpp \ - $$PWD/src/classes/csvcmanager.cpp + $$PWD/src/classes/csvcmanager.cpp \ + $$PWD/src/classes/translator.cpp ENV_PRODUCT_VERSION = $$(PRODUCT_VERSION) !isEmpty(ENV_PRODUCT_VERSION) { diff --git a/win-linux/extras/update-daemon/res/gresource.c b/win-linux/extras/update-daemon/res/gresource.c new file mode 100644 index 000000000..29deae304 --- /dev/null +++ b/win-linux/extras/update-daemon/res/gresource.c @@ -0,0 +1,402 @@ +#include + +#if defined (__ELF__) && ( __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 6)) +# define SECTION __attribute__ ((section (".gresource.gresource"), aligned (8))) +#else +# define SECTION +#endif + +static const SECTION union { const guint8 data[3129]; const double alignment; void * const ptr;} gresource_resource_data = { + "\107\126\141\162\151\141\156\164\000\000\000\000\000\000\000\000" + "\030\000\000\000\164\000\000\000\000\000\000\050\003\000\000\000" + "\000\000\000\000\001\000\000\000\002\000\000\000\052\042\323\171" + "\001\000\000\000\164\000\000\000\011\000\166\000\200\000\000\000" + "\045\014\000\000\170\110\267\050\002\000\000\000\045\014\000\000" + "\006\000\114\000\054\014\000\000\060\014\000\000\324\265\002\000" + "\377\377\377\377\060\014\000\000\001\000\114\000\064\014\000\000" + "\070\014\000\000\154\141\156\147\163\056\151\163\163\000\000\000" + "\225\013\000\000\000\000\000\000\133\103\165\163\164\157\155\115" + "\145\163\163\141\147\145\163\135\012\012\145\156\056\103\101\120" + "\124\111\117\116\137\124\105\130\124\040\075\117\116\114\131\117" + "\106\106\111\103\105\040\125\160\144\141\164\145\040\123\145\162" + "\166\151\143\145\012\162\165\056\103\101\120\124\111\117\116\137" + "\124\105\130\124\040\075\320\241\320\265\321\200\320\262\320\270" + "\321\201\040\320\276\320\261\320\275\320\276\320\262\320\273\320" + "\265\320\275\320\270\320\271\040\117\116\114\131\117\106\106\111" + "\103\105\012\012\145\156\056\115\105\123\123\101\107\105\137\124" + "\105\130\124\137\105\122\122\061\040\075\101\156\040\145\162\162" + "\157\162\040\157\143\143\165\162\162\145\144\072\012\162\165\056" + "\115\105\123\123\101\107\105\137\124\105\130\124\137\105\122\122" + "\061\040\075\320\237\321\200\320\276\320\270\320\267\320\276\321" + "\210\320\273\320\260\040\320\276\321\210\320\270\320\261\320\272" + "\320\260\072\012\012\145\156\056\115\105\123\123\101\107\105\137" + "\124\105\130\124\137\105\122\122\062\040\075\101\156\040\145\162" + "\162\157\162\040\157\143\143\165\162\162\145\144\040\167\150\151" + "\154\145\040\144\145\154\145\164\151\156\147\072\012\162\165\056" + "\115\105\123\123\101\107\105\137\124\105\130\124\137\105\122\122" + "\062\040\075\320\237\321\200\320\276\320\270\320\267\320\276\321" + "\210\320\273\320\260\040\320\276\321\210\320\270\320\261\320\272" + "\320\260\040\320\277\321\200\320\270\040\321\203\320\264\320\260" + "\320\273\320\265\320\275\320\270\320\270\072\012\012\145\156\056" + "\115\105\123\123\101\107\105\137\124\105\130\124\137\105\122\122" + "\063\040\075\101\156\040\145\162\162\157\162\040\157\143\143\165" + "\162\162\145\144\040\167\150\151\154\145\040\143\162\145\141\164" + "\151\156\147\072\012\162\165\056\115\105\123\123\101\107\105\137" + "\124\105\130\124\137\105\122\122\063\040\075\320\237\321\200\320" + "\276\320\270\320\267\320\276\321\210\320\273\320\260\040\320\276" + "\321\210\320\270\320\261\320\272\320\260\040\320\277\321\200\320" + "\270\040\321\201\320\276\320\267\320\264\320\260\320\275\320\270" + "\320\270\072\012\012\145\156\056\115\105\123\123\101\107\105\137" + "\124\105\130\124\137\105\122\122\064\040\075\101\156\040\145\162" + "\162\157\162\040\157\143\143\165\162\162\145\144\040\167\150\151" + "\154\145\040\162\145\163\164\141\162\164\151\156\147\040\164\150" + "\145\040\163\145\162\166\151\143\145\041\012\162\165\056\115\105" + "\123\123\101\107\105\137\124\105\130\124\137\105\122\122\064\040" + "\075\320\237\321\200\320\276\320\270\320\267\320\276\321\210\320" + "\273\320\260\040\320\276\321\210\320\270\320\261\320\272\320\260" + "\040\320\277\321\200\320\270\040\320\277\320\265\321\200\320\265" + "\320\267\320\260\320\277\321\203\321\201\320\272\320\265\040\321" + "\201\320\265\321\200\320\262\320\270\321\201\320\260\041\012\012" + "\145\156\056\115\105\123\123\101\107\105\137\124\105\130\124\137" + "\105\122\122\065\040\075\125\160\144\141\164\145\040\143\141\156" + "\143\145\154\154\145\144\056\040\103\141\156\047\164\040\146\151" + "\156\144\040\146\157\154\144\145\162\072\012\162\165\056\115\105" + "\123\123\101\107\105\137\124\105\130\124\137\105\122\122\065\040" + "\075\320\236\320\261\320\275\320\276\320\262\320\273\320\265\320" + "\275\320\270\320\265\040\320\276\321\202\320\274\320\265\320\275" + "\320\265\320\275\320\276\056\040\320\235\320\265\040\321\203\320" + "\264\320\260\320\273\320\276\321\201\321\214\040\320\275\320\260" + "\320\271\321\202\320\270\040\320\277\320\260\320\277\320\272\321" + "\203\072\012\012\145\156\056\115\105\123\123\101\107\105\137\124" + "\105\130\124\137\105\122\122\066\040\075\125\160\144\141\164\145" + "\040\143\141\156\143\145\154\154\145\144\056\040\124\150\145\040" + "\146\151\154\145\040\163\151\147\156\141\164\165\162\145\040\151" + "\163\040\155\151\163\163\151\156\147\072\012\162\165\056\115\105" + "\123\123\101\107\105\137\124\105\130\124\137\105\122\122\066\040" + "\075\320\236\320\261\320\275\320\276\320\262\320\273\320\265\320" + "\275\320\270\320\265\040\320\276\321\202\320\274\320\265\320\275" + "\320\265\320\275\320\276\056\040\320\236\321\202\321\201\321\203" + "\321\202\321\201\321\202\320\262\321\203\320\265\321\202\040\320" + "\277\320\276\320\264\320\277\320\270\321\201\321\214\040\321\204" + "\320\260\320\271\320\273\320\260\072\012\012\145\156\056\115\105" + "\123\123\101\107\105\137\124\105\130\124\137\105\122\122\067\040" + "\075\125\160\144\141\164\145\040\143\141\156\143\145\154\154\145" + "\144\056\040\103\141\156\047\164\040\144\145\154\145\164\145\040" + "\146\157\154\144\145\162\072\012\162\165\056\115\105\123\123\101" + "\107\105\137\124\105\130\124\137\105\122\122\067\040\075\320\236" + "\320\261\320\275\320\276\320\262\320\273\320\265\320\275\320\270" + "\320\265\040\320\276\321\202\320\274\320\265\320\275\320\265\320" + "\275\320\276\056\040\320\235\320\265\040\321\203\320\264\320\260" + "\320\273\320\276\321\201\321\214\040\321\203\320\264\320\260\320" + "\273\320\270\321\202\321\214\040\320\277\320\260\320\277\320\272" + "\321\203\072\012\012\145\156\056\115\105\123\123\101\107\105\137" + "\124\105\130\124\137\105\122\122\070\040\075\125\160\144\141\164" + "\145\040\143\141\156\143\145\154\154\145\144\056\040\124\150\145" + "\040\160\162\157\147\162\141\155\040\151\163\040\156\157\164\040" + "\143\154\157\163\145\144\072\012\162\165\056\115\105\123\123\101" + "\107\105\137\124\105\130\124\137\105\122\122\070\040\075\320\236" + "\320\261\320\275\320\276\320\262\320\273\320\265\320\275\320\270" + "\320\265\040\320\276\321\202\320\274\320\265\320\275\320\265\320" + "\275\320\276\056\040\320\237\321\200\320\270\320\273\320\276\320" + "\266\320\265\320\275\320\270\320\265\040\320\275\320\265\040\320" + "\267\320\260\320\272\321\200\321\213\321\202\320\276\072\012\012" + "\145\156\056\115\105\123\123\101\107\105\137\124\105\130\124\137" + "\105\122\122\071\040\075\125\160\144\141\164\145\040\143\141\156" + "\143\145\154\154\145\144\056\040\103\141\156\047\164\040\143\162" + "\145\141\164\145\040\146\157\154\144\145\162\072\012\162\165\056" + "\115\105\123\123\101\107\105\137\124\105\130\124\137\105\122\122" + "\071\040\075\320\236\320\261\320\275\320\276\320\262\320\273\320" + "\265\320\275\320\270\320\265\040\320\276\321\202\320\274\320\265" + "\320\275\320\265\320\275\320\276\056\040\320\235\320\265\040\321" + "\203\320\264\320\260\320\273\320\276\321\201\321\214\040\321\201" + "\320\276\320\267\320\264\320\260\321\202\321\214\040\320\277\320" + "\260\320\277\320\272\321\203\072\012\012\145\156\056\115\105\123" + "\123\101\107\105\137\124\105\130\124\137\105\122\122\061\060\040" + "\075\125\160\144\141\164\145\040\143\141\156\143\145\154\154\145" + "\144\056\040\103\141\156\047\164\040\162\145\160\154\141\143\145" + "\040\146\151\154\145\163\040\164\157\040\142\141\143\153\165\160" + "\072\012\162\165\056\115\105\123\123\101\107\105\137\124\105\130" + "\124\137\105\122\122\061\060\040\075\320\236\320\261\320\275\320" + "\276\320\262\320\273\320\265\320\275\320\270\320\265\040\320\276" + "\321\202\320\274\320\265\320\275\320\265\320\275\320\276\056\040" + "\320\235\320\265\040\321\203\320\264\320\260\320\273\320\276\321" + "\201\321\214\040\320\277\320\265\321\200\320\265\320\274\320\265" + "\321\201\321\202\320\270\321\202\321\214\040\321\204\320\260\320" + "\271\320\273\321\213\040\320\262\040\321\200\320\265\320\267\320" + "\265\321\200\320\262\320\275\321\203\321\216\040\320\272\320\276" + "\320\277\320\270\321\216\072\012\012\145\156\056\115\105\123\123" + "\101\107\105\137\124\105\130\124\137\105\122\122\061\061\040\075" + "\103\141\156\047\164\040\162\145\163\164\157\162\145\040\146\151" + "\154\145\163\040\146\162\157\155\040\142\141\143\153\165\160\041" + "\012\162\165\056\115\105\123\123\101\107\105\137\124\105\130\124" + "\137\105\122\122\061\061\040\075\320\235\320\265\040\321\203\320" + "\264\320\260\320\273\320\276\321\201\321\214\040\320\262\320\276" + "\321\201\321\201\321\202\320\260\320\275\320\276\320\262\320\270" + "\321\202\321\214\040\321\204\320\260\320\271\320\273\321\213\040" + "\320\270\320\267\040\321\200\320\265\320\267\320\265\321\200\320" + "\262\320\275\320\276\320\271\040\320\272\320\276\320\277\320\270" + "\320\270\041\012\012\145\156\056\115\105\123\123\101\107\105\137" + "\124\105\130\124\137\105\122\122\061\062\040\075\125\160\144\141" + "\164\145\040\143\141\156\143\145\154\154\145\144\056\040\103\141" + "\156\047\164\040\155\157\166\145\040\165\160\144\141\164\145\163" + "\040\164\157\040\101\160\160\040\160\141\164\150\072\012\162\165" + "\056\115\105\123\123\101\107\105\137\124\105\130\124\137\105\122" + "\122\061\062\040\075\320\236\320\261\320\275\320\276\320\262\320" + "\273\320\265\320\275\320\270\320\265\040\320\276\321\202\320\274" + "\320\265\320\275\320\265\320\275\320\276\056\040\320\235\320\265" + "\040\321\203\320\264\320\260\320\273\320\276\321\201\321\214\040" + "\320\277\320\265\321\200\320\265\320\274\320\265\321\201\321\202" + "\320\270\321\202\321\214\040\320\276\320\261\320\275\320\276\320" + "\262\320\273\320\265\320\275\320\270\321\217\040\320\262\040\320" + "\277\320\260\320\277\320\272\321\203\040\320\277\321\200\320\270" + "\320\273\320\276\320\266\320\265\320\275\320\270\321\217\072\012" + "\012\145\156\056\115\105\123\123\101\107\105\137\124\105\130\124" + "\137\105\122\122\061\063\040\075\101\156\040\145\162\162\157\162" + "\040\157\143\143\165\162\162\145\144\040\167\150\151\154\145\040" + "\162\145\155\157\166\145\040\101\160\160\040\160\141\164\150\072" + "\012\162\165\056\115\105\123\123\101\107\105\137\124\105\130\124" + "\137\105\122\122\061\063\040\075\320\237\321\200\320\276\320\270" + "\320\267\320\276\321\210\320\273\320\260\040\320\276\321\210\320" + "\270\320\261\320\272\320\260\040\320\277\321\200\320\270\040\321" + "\203\320\264\320\260\320\273\320\265\320\275\320\270\320\270\040" + "\320\277\320\260\320\277\320\272\320\270\040\320\277\321\200\320" + "\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217\072" + "\012\012\145\156\056\115\105\123\123\101\107\105\137\124\105\130" + "\124\137\105\122\122\061\064\040\075\101\156\040\145\162\162\157" + "\162\040\157\143\143\165\162\162\145\144\040\167\150\151\154\145" + "\040\162\145\163\164\157\162\145\040\146\151\154\145\163\040\146" + "\162\157\155\040\142\141\143\153\165\160\072\012\162\165\056\115" + "\105\123\123\101\107\105\137\124\105\130\124\137\105\122\122\061" + "\064\040\075\320\237\321\200\320\276\320\270\320\267\320\276\321" + "\210\320\273\320\260\040\320\276\321\210\320\270\320\261\320\272" + "\320\260\040\320\277\321\200\320\270\040\320\262\320\276\321\201" + "\321\201\321\202\320\260\320\275\320\276\320\262\320\273\320\265" + "\320\275\320\270\320\270\040\321\204\320\260\320\271\320\273\320" + "\276\320\262\040\320\270\320\267\040\321\200\320\265\320\267\320" + "\265\321\200\320\262\320\275\320\276\320\271\040\320\272\320\276" + "\320\277\320\270\320\270\072\012\012\145\156\056\115\105\123\123" + "\101\107\105\137\124\105\130\124\137\105\122\122\061\065\040\075" + "\101\156\040\145\162\162\157\162\040\157\143\143\165\162\162\145" + "\144\040\167\150\151\154\145\040\162\145\163\164\141\162\164\151" + "\156\147\040\164\150\145\040\160\162\157\147\162\141\155\041\012" + "\162\165\056\115\105\123\123\101\107\105\137\124\105\130\124\137" + "\105\122\122\061\065\040\075\320\237\321\200\320\276\320\270\320" + "\267\320\276\321\210\320\273\320\260\040\320\276\321\210\320\270" + "\320\261\320\272\320\260\040\320\277\321\200\320\270\040\320\277" + "\320\265\321\200\320\265\320\267\320\260\320\277\321\203\321\201" + "\320\272\320\265\040\320\277\321\200\320\270\320\273\320\276\320" + "\266\320\265\320\275\320\270\321\217\041\012\012\145\156\056\115" + "\105\123\123\101\107\105\137\124\105\130\124\137\105\122\122\061" + "\066\040\075\123\104\114\040\151\156\151\164\040\145\162\162\157" + "\162\072\012\162\165\056\115\105\123\123\101\107\105\137\124\105" + "\130\124\137\105\122\122\061\066\040\075\320\236\321\210\320\270" + "\320\261\320\272\320\260\040\320\270\320\275\320\270\321\206\320" + "\270\320\260\320\273\320\270\320\267\320\260\321\206\320\270\320" + "\270\040\123\104\114\072\012\012\145\156\056\115\105\123\123\101" + "\107\105\137\124\105\130\124\137\105\122\122\061\067\040\075\123" + "\145\162\166\151\143\145\103\164\162\154\104\151\163\160\141\164" + "\143\150\145\162\040\162\145\164\165\162\156\145\144\040\145\162" + "\162\157\162\072\012\162\165\056\115\105\123\123\101\107\105\137" + "\124\105\130\124\137\105\122\122\061\067\040\075\123\145\162\166" + "\151\143\145\103\164\162\154\104\151\163\160\141\164\143\150\145" + "\162\040\320\262\320\265\321\200\320\275\321\203\320\273\040\320" + "\276\321\210\320\270\320\261\320\272\321\203\072\012\000\000\050" + "\165\165\141\171\051\154\141\156\147\163\057\000\000\000\000\000" + "\057\000\000\000\001\000\000\000" }; + +static GStaticResource static_resource = { gresource_resource_data.data, sizeof (gresource_resource_data.data) - 1 /* nul terminator */, NULL, NULL, NULL }; + +G_MODULE_EXPORT +GResource *gresource_get_resource (void); +GResource *gresource_get_resource (void) +{ + return g_static_resource_get_resource (&static_resource); +} +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This 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, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_CONSTRUCTOR_H__ +#define __G_CONSTRUCTOR_H__ + +/* + If G_HAS_CONSTRUCTORS is true then the compiler support *both* constructors and + destructors, in a usable way, including e.g. on library unload. If not you're on + your own. + + Some compilers need #pragma to handle this, which does not work with macros, + so the way you need to use this is (for constructors): + + #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA + #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(my_constructor) + #endif + G_DEFINE_CONSTRUCTOR(my_constructor) + static void my_constructor(void) { + ... + } + +*/ + +#ifndef __GTK_DOC_IGNORE__ + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) + +#define G_HAS_CONSTRUCTORS 1 + +#define G_DEFINE_CONSTRUCTOR(_func) static void __attribute__((constructor)) _func (void); +#define G_DEFINE_DESTRUCTOR(_func) static void __attribute__((destructor)) _func (void); + +#elif defined (_MSC_VER) && (_MSC_VER >= 1500) +/* Visual studio 2008 and later has _Pragma */ + +/* + * Only try to include gslist.h if not already included via glib.h, + * so that items using gconstructor.h outside of GLib (such as + * GResources) continue to build properly. + */ +#ifndef __G_LIB_H__ +#include "gslist.h" +#endif + +#include + +#define G_HAS_CONSTRUCTORS 1 + +/* We do some weird things to avoid the constructors being optimized + * away on VS2015 if WholeProgramOptimization is enabled. First we + * make a reference to the array from the wrapper to make sure its + * references. Then we use a pragma to make sure the wrapper function + * symbol is always included at the link stage. Also, the symbols + * need to be extern (but not dllexport), even though they are not + * really used from another object file. + */ + +/* We need to account for differences between the mangling of symbols + * for x86 and x64/ARM/ARM64 programs, as symbols on x86 are prefixed + * with an underscore but symbols on x64/ARM/ARM64 are not. + */ +#ifdef _M_IX86 +#define G_MSVC_SYMBOL_PREFIX "_" +#else +#define G_MSVC_SYMBOL_PREFIX "" +#endif + +#define G_DEFINE_CONSTRUCTOR(_func) G_MSVC_CTOR (_func, G_MSVC_SYMBOL_PREFIX) +#define G_DEFINE_DESTRUCTOR(_func) G_MSVC_DTOR (_func, G_MSVC_SYMBOL_PREFIX) + +#define G_MSVC_CTOR(_func,_sym_prefix) \ + static void _func(void); \ + extern int (* _array ## _func)(void); \ + int _func ## _wrapper(void); \ + int _func ## _wrapper(void) { _func(); g_slist_find (NULL, _array ## _func); return 0; } \ + __pragma(comment(linker,"/include:" _sym_prefix # _func "_wrapper")) \ + __pragma(section(".CRT$XCU",read)) \ + __declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _wrapper; + +#define G_MSVC_DTOR(_func,_sym_prefix) \ + static void _func(void); \ + extern int (* _array ## _func)(void); \ + int _func ## _constructor(void); \ + int _func ## _constructor(void) { atexit (_func); g_slist_find (NULL, _array ## _func); return 0; } \ + __pragma(comment(linker,"/include:" _sym_prefix # _func "_constructor")) \ + __pragma(section(".CRT$XCU",read)) \ + __declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _constructor; + +#elif defined (_MSC_VER) + +#define G_HAS_CONSTRUCTORS 1 + +/* Pre Visual studio 2008 must use #pragma section */ +#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1 +#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1 + +#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \ + section(".CRT$XCU",read) +#define G_DEFINE_CONSTRUCTOR(_func) \ + static void _func(void); \ + static int _func ## _wrapper(void) { _func(); return 0; } \ + __declspec(allocate(".CRT$XCU")) static int (*p)(void) = _func ## _wrapper; + +#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \ + section(".CRT$XCU",read) +#define G_DEFINE_DESTRUCTOR(_func) \ + static void _func(void); \ + static int _func ## _constructor(void) { atexit (_func); return 0; } \ + __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor; + +#elif defined(__SUNPRO_C) + +/* This is not tested, but i believe it should work, based on: + * http://opensource.apple.com/source/OpenSSL098/OpenSSL098-35/src/fips/fips_premain.c + */ + +#define G_HAS_CONSTRUCTORS 1 + +#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1 +#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1 + +#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \ + init(_func) +#define G_DEFINE_CONSTRUCTOR(_func) \ + static void _func(void); + +#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \ + fini(_func) +#define G_DEFINE_DESTRUCTOR(_func) \ + static void _func(void); + +#else + +/* constructors not supported for this compiler */ + +#endif + +#endif /* __GTK_DOC_IGNORE__ */ +#endif /* __G_CONSTRUCTOR_H__ */ + +#ifdef G_HAS_CONSTRUCTORS + +#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA +#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(gresourceresource_constructor) +#endif +G_DEFINE_CONSTRUCTOR(gresourceresource_constructor) +#ifdef G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA +#pragma G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(gresourceresource_destructor) +#endif +G_DEFINE_DESTRUCTOR(gresourceresource_destructor) + +#else +#warning "Constructor not supported on this compiler, linking in resources will not work" +#endif + +static void gresourceresource_constructor (void) +{ + g_static_resource_init (&static_resource); +} + +static void gresourceresource_destructor (void) +{ + g_static_resource_fini (&static_resource); +} diff --git a/win-linux/extras/update-daemon/res/gresource.xml b/win-linux/extras/update-daemon/res/gresource.xml new file mode 100644 index 000000000..2d420e866 --- /dev/null +++ b/win-linux/extras/update-daemon/res/gresource.xml @@ -0,0 +1,12 @@ + + + + langs/langs.iss + + + + diff --git a/win-linux/extras/update-daemon/res/langs/langs.iss b/win-linux/extras/update-daemon/res/langs/langs.iss new file mode 100644 index 000000000..6ddb24233 --- /dev/null +++ b/win-linux/extras/update-daemon/res/langs/langs.iss @@ -0,0 +1,54 @@ + +en.CAPTION_TEXT =ONLYOFFICE Update Service +ru.CAPTION_TEXT =Сервис обновлений ONLYOFFICE + +en.MESSAGE_TEXT_ERR1 =An error occurred: +ru.MESSAGE_TEXT_ERR1 =Произошла ошибка: + +en.MESSAGE_TEXT_ERR2 =An error occurred while deleting: +ru.MESSAGE_TEXT_ERR2 =Произошла ошибка при удалении: + +en.MESSAGE_TEXT_ERR3 =An error occurred while creating: +ru.MESSAGE_TEXT_ERR3 =Произошла ошибка при создании: + +en.MESSAGE_TEXT_ERR4 =An error occurred while restarting the service! +ru.MESSAGE_TEXT_ERR4 =Произошла ошибка при перезапуске сервиса! + +en.MESSAGE_TEXT_ERR5 =Update cancelled. Can't find folder: +ru.MESSAGE_TEXT_ERR5 =Обновление отменено. Не удалось найти папку: + +en.MESSAGE_TEXT_ERR6 =Update cancelled. The file signature is missing: +ru.MESSAGE_TEXT_ERR6 =Обновление отменено. Отсутствует подпись файла: + +en.MESSAGE_TEXT_ERR7 =Update cancelled. Can't delete folder: +ru.MESSAGE_TEXT_ERR7 =Обновление отменено. Не удалось удалить папку: + +en.MESSAGE_TEXT_ERR8 =Update cancelled. The program is not closed: +ru.MESSAGE_TEXT_ERR8 =Обновление отменено. Приложение не закрыто: + +en.MESSAGE_TEXT_ERR9 =Update cancelled. Can't create folder: +ru.MESSAGE_TEXT_ERR9 =Обновление отменено. Не удалось создать папку: + +en.MESSAGE_TEXT_ERR10 =Update cancelled. Can't replace files to backup: +ru.MESSAGE_TEXT_ERR10 =Обновление отменено. Не удалось переместить файлы в резервную копию: + +en.MESSAGE_TEXT_ERR11 =Can't restore files from backup! +ru.MESSAGE_TEXT_ERR11 =Не удалось восстановить файлы из резервной копии! + +en.MESSAGE_TEXT_ERR12 =Update cancelled. Can't move updates to App path: +ru.MESSAGE_TEXT_ERR12 =Обновление отменено. Не удалось переместить обновления в папку приложения: + +en.MESSAGE_TEXT_ERR13 =An error occurred while remove App path: +ru.MESSAGE_TEXT_ERR13 =Произошла ошибка при удалении папки приложения: + +en.MESSAGE_TEXT_ERR14 =An error occurred while restore files from backup: +ru.MESSAGE_TEXT_ERR14 =Произошла ошибка при восстановлении файлов из резервной копии: + +en.MESSAGE_TEXT_ERR15 =An error occurred while restarting the program! +ru.MESSAGE_TEXT_ERR15 =Произошла ошибка при перезапуске приложения! + +en.MESSAGE_TEXT_ERR16 =SDL init error: +ru.MESSAGE_TEXT_ERR16 =Ошибка инициализации SDL: + +en.MESSAGE_TEXT_ERR17 =ServiceCtrlDispatcher returned error: +ru.MESSAGE_TEXT_ERR17 =ServiceCtrlDispatcher вернул ошибку: diff --git a/win-linux/extras/update-daemon/res/version.rc b/win-linux/extras/update-daemon/res/version.rc index b85c01952..923c86acc 100644 --- a/win-linux/extras/update-daemon/res/version.rc +++ b/win-linux/extras/update-daemon/res/version.rc @@ -3,6 +3,7 @@ #include "../src/platform_win/resource.h" IDI_MAINICON ICON DISCARDABLE APP_ICON_PATH +IDT_TRANSLATIONS RCDATA APP_LANG_PATH CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "./manifest/updatesvc.exe.manifest" #include "../src/version.h" diff --git a/win-linux/extras/update-daemon/src/classes/csocket.h b/win-linux/extras/update-daemon/src/classes/csocket.h index 3a7573c1b..12568e0c4 100644 --- a/win-linux/extras/update-daemon/src/classes/csocket.h +++ b/win-linux/extras/update-daemon/src/classes/csocket.h @@ -68,6 +68,7 @@ enum MsgCommands { MSG_Progress, MSG_StopDownload, MSG_OtherError, + MSG_SetLanguage, MSG_RequestContentLenght }; diff --git a/win-linux/extras/update-daemon/src/classes/csvcmanager.cpp b/win-linux/extras/update-daemon/src/classes/csvcmanager.cpp index 1ca369426..07e06e4bc 100644 --- a/win-linux/extras/update-daemon/src/classes/csvcmanager.cpp +++ b/win-linux/extras/update-daemon/src/classes/csvcmanager.cpp @@ -44,6 +44,7 @@ # define WIN32_LEAN_AND_MEAN # endif # include "platform_win/utils.h" +# include "classes/translator.h" # include # include # include @@ -132,7 +133,7 @@ auto restartService()->void { const wstring fileName = NS_File::appPath() + RESTART_BATCH; if (NS_File::fileExists(fileName) && !NS_File::removeFile(fileName)) { - NS_Logger::WriteLog(L"An error occurred while deleting: " + fileName, true); + NS_Logger::WriteLog(_TR("An error occurred while deleting:") + _T(" ") + fileName, true); return; } @@ -146,7 +147,7 @@ auto restartService()->void }; if (!NS_File::writeToFile(fileName, batch)) { - NS_Logger::WriteLog(L"An error occurred while creating: " + fileName, true); + NS_Logger::WriteLog(_TR("An error occurred while creating:") + _T(" ") + fileName, true); return; } @@ -158,7 +159,7 @@ auto restartService()->void if (!CreateProcess(NULL, const_cast(fileName.c_str()), NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &si, &pi)) { - NS_Logger::WriteLog(L"An error occurred while restarting the service!", true); + NS_Logger::WriteLog(_TR("An error occurred while restarting the service!"), true); return; } CloseHandle(pi.hProcess); @@ -265,6 +266,10 @@ void CSvcManager::init() clearTempFiles(params[1], params[2]); break; + case MSG_SetLanguage: + Translator::setLanguage(params[1]); + break; + default: break; } @@ -454,7 +459,7 @@ void CSvcManager::startReplacingFiles(const tstring &packageType, const bool res tstring updSubPath = NS_File::fileExists(updPath + SUBFOLDER + APP_LAUNCH_NAME) ? updPath + SUBFOLDER : updPath; tstring tmpPath = NS_File::parentPath(appPath) + BACKUP_PATH; if (!NS_File::dirExists(updPath)) { - NS_Logger::WriteLog(_T("Update cancelled. Can't find folder: ") + updPath, true); + NS_Logger::WriteLog(_TR("Update cancelled. Can't find folder:") + _T(" ") + updPath, true); return; } @@ -465,7 +470,7 @@ void CSvcManager::startReplacingFiles(const tstring &packageType, const bool res tstring apps[] = {APP_LAUNCH_NAME, APP_LAUNCH_NAME2, APP_HELPER, DAEMON_NAME}; for (int i = 0; i < sizeof(apps) / sizeof(apps[0]); i++) { if (!NS_File::verifyEmbeddedSignature(updSubPath + apps[i])) { - NS_Logger::WriteLog(L"Update cancelled. The file signature is missing: " + updSubPath + apps[i], true); + NS_Logger::WriteLog(_TR("Update cancelled. The file signature is missing:") + _T(" ") + updSubPath + apps[i], true); return; } } @@ -475,7 +480,7 @@ void CSvcManager::startReplacingFiles(const tstring &packageType, const bool res // Check backup folder if (NS_File::dirExists(tmpPath) && !NS_File::removeDirRecursively(tmpPath)) { - NS_Logger::WriteLog(_T("Update cancelled. Can't delete folder: ") + tmpPath, true); + NS_Logger::WriteLog(_TR("Update cancelled. Can't delete folder:") + _T(" ") + tmpPath, true); return; } @@ -494,7 +499,7 @@ void CSvcManager::startReplacingFiles(const tstring &packageType, const bool res sleep(500); if (NS_File::isProcessRunning(app)) { - NS_Logger::WriteLog(_T("Update cancelled. The ") + app + _T(" is not closed!"), true); + NS_Logger::WriteLog(_TR("Update cancelled. The program is not closed:") + _T(" ") + app, true); return; } } @@ -503,29 +508,29 @@ void CSvcManager::startReplacingFiles(const tstring &packageType, const bool res // Replace app path to Backup #ifdef _WIN32 if (!NS_File::dirExists(tmpPath) && !NS_File::makePath(tmpPath)) { - NS_Logger::WriteLog(L"Update cancelled. Can't create folder: " + tmpPath, true); + NS_Logger::WriteLog(_TR("Update cancelled. Can't create folder:") + _T(" ") + tmpPath, true); return; } if (!NS_File::replaceFolder(appPath, tmpPath, false)) { #else if (!NS_File::replaceFolder(appPath, tmpPath, true)) { #endif - NS_Logger::WriteLog(_T("Update cancelled. Can't replace files to backup: ") + NS_Utils::GetLastErrorAsString(), true); + NS_Logger::WriteLog(_TR("Update cancelled. Can't replace files to backup:") + _T(" ") + NS_Utils::GetLastErrorAsString(), true); if (NS_File::dirExists(tmpPath) && !NS_File::dirIsEmpty(tmpPath) && !NS_File::replaceFolder(tmpPath, appPath)) - NS_Logger::WriteLog(_T("Can't restore files from backup!"), true); + NS_Logger::WriteLog(_TR("Can't restore files from backup!"), true); return; } // Move update path to app path if (!NS_File::replaceFolder(updSubPath, appPath, true)) { - NS_Logger::WriteLog(_T("Update cancelled. Can't move updates to App path: ") + NS_Utils::GetLastErrorAsString(), true); + NS_Logger::WriteLog(_TR("Update cancelled. Can't move updates to App path:") + _T(" ") + NS_Utils::GetLastErrorAsString(), true); if (NS_File::dirExists(appPath) && !NS_File::removeDirRecursively(appPath)) { - NS_Logger::WriteLog(_T("An error occurred while remove App path: ") + NS_Utils::GetLastErrorAsString(), true); + NS_Logger::WriteLog(_TR("An error occurred while remove App path:") + _T(" ") + NS_Utils::GetLastErrorAsString(), true); return; } if (!NS_File::replaceFolder(tmpPath, appPath, true)) - NS_Logger::WriteLog(_T("An error occurred while restore files from backup: ") + NS_Utils::GetLastErrorAsString(), true); + NS_Logger::WriteLog(_TR("An error occurred while restore files from backup:") + _T(" ") + NS_Utils::GetLastErrorAsString(), true); NS_File::removeDirRecursively(updPath); return; @@ -598,7 +603,7 @@ void CSvcManager::startReplacingFiles(const tstring &packageType, const bool res // Restart program if (restartAfterUpdate) { if (!NS_File::runProcess(appPath + APP_LAUNCH_NAME, _T(""))) - NS_Logger::WriteLog(_T("An error occurred while restarting the program!"), true); + NS_Logger::WriteLog(_TR("An error occurred while restarting the program!"), true); } // Remove Backup dir diff --git a/win-linux/extras/update-daemon/src/classes/platform_linux/capplication.cpp b/win-linux/extras/update-daemon/src/classes/platform_linux/capplication.cpp index a48290b2f..ef372763c 100644 --- a/win-linux/extras/update-daemon/src/classes/platform_linux/capplication.cpp +++ b/win-linux/extras/update-daemon/src/classes/platform_linux/capplication.cpp @@ -32,6 +32,7 @@ #include "capplication.h" #include "platform_linux/utils.h" +#include "classes/translator.h" #include #include @@ -39,7 +40,7 @@ CApplication::CApplication() { if (SDL_Init(SDL_INIT_EVENTS | SDL_INIT_TIMER) != 0) - NS_Logger::WriteLog(string("SDL_Init error: ") + SDL_GetError(), true); + NS_Logger::WriteLog(_TR("SDL init error:") + _T(" ") + SDL_GetError(), true); } CApplication::~CApplication() diff --git a/win-linux/extras/update-daemon/src/classes/translator.cpp b/win-linux/extras/update-daemon/src/classes/translator.cpp new file mode 100644 index 000000000..a0bada119 --- /dev/null +++ b/win-linux/extras/update-daemon/src/classes/translator.cpp @@ -0,0 +1,307 @@ +#include "translator.h" +#ifdef _WIN32 +# include "platform_win/resource.h" +# include "platform_win/utils.h" +# include +# include +# define istalnum(c) std::iswalnum(c) +# define istalpha(c) std::iswalpha(c) +#else +# include "platform_linux/utils.h" +# include "res/gresource.c" +# include +# define istalnum(c) std::isalnum(c) +# define istalpha(c) std::isalpha(c) +#endif + + +bool isSeparator(tchar c) +{ + return c == _T(' ') || c == _T('\t') || c == _T('\r') || c == _T('\n'); +} + +bool isValidStringIdCharacter(tchar c) +{ + return istalnum(c) || istalpha(c) || c == _T('_'); +} + +bool isValidLocaleCharacter(tchar c) +{ + return istalpha(c) || c == _T('_'); +} + +tstring getPrimaryLang(const tstring &lang) +{ + if (lang.empty()) { + NS_Logger::WriteLog(ADVANCED_ERROR_MESSAGE); + return _T("en"); + } + size_t pos = lang.find(_T('_')); + if (pos == tstring::npos) { + if (lang.length() == 2) + return lang; + } else { + tstring _lang = lang.substr(0, pos); + if (_lang.length() == 2) + return _lang; + } + NS_Logger::WriteLog(ADVANCED_ERROR_MESSAGE); + return _T("en"); +} + +#ifdef _WIN32 +wstring StrToWStr(const char* str) +{ + wstring wstr; + { + size_t len = strlen(str), outSize = 0; + wchar_t *pDestBuf = new wchar_t[len + 1]; + mbstowcs_s(&outSize, pDestBuf, len + 1, str, len); + if (outSize > 0) + wstr = pDestBuf; + else + NS_Logger::WriteLog(DEFAULT_ERROR_MESSAGE); + delete[] pDestBuf; + } + return wstr; +} +#endif + +TranslationsMap Translator::translMap = TranslationsMap(); +tstring Translator::langName = _T("en"); +bool Translator::is_translations_valid = false; + +#ifdef _WIN32 +Translator::Translator(const tstring &lang, int resourceId) +#else +Translator::Translator(const tstring &lang, const char *resourcePath) +#endif +{ + langName = lang; + NS_Logger::WriteLog(_T("Current locale: ") + langName); + +#ifdef _WIN32 + HMODULE hInst = GetModuleHandle(NULL); + if (HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(resourceId), RT_RCDATA)) { + if (HGLOBAL hResData = LoadResource(hInst, hRes)) { + if (LPVOID pData = LockResource(hResData)) { + DWORD dataSize = SizeofResource(hInst, hRes); + if (dataSize > 0) { + string text((const char*)pData, dataSize); + translations = StrToWStr(text.c_str()); + } else + NS_Logger::WriteLog(ADVANCED_ERROR_MESSAGE); + } else + NS_Logger::WriteLog(ADVANCED_ERROR_MESSAGE); + FreeResource(hResData); + } else + NS_Logger::WriteLog(ADVANCED_ERROR_MESSAGE); + } else + NS_Logger::WriteLog(ADVANCED_ERROR_MESSAGE); +#else + if (GResource *res = gresource_get_resource()) { + g_resources_register(res); + if (GBytes *bytes = g_resource_lookup_data(res, resourcePath, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL)) { + gsize dataSize = 0; + const char *pData = (const char*)g_bytes_get_data(bytes, &dataSize); + if (dataSize > 0) { + string text(pData, dataSize); + translations = text; + } else + NS_Logger::WriteLog(ADVANCED_ERROR_MESSAGE); + g_bytes_unref(bytes); + } else + NS_Logger::WriteLog(ADVANCED_ERROR_MESSAGE); + g_resource_unref(res); + } else + NS_Logger::WriteLog(ADVANCED_ERROR_MESSAGE); +#endif + + if (!translations.empty()) { + parseTranslations(); + if (!is_translations_valid) + NS_Logger::WriteLog(_T("Cannot parse translations, error in string: ") + error_substr + _T(" <---")); + } else + NS_Logger::WriteLog(_T("Error: translations is empty.")); +} + +Translator::~Translator() +{ + +} + +tstring Translator::tr(const char *str) +{ +#ifdef _WIN32 + tstring translatedStr = StrToWStr(str); +#else + tstring translatedStr = str; +#endif + if (is_translations_valid) { + for (auto &strIdPair : translMap) { + //LocaleMap locMap = strIdPair.second; + for (LocaleMap::const_iterator it = strIdPair.second.begin(); it != strIdPair.second.end(); ++it) { + //wcout << L"\n\n" << translatedStr << L"\n" << it->second; + if (it->second == translatedStr) { + if (strIdPair.second.find(langName) != strIdPair.second.end()) + translatedStr = strIdPair.second[langName]; + else { + tstring primaryLang = getPrimaryLang(langName); + if (strIdPair.second.find(primaryLang) != strIdPair.second.end()) + translatedStr = strIdPair.second[primaryLang]; + } + break; + } + } + } + } + return translatedStr; +} + +void Translator::setLanguage(const tstring &lang) +{ + langName = lang; + NS_Logger::WriteLog(_T("Current locale: ") + langName); +} + +void Translator::parseTranslations() +{ + int token = TOKEN_BEGIN_DOCUMENT; + tstring stringId, currentLocale; + size_t pos = 0, len = translations.length(); + while (pos < len) { + size_t incr = 1; + tchar ch = translations.at(pos); + + switch (token) { + case TOKEN_BEGIN_DOCUMENT: + case TOKEN_END_VALUE: + if (!isSeparator(ch)) { + if (ch == _T(';')) { + // string is comment + size_t end = translations.find_first_of(_T('\n'), pos); + incr = (end == tstring::npos) ? len - pos : end - pos + 1; + } else { + size_t end; + for (end = pos; end < len; end++) { + tchar c = translations.at(end); + if (!isValidLocaleCharacter(c)) + break; + } + size_t locale_len = end - pos; + if (locale_len == 2 || locale_len == 5) { + token = TOKEN_BEGIN_LOCALE; + continue; + } else { + // TOKEN_ERROR + error_substr = translations.substr(0, pos + 1); + return; + } + } + } + break; + + case TOKEN_BEGIN_STRING_ID: + if (!isSeparator(ch)) { + size_t end; + tchar c; + for (end = pos; end < len; end++) { + c = translations.at(end); + if (!isValidStringIdCharacter(c)) + break; + } + c = translations.at(end); + if (end < len && !isSeparator(c) && c != _T('=')) { + // TOKEN_ERROR + error_substr = translations.substr(0, end + 1); + return; + } + stringId = translations.substr(pos, end - pos); + if (!stringId.empty() && translMap.find(stringId) == translMap.end()) + translMap[stringId] = LocaleMap(); + + token = TOKEN_END_STRING_ID; + incr = end - pos; + } + break; + + case TOKEN_END_STRING_ID: + if (!isSeparator(ch)) { + if (ch == _T('=')) { + token = TOKEN_BEGIN_VALUE; + } else { + // TOKEN_ERROR + error_substr = translations.substr(0, pos + 1); + return; + } + } + break; + + case TOKEN_BEGIN_LOCALE: { + size_t end; + for (end = pos; end < len; end++) { + tchar c = translations.at(end); + if (!isValidLocaleCharacter(c)) + break; + } + size_t locale_len = end - pos; + currentLocale = translations.substr(pos, locale_len); + if (pos + locale_len == len) { + error_substr = translations.substr(0, pos + locale_len); + return; + } + token = TOKEN_END_LOCALE; + incr = locale_len; + break; + } + + case TOKEN_END_LOCALE: + if (!isSeparator(ch)) { + if (ch == _T('.')) { + token = TOKEN_BEGIN_STRING_ID; + } else { + // TOKEN_ERROR + error_substr = translations.substr(0, pos + 1); + return; + } + } + break; + + case TOKEN_BEGIN_VALUE: { + size_t end = translations.find_first_of(_T('\n'), pos); + tstring val; + if (end == tstring::npos) { + val = translations.substr(pos); + incr = len - pos; + } else { + val = translations.substr(pos, end - pos); + incr = end - pos; + } + + if (!val.empty() && val.back() == _T('\r')) + val.pop_back(); + + size_t p = val.find(_T("\\n")); + while (p != std::string::npos) { + val.replace(p, 2, _T("\\")); + val[p] = _T('\n'); + p = val.find(_T("\\n"), p + 1); + } + if (!currentLocale.empty() && translMap.find(stringId) != translMap.end()) + translMap[stringId][currentLocale] = val; + + token = TOKEN_END_VALUE; + break; + } + + default: + break; + } + pos += incr; + if (pos == len) + token = TOKEN_END_DOCUMENT; + } + + if (token == TOKEN_END_DOCUMENT) + is_translations_valid = true; +} diff --git a/win-linux/extras/update-daemon/src/classes/translator.h b/win-linux/extras/update-daemon/src/classes/translator.h new file mode 100644 index 000000000..c27c81b26 --- /dev/null +++ b/win-linux/extras/update-daemon/src/classes/translator.h @@ -0,0 +1,56 @@ +#ifndef TRANSLATOR_H +#define TRANSLATOR_H + +#include +#include +#ifdef _WIN32 +# include +# define tchar wchar_t +# define tstring std::wstring +#else +# define _T(str) str +# define tchar char +# define tstring std::string +#endif + +using std::unordered_map; + +typedef unordered_map LocaleMap; +typedef unordered_map TranslationsMap; + + +class Translator +{ +public: +#ifdef _WIN32 + Translator(const tstring &lang, int resourceId); +#else + Translator(const tstring &lang, const char *resourcePath); +#endif + ~Translator(); + + static tstring tr(const char*); + static void setLanguage(const tstring &lang); + +private: + void parseTranslations(); + + static TranslationsMap translMap; + tstring translations, + error_substr; + static tstring langName; + static bool is_translations_valid; + + enum TokenType { + TOKEN_BEGIN_DOCUMENT = 0, + TOKEN_END_DOCUMENT, + TOKEN_BEGIN_STRING_ID, + TOKEN_END_STRING_ID, + TOKEN_BEGIN_LOCALE, + TOKEN_END_LOCALE, + TOKEN_BEGIN_VALUE, + TOKEN_END_VALUE + }; +}; + +#endif // TRANSLATOR_H diff --git a/win-linux/extras/update-daemon/src/platform_linux/main.cpp b/win-linux/extras/update-daemon/src/platform_linux/main.cpp index 9b250eac3..e9ed6f057 100644 --- a/win-linux/extras/update-daemon/src/platform_linux/main.cpp +++ b/win-linux/extras/update-daemon/src/platform_linux/main.cpp @@ -34,10 +34,12 @@ #include "classes/platform_linux/capplication.h" #include "classes/platform_linux/ctimer.h" #include "classes/csvcmanager.h" +#include "classes/translator.h" #include "../../src/defines.h" #include "../../src/prop/defines_p.h" #include #include +#include void strToNum(const char *str, int &num) @@ -54,6 +56,8 @@ int main(int argc, char *argv[]) if (argc > 1) { if (strcmp(argv[1], "--run-as-app") == 0) { + std::locale::global(std::locale("")); + Translator lang(NS_Utils::GetSysLanguage(), "/langs/langs.iss"); CSocket socket(0, INSTANCE_SVC_PORT); if (!socket.isPrimaryInstance()) return 0; diff --git a/win-linux/extras/update-daemon/src/platform_linux/utils.cpp b/win-linux/extras/update-daemon/src/platform_linux/utils.cpp index 3e4d8dd44..72ff212ad 100644 --- a/win-linux/extras/update-daemon/src/platform_linux/utils.cpp +++ b/win-linux/extras/update-daemon/src/platform_linux/utils.cpp @@ -142,13 +142,25 @@ namespace NS_Utils gtk_init(NULL, NULL); GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", str.c_str()); - gtk_window_set_title(GTK_WINDOW(dialog), VER_PRODUCTNAME_STR); + string prod_name = _TR(VER_PRODUCTNAME_STR); + gtk_window_set_title(GTK_WINDOW(dialog), prod_name.c_str()); int res = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); while (gtk_events_pending()) gtk_main_iteration_do(FALSE); return res; } + + string GetSysLanguage() + { + string lang("en_EN"); + size_t pos = std::string::npos; + if (char *_lang = getenv("LANG")) { + lang = _lang; + pos = lang.find('.'); + } + return (pos == std::string::npos) ? lang : lang.substr(0, pos); + } } namespace NS_File diff --git a/win-linux/extras/update-daemon/src/platform_linux/utils.h b/win-linux/extras/update-daemon/src/platform_linux/utils.h index fbff00db6..e459fe5d3 100644 --- a/win-linux/extras/update-daemon/src/platform_linux/utils.h +++ b/win-linux/extras/update-daemon/src/platform_linux/utils.h @@ -35,13 +35,16 @@ #include #include +#include "classes/translator.h" using std::string; using std::to_string; using std::list; +#define _TR(str) Translator::tr(str) + #define FUNCTION_INFO string(__FUNCTION__) + " Line: " + to_string(__LINE__) -#define DEFAULT_ERROR_MESSAGE "An error occurred: " + FUNCTION_INFO +#define DEFAULT_ERROR_MESSAGE _TR("An error occurred:") + " " + FUNCTION_INFO #define ADVANCED_ERROR_MESSAGE DEFAULT_ERROR_MESSAGE + \ " " + NS_Utils::GetLastErrorAsString() @@ -49,6 +52,7 @@ namespace NS_Utils { string GetLastErrorAsString(); int ShowMessage(string str, bool showError = false); +string GetSysLanguage(); } namespace NS_File diff --git a/win-linux/extras/update-daemon/src/platform_win/main.cpp b/win-linux/extras/update-daemon/src/platform_win/main.cpp index 016f58090..9c1e40f1d 100644 --- a/win-linux/extras/update-daemon/src/platform_win/main.cpp +++ b/win-linux/extras/update-daemon/src/platform_win/main.cpp @@ -30,11 +30,14 @@ * */ +#include #include "utils.h" +#include "platform_win/resource.h" #include "platform_win/svccontrol.h" #include "classes/platform_win/capplication.h" #include "classes/platform_win/ctimer.h" #include "classes/csvcmanager.h" +#include "classes/translator.h" #include "../../src/defines.h" #include "../../src/prop/defines_p.h" @@ -91,6 +94,8 @@ int __cdecl _tmain (int argc, TCHAR *argv[]) } else if (lstrcmpi(argv[1], _T("--run-as-app")) == 0) { NS_Utils::setRunAsApp(); + std::locale::global(std::locale("")); + Translator lang(NS_Utils::GetAppLanguage().c_str(), IDT_TRANSLATIONS); CSocket socket(0, INSTANCE_SVC_PORT); if (!socket.isPrimaryInstance()) return 0; @@ -131,6 +136,8 @@ int __cdecl _tmain (int argc, TCHAR *argv[]) } } + std::locale::global(std::locale("")); + Translator lang(NS_Utils::GetAppLanguage().c_str(), IDT_TRANSLATIONS); SERVICE_TABLE_ENTRY DispatchTable[] = { {(LPTSTR)SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)SvcMain}, @@ -138,7 +145,7 @@ int __cdecl _tmain (int argc, TCHAR *argv[]) }; if (StartServiceCtrlDispatcher(DispatchTable) == 0) { - NS_Utils::ShowMessage(L"ServiceCtrlDispatcher returned error:", true); + NS_Utils::ShowMessage(_TR("ServiceCtrlDispatcher returned error:") + _T(" ") + NS_Utils::GetLastErrorAsString(), true); return GetLastError(); } diff --git a/win-linux/extras/update-daemon/src/platform_win/resource.h b/win-linux/extras/update-daemon/src/platform_win/resource.h index 6416ebb85..f3d59c80f 100644 --- a/win-linux/extras/update-daemon/src/platform_win/resource.h +++ b/win-linux/extras/update-daemon/src/platform_win/resource.h @@ -1 +1,3 @@ #define IDI_MAINICON 101 + +#define IDT_TRANSLATIONS 10001 diff --git a/win-linux/extras/update-daemon/src/platform_win/svccontrol.cpp b/win-linux/extras/update-daemon/src/platform_win/svccontrol.cpp index e6863fca9..0a0fa4bfa 100644 --- a/win-linux/extras/update-daemon/src/platform_win/svccontrol.cpp +++ b/win-linux/extras/update-daemon/src/platform_win/svccontrol.cpp @@ -31,6 +31,7 @@ */ #include "svccontrol.h" +#include "classes/translator.h" #include "platform_win/utils.h" #include #include diff --git a/win-linux/extras/update-daemon/src/platform_win/utils.cpp b/win-linux/extras/update-daemon/src/platform_win/utils.cpp index 24a68cd52..eebf123c1 100644 --- a/win-linux/extras/update-daemon/src/platform_win/utils.cpp +++ b/win-linux/extras/update-daemon/src/platform_win/utils.cpp @@ -31,6 +31,7 @@ */ #include "platform_win/utils.h" +#include "classes/translator.h" #include "version.h" #include #include @@ -49,6 +50,8 @@ #include #include #include +#include "../../src/defines.h" +#include "../../src/prop/defines_p.h" #define BUFSIZE 1024 @@ -101,7 +104,8 @@ namespace NS_Utils { if (showError) str += L" " + GetLastErrorAsString(); - wchar_t *title = const_cast(TEXT(VER_PRODUCTNAME_STR)); + wstring prod_name = _TR(VER_PRODUCTNAME_STR); + wchar_t *title = const_cast(prod_name.c_str()); if (isRunAsApp()) { MessageBox(NULL, str.c_str(), title, MB_ICONERROR | MB_SERVICE_NOTIFICATION_NT3X | MB_SETFOREGROUND); return 0; @@ -114,6 +118,23 @@ namespace NS_Utils MB_OK | MB_ICONERROR | MB_SERVICE_NOTIFICATION_NT3X | MB_SETFOREGROUND, 30, &res, TRUE); return res; } + + wstring GetAppLanguage() + { + wstring lang = TEXT("en"), subkey = TEXT("SOFTWARE\\" REG_GROUP_KEY "\\" REG_APP_NAME); + HKEY hKey = NULL; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, subkey.c_str(), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) { + DWORD type = REG_SZ, cbData = 0; + if (RegGetValue(hKey, NULL, TEXT("locale"), RRF_RT_REG_SZ, &type, NULL, &cbData) == ERROR_SUCCESS) { + wchar_t *pvData = (wchar_t*)malloc(cbData); + if (RegGetValueW(hKey, NULL, TEXT("locale"), RRF_RT_REG_SZ, &type, (void*)pvData, &cbData) == ERROR_SUCCESS) + lang = pvData; + free(pvData); + } + RegCloseKey(hKey); + } + return lang; + } } namespace NS_File diff --git a/win-linux/extras/update-daemon/src/platform_win/utils.h b/win-linux/extras/update-daemon/src/platform_win/utils.h index 94ccd1817..de0aa79ed 100644 --- a/win-linux/extras/update-daemon/src/platform_win/utils.h +++ b/win-linux/extras/update-daemon/src/platform_win/utils.h @@ -41,8 +41,10 @@ using std::wstring; using std::to_wstring; using std::list; +#define _TR(str) Translator::tr(str) + #define FUNCTION_INFO wstring(TEXT(__FUNCTION__)) + L" Line: " + to_wstring(__LINE__) -#define DEFAULT_ERROR_MESSAGE L"An error occurred: " + FUNCTION_INFO +#define DEFAULT_ERROR_MESSAGE _TR("An error occurred:") + L" " + FUNCTION_INFO #define ADVANCED_ERROR_MESSAGE DEFAULT_ERROR_MESSAGE + \ L" " + NS_Utils::GetLastErrorAsString() @@ -52,6 +54,7 @@ void setRunAsApp(); bool isRunAsApp(); wstring GetLastErrorAsString(); int ShowMessage(wstring str, bool showError = false); +wstring GetAppLanguage(); } namespace NS_File diff --git a/win-linux/src/cascapplicationmanagerwrapper.cpp b/win-linux/src/cascapplicationmanagerwrapper.cpp index 43a9db301..65b994136 100644 --- a/win-linux/src/cascapplicationmanagerwrapper.cpp +++ b/win-linux/src/cascapplicationmanagerwrapper.cpp @@ -950,6 +950,7 @@ void CAscApplicationManagerWrapper::onDocumentReady(int uid) #ifdef _UPDMODULE if (!m_pUpdateManager) { m_pUpdateManager = new CUpdateManager(this); + m_pUpdateManager->setServiceLang(); m_pUpdateManager->launchIntervalStartTimer(); } if (uid < 0) { @@ -1660,8 +1661,10 @@ bool CAscApplicationManagerWrapper::applySettings(const wstring& wstrjson) _reg_user.setValue("locale", _lang_id); CLangater::reloadTranslations(_lang_id); #ifdef _UPDMODULE - if (m_pUpdateManager) + if (m_pUpdateManager) { + m_pUpdateManager->setServiceLang(_lang_id); m_pUpdateManager->refreshStartPage(); + } #endif } } diff --git a/win-linux/src/cupdatemanager.cpp b/win-linux/src/cupdatemanager.cpp index 468389454..31cb53b80 100644 --- a/win-linux/src/cupdatemanager.cpp +++ b/win-linux/src/cupdatemanager.cpp @@ -611,6 +611,15 @@ void CUpdateManager::launchIntervalStartTimer() m_pIntervalStartTimer->start(); } +void CUpdateManager::setServiceLang(QString lang) +{ + if (lang.isEmpty()) + lang = CLangater::getLangName(); + lang.replace('-', '_'); + if (!m_socket->sendMessage(MSG_SetLanguage, QStrToTStr(lang))) + CLogger::log("Cannot set service language to: " + lang); +} + QString CUpdateManager::getVersion() const { return m_packageData->version; diff --git a/win-linux/src/cupdatemanager.h b/win-linux/src/cupdatemanager.h index 07d49e52c..56303444d 100644 --- a/win-linux/src/cupdatemanager.h +++ b/win-linux/src/cupdatemanager.h @@ -94,6 +94,7 @@ public: void installUpdates(); void refreshStartPage(const Command &cmd = Command()); void launchIntervalStartTimer(); + void setServiceLang(QString lang = QString()); public slots: void checkUpdates(bool manualCheck = false);