From 51a1c660b4639765aff83f9ba75fae53d6bd51e7 Mon Sep 17 00:00:00 2001 From: Ansa89 Date: Mon, 25 May 2015 16:38:52 +0200 Subject: [PATCH] Add localization system (gettext) --- INSTALL.md | 53 +- cfg/checks/check_features.mk | 6 + cfg/global_vars.mk | 5 + cfg/systems/Darwin.mk | 6 + cfg/targets/help.mk | 1 + cfg/targets/install.mk | 11 + src/audio_call.c | 118 +-- src/autocomplete.c | 8 +- src/avatars.c | 10 +- src/chat.c | 101 +- src/chat_commands.c | 78 +- src/configdir.c | 8 +- src/dns.c | 52 +- src/execute.c | 12 +- src/friendlist.c | 60 +- src/global_commands.c | 112 ++- src/group_commands.c | 18 +- src/groupchat.c | 46 +- src/help.c | 143 ++- src/line_info.c | 10 +- src/log.c | 12 +- src/message_queue.c | 8 +- src/misc_tools.c | 10 +- src/prompt.c | 52 +- src/toxic.c | 176 ++-- src/toxic.h | 4 +- src/windows.c | 10 +- translations/en.mo | Bin 0 -> 28644 bytes translations/en.po | 1599 +++++++++++++++++++++++++++++ translations/it.mo | Bin 0 -> 30657 bytes translations/it.po | 1607 ++++++++++++++++++++++++++++++ translations/tools/create_mo.sh | 19 + translations/tools/create_po.sh | 23 + translations/tools/update_po.sh | 19 + translations/tools/update_pot.sh | 12 + translations/toxic.pot | 1574 +++++++++++++++++++++++++++++ 36 files changed, 5546 insertions(+), 437 deletions(-) create mode 100644 translations/en.mo create mode 100644 translations/en.po create mode 100644 translations/it.mo create mode 100644 translations/it.po create mode 100755 translations/tools/create_mo.sh create mode 100755 translations/tools/create_po.sh create mode 100755 translations/tools/update_po.sh create mode 100755 translations/tools/update_pot.sh create mode 100644 translations/toxic.pot diff --git a/INSTALL.md b/INSTALL.md index 4e96a30..49fbb8b 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -3,6 +3,10 @@ * [OS X Notes](#deps_osx) * [Compiling](#compiling) * [Documentation](#docs) +* [Translating](#langs) + * [Create new translation 1: PO file](#new_lang_1) + * [Create new translation 2: MO file](#new_lang_2) + * [Update existing translation](#upd_lang) * [Notes](#notes) * [Compilation variables](#comp_vars) * [Packaging](#packaging) @@ -20,20 +24,23 @@ | [OpenALUT](http://openal.org) | SOUND NOTIFICATIONS | libalut-dev | | [LibNotify](https://developer.gnome.org/libnotify) | DESKTOP NOTIFICATIONS | libnotify-dev | | [AsciiDoc](http://asciidoc.org/index.html) | DOCUMENTATION1 | asciidoc | -1: see [Documentation](#docs) +| [Gettext](https://www.gnu.org/software/gettext) | LOCALIZATION2 | gettext | +1: see [Documentation](#docs)
+2: see [Translating](#langs) #### OS X Notes Using [Homebrew](http://brew.sh): ``` -brew install openal-soft freealut libconfig +brew install openal-soft freealut libconfig gettext brew install https://raw.githubusercontent.com/Tox/homebrew-tox/master/Formula/libtoxcore.rb brew install https://raw.githubusercontent.com/Homebrew/homebrew-x11/master/libnotify.rb +brew link gettext ``` You can omit `libnotify` if you intend to build without desktop notifications enabled. - + ## Compiling ``` make PREFIX="/where/to/install" @@ -46,6 +53,45 @@ Run `make doc` in the build directory after editing the asciidoc files to regene **NOTE FOR DEVELOPERS**: asciidoc files and generated manpages will need to be commited together.
**NOTE FOR EVERYONE**: [asciidoc](http://asciidoc.org/index.html) (and this step) is only required for regenerating manpages when you modify them. +
+## Translating +Toxic uses gettext to localize some strings in various languages.
+These notes are for people who want help translating toxic in new languages (or improve an existing translation).
+The following example shows how to create/update german translation (de). + +
+#### Create new translation 1: PO file +To start a new translation, you can use the [provided script](translations/tools/create_po.sh): +``` +cd toxic-src/translations/tools +./create_po.sh +Insert locale to create (for example "en"): de +Created de.po. +``` +Now you can proceed to translate `toxic-src/translations/de.po`. + + +#### Create new translation 2: MO file +When you fully translated the PO file, you are ready to create the MO (Machine Object) file.
+Again you can use the [provided script](translations/tools/create_mo.sh) to achieve this: +``` +cd toxic-src/translations/tools +./create_mo.sh +Insert locale (for example "en"): de +``` + +
+#### Update existing translation +When the toxic sources are updated, you probably need to update your translation as well.
+To do so use the [provided script](translations/tools/update_po.sh) to update the PO file: +``` +cd toxic-src/translations/tools +./update_po.sh +Insert locale to update (for example "en"): de +..................................... done. +``` +Then you need to translate new/changed strings and after you fully updated the PO file, create the MO file as described [above](#new_lang_2). +
## Notes @@ -58,6 +104,7 @@ Run `make doc` in the build directory after editing the asciidoc files to regene * `DISABLE_AV=1` → build toxic without audio call support * `DISABLE_SOUND_NOTIFY=1` → build toxic without sound notifications support * `DISABLE_DESKTOP_NOTIFY=1` → build toxic without desktop notifications support + * `DISABLE_LOCALIZATION=1` → build toxic without localization support #### Packaging diff --git a/cfg/checks/check_features.mk b/cfg/checks/check_features.mk index 430d1af..d6bcc57 100644 --- a/cfg/checks/check_features.mk +++ b/cfg/checks/check_features.mk @@ -24,6 +24,12 @@ ifneq ($(DESK_NOTIFY), disabled) -include $(CHECKS_DIR)/desktop_notifications.mk endif +# Check if we want build localization support +LOCALIZATION = $(shell if [ -z "$(DISABLE_LOCALIZATION)" ] || [ "$(DISABLE_LOCALIZATION)" = "0" ] ; then echo enabled ; else echo disabled ; fi) +ifneq ($(LOCALIZATION), enabled) + CFLAGS += -DNO_GETTEXT +endif + # Check if we can build Toxic CHECK_LIBS = $(shell pkg-config --exists $(LIBS) || echo -n "error") ifneq ($(CHECK_LIBS), error) diff --git a/cfg/global_vars.mk b/cfg/global_vars.mk index d5c7b57..5d4a14c 100644 --- a/cfg/global_vars.mk +++ b/cfg/global_vars.mk @@ -13,6 +13,7 @@ DOC_DIR = $(BASE_DIR)/doc SRC_DIR = $(BASE_DIR)/src SND_DIR = $(BASE_DIR)/sounds MISC_DIR = $(BASE_DIR)/misc +TRANSLATIONS_DIR = $(BASE_DIR)/translations # Project files MANFILES = toxic.1 toxic.conf.5 @@ -22,9 +23,13 @@ SNDFILES = ToxicContactOnline.wav ToxicContactOffline.wav ToxicError.wav SNDFILES += ToxicRecvMessage.wav ToxicOutgoingCall.wav ToxicIncomingCall.wav SNDFILES += ToxicTransferComplete.wav ToxicTransferStart.wav +# Available languages (sorted alphabetically) +LANGS = en it + # Install directories PREFIX = /usr/local BINDIR = $(PREFIX)/bin DATADIR = $(PREFIX)/share/toxic MANDIR = $(PREFIX)/share/man APPDIR = $(PREFIX)/share/applications +LOCALEDIR = ${PREFIX}/share/locale diff --git a/cfg/systems/Darwin.mk b/cfg/systems/Darwin.mk index f33a4be..b4c82ad 100644 --- a/cfg/systems/Darwin.mk +++ b/cfg/systems/Darwin.mk @@ -8,3 +8,9 @@ LIBS := $(filter-out ncursesw, $(LIBS)) # OS X ships a usable, recent version of ncurses, but calls it ncurses not ncursesw. LDFLAGS += -lncurses -lalut -ltoxav -ltoxcore -ltoxdns -lresolv -lconfig -ltoxencryptsave -g CFLAGS += -I/usr/local/opt/freealut/include/AL -I/usr/local/opt/glib/include/glib-2.0 -g + +# Check if we want build localization support +LOCALIZATION = $(shell if [ -z "$(DISABLE_LOCALIZATION)" ] || [ "$(DISABLE_LOCALIZATION)" = "0" ] ; then echo enabled ; else echo disabled ; fi) +ifneq ($(LOCALIZATION), disabled) + LDFLAGS += -lintl +endif diff --git a/cfg/targets/help.mk b/cfg/targets/help.mk index fba1c8f..4946b00 100644 --- a/cfg/targets/help.mk +++ b/cfg/targets/help.mk @@ -14,6 +14,7 @@ help: @echo " DISABLE_AV: Set to \"1\" to force building without audio call support" @echo " DISABLE_SOUND_NOTIFY: Set to \"1\" to force building without sound notification support" @echo " DISABLE_DESKTOP_NOTIFY: Set to \"1\" to force building without desktop notifications support" + @echo " DISABLE_LOCALIZATION: Set to \"1\" to force building without localization support" @echo " USER_CFLAGS: Add custom flags to default CFLAGS" @echo " USER_LDFLAGS: Add custom flags to default LDFLAGS" @echo " PREFIX: Specify a prefix directory for binaries, data files,... (default is \"$(abspath $(PREFIX))\")" diff --git a/cfg/targets/install.mk b/cfg/targets/install.mk index 12050ff..3f9bf47 100644 --- a/cfg/targets/install.mk +++ b/cfg/targets/install.mk @@ -8,6 +8,17 @@ install: $(BUILD_DIR)/toxic @mkdir -p $(abspath $(DESTDIR)/$(APPDIR)) @install -m 0644 $(MISC_DIR)/$(DESKFILE) $(abspath $(DESTDIR)/$(APPDIR)/$(DESKFILE)) + @if [ -z "$(DISABLE_LOCALIZATION)" -o "$(DISABLE_LOCALIZATION)" = "0" ]; then \ + echo "Installing translations" ; \ + for i in $(LANGS) ; do \ + if [ ! -e $(TRANSLATIONS_DIR)/$$i.mo ]; then \ + continue ; \ + fi ; \ + mkdir -p $(abspath $(DESTDIR)/$(LOCALEDIR)/$$i/LC_MESSAGES) ; \ + install -m 0644 $(TRANSLATIONS_DIR)/$$i.mo $(abspath $(DESTDIR)/$(LOCALEDIR)/$$i/LC_MESSAGES/toxic.mo) ; \ + done ; \ + fi + @echo "Installing data files" @mkdir -p $(abspath $(DESTDIR)/$(DATADIR)) @for f in $(DATAFILES) ; do \ diff --git a/src/audio_call.c b/src/audio_call.c index 54b865b..274b5bb 100644 --- a/src/audio_call.c +++ b/src/audio_call.c @@ -37,6 +37,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #ifdef __APPLE__ #include #include @@ -124,7 +130,7 @@ ToxAv *init_audio(ToxWindow *self, Tox *tox) } if ( init_devices(ASettins.av) == de_InternalError ) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to init devices"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to init devices")); toxav_kill(ASettins.av); return ASettins.av = NULL; } @@ -167,7 +173,7 @@ void read_device_callback (const int16_t* captured, uint32_t size, void* data) uint8_t encoded_payload[RTP_PAYLOAD_SIZE]; int32_t payload_size = toxav_prepare_audio_frame(ASettins.av, call_index, encoded_payload, RTP_PAYLOAD_SIZE, captured, size); if ( payload_size <= 0 || toxav_send_audio(ASettins.av, call_index, encoded_payload, payload_size) < 0 ) { - /*fprintf(stderr, "Could not encode audio packet\n");*/ + /*fprintf(stderr, gettext("Could not encode audio packet\n"));*/ } } @@ -186,13 +192,13 @@ void write_device_callback(void *agent, int32_t call_index, const int16_t* PCM, int start_transmission(ToxWindow *self, Call *call) { if ( !self || !ASettins.av || self->call_idx == -1 ) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Could not prepare transmission"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Could not prepare transmission")); return -1; } /* Don't provide support for video */ if ( 0 != toxav_prepare_transmission(ASettins.av, self->call_idx, 0) ) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Could not prepare transmission"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Could not prepare transmission")); return -1; } @@ -208,16 +214,16 @@ int start_transmission(ToxWindow *self, Call *call) if ( open_primary_device(input, &call->in_idx, csettings.audio_sample_rate, csettings.audio_frame_duration, csettings.audio_channels) != de_None ) - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to open input device!"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to open input device!")); if ( register_device_callback(self->call_idx, call->in_idx, read_device_callback, &self->call_idx, true) != de_None) /* Set VAD as true for all; TODO: Make it more dynamic */ - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to register input handler!"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to register input handler!")); if ( open_primary_device(output, &call->out_idx, csettings.audio_sample_rate, csettings.audio_frame_duration, csettings.audio_channels) != de_None ) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to open output device!"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to open output device!")); call->has_output = 0; } @@ -275,7 +281,7 @@ void callback_recv_starting ( void* av, int32_t call_index, void* arg ) if (windows[i].onStarting != NULL && windows[i].call_idx == call_index) { windows[i].onStarting(&windows[i], ASettins.av, call_index); if ( 0 != start_transmission(&windows[i], &ASettins.calls[call_index])) {/* YEAH! */ - line_info_add(&windows[i], NULL, NULL, NULL, SYS_MSG, 0, 0 , "Error starting transmission!"); + line_info_add(&windows[i], NULL, NULL, NULL, SYS_MSG, 0, 0 , gettext("Error starting transmission!")); } return; } @@ -294,7 +300,7 @@ void callback_call_started ( void* av, int32_t call_index, void* arg ) if (windows[i].onStart != NULL && windows[i].call_idx == call_index) { windows[i].onStart(&windows[i], ASettins.av, call_index); if ( 0 != start_transmission(&windows[i], &ASettins.calls[call_index]) ) {/* YEAH! */ - line_info_add(&windows[i], NULL, NULL, NULL, SYS_MSG, 0, 0, "Error starting transmission!"); + line_info_add(&windows[i], NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Error starting transmission!")); return; } } @@ -348,30 +354,30 @@ void cmd_call(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA const char *error_str; if (argc != 0) { - error_str = "Unknown arguments."; + error_str = gettext("Unknown arguments."); goto on_error; } if ( !ASettins.av ) { - error_str = "Audio not supported!"; + error_str = gettext("Audio not supported!"); goto on_error; } if (!self->stb->connection) { - error_str = "Friend is offline."; + error_str = gettext("Friend is offline."); goto on_error; } ToxAvError error = toxav_call(ASettins.av, &self->call_idx, self->num, &ASettins.cs, 30); if ( error != av_ErrorNone ) { - if ( error == av_ErrorAlreadyInCallWithPeer ) error_str = "Already in a call!"; - else error_str = "Internal error!"; + if ( error == av_ErrorAlreadyInCallWithPeer ) error_str = gettext("Already in a call!"); + else error_str = gettext("Internal error!"); goto on_error; } - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Calling... idx: %d", self->call_idx); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Calling... idx: %d"), self->call_idx); return; on_error: @@ -383,21 +389,21 @@ void cmd_answer(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ const char *error_str; if (argc != 0) { - error_str = "Unknown arguments."; + error_str = gettext("Unknown arguments."); goto on_error; } if ( !ASettins.av ) { - error_str = "Audio not supported!"; + error_str = gettext("Audio not supported!"); goto on_error; } ToxAvError error = toxav_answer(ASettins.av, self->call_idx, &ASettins.cs); if ( error != av_ErrorNone ) { - if ( error == av_ErrorInvalidState ) error_str = "Cannot answer in invalid state!"; - else if ( error == av_ErrorNoCall ) error_str = "No incoming call!"; - else error_str = "Internal error!"; + if ( error == av_ErrorInvalidState ) error_str = gettext("Cannot answer in invalid state!"); + else if ( error == av_ErrorNoCall ) error_str = gettext("No incoming call!"); + else error_str = gettext("Internal error!"); goto on_error; } @@ -414,21 +420,21 @@ void cmd_reject(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ const char *error_str; if (argc != 0) { - error_str = "Unknown arguments."; + error_str = gettext("Unknown arguments."); goto on_error; } if ( !ASettins.av ) { - error_str = "Audio not supported!"; + error_str = gettext("Audio not supported!"); goto on_error; } - ToxAvError error = toxav_reject(ASettins.av, self->call_idx, "Why not?"); + ToxAvError error = toxav_reject(ASettins.av, self->call_idx, gettext("Why not?")); if ( error != av_ErrorNone ) { - if ( error == av_ErrorInvalidState ) error_str = "Cannot reject in invalid state!"; - else if ( error == av_ErrorNoCall ) error_str = "No incoming call!"; - else error_str = "Internal error!"; + if ( error == av_ErrorInvalidState ) error_str = gettext("Cannot reject in invalid state!"); + else if ( error == av_ErrorNoCall ) error_str = gettext("No incoming call!"); + else error_str = gettext("Internal error!"); goto on_error; } @@ -445,12 +451,12 @@ void cmd_hangup(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ const char *error_str; if (argc != 0) { - error_str = "Unknown arguments."; + error_str = gettext("Unknown arguments."); goto on_error; } if ( !ASettins.av ) { - error_str = "Audio not supported!"; + error_str = gettext("Audio not supported!"); goto on_error; } @@ -458,19 +464,19 @@ void cmd_hangup(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ if (toxav_get_call_state(ASettins.av, self->call_idx) == av_CallInviting) { error = toxav_cancel(ASettins.av, self->call_idx, self->num, - "Only those who appreciate small things know the beauty that is life"); + gettext("Only those who appreciate small things know the beauty that is life")); #ifdef SOUND_NOTIFY stop_sound(self->ringing_sound); #endif - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call canceled!"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Call canceled!")); } else { error = toxav_hangup(ASettins.av, self->call_idx); } if ( error != av_ErrorNone ) { - if ( error == av_ErrorInvalidState ) error_str = "Cannot hangup in invalid state!"; - else if ( error == av_ErrorNoCall ) error_str = "No call!"; - else error_str = "Internal error!"; + if ( error == av_ErrorInvalidState ) error_str = gettext("Cannot hangup in invalid state!"); + else if ( error == av_ErrorNoCall ) error_str = gettext("No call!"); + else error_str = gettext("Internal error!"); goto on_error; } @@ -485,8 +491,8 @@ void cmd_list_devices(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (* const char *error_str; if ( argc != 1 ) { - if ( argc < 1 ) error_str = "Type must be specified!"; - else error_str = "Only one argument allowed!"; + if ( argc < 1 ) error_str = gettext("Type must be specified!"); + else error_str = gettext("Only one argument allowed!"); goto on_error; } @@ -500,7 +506,7 @@ void cmd_list_devices(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (* type = output; else { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid type: %s", argv[1]); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid type: %s"), argv[1]); return; } @@ -517,9 +523,9 @@ void cmd_change_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char ( const char *error_str; if ( argc != 2 ) { - if ( argc < 1 ) error_str = "Type must be specified!"; - else if ( argc < 2 ) error_str = "Must have id!"; - else error_str = "Only two arguments allowed!"; + if ( argc < 1 ) error_str = gettext("Type must be specified!"); + else if ( argc < 2 ) error_str = gettext("Must have id!"); + else error_str = gettext("Only two arguments allowed!"); goto on_error; } @@ -533,7 +539,7 @@ void cmd_change_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char ( type = output; else { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid type: %s", argv[1]); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid type: %s"), argv[1]); return; } @@ -542,12 +548,12 @@ void cmd_change_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char ( long int selection = strtol(argv[2], &end, 10); if ( *end ) { - error_str = "Invalid input"; + error_str = gettext("Invalid input"); goto on_error; } if ( set_primary_device(type, selection) == de_InvalidSelection ) { - error_str="Invalid selection!"; + error_str=gettext("Invalid selection!"); goto on_error; } @@ -561,9 +567,9 @@ void cmd_ccur_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*a const char *error_str; if ( argc != 2 ) { - if ( argc < 1 ) error_str = "Type must be specified!"; - else if ( argc < 2 ) error_str = "Must have id!"; - else error_str = "Only two arguments allowed!"; + if ( argc < 1 ) error_str = gettext("Type must be specified!"); + else if ( argc < 2 ) error_str = gettext("Must have id!"); + else error_str = gettext("Only two arguments allowed!"); goto on_error; } @@ -577,7 +583,7 @@ void cmd_ccur_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*a type = output; else { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid type: %s", argv[1]); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid type: %s"), argv[1]); return; } @@ -586,12 +592,12 @@ void cmd_ccur_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*a long int selection = strtol(argv[2], &end, 10); if ( *end ) { - error_str = "Invalid input"; + error_str = gettext("Invalid input"); goto on_error; } if ( selection_valid(type, selection) == de_InvalidSelection ) { - error_str="Invalid selection!"; + error_str=gettext("Invalid selection!"); goto on_error; } @@ -634,8 +640,8 @@ void cmd_mute(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA const char *error_str; if ( argc != 1 ) { - if ( argc < 1 ) error_str = "Type must be specified!"; - else error_str = "Only two arguments allowed!"; + if ( argc < 1 ) error_str = gettext("Type must be specified!"); + else error_str = gettext("Only two arguments allowed!"); goto on_error; } @@ -649,7 +655,7 @@ void cmd_mute(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA type = output; else { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid type: %s", argv[1]); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid type: %s"), argv[1]); return; } @@ -680,8 +686,8 @@ void cmd_sense(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[M const char *error_str; if ( argc != 1 ) { - if ( argc < 1 ) error_str = "Must have value!"; - else error_str = "Only two arguments allowed!"; + if ( argc < 1 ) error_str = gettext("Must have value!"); + else error_str = gettext("Only two arguments allowed!"); goto on_error; } @@ -690,7 +696,7 @@ void cmd_sense(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[M float value = strtof(argv[1], &end); if ( *end ) { - error_str = "Invalid input"; + error_str = gettext("Invalid input"); goto on_error; } @@ -719,10 +725,10 @@ void stop_current_call(ToxWindow* self) toxav_hangup(ASettins.av, self->call_idx); break; case av_CallInviting: - toxav_cancel(ASettins.av, self->call_idx, 0, "Not interested anymore"); + toxav_cancel(ASettins.av, self->call_idx, 0, gettext("Not interested anymore")); break; case av_CallStarting: - toxav_reject(ASettins.av, self->call_idx, "Not interested"); + toxav_reject(ASettins.av, self->call_idx, gettext("Not interested")); break; default: break; diff --git a/src/autocomplete.c b/src/autocomplete.c index 8cf703c..c500a03 100644 --- a/src/autocomplete.c +++ b/src/autocomplete.c @@ -24,6 +24,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #ifdef __APPLE__ #include #include @@ -117,7 +123,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size) char *sub = malloc(strlen(ubuf) + 1); if (sub == NULL) - exit_toxic_err("failed in complete_line", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in complete_line"), FATALERR_MEMORY); if (!s && !dir_search) { strcpy(sub, tmp); diff --git a/src/avatars.c b/src/avatars.c index a17c3be..d9c621a 100644 --- a/src/avatars.c +++ b/src/avatars.c @@ -24,6 +24,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "misc_tools.h" #include "file_transfers.h" #include "friendlist.h" @@ -59,7 +65,7 @@ int avatar_send(Tox *m, uint32_t friendnum) return 0; if (err != TOX_ERR_FILE_SEND_OK) { - fprintf(stderr, "tox_file_send failed for friendnumber %d (error %d)\n", friendnum, err); + fprintf(stderr, gettext("tox_file_send failed for friendnumber %d (error %d)\n"), friendnum, err); return -1; } @@ -203,7 +209,7 @@ void on_avatar_chunk_request(Tox *m, struct FileTransfer *ft, uint64_t position, tox_file_send_chunk(m, ft->friendnum, ft->filenum, position, send_data, send_length, &err); if (err != TOX_ERR_FILE_SEND_CHUNK_OK) - fprintf(stderr, "tox_file_send_chunk failed in avatar callback (error %d)\n", err); + fprintf(stderr, gettext("tox_file_send_chunk failed in avatar callback (error %d)\n"), err); ft->position += send_length; } diff --git a/src/chat.c b/src/chat.c index 9eaed52..6dafd9e 100644 --- a/src/chat.c +++ b/src/chat.c @@ -31,6 +31,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "toxic.h" #include "windows.h" #include "execute.h" @@ -47,6 +53,9 @@ #include "notify.h" #include "message_queue.h" +#define YES_STR gettext("yes") +#define NO_STR gettext("no") + #ifdef AUDIO #include "audio_call.h" #endif /* AUDIO */ @@ -211,7 +220,7 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, uint32_t num, TOX_C ? tox_friend_get_typing(m, num, NULL) : false; chat_resume_file_transfers(m, num); - msg = "has come online"; + msg = gettext("has come online"); line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, GREEN, msg); write_to_log(msg, nick, ctx->log, true); } else if (connection_status == TOX_CONNECTION_NONE) { @@ -222,7 +231,7 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, uint32_t num, TOX_C chat_stop_file_senders(m, num); - msg = "has gone offline"; + msg = gettext("has gone offline"); line_info_add(self, timefrmt, nick, NULL, DISCONNECTION, 0, RED, msg); write_to_log(msg, nick, ctx->log, true); } @@ -307,21 +316,21 @@ static void chat_onFileChunkRequest(ToxWindow *self, Tox *m, uint32_t friendnum, char msg[MAX_STR_SIZE]; if (length == 0) { - snprintf(msg, sizeof(msg), "File '%s' successfully sent.", ft->file_name); + snprintf(msg, sizeof(msg), gettext("File '%s' successfully sent."), ft->file_name); print_progress_bar(self, ft->bps, 100.0, ft->line_id); close_file_transfer(self, m, ft, -1, msg, transfer_completed); return; } if (ft->file == NULL) { - snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Null file pointer.", ft->file_name); + snprintf(msg, sizeof(msg), gettext("File transfer for '%s' failed: Null file pointer."), ft->file_name); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); return; } if (ft->position != position) { if (fseek(ft->file, position, SEEK_SET) == -1) { - snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Seek fail.", ft->file_name); + snprintf(msg, sizeof(msg), gettext("File transfer for '%s' failed: Seek fail."), ft->file_name); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); return; } @@ -333,7 +342,7 @@ static void chat_onFileChunkRequest(ToxWindow *self, Tox *m, uint32_t friendnum, size_t send_length = fread(send_data, 1, sizeof(send_data), ft->file); if (send_length != length) { - snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Read fail.", ft->file_name); + snprintf(msg, sizeof(msg), gettext("File transfer for '%s' failed: Read fail."), ft->file_name); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); return; } @@ -342,7 +351,7 @@ static void chat_onFileChunkRequest(ToxWindow *self, Tox *m, uint32_t friendnum, tox_file_send_chunk(m, ft->friendnum, ft->filenum, position, send_data, send_length, &err); if (err != TOX_ERR_FILE_SEND_CHUNK_OK) - fprintf(stderr, "tox_file_send_chunk failed in chat callback (error %d)\n", err); + fprintf(stderr, gettext("tox_file_send_chunk failed in chat callback (error %d)\n"), err); ft->position += send_length; ft->bps += send_length; @@ -365,20 +374,20 @@ static void chat_onFileRecvChunk(ToxWindow *self, Tox *m, uint32_t friendnum, ui char msg[MAX_STR_SIZE]; if (length == 0) { - snprintf(msg, sizeof(msg), "File '%s' successfully received.", ft->file_name); + snprintf(msg, sizeof(msg), gettext("File '%s' successfully received."), ft->file_name); print_progress_bar(self, ft->bps, 100.0, ft->line_id); close_file_transfer(self, m, ft, -1, msg, transfer_completed); return; } if (ft->file == NULL) { - snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Invalid file pointer.", ft->file_name); + snprintf(msg, sizeof(msg), gettext("File transfer for '%s' failed: Invalid file pointer."), ft->file_name); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); return; } if (fwrite(data, length, 1, ft->file) != 1) { - snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Write fail.", ft->file_name); + snprintf(msg, sizeof(msg), gettext("File transfer for '%s' failed: Write fail."), ft->file_name); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); return; } @@ -404,7 +413,7 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, uint32_t friendnum, uint /* transfer is accepted */ if (ft->state == FILE_TRANSFER_PENDING) { ft->state = FILE_TRANSFER_STARTED; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer [%d] for '%s' accepted.", + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer [%d] for '%s' accepted."), ft->index, ft->file_name); char progline[MAX_STR_SIZE]; prep_prog_line(progline); @@ -422,7 +431,7 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, uint32_t friendnum, uint break; case TOX_FILE_CONTROL_CANCEL: - snprintf(msg, sizeof(msg), "File transfer for '%s' was aborted.", ft->file_name); + snprintf(msg, sizeof(msg), gettext("File transfer for '%s' was aborted."), ft->file_name); close_file_transfer(self, m, ft, -1, msg, notif_error); break; } @@ -438,13 +447,13 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_ if (!ft) { tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Too many concurrent file transfers."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed: Too many concurrent file transfers.")); return; } char sizestr[32]; bytes_convert_str(sizestr, sizeof(sizestr), file_size); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer request for '%s' (%s)", filename, sizestr); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer request for '%s' (%s)"), filename, sizestr); char file_path[MAX_STR_SIZE]; size_t path_len = name_length; @@ -459,7 +468,7 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_ if (path_len >= sizeof(ft->file_path) || name_length >= sizeof(ft->file_name)) { tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer faield: File path too long."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer faield: File path too long.")); return; } @@ -485,12 +494,12 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_ if (count > 999) { tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: invalid file path."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed: invalid file path.")); return; } } - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type '/savefile %d' to accept the file transfer.", ft->index); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Type '%s %d' to accept the file transfer."), "/savefile", ft->index); ft->state = FILE_TRANSFER_PENDING; ft->direction = FILE_TRANSFER_RECV; @@ -503,10 +512,10 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_ if (self->active_box != -1) box_notify2(self, transfer_pending, NT_WNDALERT_0 | NT_NOFOCUS, self->active_box, - "Incoming file: %s", filename ); + gettext("Incoming file: %s"), filename ); else box_notify(self, transfer_pending, NT_WNDALERT_0 | NT_NOFOCUS, &self->active_box, self->name, - "Incoming file: %s", filename ); + gettext("Incoming file: %s"), filename ); } static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, uint8_t type, const char *group_pub_key, @@ -521,7 +530,7 @@ static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, ui char *k = malloc(length); if (k == NULL) - exit_toxic_err("Failed in chat_onGroupInvite", FATALERR_MEMORY); + exit_toxic_err(gettext("Failed in chat_onGroupInvite"), FATALERR_MEMORY); memcpy(k, group_pub_key, length); Friends.list[friendnumber].group_invite.key = k; @@ -535,12 +544,12 @@ static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, ui get_nick_truncate(m, name, friendnumber); if (self->active_box != -1) - box_silent_notify2(self, NT_WNDALERT_2 | NT_NOFOCUS, self->active_box, "invites you to join group chat"); + box_silent_notify2(self, NT_WNDALERT_2 | NT_NOFOCUS, self->active_box, gettext("invites you to join group chat")); else - box_silent_notify(self, NT_WNDALERT_2 | NT_NOFOCUS, &self->active_box, name, "invites you to join group chat"); + box_silent_notify(self, NT_WNDALERT_2 | NT_NOFOCUS, &self->active_box, name, gettext("invites you to join group chat")); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to a group chat.", name); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type \"/join\" to join the chat."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("%s has invited you to a group chat."), name); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Type \"%s\" to join the chat."), "/join"); } /* Av Stuff */ @@ -554,16 +563,16 @@ void chat_onInvite (ToxWindow *self, ToxAv *av, int call_index) /* call_index is set here and reset on call end */ self->call_idx = call_index; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Incoming audio call! Type: \"/answer\" or \"/reject\""); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Incoming audio call! Type: \"%s\" or \"%s\""), "/answer", "/reject"); if (self->ringing_sound == -1) sound_notify(self, call_incoming, NT_LOOP, &self->ringing_sound); if (self->active_box != -1) - box_silent_notify2(self, NT_NOFOCUS | NT_WNDALERT_0, self->active_box, "Incoming audio call!"); + box_silent_notify2(self, NT_NOFOCUS | NT_WNDALERT_0, self->active_box, gettext("Incoming audio call!")); else - box_silent_notify(self, NT_NOFOCUS | NT_WNDALERT_0, &self->active_box, self->name, "Incoming audio call!"); + box_silent_notify(self, NT_NOFOCUS | NT_WNDALERT_0, &self->active_box, self->name, gettext("Incoming audio call!")); } void chat_onRinging (ToxWindow *self, ToxAv *av, int call_index) @@ -571,7 +580,7 @@ void chat_onRinging (ToxWindow *self, ToxAv *av, int call_index) if ( !self || self->call_idx != call_index || self->num != toxav_get_peer_id(av, call_index, 0)) return; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Ringing...type \"/hangup\" to cancel it."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Ringing...type \"%s\" to cancel it."), "/hangup"); #ifdef SOUND_NOTIFY if (self->ringing_sound == -1) @@ -586,7 +595,7 @@ void chat_onStarting (ToxWindow *self, ToxAv *av, int call_index) init_infobox(self); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call started! Type: \"/hangup\" to end it."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Call started! Type: \"%s\" to end it."), "/hangup"); #ifdef SOUND_NOTIFY stop_sound(self->ringing_sound); @@ -600,7 +609,7 @@ void chat_onEnding (ToxWindow *self, ToxAv *av, int call_index) kill_infobox(self); self->call_idx = -1; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call ended!"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Call ended!")); #ifdef SOUND_NOTIFY stop_sound(self->ringing_sound); @@ -613,7 +622,7 @@ void chat_onError (ToxWindow *self, ToxAv *av, int call_index) return; self->call_idx = -1; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Error!"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Error!")); #ifdef SOUND_NOTIFY stop_sound(self->ringing_sound); @@ -627,7 +636,7 @@ void chat_onStart (ToxWindow *self, ToxAv *av, int call_index) init_infobox(self); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call started! Type: \"/hangup\" to end it."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Call started! Type: \"%s\" to end it."), "/hangup"); #ifdef SOUND_NOTIFY stop_sound(self->ringing_sound); @@ -641,7 +650,7 @@ void chat_onCancel (ToxWindow *self, ToxAv *av, int call_index) kill_infobox(self); self->call_idx = -1; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call canceled!"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Call canceled!")); #ifdef SOUND_NOTIFY stop_sound(self->ringing_sound); @@ -654,7 +663,7 @@ void chat_onReject (ToxWindow *self, ToxAv *av, int call_index) return; self->call_idx = -1; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Rejected!"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Rejected!")); #ifdef SOUND_NOTIFY stop_sound(self->ringing_sound); @@ -668,7 +677,7 @@ void chat_onEnd (ToxWindow *self, ToxAv *av, int call_index) kill_infobox(self); self->call_idx = -1; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call ended!"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Call ended!")); #ifdef SOUND_NOTIFY stop_sound(self->ringing_sound); @@ -681,7 +690,7 @@ void chat_onRequestTimeout (ToxWindow *self, ToxAv *av, int call_index) return; self->call_idx = -1; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No answer!"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No answer!")); #ifdef SOUND_NOTIFY stop_sound(self->ringing_sound); @@ -695,7 +704,7 @@ void chat_onPeerTimeout (ToxWindow *self, ToxAv *av, int call_index) kill_infobox(self); self->call_idx = -1; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer disconnected; call ended!"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Peer disconnected; call ended!")); #ifdef SOUND_NOTIFY stop_sound(self->ringing_sound); @@ -752,31 +761,31 @@ static void draw_infobox(ToxWindow *self) infobox->lastupdate = curtime; - const char *in_is_muted = infobox->in_is_muted ? "yes" : "no"; - const char *out_is_muted = infobox->out_is_muted ? "yes" : "no"; + const char *in_is_muted = infobox->in_is_muted ? YES_STR : NO_STR; + const char *out_is_muted = infobox->out_is_muted ? YES_STR : NO_STR; wmove(infobox->win, 1, 1); wattron(infobox->win, COLOR_PAIR(RED) | A_BOLD); - wprintw(infobox->win, " Call Active\n"); + wprintw(infobox->win, gettext(" Call Active\n")); wattroff(infobox->win, COLOR_PAIR(RED) | A_BOLD); wattron(infobox->win, A_BOLD); - wprintw(infobox->win, " Duration: "); + wprintw(infobox->win, gettext(" Duration: ")); wattroff(infobox->win, A_BOLD); wprintw(infobox->win, "%s\n", infobox->timestr); wattron(infobox->win, A_BOLD); - wprintw(infobox->win, " In muted: "); + wprintw(infobox->win, gettext(" In muted: ")); wattroff(infobox->win, A_BOLD); wprintw(infobox->win, "%s\n", in_is_muted); wattron(infobox->win, A_BOLD); - wprintw(infobox->win, " Out muted: "); + wprintw(infobox->win, gettext(" Out muted: ")); wattroff(infobox->win, A_BOLD); wprintw(infobox->win, "%s\n", out_is_muted); wattron(infobox->win, A_BOLD); - wprintw(infobox->win, " VAD level: "); + wprintw(infobox->win, gettext(" VAD level: ")); wattroff(infobox->win, A_BOLD); wprintw(infobox->win, "%.2f\n", infobox->vad_lvl); @@ -1068,7 +1077,7 @@ static void chat_onInit(ToxWindow *self, Tox *m) ctx->cqueue = calloc(1, sizeof(struct chat_queue)); if (ctx->log == NULL || ctx->hst == NULL || ctx->cqueue == NULL) - exit_toxic_err("failed in chat_onInit", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in chat_onInit"), FATALERR_MEMORY); line_info_init(ctx->hst); @@ -1140,7 +1149,7 @@ ToxWindow new_chat(Tox *m, uint32_t friendnum) Help *help = calloc(1, sizeof(Help)); if (stb == NULL || chatwin == NULL || help == NULL) - exit_toxic_err("failed in new_chat", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in new_chat"), FATALERR_MEMORY); ret.chatwin = chatwin; ret.stb = stb; diff --git a/src/chat_commands.c b/src/chat_commands.c index 3352f47..63218e5 100644 --- a/src/chat_commands.c +++ b/src/chat_commands.c @@ -23,6 +23,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "toxic.h" #include "windows.h" #include "misc_tools.h" @@ -39,7 +45,7 @@ extern FriendsList Friends; void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc < 2) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Requires type in|out and the file ID."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Requires type %s and the file ID."), "in|out"); return; } @@ -48,7 +54,7 @@ void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar int idx = atoi(argv[2]); if (idx >= MAX_FILES || idx < 0) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid file ID.")); return; } @@ -60,50 +66,50 @@ void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar } else if (strcasecmp(inoutstr, "out") == 0) { ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_SEND); } else { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type must be 'in' or 'out'."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Type must be '%s' or '%s'."), "in", "out"); return; } if (!ft) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid file ID.")); return; } if (ft->state == FILE_TRANSFER_INACTIVE) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid file ID.")); return; } - snprintf(msg, sizeof(msg), "File transfer for '%s' aborted.", ft->file_name); + snprintf(msg, sizeof(msg), gettext("File transfer for '%s' aborted."), ft->file_name); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, silent); } void cmd_groupinvite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc < 1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group number required."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Group number required.")); return; } int groupnum = atoi(argv[1]); if (groupnum == 0 && strcmp(argv[1], "0")) { /* atoi returns 0 value on invalid input */ - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid group number."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid group number.")); return; } if (tox_invite_friend(m, self->num, groupnum) == -1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to invite contact to group."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to invite contact to group.")); return; } - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invited contact to Group %d.", groupnum); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invited contact to Group %d."), groupnum); } void cmd_join_group(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (get_num_active_windows() >= MAX_WINDOWS_NUM) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext(" * Warning: Too many windows are open.")); return; } @@ -112,7 +118,7 @@ void cmd_join_group(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar uint8_t type = Friends.list[self->num].group_invite.type; if (!Friends.list[self->num].group_invite.pending) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending group chat invite."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending group chat invite.")); return; } @@ -127,12 +133,12 @@ void cmd_join_group(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar #endif if (groupnum == -1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat instance failed to initialize."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Group chat instance failed to initialize.")); return; } if (init_groupchat_win(prompt, m, groupnum, type) == -1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Group chat window failed to initialize.")); tox_del_groupchat(m, groupnum); return; } @@ -142,31 +148,31 @@ void cmd_join_group(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc < 1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File ID required."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File ID required.")); return; } int idx = atoi(argv[1]); if ((idx == 0 && strcmp(argv[1], "0")) || idx >= MAX_FILES) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending file transfers with that ID.")); return; } struct FileTransfer *ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_RECV); if (!ft) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending file transfers with that ID.")); return; } if (ft->state != FILE_TRANSFER_PENDING) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending file transfers with that ID.")); return; } if ((ft->file = fopen(ft->file_path, "a")) == NULL) { - const char *msg = "File transfer failed: Invalid file path."; + const char *msg = gettext("File transfer failed: Invalid file path."); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); return; } @@ -177,7 +183,7 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv if (err != TOX_ERR_FILE_CONTROL_OK) goto on_recv_error; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Saving file [%d] as: '%s'", idx, ft->file_path); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Saving file [%d] as: '%s'"), idx, ft->file_path); /* prep progress bar line */ char progline[MAX_STR_SIZE]; @@ -192,23 +198,23 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv on_recv_error: switch (err) { case TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND: - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Friend not found."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed: Friend not found.")); return; case TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED: - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Friend is not online."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed: Friend is not online.")); return; case TOX_ERR_FILE_CONTROL_NOT_FOUND: - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Invalid filenumber."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed: Invalid filenumber.")); return; case TOX_ERR_FILE_CONTROL_SENDQ: - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Connection error."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed: Connection error.")); return; default: - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed (error %d)\n", err); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed (error %d)\n"), err); return; } } @@ -218,12 +224,12 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv const char *errmsg = NULL; if (argc < 1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File path required."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File path required.")); return; } if (argv[1][0] != '\"') { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File path must be enclosed in quotes."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File path must be enclosed in quotes.")); return; } @@ -234,21 +240,21 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv path[path_len] = '\0'; if (path_len >= MAX_STR_SIZE) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File path exceeds character limit."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File path exceeds character limit.")); return; } FILE *file_to_send = fopen(path, "r"); if (file_to_send == NULL) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File not found."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File not found.")); return; } off_t filesize = file_size(path); if (filesize == 0) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid file.")); fclose(file_to_send); return; } @@ -281,30 +287,30 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv char sizestr[32]; bytes_convert_str(sizestr, sizeof(sizestr), filesize); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Sending file [%d]: '%s' (%s)", filenum, file_name, sizestr); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Sending file [%d]: '%s' (%s)"), filenum, file_name, sizestr); return; on_send_error: switch (err) { case TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND: - errmsg = "File transfer failed: Invalid friend."; + errmsg = gettext("File transfer failed: Invalid friend."); break; case TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED: - errmsg = "File transfer failed: Friend is offline."; + errmsg = gettext("File transfer failed: Friend is offline."); break; case TOX_ERR_FILE_SEND_NAME_TOO_LONG: - errmsg = "File transfer failed: Filename is too long."; + errmsg = gettext("File transfer failed: Filename is too long."); break; case TOX_ERR_FILE_SEND_TOO_MANY: - errmsg = "File transfer failed: Too many concurrent file transfers."; + errmsg = gettext("File transfer failed: Too many concurrent file transfers."); break; default: - errmsg = "File transfer failed."; + errmsg = gettext("File transfer failed."); break; } diff --git a/src/configdir.c b/src/configdir.c index 8a9f60c..a6fda82 100644 --- a/src/configdir.c +++ b/src/configdir.c @@ -29,6 +29,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "toxic.h" #include "configdir.h" @@ -116,7 +122,7 @@ int create_user_config_dirs(char *path) char *logpath = malloc(strlen(path) + strlen(LOGDIR) + 1); if (fullpath == NULL || logpath == NULL) - exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in load_data_structures"), FATALERR_MEMORY); strcpy(fullpath, path); strcat(fullpath, CONFIGDIR); diff --git a/src/dns.c b/src/dns.c index ade723c..8a7a6f3 100644 --- a/src/dns.c +++ b/src/dns.c @@ -26,6 +26,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #ifdef __APPLE__ #include #else @@ -146,7 +152,7 @@ static int load_dns_domainlist(const char *path) static int dns_error(ToxWindow *self, const char *errmsg) { pthread_mutex_lock(&Winthread.lock); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "User lookup failed: %s", errmsg); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("User lookup failed: %s"), errmsg); pthread_mutex_unlock(&Winthread.lock); return -1; @@ -172,18 +178,18 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char int len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans)); if (len == -1) - return dns_error(self, "dn_expand failed."); + return dns_error(self, gettext("dn_expand failed.")); ans_pt += len; if (ans_pt > ans_end - 4) - return dns_error(self, "DNS reply was too short."); + return dns_error(self, gettext("DNS reply was too short.")); int type; GETSHORT(type, ans_pt); if (type != T_TXT) - return dns_error(self, "Broken DNS reply."); + return dns_error(self, gettext("Broken DNS reply.")); ans_pt += INT16SZ; /* class */ @@ -195,12 +201,12 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans)); if (len == -1) - return dns_error(self, "Second dn_expand failed."); + return dns_error(self, gettext("Second dn_expand failed.")); ans_pt += len; if (ans_pt > ans_end - 10) - return dns_error(self, "DNS reply was too short."); + return dns_error(self, gettext("DNS reply was too short.")); GETSHORT(type, ans_pt); ans_pt += INT16SZ; @@ -208,20 +214,20 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char GETSHORT(size, ans_pt); if (ans_pt + size < answer || ans_pt + size > ans_end) - return dns_error(self, "RR overflow."); + return dns_error(self, gettext("RR overflow.")); } while (type == T_CNAME); if (type != T_TXT) - return dns_error(self, "DNS response failed."); + return dns_error(self, gettext("DNS response failed.")); uint32_t txt_len = *ans_pt; if (!size || txt_len >= size || !txt_len) - return dns_error(self, "No record found."); + return dns_error(self, gettext("No record found.")); if (txt_len > MAX_DNS_REQST_SIZE) - return dns_error(self, "Invalid DNS response."); + return dns_error(self, gettext("Invalid DNS response.")); ans_pt++; ans_pt[txt_len] = '\0'; @@ -298,7 +304,7 @@ void *dns3_lookup_thread(void *data) int namelen = parse_addr(t_data.addr, name, inputdomain); if (namelen == -1) { - dns_error(self, "Must be a Tox ID or an address in the form username@domain"); + dns_error(self, gettext("Must be a Tox ID or an address in the form username@domain")); killdns_thread(NULL); } @@ -308,14 +314,14 @@ void *dns3_lookup_thread(void *data) int match = get_domain_match(DNS_pubkey, domain, inputdomain); if (match == -1) { - dns_error(self, "Domain not found."); + dns_error(self, gettext("Domain not found.")); killdns_thread(NULL); } void *dns_obj = tox_dns3_new((uint8_t *) DNS_pubkey); if (dns_obj == NULL) { - dns_error(self, "Core failed to create DNS object."); + dns_error(self, gettext("Core failed to create DNS object.")); killdns_thread(NULL); } @@ -326,7 +332,7 @@ void *dns3_lookup_thread(void *data) (uint8_t *) name, namelen); if (str_len == -1) { - dns_error(self, "Core failed to generate DNS3 string."); + dns_error(self, gettext("Core failed to generate DNS3 string.")); killdns_thread(dns_obj); } @@ -340,7 +346,7 @@ void *dns3_lookup_thread(void *data) int ans_len = res_query(d_string, C_IN, T_TXT, answer, sizeof(answer)); if (ans_len <= 0) { - dns_error(self, "DNS query failed."); + dns_error(self, gettext("DNS query failed.")); killdns_thread(dns_obj); } @@ -355,7 +361,7 @@ void *dns3_lookup_thread(void *data) /* extract the encrypted ID from TXT response */ if (strncmp(ans_id, TOX_DNS3_TXT_PREFIX, prfx_len) != 0) { - dns_error(self, "Bad DNS3 TXT response."); + dns_error(self, gettext("Bad DNS3 TXT response.")); killdns_thread(dns_obj); } @@ -363,7 +369,7 @@ void *dns3_lookup_thread(void *data) if (tox_decrypt_dns3_TXT(dns_obj, (uint8_t *) t_data.id_bin, (uint8_t *) encrypted_id, strlen(encrypted_id), request_id) == -1) { - dns_error(self, "Core failed to decrypt DNS response."); + dns_error(self, gettext("Core failed to decrypt DNS response.")); killdns_thread(dns_obj); } @@ -379,12 +385,12 @@ void *dns3_lookup_thread(void *data) void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *msg) { if (arg_opts.proxy_type != TOX_PROXY_TYPE_NONE && arg_opts.force_tcp) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "DNS lookups are disabled."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("DNS lookups are disabled.")); return; } if (t_data.busy) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Please wait for previous user lookup to finish."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Please wait for previous user lookup to finish.")); return; } @@ -394,7 +400,7 @@ void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, int ret = load_dns_domainlist(path); if (ret < 0) { - const char *errmsg = "DNS server list failed to load with error code %d. Falling back to hard-coded list."; + const char *errmsg = gettext("DNS server list failed to load with error code %d. Falling back to hard-coded list."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg, ret); } } @@ -407,20 +413,20 @@ void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, t_data.busy = 1; if (pthread_attr_init(&dns_thread.attr) != 0) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: DNS thread attr failed to init"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext("Error: DNS thread attr failed to init")); memset(&t_data, 0, sizeof(struct thread_data)); return; } if (pthread_attr_setdetachstate(&dns_thread.attr, PTHREAD_CREATE_DETACHED) != 0) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: DNS thread attr failed to set"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext("Error: DNS thread attr failed to set")); pthread_attr_destroy(&dns_thread.attr); memset(&t_data, 0, sizeof(struct thread_data)); return; } if (pthread_create(&dns_thread.tid, &dns_thread.attr, dns3_lookup_thread, NULL) != 0) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: DNS thread failed to init"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext("Error: DNS thread failed to init")); pthread_attr_destroy(&dns_thread.attr); memset(&t_data, 0, sizeof(struct thread_data)); return; diff --git a/src/execute.c b/src/execute.c index 9e83a83..81dfb70 100644 --- a/src/execute.c +++ b/src/execute.c @@ -24,6 +24,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "toxic.h" #include "windows.h" #include "execute.h" @@ -98,7 +104,7 @@ static int parse_command(WINDOW *w, ToxWindow *self, const char *input, char (*a char *cmd = strdup(input); if (cmd == NULL) - exit_toxic_err("failed in parse_command", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in parse_command"), FATALERR_MEMORY); int num_args = 0; int i = 0; /* index of last char in an argument */ @@ -112,7 +118,7 @@ static int parse_command(WINDOW *w, ToxWindow *self, const char *input, char (*a i = char_find(1, cmd, '\"'); if (cmd[i] == '\0') { - const char *errmsg = "Invalid argument. Did you forget a closing \"?"; + const char *errmsg = gettext("Invalid argument. Did you forget a closing \"?"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); free(cmd); return -1; @@ -183,5 +189,5 @@ void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode) if (do_command(w, self, m, num_args, global_commands, args) == 0) return; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid command."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid command.")); } diff --git a/src/friendlist.c b/src/friendlist.c index c8df965..45af2b2 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -26,6 +26,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include #include "toxic.h" @@ -84,7 +90,7 @@ static void realloc_friends(int n) uint32_t *f_idx = realloc(Friends.index, n * sizeof(uint32_t)); if (f == NULL || f_idx == NULL) - exit_toxic_err("failed in realloc_friends", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in realloc_friends"), FATALERR_MEMORY); Friends.list = f; Friends.index = f_idx; @@ -104,7 +110,7 @@ static void realloc_blocklist(int n) uint32_t *b_idx = realloc(Blocked.index, n * sizeof(uint32_t)); if (b == NULL || b_idx == NULL) - exit_toxic_err("failed in realloc_blocklist", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in realloc_blocklist"), FATALERR_MEMORY); Blocked.list = b; Blocked.index = b_idx; @@ -132,7 +138,7 @@ static int save_blocklist(char *path) char *data = malloc(len); if (data == NULL) - exit_toxic_err("Failed in save_blocklist", FATALERR_MEMORY); + exit_toxic_err(gettext("Failed in save_blocklist"), FATALERR_MEMORY); int i; @@ -199,7 +205,7 @@ int load_blocklist(char *path) if (data == NULL) { fclose(fp); - exit_toxic_err("Failed in load_blocklist", FATALERR_MEMORY); + exit_toxic_err(gettext("Failed in load_blocklist"), FATALERR_MEMORY); } if (fread(data, len, 1, fp) != 1) { @@ -322,7 +328,7 @@ static void friendlist_onMessage(ToxWindow *self, Tox *m, uint32_t num, TOX_MESS get_time_str(timefrmt, sizeof(timefrmt)); line_info_add(prompt, timefrmt, nick, NULL, IN_MSG, 0, 0, "%s", str); - line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Warning: Too many windows are open."); + line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext("* Warning: Too many windows are open.")); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); } @@ -337,7 +343,7 @@ static void friendlist_onConnectionChange(ToxWindow *self, Tox *m, uint32_t num, ++Friends.num_online; if (avatar_send(m, num) == -1) - fprintf(stderr, "avatar_send failed for friend %d\n", num); + fprintf(stderr, gettext("avatar_send failed for friend %d\n"), num); } Friends.list[num].connection_status = connection_status; @@ -412,7 +418,7 @@ void friendlist_onFriendAdded(ToxWindow *self, Tox *m, uint32_t num, bool sort) tox_friend_get_public_key(m, num, (uint8_t *) Friends.list[i].pub_key, &pkerr); if (pkerr != TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK) - fprintf(stderr, "tox_friend_get_public_key failed (error %d)\n", pkerr); + fprintf(stderr, gettext("tox_friend_get_public_key failed (error %d)\n"), pkerr); TOX_ERR_FRIEND_GET_LAST_ONLINE loerr; uint64_t t = tox_friend_get_last_online(m, num, &loerr); @@ -491,7 +497,7 @@ static void friendlist_onFileRecv(ToxWindow *self, Tox *m, uint32_t num, uint32_ get_nick_truncate(m, nick, num); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, - "* File transfer from %s failed: too many windows are open.", nick); + gettext("* File transfer from %s failed: too many windows are open."), nick); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); } @@ -514,7 +520,7 @@ static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, uint8 get_nick_truncate(m, nick, num); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, - "* Group chat invite from %s failed: too many windows are open.", nick); + gettext("* Group chat invite from %s failed: too many windows are open."), nick); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); } @@ -537,7 +543,7 @@ static void delete_friend(Tox *m, uint32_t f_num) { TOX_ERR_FRIEND_DELETE err; if (tox_friend_delete(m, f_num, &err) != true) { - fprintf(stderr, "tox_friend_delete failed with error %d\n", err); + fprintf(stderr, gettext("tox_friend_delete failed with error %d\n"), err); return; } @@ -617,7 +623,7 @@ static void draw_del_popup(void) wattroff(PendingDelete.popup, A_BOLD); wmove(PendingDelete.popup, 1, 1); - wprintw(PendingDelete.popup, "Delete contact "); + wprintw(PendingDelete.popup, gettext("Delete contact ")); wattron(PendingDelete.popup, A_BOLD); if (blocklist_view == 0) @@ -698,7 +704,7 @@ static void unblock_friend(Tox *m, uint32_t bnum) uint32_t friendnum = tox_friend_add_norequest(m, (uint8_t *) Blocked.list[bnum].pub_key, &err); if (err != TOX_ERR_FRIEND_ADD_OK) { - line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to unblock friend (error %d)\n", err); + line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to unblock friend (error %d)\n"), err); return; } @@ -757,7 +763,7 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) Friends.list[f].chatwin = add_window(m, new_chat(m, Friends.list[f].num)); set_active_window(Friends.list[f].chatwin); } else { - const char *msg = "* Warning: Too many windows are open."; + const char *msg = gettext("* Warning: Too many windows are open."); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, msg); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); } @@ -794,7 +800,7 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) static void blocklist_onDraw(ToxWindow *self, Tox *m, int y2, int x2) { wattron(self->window, A_BOLD); - wprintw(self->window, " Blocked: "); + wprintw(self->window, gettext(" Blocked: ")); wattroff(self->window, A_BOLD); wprintw(self->window, "%d\n\n", Blocked.num_blocked); @@ -846,7 +852,7 @@ static void blocklist_onDraw(ToxWindow *self, Tox *m, int y2, int x2) wmove(self->window, y2 - 1, 1); wattron(self->window, A_BOLD); - wprintw(self->window, "Key: "); + wprintw(self->window, gettext("Key: ")); wattroff(self->window, A_BOLD); int i; @@ -872,11 +878,11 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m) bool fix_statuses = x2 != self->x; /* true if window max x value has changed */ wattron(self->window, COLOR_PAIR(CYAN)); - wprintw(self->window, " Press the"); + wprintw(self->window, gettext(" Press the")); wattron(self->window, A_BOLD); wprintw(self->window, " h "); wattroff(self->window, A_BOLD); - wprintw(self->window, "key for help\n\n"); + wprintw(self->window, gettext("key for help\n\n")); wattroff(self->window, COLOR_PAIR(CYAN)); if (blocklist_view == 1) { @@ -888,7 +894,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m) struct tm cur_loc_tm = *localtime((const time_t *) &cur_time); wattron(self->window, A_BOLD); - wprintw(self->window, " Online: "); + wprintw(self->window, gettext(" Online: ")); wattroff(self->window, A_BOLD); wprintw(self->window, "%d/%d \n\n", Friends.num_online, Friends.num_friends); @@ -1002,19 +1008,19 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m) switch (day_dist) { case 0: - wprintw(self->window, " Last seen: Today %s\n", hourmin); + wprintw(self->window, gettext(" Last seen: Today %s\n"), hourmin); break; case 1: - wprintw(self->window, " Last seen: Yesterday %s\n", hourmin); + wprintw(self->window, gettext(" Last seen: Yesterday %s\n"), hourmin); break; default: - wprintw(self->window, " Last seen: %d days ago\n", day_dist); + wprintw(self->window, gettext(" Last seen: %d days ago\n"), day_dist); break; } } else { - wprintw(self->window, " Last seen: Never\n"); + wprintw(self->window, gettext(" Last seen: Never\n")); } } } @@ -1026,7 +1032,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m) wmove(self->window, y2 - 1, 1); wattron(self->window, A_BOLD); - wprintw(self->window, "Key: "); + wprintw(self->window, gettext("Key: ")); wattroff(self->window, A_BOLD); int i; @@ -1065,9 +1071,9 @@ static void friendlist_onAv(ToxWindow *self, ToxAv *av, int call_index) } else { char nick[TOX_MAX_NAME_LENGTH]; get_nick_truncate(m, nick, Friends.list[id].num); - line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Audio action from: %s!", nick); + line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Audio action from: %s!"), nick); - const char *errmsg = "* Warning: Too many windows are open."; + const char *errmsg = gettext("* Warning: Too many windows are open."); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); @@ -1117,9 +1123,9 @@ ToxWindow new_friendlist(void) Help *help = calloc(1, sizeof(Help)); if (help == NULL) - exit_toxic_err("failed in new_friendlist", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in new_friendlist"), FATALERR_MEMORY); ret.help = help; - strcpy(ret.name, "contacts"); + strcpy(ret.name, gettext("contacts")); return ret; } diff --git a/src/global_commands.c b/src/global_commands.c index fc7e3b8..50e0eb2 100644 --- a/src/global_commands.c +++ b/src/global_commands.c @@ -24,6 +24,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "toxic.h" #include "windows.h" #include "misc_tools.h" @@ -46,19 +52,19 @@ extern FriendRequests FrndRequests; void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc < 1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Request ID required."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Request ID required.")); return; } int req = atoi(argv[1]); if ((req == 0 && strcmp(argv[1], "0")) || req < 0 || req > MAX_FRIEND_REQUESTS) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend request with that ID."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending friend request with that ID.")); return; } if (!FrndRequests.request[req].active) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend request with that ID."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending friend request with that ID.")); return; } @@ -66,10 +72,10 @@ void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ uint32_t friendnum = tox_friend_add_norequest(m, FrndRequests.request[req].key, &err); if (err != TOX_ERR_FRIEND_ADD_OK) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to add friend (error %d\n)", err); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to add friend (error %d)\n"), err); return; } else { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Friend request accepted."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Friend request accepted.")); on_friendadded(m, friendnum, true); } @@ -96,42 +102,42 @@ void cmd_add_helper(ToxWindow *self, Tox *m, const char *id_bin, const char *msg switch (err) { case TOX_ERR_FRIEND_ADD_TOO_LONG: - errmsg = "Message is too long."; + errmsg = gettext("Message is too long."); break; case TOX_ERR_FRIEND_ADD_NO_MESSAGE: - errmsg = "Please add a message to your request."; + errmsg = gettext("Please add a message to your request."); break; case TOX_ERR_FRIEND_ADD_OWN_KEY: - errmsg = "That appears to be your own ID."; + errmsg = gettext("That appears to be your own ID."); break; case TOX_ERR_FRIEND_ADD_ALREADY_SENT: - errmsg = "Friend request has already been sent."; + errmsg = gettext("Friend request has already been sent."); break; case TOX_ERR_FRIEND_ADD_BAD_CHECKSUM: - errmsg = "Bad checksum in address."; + errmsg = gettext("Bad checksum in address."); break; case TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM: - errmsg = "Nospam was different."; + errmsg = gettext("Nospam was different."); break; case TOX_ERR_FRIEND_ADD_MALLOC: - errmsg = "Core memory allocation failed."; + errmsg = gettext("Core memory allocation failed."); break; case TOX_ERR_FRIEND_ADD_OK: - errmsg = "Friend request sent."; + errmsg = gettext("Friend request sent."); on_friendadded(m, f_num, true); break; case TOX_ERR_FRIEND_ADD_NULL: /* fallthrough */ default: - errmsg = "Faile to add friend: Unknown error."; + errmsg = gettext("Failed to add friend: Unknown error."); break; } @@ -141,7 +147,7 @@ void cmd_add_helper(ToxWindow *self, Tox *m, const char *id_bin, const char *msg void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc < 1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Tox ID or address required."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Tox ID or address required.")); return; } @@ -150,7 +156,7 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX if (argc > 1) { if (argv[2][0] != '\"') { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Message must be enclosed in quotes."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Message must be enclosed in quotes.")); return; } @@ -166,7 +172,7 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX size_t n_len = tox_self_get_name_size(m); selfname[n_len] = '\0'; - snprintf(msg, sizeof(msg), "Hello, my name is %s. Care to Tox?", selfname); + snprintf(msg, sizeof(msg), gettext("Hello, my name is %s. Care to Tox?"), selfname); } char id_bin[TOX_ADDRESS_SIZE] = {0}; @@ -184,7 +190,7 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX xx[2] = '\0'; if (sscanf(xx, "%02x", &x) != 1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid Tox ID."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid Tox ID.")); return; } @@ -201,12 +207,12 @@ void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ { if (argc < 2 || strlen(argv[1]) < 3) { avatar_unset(m); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Avatar is not set."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Avatar is not set.")); return; } if (argv[1][0] != '\"') { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Path must be enclosed in quotes."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Path must be enclosed in quotes.")); return; } @@ -216,7 +222,7 @@ void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ int len = strlen(path) - 1; if (len <= 0) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid path."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid path.")); return; } @@ -226,12 +232,12 @@ void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ if (avatar_set(m, path, len) == -1) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, - "Failed to set avatar. Avatars must be in PNG format and may not exceed %d bytes.", + gettext("Failed to set avatar. Avatars must be in PNG format and may not exceed %d bytes."), MAX_AVATAR_FILE_SIZE); return; } - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Avatar set to '%s'", filename); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Avatar set to '%s'"), filename); } void cmd_clear(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) @@ -243,7 +249,7 @@ void cmd_clear(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[M void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc != 3) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Require: "); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Require: ")); return; } @@ -252,7 +258,7 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv) const char *key = argv[3]; if (atoi(port) == 0) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid port."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid port.")); return; } @@ -265,15 +271,15 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv) switch (err) { case TOX_ERR_BOOTSTRAP_BAD_HOST: - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed: Invalid IP."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Bootstrap failed: Invalid IP.")); break; case TOX_ERR_BOOTSTRAP_BAD_PORT: - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed: Invalid port."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Bootstrap failed: Invalid port.")); break; case TOX_ERR_BOOTSTRAP_NULL: - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Bootstrap failed.")); break; default: break; @@ -283,19 +289,19 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv) void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc < 1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Request ID required."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Request ID required.")); return; } int req = atoi(argv[1]); if ((req == 0 && strcmp(argv[1], "0")) || req < 0 || req > MAX_FRIEND_REQUESTS) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend request with that ID."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending friend request with that ID.")); return; } if (!FrndRequests.request[req].active) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend request with that ID."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending friend request with that ID.")); return; } @@ -315,12 +321,12 @@ void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv) void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (get_num_active_windows() >= MAX_WINDOWS_NUM) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext(" * Warning: Too many windows are open.")); return; } if (argc < 1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Please specify group type: text | audio"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Please specify group type: %s"), "text|audio"); return; } @@ -331,7 +337,7 @@ void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg else if (!strcasecmp(argv[1], "text")) type = TOX_GROUPCHAT_TYPE_TEXT; else { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Valid group types are: text | audio"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Valid group types are: %s"), "text|audio"); return; } @@ -345,17 +351,17 @@ void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg #endif if (groupnum == -1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat instance failed to initialize."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Group chat instance failed to initialize.")); return; } if (init_groupchat_win(prompt, m, groupnum, type) == -1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Group chat window failed to initialize.")); tox_del_groupchat(m, groupnum); return; } - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat [%d] created.", groupnum); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Group chat [%d] created."), groupnum); } void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) @@ -365,9 +371,9 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX if (argc == 0) { if (log->log_on) - msg = "Logging for this window is ON. Type \"/log off\" to disable."; + msg = gettext("Logging for this window is ON. Type \"/log off\" to disable."); else - msg = "Logging for this window is OFF. Type \"/log on\" to enable."; + msg = gettext("Logging for this window is OFF. Type \"/log on\" to enable."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); return; @@ -388,7 +394,7 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX log_enable(self->name, myid, NULL, log, LOG_GROUP); } - msg = "Logging enabled"; + msg = gettext("Logging enabled"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); return; } else if (!strcmp(swch, "0") || !strcmp(swch, "off")) { @@ -397,13 +403,13 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX log_disable(log); - msg = "Logging disabled"; + msg = gettext("Logging disabled"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); return; } - msg = "Invalid option. Use \"/log on\" and \"/log off\" to toggle logging."; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); + msg = gettext("Invalid option. Use \"%s\" to toggle logging."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg, "/log on|off"); } void cmd_myid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) @@ -426,7 +432,7 @@ void cmd_myid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc < 1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Input required."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Input required.")); return; } @@ -443,7 +449,7 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA } if (!valid_nick(nick)) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid name."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid name.")); return; } @@ -459,12 +465,12 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (argc < 1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Input required."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Input required.")); return; } if (argv[1][0] != '\"') { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Note must be enclosed in quotes."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Note must be enclosed in quotes.")); return; } @@ -490,7 +496,7 @@ void cmd_quit(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA void cmd_requests(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { if (FrndRequests.num_requests == 0) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend requests."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending friend requests.")); return; } @@ -527,8 +533,8 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ if (argc >= 2) { have_note = true; } else if (argc < 1) { - errmsg = "Require a status. Statuses are: online, busy and away."; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); + errmsg = gettext("Require a status. Statuses are: %s."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg, "online|busy|away"); goto finish; } @@ -542,8 +548,8 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ else if (!strcasecmp(status_str, "busy")) status = TOX_USER_STATUS_BUSY; else { - errmsg = "Invalid status. Valid statuses are: online, busy and away."; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); + errmsg = gettext("Invalid status. Valid statuses are: %s."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg, "online|busy|away"); goto finish; } @@ -552,7 +558,7 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ if (have_note) { if (argv[2][0] != '\"') { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Note must be enclosed in quotes."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Note must be enclosed in quotes.")); goto finish; } diff --git a/src/group_commands.c b/src/group_commands.c index fb73a0b..2589370 100644 --- a/src/group_commands.c +++ b/src/group_commands.c @@ -22,6 +22,12 @@ #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "toxic.h" #include "windows.h" #include "line_info.h" @@ -37,16 +43,16 @@ void cmd_set_title(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg if (tlen != -1) { title[tlen] = '\0'; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Title is set to: %s", title); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Title is set to: %s"), title); } else { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Title is not set"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Title is not set")); } return; } if (argv[1][0] != '\"') { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Title must be enclosed in quotes."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Title must be enclosed in quotes.")); return; } @@ -56,7 +62,7 @@ void cmd_set_title(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg title[len] = '\0'; if (tox_group_set_title(m, self->num, (uint8_t *) title, len) != 0) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set title."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to set title.")); return; } @@ -71,9 +77,9 @@ void cmd_set_title(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg size_t sn_len = tox_self_get_name_size(m); selfnick[sn_len] = '\0'; - line_info_add(self, timefrmt, selfnick, NULL, NAME_CHANGE, 0, 0, " set the group title to: %s", title); + line_info_add(self, timefrmt, selfnick, NULL, NAME_CHANGE, 0, 0, gettext(" set the group title to: %s"), title); char tmp_event[MAX_STR_SIZE]; - snprintf(tmp_event, sizeof(tmp_event), "set title to %s", title); + snprintf(tmp_event, sizeof(tmp_event), gettext("set title to %s"), title); write_to_log(tmp_event, selfnick, self->chatwin->log, true); } diff --git a/src/groupchat.c b/src/groupchat.c index 57885c9..1c8f990 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -31,6 +31,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #ifdef AUDIO #ifdef __APPLE__ #include @@ -134,7 +140,7 @@ int init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum, uint8_t type) if (groupchats[i].peer_names == NULL || groupchats[i].oldpeer_names == NULL || groupchats[i].peer_name_lengths == NULL || groupchats[i].oldpeer_name_lengths == NULL) - exit_toxic_err("failed in init_groupchat_win", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in init_groupchat_win"), FATALERR_MEMORY); memcpy(&groupchats[i].oldpeer_names[0], UNKNOWN_NAME, sizeof(UNKNOWN_NAME)); groupchats[i].oldpeer_name_lengths[0] = (uint16_t) strlen(UNKNOWN_NAME); @@ -142,7 +148,7 @@ int init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum, uint8_t type) #ifdef AUDIO if (type == TOX_GROUPCHAT_TYPE_AV) if (group_audio_open_out_device(i) == -1) - fprintf(stderr, "Group Audio failed to init\n"); + fprintf(stderr, gettext("Group Audio failed to init\n")); #endif /* AUDIO */ set_active_window(groupchats[i].chatwin); @@ -328,10 +334,10 @@ static void groupchat_onGroupTitleChange(ToxWindow *self, Tox *m, int groupnum, char nick[TOX_MAX_NAME_LENGTH]; get_group_nick_truncate(m, nick, peernum, groupnum); - line_info_add(self, timefrmt, nick, NULL, NAME_CHANGE, 0, 0, " set the group title to: %s", title); + line_info_add(self, timefrmt, nick, NULL, NAME_CHANGE, 0, 0, gettext(" set the group title to: %s"), title); char tmp_event[MAX_STR_SIZE]; - snprintf(tmp_event, sizeof(tmp_event), "set title to %s", title); + snprintf(tmp_event, sizeof(tmp_event), gettext("set title to %s"), title); write_to_log(tmp_event, nick, ctx->log, true); } @@ -353,7 +359,7 @@ static void copy_peernames(int gnum, uint8_t peerlist[][TOX_MAX_NAME_LENGTH], ui if (groupchats[gnum].peer_names == NULL || groupchats[gnum].oldpeer_names == NULL || groupchats[gnum].peer_name_lengths == NULL || groupchats[gnum].oldpeer_name_lengths == NULL) { - exit_toxic_err("failed in copy_peernames", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in copy_peernames"), FATALERR_MEMORY); } uint16_t u_len = strlen(UNKNOWN_NAME); @@ -410,7 +416,7 @@ void *group_add_wait(void *data) pthread_mutex_unlock(&Winthread.lock); } - const char *event = "has joined the room"; + const char *event = gettext("has joined the room"); char timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); @@ -508,7 +514,7 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu break; case TOX_CHAT_CHANGE_PEER_DEL: - event = "has left the room"; + event = gettext("has left the room"); line_info_add(self, timefrmt, (char *) oldpeername, NULL, DISCONNECTION, 0, RED, event); if (groupchats[self->num].side_pos > 0) @@ -525,11 +531,11 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu if (strcmp((char *) oldpeername, DEFAULT_TOX_NAME) == 0) return; - event = " is now known as "; + event = gettext(" is now known as "); line_info_add(self, timefrmt, (char *) oldpeername, (char *) peername, NAME_CHANGE, 0, 0, event); char tmp_event[TOXIC_MAX_NAME_LENGTH * 2 + 32]; - snprintf(tmp_event, sizeof(tmp_event), "is now known as %s", (char *) peername); + snprintf(tmp_event, sizeof(tmp_event), gettext("is now known as %s"), (char *) peername); write_to_log(tmp_event, (char *) oldpeername, ctx->log, true); break; } @@ -540,12 +546,12 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu static void send_group_action(ToxWindow *self, ChatContext *ctx, Tox *m, char *action) { if (action == NULL) { - wprintw(ctx->history, "Invalid syntax.\n"); + wprintw(ctx->history, gettext("Invalid syntax.\n")); return; } if (tox_group_action_send(m, self->num, (uint8_t *) action, strlen(action)) == -1) { - const char *errmsg = " * Failed to send action."; + const char *errmsg = gettext(" * Failed to send action."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg); } } @@ -632,7 +638,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) } } else if (!string_is_empty(line)) { if (tox_group_message_send(m, self->num, (uint8_t *) line, strlen(line)) == -1) { - const char *errmsg = " * Failed to send message."; + const char *errmsg = gettext(" * Failed to send message."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg); } } @@ -669,7 +675,7 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m) wmove(ctx->sidebar, 0, 1); wattron(ctx->sidebar, A_BOLD); - wprintw(ctx->sidebar, "Peers: %d\n", num_peers); + wprintw(ctx->sidebar, gettext("Peers: %d\n"), num_peers); wattroff(ctx->sidebar, A_BOLD); mvwaddch(ctx->sidebar, 1, 0, ACS_LTEE); @@ -719,7 +725,7 @@ static void groupchat_onInit(ToxWindow *self, Tox *m) ctx->log = calloc(1, sizeof(struct chatlog)); if (ctx->log == NULL || ctx->hst == NULL) - exit_toxic_err("failed in groupchat_onInit", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in groupchat_onInit"), FATALERR_MEMORY); line_info_init(ctx->hst); @@ -804,7 +810,7 @@ static int group_audio_write(int peernum, int groupnum, const int16_t *pcm, unsi alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_PROCESSED, &processed); alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_QUEUED, &queued); - fprintf(stderr, "source: %d, queued: %d, processed: %d\n", groupchats[groupnum].audio.source, queued, processed); + fprintf(stderr, gettext("source: %d, queued: %d, processed: %d\n"), groupchats[groupnum].audio.source, queued, processed); if (processed) { ALuint bufids[processed]; @@ -843,13 +849,13 @@ static void groupchat_onWriteDevice(ToxWindow *self, Tox *m, int groupnum, int p return; if (groupchats[groupnum].audio.dvhandle == NULL) - fprintf(stderr, "dvhandle is null)\n"); + fprintf(stderr, gettext("dvhandle is null)\n")); if (groupchats[groupnum].audio.dvctx == NULL) - fprintf(stderr, "ctx is null\n"); + fprintf(stderr, gettext("ctx is null\n")); int ret = group_audio_write(peernum, groupnum, pcm, samples, channels, sample_rate); - fprintf(stderr, "write: %d\n", ret); + fprintf(stderr, gettext("write: %d\n"), ret); } #endif /* AUDIO */ @@ -873,13 +879,13 @@ ToxWindow new_group_chat(Tox *m, int groupnum) ret.onWriteDevice = &groupchat_onWriteDevice; #endif - snprintf(ret.name, sizeof(ret.name), "Group %d", groupnum); + snprintf(ret.name, sizeof(ret.name), gettext("Group %d"), groupnum); ChatContext *chatwin = calloc(1, sizeof(ChatContext)); Help *help = calloc(1, sizeof(Help)); if (chatwin == NULL || help == NULL) - exit_toxic_err("failed in new_group_chat", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in new_group_chat"), FATALERR_MEMORY); ret.chatwin = chatwin; ret.help = help; diff --git a/src/help.c b/src/help.c index 8989c11..0838433 100644 --- a/src/help.c +++ b/src/help.c @@ -22,6 +22,12 @@ #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "windows.h" #include "toxic.h" #include "help.h" @@ -139,32 +145,50 @@ static void help_draw_global(ToxWindow *self) wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); - wprintw(win, "Global Commands:\n"); + wprintw(win, gettext("Global Commands:\n")); wattroff(win, A_BOLD | COLOR_PAIR(RED)); - wprintw(win, " /add : Add contact with optional message\n"); - wprintw(win, " /accept : Accept friend request\n"); - wprintw(win, " /avatar : Set an avatar (leave path empty to unset)\n"); - wprintw(win, " /decline : Decline friend request\n"); - wprintw(win, " /requests : List pending friend requests\n"); - wprintw(win, " /connect : Manually connect to a DHT node\n"); - wprintw(win, " /status : Set status with optional note\n"); - wprintw(win, " /note : Set a personal note\n"); - wprintw(win, " /nick : Set your nickname\n"); - wprintw(win, " /log or : Enable/disable logging\n"); - wprintw(win, " /group : Create a group chat where type: text | audio\n"); - wprintw(win, " /myid : Print your Tox ID\n"); - wprintw(win, " /clear : Clear window history\n"); - wprintw(win, " /close : Close the current chat window\n"); - wprintw(win, " /quit or /exit : Exit Toxic\n"); + wprintw(win, " /add : "); + wprintw(win, gettext("Add contact with optional message\n")); + wprintw(win, " /accept : "); + wprintw(win, gettext("Accept friend request\n")); + wprintw(win, " /avatar : "); + wprintw(win, gettext("Set an avatar (leave path empty to unset)\n")); + wprintw(win, " /decline : "); + wprintw(win, gettext("Decline friend request\n")); + wprintw(win, " /requests : "); + wprintw(win, gettext("List pending friend requests\n")); + wprintw(win, " /connect : "); + wprintw(win, gettext("Manually connect to a DHT node\n")); + wprintw(win, " /status : "); + wprintw(win, gettext("Set status with optional note\n")); + wprintw(win, " /note : "); + wprintw(win, gettext("Set a personal note\n")); + wprintw(win, " /nick : "); + wprintw(win, gettext("Set your nickname\n")); + wprintw(win, " /log or : "); + wprintw(win, gettext("Enable/disable logging\n")); + wprintw(win, " /group : "); + wprintw(win, gettext("Create a group chat where type: text | audio\n")); + wprintw(win, " /myid : "); + wprintw(win, gettext("Print your Tox ID\n")); + wprintw(win, " /clear : "); + wprintw(win, gettext("Clear window history\n")); + wprintw(win, " /close : "); + wprintw(win, gettext("Close the current chat window\n")); + wprintw(win, " /quit or /exit : "); + wprintw(win, gettext("Exit Toxic\n")); #ifdef AUDIO wattron(win, A_BOLD); - wprintw(win, "\n Audio:\n"); + wprintw(win, gettext("\n Audio:\n")); wattroff(win, A_BOLD); - wprintw(win, " /lsdev : List devices where type: in|out\n"); - wprintw(win, " /sdev : Set active device\n"); + wprintw(win, " /lsdev : "); + wprintw(win, gettext("List devices where type:")); + wprintw(win, " in|out\n"); + wprintw(win, " /sdev : "); + wprintw(win, gettext("Set active device\n")); #endif /* AUDIO */ help_draw_bottom_menu(win); @@ -180,27 +204,40 @@ static void help_draw_chat(ToxWindow *self) wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); - wprintw(win, "Chat Commands:\n"); + wprintw(win, gettext("Chat Commands:\n")); wattroff(win, A_BOLD | COLOR_PAIR(RED)); - wprintw(win, " /invite : Invite contact to a group chat\n"); - wprintw(win, " /join : Join a pending group chat\n"); - wprintw(win, " /sendfile : Send a file\n"); - wprintw(win, " /savefile : Receive a file\n"); - wprintw(win, " /cancel : Cancel file transfer where type: in|out\n"); + wprintw(win, " /invite : "); + wprintw(win, gettext("Invite contact to a group chat\n")); + wprintw(win, " /join : "); + wprintw(win, gettext("Join a pending group chat\n")); + wprintw(win, " /sendfile : "); + wprintw(win, gettext("Send a file\n")); + wprintw(win, " /savefile : "); + wprintw(win, gettext("Receive a file\n")); + wprintw(win, " /cancel : "); + wprintw(win, gettext("Cancel file transfer where type:")); + wprintw(win, " in|out\n"); #ifdef AUDIO wattron(win, A_BOLD); - wprintw(win, "\n Audio:\n"); + wprintw(win, gettext("\n Audio:\n")); wattroff(win, A_BOLD); - wprintw(win, " /call : Audio call\n"); - wprintw(win, " /answer : Answer incoming call\n"); - wprintw(win, " /reject : Reject incoming call\n"); - wprintw(win, " /hangup : Hangup active call\n"); - wprintw(win, " /sdev : Change active device\n"); - wprintw(win, " /mute : Mute active device if in call\n"); - wprintw(win, " /sense : VAD sensitivity threshold\n"); + wprintw(win, " /call : "); + wprintw(win, gettext("Audio call\n")); + wprintw(win, " /answer : "); + wprintw(win, gettext("Answer incoming call\n")); + wprintw(win, " /reject : "); + wprintw(win, gettext("Reject incoming call\n")); + wprintw(win, " /hangup : "); + wprintw(win, gettext("Hangup active call\n")); + wprintw(win, " /sdev : "); + wprintw(win, gettext("Change active device\n")); + wprintw(win, " /mute : "); + wprintw(win, gettext("Mute active device if in call\n")); + wprintw(win, " /sense : "); + wprintw(win, gettext("VAD sensitivity threshold\n")); #endif /* AUDIO */ help_draw_bottom_menu(win); @@ -216,16 +253,22 @@ static void help_draw_keys(ToxWindow *self) wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); - wprintw(win, "Key bindings:\n"); + wprintw(win, gettext("Key bindings:\n")); wattroff(win, A_BOLD | COLOR_PAIR(RED)); - wprintw(win, " Ctrl+O and Ctrl+P : Navigate through the tabs\n"); - wprintw(win, " Page Up and Page Down : Scroll window history one line\n"); - wprintw(win, " Ctrl+F and Ctrl+V : Scroll window history half a page\n"); - wprintw(win, " Ctrl+H : Move to the bottom of window history\n"); - wprintw(win, " Ctrl+[ and Ctrl+] : Scroll peer list in groupchats\n"); - wprintw(win, " Ctrl+B : Toggle the groupchat peerlist\n\n"); - wprintw(win, " (Note: Custom keybindings override these defaults.)\n\n"); + wprintw(win, " Ctrl+O -- Ctrl+P : "); + wprintw(win, gettext("Navigate through the tabs\n")); + wprintw(win, " Page Up -- Page Down : "); + wprintw(win, gettext("Scroll window history one line\n")); + wprintw(win, " Ctrl+F -- Ctrl+V : "); + wprintw(win, gettext("Scroll window history half a page\n")); + wprintw(win, " Ctrl+H : "); + wprintw(win, gettext("Move to the bottom of window history\n")); + wprintw(win, " Ctrl+[ -- Ctrl+] : "); + wprintw(win, gettext("Scroll peer list in groupchats\n")); + wprintw(win, " Ctrl+B : "); + wprintw(win, gettext("Toggle the groupchat peerlist\n\n")); + wprintw(win, gettext(" (Note: Custom keybindings override these defaults.)\n\n")); help_draw_bottom_menu(win); @@ -240,10 +283,11 @@ static void help_draw_group(ToxWindow *self) wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); - wprintw(win, "Group commands:\n"); + wprintw(win, gettext("Group commands:\n")); wattroff(win, A_BOLD | COLOR_PAIR(RED)); - wprintw(win, " /title : Set group title (show current title if no msg)\n\n"); + wprintw(win, " /title : "); + wprintw(win, gettext("Set group title (show current title if no msg)\n\n")); help_draw_bottom_menu(win); @@ -258,14 +302,15 @@ static void help_draw_contacts(ToxWindow *self) wmove(win, 1, 1); wattron(win, A_BOLD | COLOR_PAIR(RED)); - wprintw(win, "Friendlist controls:\n"); + wprintw(win, gettext("Friendlist controls:\n")); wattroff(win, A_BOLD | COLOR_PAIR(RED)); - wprintw(win, " Up and Down arrows : Scroll through list\n"); - wprintw(win, " Right and Left arrows : Switch between friendlist and blocked list\n"); - wprintw(win, " Enter : Open a chat window with selected contact\n"); - wprintw(win, " Delete : Permanently delete a contact\n"); - wprintw(win, " B : Block or unblock a contact\n"); + wprintw(win, gettext(" Up and Down arrows : Scroll through list\n")); + wprintw(win, gettext(" Right and Left arrows : Switch between friendlist and blocked list\n")); + wprintw(win, gettext(" Enter : Open a chat window with selected contact\n")); + wprintw(win, gettext(" Delete : Permanently delete a contact\n")); + wprintw(win, " B : "); + wprintw(win, gettext("Block or unblock a contact\n")); help_draw_bottom_menu(win); diff --git a/src/line_info.c b/src/line_info.c index b645e8f..12eea6d 100644 --- a/src/line_info.c +++ b/src/line_info.c @@ -25,6 +25,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "toxic.h" #include "windows.h" #include "line_info.h" @@ -41,7 +47,7 @@ void line_info_init(struct history *hst) hst->line_root = calloc(1, sizeof(struct line_info)); if (hst->line_root == NULL) - exit_toxic_err("failed in line_info_init", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in line_info_init"), FATALERR_MEMORY); hst->line_start = hst->line_root; hst->line_end = hst->line_start; @@ -141,7 +147,7 @@ void line_info_add(ToxWindow *self, const char *timestr, const char *name1, cons struct line_info *new_line = calloc(1, sizeof(struct line_info)); if (new_line == NULL) - exit_toxic_err("failed in line_info_add", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in line_info_add"), FATALERR_MEMORY); char frmt_msg[MAX_LINE_INFO_MSG_SIZE] = {0}; diff --git a/src/log.c b/src/log.c index f04c83d..a3331ef 100644 --- a/src/log.c +++ b/src/log.c @@ -25,6 +25,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "configdir.h" #include "toxic.h" #include "windows.h" @@ -180,17 +186,17 @@ void load_chat_history(ToxWindow *self, struct chatlog *log) char *hstbuf = malloc(sz); if (hstbuf == NULL) - exit_toxic_err("failed in load_chat_history", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in load_chat_history"), FATALERR_MEMORY); if (fseek(log->file, 0L, SEEK_SET) == -1) { free(hstbuf); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Failed to read log file"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext(" * Failed to read log file")); return; } if (fread(hstbuf, sz, 1, log->file) != 1) { free(hstbuf); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Failed to read log file"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext(" * Failed to read log file")); return; } diff --git a/src/message_queue.c b/src/message_queue.c index 70ccadb..996e4eb 100644 --- a/src/message_queue.c +++ b/src/message_queue.c @@ -22,6 +22,12 @@ #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "toxic.h" #include "windows.h" #include "message_queue.h" @@ -47,7 +53,7 @@ void cqueue_add(struct chat_queue *q, const char *msg, size_t len, uint8_t type, struct cqueue_msg *new_m = malloc(sizeof(struct cqueue_msg)); if (new_m == NULL) - exit_toxic_err("failed in cqueue_message", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in cqueue_message"), FATALERR_MEMORY); snprintf(new_m->message, sizeof(new_m->message), "%s", msg); new_m->len = len; diff --git a/src/misc_tools.c b/src/misc_tools.c index 0d0a749..65114a1 100644 --- a/src/misc_tools.c +++ b/src/misc_tools.c @@ -28,6 +28,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "toxic.h" #include "windows.h" #include "misc_tools.h" @@ -231,7 +237,7 @@ size_t get_file_name(char *namebuf, size_t bufsize, const char *pathname) char *path = strdup(pathname); if (path == NULL) - exit_toxic_err("failed in get_file_name", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in get_file_name"), FATALERR_MEMORY); while (len >= 0 && pathname[len] == '/') path[len--] = '\0'; @@ -239,7 +245,7 @@ size_t get_file_name(char *namebuf, size_t bufsize, const char *pathname) char *finalname = strdup(path); if (finalname == NULL) - exit_toxic_err("failed in get_file_name", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in get_file_name"), FATALERR_MEMORY); const char *basenm = strrchr(path, '/'); diff --git a/src/prompt.c b/src/prompt.c index 8377125..355d0d3 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -28,6 +28,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "toxic.h" #include "windows.h" #include "prompt.h" @@ -130,7 +136,7 @@ void prompt_update_statusmessage(ToxWindow *prompt, Tox *m, const char *statusms tox_self_set_status_message(m, (uint8_t *) statusmsg, len, &err); if (err != TOX_ERR_SET_INFO_OK) - line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set note (error %d)\n", err); + line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to set note (error %d)\n"), err); } /* Updates own status in prompt statusbar */ @@ -262,19 +268,19 @@ static void prompt_onDraw(ToxWindow *self, Tox *m) if (statusbar->connection != TOX_CONNECTION_NONE) { int colour = MAGENTA; - const char *status_text = "ERROR"; + const char *status_text = gettext("ERROR"); switch (statusbar->status) { case TOX_USER_STATUS_NONE: - status_text = "Online"; + status_text = gettext("Online"); colour = GREEN; break; case TOX_USER_STATUS_AWAY: - status_text = "Away"; + status_text = gettext("Away"); colour = YELLOW; break; case TOX_USER_STATUS_BUSY: - status_text = "Busy"; + status_text = gettext("Busy"); colour = RED; break; } @@ -287,7 +293,7 @@ static void prompt_onDraw(ToxWindow *self, Tox *m) wprintw(statusbar->topline, " %s", statusbar->nick); wattroff(statusbar->topline, A_BOLD); } else { - wprintw(statusbar->topline, " [Offline]"); + wprintw(statusbar->topline, gettext(" [Offline]")); wattron(statusbar->topline, A_BOLD); wprintw(statusbar->topline, " %s", statusbar->nick); wattroff(statusbar->topline, A_BOLD); @@ -351,28 +357,28 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, uint32_t friendnu const char *msg; if (connection_status != TOX_CONNECTION_NONE && Friends.list[friendnum].connection_status == TOX_CONNECTION_NONE) { - msg = "has come online"; + msg = gettext("has come online"); line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, GREEN, msg); write_to_log(msg, nick, ctx->log, true); if (self->active_box != -1) box_notify2(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box, - "%s has come online", nick ); + gettext("%s has come online"), nick ); else box_notify(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, &self->active_box, - "Toxic", "%s has come online", nick ); + "Toxic", gettext("%s has come online"), nick ); } else if (connection_status == TOX_CONNECTION_NONE) { - msg = "has gone offline"; + msg = gettext("has gone offline"); line_info_add(self, timefrmt, nick, NULL, DISCONNECTION, 0, RED, msg); write_to_log(msg, nick, ctx->log, true); if (self->active_box != -1) box_notify2(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box, - "%s has gone offline", nick ); + gettext("%s has gone offline"), nick ); else box_notify(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, &self->active_box, - "Toxic", "%s has gone offline", nick ); + "Toxic", gettext("%s has gone offline"), nick ); } } @@ -383,18 +389,18 @@ static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, con char timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); - line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 0, 0, "Friend request with the message '%s'", data); - write_to_log("Friend request with the message '%s'", "", ctx->log, true); + line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 0, 0, gettext("Friend request with the message '%s'"), data); + write_to_log(gettext("Friend request with the message '%s'"), "", ctx->log, true); int n = add_friend_request(key, data); if (n == -1) { - const char *errmsg = "Friend request queue is full. Discarding request."; + const char *errmsg = gettext("Friend request queue is full. Discarding request."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); return; } - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type \"/accept %d\" or \"/decline %d\"", n, n); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Type \"%s %d\" or \"%s %d\""), "/accept", n, "/decline", n); sound_notify(self, generic_message, NT_WNDALERT_1 | NT_NOTIFWND, NULL); } @@ -423,8 +429,8 @@ void prompt_init_statusbar(ToxWindow *self, Tox *m) nick[n_len] = '\0'; statusmsg[s_len] = '\0'; - if (s_len == 0 || !strncmp(statusmsg, "Toxing on Toxic", strlen("Toxing on Toxic"))) { - snprintf(statusmsg, sizeof(statusmsg), "Toxing on Toxic"); + if (s_len == 0 || !strncmp(statusmsg, gettext("Toxing on Toxic"), strlen(gettext("Toxing on Toxic")))) { + snprintf(statusmsg, sizeof(statusmsg), gettext("Toxing on Toxic")); s_len = strlen(statusmsg); statusmsg[s_len] = '\0'; } @@ -446,10 +452,10 @@ static void print_welcome_msg(ToxWindow *self) line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, BLUE, " |_| \\___/_/\\_\\___\\____| v." TOXICVER); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, ""); - const char *msg = "Welcome to Toxic, a free, open source Tox-based instant messenging client."; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, CYAN, msg); - msg = "Type \"/help\" for assistance. Further help may be found via the man page."; + const char *msg = gettext("Welcome to Toxic, a free, open source Tox-based instant messenging client."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, CYAN, msg); + msg = gettext("Type \"%s\" for assistance. Further help may be found via the man page."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, CYAN, msg, "/help"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, ""); } @@ -467,7 +473,7 @@ static void prompt_onInit(ToxWindow *self, Tox *m) ctx->hst = calloc(1, sizeof(struct history)); if (ctx->log == NULL || ctx->hst == NULL) - exit_toxic_err("failed in prompt_onInit", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in prompt_onInit"), FATALERR_MEMORY); line_info_init(ctx->hst); @@ -505,7 +511,7 @@ ToxWindow new_prompt(void) Help *help = calloc(1, sizeof(Help)); if (stb == NULL || chatwin == NULL || help == NULL) - exit_toxic_err("failed in new_prompt", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in new_prompt"), FATALERR_MEMORY); ret.chatwin = chatwin; ret.stb = stb; diff --git a/src/toxic.c b/src/toxic.c index 9d14328..31154eb 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -40,6 +40,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include #include @@ -103,7 +109,7 @@ static void catch_SIGSEGV(int sig) { freopen("/dev/tty", "w", stderr); // make sure stderr is enabled since we may have disabled it endwin(); - fprintf(stderr, "Caught SIGSEGV: Aborting toxic session.\n"); + fprintf(stderr, gettext("Caught SIGSEGV: Aborting toxic session.\n")); exit(EXIT_FAILURE); } @@ -152,7 +158,7 @@ void exit_toxic_err(const char *errmsg, int errcode) { freopen("/dev/tty", "w", stderr); endwin(); - fprintf(stderr, "Toxic session aborted with error code %d (%s)\n", errcode, errmsg); + fprintf(stderr, gettext("Toxic session aborted with error code %d (%s)\n"), errcode, errmsg); exit(EXIT_FAILURE); } @@ -162,12 +168,16 @@ static void init_term(void) if (!arg_opts.default_locale) { if (setlocale(LC_ALL, "") == NULL) - exit_toxic_err("Could not set your locale, please check your locale settings or " - "disable unicode support with the -d flag.", FATALERR_LOCALE_NOT_SET); + exit_toxic_err(gettext("Could not set your locale, please check your locale settings or " + "disable unicode support with the -d flag."), FATALERR_LOCALE_NOT_SET); } #endif +#ifndef NO_GETTEXT + textdomain("toxic"); +#endif + initscr(); cbreak(); keypad(stdscr, 1); @@ -218,12 +228,12 @@ static void queue_init_message(const char *msg, ...) char **new_msgs = realloc(init_messages.msgs, sizeof(char *) * init_messages.num); if (new_msgs == NULL) - exit_toxic_err("Failed in queue_init_message", FATALERR_MEMORY); + exit_toxic_err(gettext("Failed in queue_init_message"), FATALERR_MEMORY); new_msgs[i] = malloc(MAX_STR_SIZE); if (new_msgs[i] == NULL) - exit_toxic_err("Failed in queue_init_message", FATALERR_MEMORY); + exit_toxic_err(gettext("Failed in queue_init_message"), FATALERR_MEMORY); snprintf(new_msgs[i], MAX_STR_SIZE, "%s", frmt_msg); init_messages.msgs = new_msgs; @@ -315,14 +325,14 @@ int init_connection_helper(Tox *m, int line) tox_bootstrap(m, toxNodes.nodes[line], toxNodes.ports[line], (uint8_t *) toxNodes.keys[line], &err); if (err != TOX_ERR_BOOTSTRAP_OK) { - fprintf(stderr, "Failed to bootstrap %s:%d\n", toxNodes.nodes[line], toxNodes.ports[line]); + fprintf(stderr, gettext("Failed to bootstrap %s:%d\n"), toxNodes.nodes[line], toxNodes.ports[line]); return -1; } tox_add_tcp_relay(m, toxNodes.nodes[line], toxNodes.ports[line], (uint8_t *) toxNodes.keys[line], &err); if (err != TOX_ERR_BOOTSTRAP_OK) { - fprintf(stderr, "Failed to add TCP relay %s:%d\n", toxNodes.nodes[line], toxNodes.ports[line]); + fprintf(stderr, gettext("Failed to add TCP relay %s:%d\n"), toxNodes.nodes[line], toxNodes.ports[line]); return -1; } @@ -453,7 +463,7 @@ static void first_time_encrypt(const char *msg) bool valid_password = false; char passconfirm[MAX_PASSWORD_LEN + 1] = {0}; - printf("Enter a new password (must be at least %d characters) ", MIN_PASSWORD_LEN); + printf(gettext("Enter a new password (must be at least %d characters) "), MIN_PASSWORD_LEN); while (valid_password == false) { len = password_prompt(user_password.pass, sizeof(user_password.pass)); @@ -463,12 +473,12 @@ static void first_time_encrypt(const char *msg) exit(0); if (string_is_empty(passconfirm) && (len < MIN_PASSWORD_LEN || len > MAX_PASSWORD_LEN)) { - printf("Password must be between %d and %d characters long. ", MIN_PASSWORD_LEN, MAX_PASSWORD_LEN); + printf(gettext("Password must be between %d and %d characters long. "), MIN_PASSWORD_LEN, MAX_PASSWORD_LEN); continue; } if (string_is_empty(passconfirm)) { - printf("Enter password again "); + printf(gettext("Enter password again ")); snprintf(passconfirm, sizeof(passconfirm), "%s", user_password.pass); continue; } @@ -476,14 +486,14 @@ static void first_time_encrypt(const char *msg) if (strcmp(user_password.pass, passconfirm) != 0) { memset(passconfirm, 0, sizeof(passconfirm)); memset(user_password.pass, 0, sizeof(user_password.pass)); - printf("Passwords don't match. Try again. "); + printf(gettext("Passwords don't match. Try again. ")); continue; } valid_password = true; } - queue_init_message("Data file '%s' is encrypted", DATA_FILE); + queue_init_message(gettext("Data file '%s' is encrypted"), DATA_FILE); memset(passconfirm, 0, sizeof(passconfirm)); user_password.data_is_encrypted = true; } @@ -520,7 +530,7 @@ int store_data(Tox *m, const char *path) (uint8_t *) enc_data, &err); if (err != TOX_ERR_ENCRYPTION_OK) { - fprintf(stderr, "tox_pass_encrypt() failed with error %d\n", err); + fprintf(stderr, gettext("tox_pass_encrypt() failed with error %d\n"), err); fclose(fp); return -1; } @@ -571,7 +581,7 @@ static void init_tox_options(struct Tox_Options *tox_opts) tox_opts->proxy_type = arg_opts.proxy_type; if (!tox_opts->ipv6_enabled) - queue_init_message("Forcing IPv4 connection"); + queue_init_message(gettext("Forcing IPv4 connection")); if (tox_opts->proxy_type != TOX_PROXY_TYPE_NONE) { tox_opts->proxy_port = arg_opts.proxy_port; @@ -579,16 +589,16 @@ static void init_tox_options(struct Tox_Options *tox_opts) const char *ps = tox_opts->proxy_type == TOX_PROXY_TYPE_SOCKS5 ? "SOCKS5" : "HTTP"; char tmp[48]; - snprintf(tmp, sizeof(tmp), "Using %s proxy %s : %d", ps, arg_opts.proxy_address, arg_opts.proxy_port); + snprintf(tmp, sizeof(tmp), gettext("Using %s proxy %s : %d"), ps, arg_opts.proxy_address, arg_opts.proxy_port); queue_init_message("%s", tmp); } if (!tox_opts->udp_enabled) { - queue_init_message("UDP disabled"); + queue_init_message(gettext("UDP disabled")); } else if (tox_opts->proxy_type != TOX_PROXY_TYPE_NONE) { - const char *msg = "WARNING: Using a proxy without disabling UDP may leak your real IP address."; + const char *msg = gettext("WARNING: Using a proxy without disabling UDP may leak your real IP address."); queue_init_message("%s", msg); - msg = "Use the -t option to disable UDP."; + msg = gettext("Use the -t option to disable UDP."); queue_init_message("%s", msg); } } @@ -607,14 +617,14 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW if (len == 0) { fclose(fp); - exit_toxic_err("failed in load_toxic", FATALERR_FILEOP); + exit_toxic_err(gettext("failed in load_toxic"), FATALERR_FILEOP); } char data[len]; if (fread(data, sizeof(data), 1, fp) != 1) { fclose(fp); - exit_toxic_err("failed in load_toxic", FATALERR_FILEOP); + exit_toxic_err(gettext("failed in load_toxic"), FATALERR_FILEOP); } bool is_encrypted = tox_is_data_encrypted((uint8_t *) data); @@ -622,13 +632,13 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW /* attempt to encrypt an already encrypted data file */ if (arg_opts.encrypt_data && is_encrypted) { fclose(fp); - exit_toxic_err("failed in load_toxic", FATALERR_ENCRYPT); + exit_toxic_err(gettext("failed in load_toxic"), FATALERR_ENCRYPT); } if (arg_opts.unencrypt_data && is_encrypted) - queue_init_message("Data file '%s' has been unencrypted", data_path); + queue_init_message(gettext("Data file '%s' has been unencrypted"), data_path); else if (arg_opts.unencrypt_data) - queue_init_message("Warning: passed --unencrypt-data option with unencrypted data file '%s'", data_path); + queue_init_message(gettext("Warning: passed --unencrypt-data option with unencrypted data file '%s'"), data_path); if (is_encrypted) { if (!arg_opts.unencrypt_data) @@ -636,7 +646,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW size_t pwlen = 0; system("clear"); // TODO: is this portable? - printf("Enter password (q to quit) "); + printf(gettext("Enter password (\"%s\" to quit) "), "q"); size_t plain_len = len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; char plain[plain_len]; @@ -653,7 +663,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW if (pwlen < MIN_PASSWORD_LEN) { system("clear"); sleep(1); - printf("Invalid password. Try again. "); + printf(gettext("Invalid password. Try again. ")); continue; } @@ -677,10 +687,10 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW } else if (pwerr == TOX_ERR_DECRYPTION_FAILED) { system("clear"); sleep(1); - printf("Invalid password. Try again. "); + printf(gettext("Invalid password. Try again. ")); } else { fclose(fp); - exit_toxic_err("tox_pass_decrypt() failed", pwerr); + exit_toxic_err(gettext("tox_pass_decrypt() failed"), pwerr); } } } else { /* data is not encrypted */ @@ -699,7 +709,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW fclose(fp); } else { /* Data file does not/should not exist */ if (file_exists(data_path)) - exit_toxic_err("failed in load_toxic", FATALERR_FILEOP); + exit_toxic_err(gettext("failed in load_toxic"), FATALERR_FILEOP); tox_opts->savedata_type = TOX_SAVEDATA_TYPE_NONE; @@ -709,7 +719,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW return NULL; if (store_data(m, data_path) == -1) - exit_toxic_err("failed in load_toxic", FATALERR_FILEOP); + exit_toxic_err(gettext("failed in load_toxic"), FATALERR_FILEOP); } return m; @@ -724,23 +734,23 @@ static Tox *load_toxic(char *data_path) Tox *m = load_tox(data_path, &tox_opts, &new_err); if (new_err == TOX_ERR_NEW_PORT_ALLOC && tox_opts.ipv6_enabled) { - queue_init_message("Falling back to ipv4"); + queue_init_message(gettext("Falling back to ipv4")); tox_opts.ipv6_enabled = false; m = load_tox(data_path, &tox_opts, &new_err); } if (!m) - exit_toxic_err("tox_new returned fatal error", new_err); + exit_toxic_err(gettext("tox_new returned fatal error"), new_err); if (new_err != TOX_ERR_NEW_OK) - queue_init_message("tox_new returned non-fatal error %d", new_err); + queue_init_message(gettext("tox_new returned non-fatal error %d"), new_err); init_tox_callbacks(m); load_friendlist(m); load_blocklist(BLOCK_FILE); if (tox_self_get_name_size(m) == 0) - tox_self_set_name(m, (uint8_t *) "Toxic User", strlen("Toxic User"), NULL); + tox_self_set_name(m, (uint8_t *) gettext("Toxic User"), strlen(gettext("Toxic User")), NULL); return m; } @@ -766,7 +776,7 @@ static void do_bootstrap(Tox *m) conn_err = init_connection(m); if (conn_err != 0) - line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Auto-connect failed with error code %d", conn_err); + line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Auto-connect failed with error code %d"), conn_err); } static void do_toxic(Tox *m, ToxWindow *prompt) @@ -847,21 +857,35 @@ void *thread_audio(void *data) static void print_usage(void) { - fprintf(stderr, "usage: toxic [OPTION] [FILE ...]\n"); - fprintf(stderr, " -4, --ipv4 Force IPv4 connection\n"); - fprintf(stderr, " -b, --debug Enable stderr for debugging\n"); - fprintf(stderr, " -c, --config Use specified config file\n"); - fprintf(stderr, " -d, --default-locale Use default POSIX locale\n"); - fprintf(stderr, " -e, --encrypt-data Encrypt an unencrypted data file\n"); - fprintf(stderr, " -f, --file Use specified data file\n"); - fprintf(stderr, " -h, --help Show this message and exit\n"); - fprintf(stderr, " -n, --nodes Use specified DHTnodes file\n"); - fprintf(stderr, " -o, --noconnect Do not connect to the DHT network\n"); - fprintf(stderr, " -p, --SOCKS5-proxy Use SOCKS5 proxy: Requires [IP] [port]\n"); - fprintf(stderr, " -P, --HTTP-proxy Use HTTP proxy: Requires [IP] [port]\n"); - fprintf(stderr, " -r, --dnslist Use specified DNSservers file\n"); - fprintf(stderr, " -t, --force-tcp Force TCP connection (use this with proxies)\n"); - fprintf(stderr, " -u, --unencrypt-data Unencrypt an encrypted data file\n"); + fprintf(stderr, gettext("usage: toxic [OPTION] [FILE ...]\n")); + fprintf(stderr, " -4, --ipv4 "); + fprintf(stderr, gettext("Force IPv4 connection\n")); + fprintf(stderr, " -b, --debug "); + fprintf(stderr, gettext("Enable stderr for debugging\n")); + fprintf(stderr, " -c, --config "); + fprintf(stderr, gettext("Use specified config file\n")); + fprintf(stderr, " -d, --default-locale "); + fprintf(stderr, gettext("Use default POSIX locale\n")); + fprintf(stderr, " -e, --encrypt-data "); + fprintf(stderr, gettext("Encrypt an unencrypted data file\n")); + fprintf(stderr, " -f, --file "); + fprintf(stderr, gettext("Use specified data file\n")); + fprintf(stderr, " -h, --help "); + fprintf(stderr, gettext("Show this message and exit\n")); + fprintf(stderr, " -n, --nodes "); + fprintf(stderr, gettext("Use specified DHTnodes file\n")); + fprintf(stderr, " -o, --noconnect "); + fprintf(stderr, gettext("Do not connect to the DHT network\n")); + fprintf(stderr, " -p, --SOCKS5-proxy "); + fprintf(stderr, gettext("Use SOCKS5 proxy: Requires [IP] [port]\n")); + fprintf(stderr, " -P, --HTTP-proxy "); + fprintf(stderr, gettext("Use HTTP proxy: Requires [IP] [port]\n")); + fprintf(stderr, " -r, --dnslist "); + fprintf(stderr, gettext("Use specified DNSservers file\n")); + fprintf(stderr, " -t, --force-tcp "); + fprintf(stderr, gettext("Force TCP connection (use this with proxies)\n")); + fprintf(stderr, " -u, --unencrypt-data "); + fprintf(stderr, gettext("Unencrypt an encrypted data file\n")); } static void set_default_opts(void) @@ -905,20 +929,20 @@ static void parse_args(int argc, char *argv[]) case 'b': arg_opts.debug = 1; - queue_init_message("stderr enabled"); + queue_init_message(gettext("stderr enabled")); break; case 'c': snprintf(arg_opts.config_path, sizeof(arg_opts.config_path), "%s", optarg); if (!file_exists(arg_opts.config_path)) - queue_init_message("Config file not found"); + queue_init_message(gettext("Config file not found")); break; case 'd': arg_opts.default_locale = 1; - queue_init_message("Using default POSIX locale"); + queue_init_message(gettext("Using default POSIX locale")); break; case 'e': @@ -931,12 +955,12 @@ static void parse_args(int argc, char *argv[]) BLOCK_FILE = malloc(strlen(optarg) + strlen("-blocklist") + 1); if (DATA_FILE == NULL || BLOCK_FILE == NULL) - exit_toxic_err("failed in parse_args", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in parse_args"), FATALERR_MEMORY); strcpy(BLOCK_FILE, optarg); strcat(BLOCK_FILE, "-blocklist"); - queue_init_message("Using '%s' data file", DATA_FILE); + queue_init_message(gettext("Using '%s' data file"), DATA_FILE); break; @@ -944,13 +968,13 @@ static void parse_args(int argc, char *argv[]) snprintf(arg_opts.nodes_path, sizeof(arg_opts.nodes_path), "%s", optarg); if (!file_exists(arg_opts.nodes_path)) - queue_init_message("DHTnodes file not found"); + queue_init_message(gettext("DHTnodes file not found")); break; case 'o': arg_opts.no_connect = 1; - queue_init_message("DHT disabled"); + queue_init_message(gettext("DHT disabled")); break; case 'p': @@ -958,7 +982,7 @@ static void parse_args(int argc, char *argv[]) snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg); if (++optind > argc || argv[optind-1][0] == '-') - exit_toxic_err("Proxy error", FATALERR_PROXY); + exit_toxic_err(gettext("Proxy error"), FATALERR_PROXY); arg_opts.proxy_port = (uint16_t) atoi(argv[optind-1]); break; @@ -968,7 +992,7 @@ static void parse_args(int argc, char *argv[]) snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg); if (++optind > argc || argv[optind-1][0] == '-') - exit_toxic_err("Proxy error", FATALERR_PROXY); + exit_toxic_err(gettext("Proxy error"), FATALERR_PROXY); arg_opts.proxy_port = (uint16_t) atoi(argv[optind-1]); break; @@ -977,7 +1001,7 @@ static void parse_args(int argc, char *argv[]) snprintf(arg_opts.dns_path, sizeof(arg_opts.dns_path), "%s", optarg); if (!file_exists(arg_opts.dns_path)) - queue_init_message("DNSservers file not found"); + queue_init_message(gettext("DNSservers file not found")); break; @@ -1012,13 +1036,13 @@ static int init_default_data_files(void) BLOCK_FILE = strdup(BLOCKNAME); if (DATA_FILE == NULL || BLOCK_FILE == NULL) - exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in load_data_structures"), FATALERR_MEMORY); } else { DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(DATANAME) + 1); BLOCK_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(BLOCKNAME) + 1); if (DATA_FILE == NULL || BLOCK_FILE == NULL) - exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in load_data_structures"), FATALERR_MEMORY); strcpy(DATA_FILE, user_config_dir); strcat(DATA_FILE, CONFIGDIR); @@ -1074,7 +1098,7 @@ int main(int argc, char *argv[]) if (arg_opts.encrypt_data && arg_opts.unencrypt_data) { arg_opts.encrypt_data = 0; arg_opts.unencrypt_data = 0; - queue_init_message("Warning: Using --unencrypt-data and --encrypt-data simultaneously has no effect"); + queue_init_message(gettext("Warning: Using \"%s\" and \"%s\" simultaneously has no effect"), "--unencrypt-data", "--encrypt-data"); } /* Make sure all written files are read/writeable only by the current user. */ @@ -1087,23 +1111,23 @@ int main(int argc, char *argv[]) last_bootstrap_time = get_unix_time(); if (!datafile_exists && !arg_opts.unencrypt_data) - first_time_encrypt("Creating new data file. Would you like to encrypt it? Y/n (q to quit)"); + first_time_encrypt(gettext("Creating new data file. Would you like to encrypt it? Y/n (q to quit)")); else if (arg_opts.encrypt_data) - first_time_encrypt("Encrypt existing data file? Y/n (q to quit)"); + first_time_encrypt(gettext("Encrypt existing data file? Y/n (q to quit)")); /* init user_settings struct and load settings from conf file */ user_settings = calloc(1, sizeof(struct user_settings)); if (user_settings == NULL) - exit_toxic_err("failed in main", FATALERR_MEMORY); + exit_toxic_err(gettext("failed in main"), FATALERR_MEMORY); const char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL; int settings_err = settings_load(user_settings, p); #ifdef X11 if (init_xtra(DnD_callback) == -1) - queue_init_message("X failed to initialize"); + queue_init_message(gettext("X failed to initialize")); #endif Tox *m = load_toxic(DATA_FILE); @@ -1119,14 +1143,14 @@ int main(int argc, char *argv[]) /* thread for ncurses stuff */ if (pthread_mutex_init(&Winthread.lock, NULL) != 0) - exit_toxic_err("failed in main", FATALERR_MUTEX_INIT); + exit_toxic_err(gettext("failed in main"), FATALERR_MUTEX_INIT); if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0) - exit_toxic_err("failed in main", FATALERR_THREAD_CREATE); + exit_toxic_err(gettext("failed in main"), FATALERR_THREAD_CREATE); /* thread for message queue */ if (pthread_create(&cqueue_thread.tid, NULL, thread_cqueue, (void *) m) != 0) - exit_toxic_err("failed in main", FATALERR_THREAD_CREATE); + exit_toxic_err(gettext("failed in main"), FATALERR_THREAD_CREATE); #ifdef AUDIO @@ -1134,14 +1158,14 @@ int main(int argc, char *argv[]) /* audio thread */ if (pthread_create(&audio_thread.tid, NULL, thread_audio, (void *) av) != 0) - exit_toxic_err("failed in main", FATALERR_THREAD_CREATE); + exit_toxic_err(gettext("failed in main"), FATALERR_THREAD_CREATE); set_primary_device(input, user_settings->audio_in_dev); set_primary_device(output, user_settings->audio_out_dev); #elif SOUND_NOTIFY if ( init_devices() == de_InternalError ) - queue_init_message("Failed to init audio devices"); + queue_init_message(gettext("Failed to init audio devices")); #endif /* AUDIO */ @@ -1150,16 +1174,16 @@ int main(int argc, char *argv[]) const char *msg; if (config_err) { - msg = "Unable to determine configuration directory. Defaulting to 'data' for data file..."; + msg = gettext("Unable to determine configuration directory. Defaulting to 'data' for data file..."); queue_init_message("%s", msg); } if (settings_err == -1) - queue_init_message("Failed to load user settings"); + queue_init_message(gettext("Failed to load user settings")); /* screen/tmux auto-away timer */ if (init_mplex_away_timer(m) == -1) - queue_init_message("Failed to init mplex auto-away."); + queue_init_message(gettext("Failed to init mplex auto-away.")); print_init_messages(prompt); cleanup_init_messages(); @@ -1182,7 +1206,7 @@ int main(int argc, char *argv[]) if (timed_out(last_save, cur_time, AUTOSAVE_FREQ)) { pthread_mutex_lock(&Winthread.lock); if (store_data(m, DATA_FILE) != 0) - line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, "WARNING: Failed to save to data file"); + line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext("WARNING: Failed to save to data file")); pthread_mutex_unlock(&Winthread.lock); last_save = cur_time; diff --git a/src/toxic.h b/src/toxic.h index 6129fab..0adb759 100644 --- a/src/toxic.h +++ b/src/toxic.h @@ -40,8 +40,8 @@ #include -#define UNKNOWN_NAME "Anonymous" -#define DEFAULT_TOX_NAME "Tox User" /* should always be the same as toxcore's default name */ +#define UNKNOWN_NAME gettext("Anonymous") +#define DEFAULT_TOX_NAME gettext("Tox User") /* should always be the same as toxcore's default name */ #define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH /* must be >= TOX_MAX_MESSAGE_LENGTH */ #define MAX_CMDNAME_SIZE 64 diff --git a/src/windows.c b/src/windows.c index de41a31..4075371 100644 --- a/src/windows.c +++ b/src/windows.c @@ -25,6 +25,12 @@ #include #include +#ifdef NO_GETTEXT +#define gettext(A) (A) +#else +#include +#endif + #include "friendlist.h" #include "prompt.h" #include "toxic.h" @@ -359,7 +365,7 @@ void set_next_window(int ch) return; if (active_window == inf) /* infinite loop check */ - exit_toxic_err("failed in set_next_window", FATALERR_INFLOOP); + exit_toxic_err(gettext("failed in set_next_window"), FATALERR_INFLOOP); } } @@ -381,7 +387,7 @@ ToxWindow *init_windows(Tox *m) int n_prompt = add_window(m, new_prompt()); if (n_prompt == -1 || add_window(m, new_friendlist()) == -1) - exit_toxic_err("failed in init_windows", FATALERR_WININIT); + exit_toxic_err(gettext("failed in init_windows"), FATALERR_WININIT); prompt = &windows[n_prompt]; active_window = prompt; diff --git a/translations/en.mo b/translations/en.mo new file mode 100644 index 0000000000000000000000000000000000000000..c30c0646ae437e00ea0a2b64515d56b7dc679837 GIT binary patch literal 28644 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 " +msgstr "Require: " + +#: ../src/global_commands.c:261 +msgid "Invalid port." +msgstr "Invalid port." + +#: ../src/global_commands.c:274 +msgid "Bootstrap failed: Invalid IP." +msgstr "Bootstrap failed: Invalid IP." + +#: ../src/global_commands.c:278 +msgid "Bootstrap failed: Invalid port." +msgstr "Bootstrap failed: Invalid port." + +#: ../src/global_commands.c:282 +msgid "Bootstrap failed." +msgstr "Bootstrap failed." + +#: ../src/global_commands.c:329 +#, c-format +msgid "Please specify group type: %s" +msgstr "Please specify group type: %s" + +#: ../src/global_commands.c:340 +#, c-format +msgid "Valid group types are: %s" +msgstr "Valid group types are: %s" + +#: ../src/global_commands.c:364 +#, c-format +msgid "Group chat [%d] created." +msgstr "Group chat [%d] created." + +#: ../src/global_commands.c:374 +msgid "Logging for this window is ON. Type \"/log off\" to disable." +msgstr "Logging for this window is ON. Type \"/log off\" to disable." + +#: ../src/global_commands.c:376 +msgid "Logging for this window is OFF. Type \"/log on\" to enable." +msgstr "Logging for this window is OFF. Type \"/log on\" to enable." + +#: ../src/global_commands.c:397 +msgid "Logging enabled" +msgstr "Logging enabled" + +#: ../src/global_commands.c:406 +msgid "Logging disabled" +msgstr "Logging disabled" + +#: ../src/global_commands.c:411 +#, c-format +msgid "Invalid option. Use \"%s\" to toggle logging." +msgstr "Invalid option. Use \"%s\" to toggle logging." + +#: ../src/global_commands.c:435 ../src/global_commands.c:468 +msgid "Input required." +msgstr "Input required." + +#: ../src/global_commands.c:452 +msgid "Invalid name." +msgstr "Invalid name." + +#: ../src/global_commands.c:473 ../src/global_commands.c:561 +msgid "Note must be enclosed in quotes." +msgstr "Note must be enclosed in quotes." + +#: ../src/global_commands.c:499 +msgid "No pending friend requests." +msgstr "No pending friend requests." + +#: ../src/global_commands.c:536 +#, c-format +msgid "Require a status. Statuses are: %s." +msgstr "Require a status. Statuses are: %s." + +#: ../src/global_commands.c:551 +#, c-format +msgid "Invalid status. Valid statuses are: %s." +msgstr "Invalid status. Valid statuses are: %s." + +#: ../src/group_commands.c:46 +#, c-format +msgid "Title is set to: %s" +msgstr "Title is set to: %s" + +#: ../src/group_commands.c:48 +msgid "Title is not set" +msgstr "Title is not set" + +#: ../src/group_commands.c:55 +msgid "Title must be enclosed in quotes." +msgstr "Title must be enclosed in quotes." + +#: ../src/group_commands.c:65 +msgid "Failed to set title." +msgstr "Failed to set title." + +#: ../src/group_commands.c:80 ../src/groupchat.c:337 +#, c-format +msgid " set the group title to: %s" +msgstr " set the group title to: %s" + +#: ../src/group_commands.c:83 ../src/groupchat.c:340 +#, c-format +msgid "set title to %s" +msgstr "set title to %s" + +#: ../src/groupchat.c:143 +msgid "failed in init_groupchat_win" +msgstr "failed in init_groupchat_win" + +#: ../src/groupchat.c:151 +#, c-format +msgid "Group Audio failed to init\n" +msgstr "Group Audio failed to init\n" + +#: ../src/groupchat.c:362 +msgid "failed in copy_peernames" +msgstr "failed in copy_peernames" + +#: ../src/groupchat.c:419 +msgid "has joined the room" +msgstr "has joined the room" + +#: ../src/groupchat.c:517 +msgid "has left the room" +msgstr "has left the room" + +#: ../src/groupchat.c:534 +msgid " is now known as " +msgstr " is now known as " + +#: ../src/groupchat.c:538 +#, c-format +msgid "is now known as %s" +msgstr "is now known as %s" + +#: ../src/groupchat.c:549 +msgid "Invalid syntax.\n" +msgstr "Invalid syntax.\n" + +#: ../src/groupchat.c:554 +msgid " * Failed to send action." +msgstr " * Failed to send action." + +#: ../src/groupchat.c:641 +msgid " * Failed to send message." +msgstr " * Failed to send message." + +#: ../src/groupchat.c:678 +#, c-format +msgid "Peers: %d\n" +msgstr "Peers: %d\n" + +#: ../src/groupchat.c:728 +msgid "failed in groupchat_onInit" +msgstr "failed in groupchat_onInit" + +#: ../src/groupchat.c:813 +#, c-format +msgid "source: %d, queued: %d, processed: %d\n" +msgstr "source: %d, queued: %d, processed: %d\n" + +#: ../src/groupchat.c:852 +#, c-format +msgid "dvhandle is null)\n" +msgstr "dvhandle is null)\n" + +#: ../src/groupchat.c:855 +#, c-format +msgid "ctx is null\n" +msgstr "ctx is null\n" + +#: ../src/groupchat.c:858 +#, c-format +msgid "write: %d\n" +msgstr "write: %d\n" + +#: ../src/groupchat.c:882 +#, c-format +msgid "Group %d" +msgstr "Group %d" + +#: ../src/groupchat.c:888 +msgid "failed in new_group_chat" +msgstr "failed in new_group_chat" + +#: ../src/help.c:148 +msgid "Global Commands:\n" +msgstr "Global Commands:\n" + +#: ../src/help.c:152 +msgid "Add contact with optional message\n" +msgstr "Add contact with optional message\n" + +#: ../src/help.c:154 +msgid "Accept friend request\n" +msgstr "Accept friend request\n" + +#: ../src/help.c:156 +msgid "Set an avatar (leave path empty to unset)\n" +msgstr "Set an avatar (leave path empty to unset)\n" + +#: ../src/help.c:158 +msgid "Decline friend request\n" +msgstr "Decline friend request\n" + +#: ../src/help.c:160 +msgid "List pending friend requests\n" +msgstr "List pending friend requests\n" + +#: ../src/help.c:162 +msgid "Manually connect to a DHT node\n" +msgstr "Manually connect to a DHT node\n" + +#: ../src/help.c:164 +msgid "Set status with optional note\n" +msgstr "Set status with optional note\n" + +#: ../src/help.c:166 +msgid "Set a personal note\n" +msgstr "Set a personal note\n" + +#: ../src/help.c:168 +msgid "Set your nickname\n" +msgstr "Set your nickname\n" + +#: ../src/help.c:170 +msgid "Enable/disable logging\n" +msgstr "Enable/disable logging\n" + +#: ../src/help.c:172 +msgid "Create a group chat where type: text | audio\n" +msgstr "Create a group chat where type: text | audio\n" + +#: ../src/help.c:174 +msgid "Print your Tox ID\n" +msgstr "Print your Tox ID\n" + +#: ../src/help.c:176 +msgid "Clear window history\n" +msgstr "Clear window history\n" + +#: ../src/help.c:178 +msgid "Close the current chat window\n" +msgstr "Close the current chat window\n" + +#: ../src/help.c:180 +msgid "Exit Toxic\n" +msgstr "Exit Toxic\n" + +#: ../src/help.c:184 ../src/help.c:224 +msgid "" +"\n" +" Audio:\n" +msgstr "" +"\n" +" Audio:\n" + +#: ../src/help.c:188 +msgid "List devices where type:" +msgstr "List devices where type:" + +#: ../src/help.c:191 +msgid "Set active device\n" +msgstr "Set active device\n" + +#: ../src/help.c:207 +msgid "Chat Commands:\n" +msgstr "Chat Commands:\n" + +#: ../src/help.c:211 +msgid "Invite contact to a group chat\n" +msgstr "Invite contact to a group chat\n" + +#: ../src/help.c:213 +msgid "Join a pending group chat\n" +msgstr "Join a pending group chat\n" + +#: ../src/help.c:215 +msgid "Send a file\n" +msgstr "Send a file\n" + +#: ../src/help.c:217 +msgid "Receive a file\n" +msgstr "Receive a file\n" + +#: ../src/help.c:219 +msgid "Cancel file transfer where type:" +msgstr "Cancel file transfer where type:" + +#: ../src/help.c:228 +msgid "Audio call\n" +msgstr "Audio call\n" + +#: ../src/help.c:230 +msgid "Answer incoming call\n" +msgstr "Answer incoming call\n" + +#: ../src/help.c:232 +msgid "Reject incoming call\n" +msgstr "Reject incoming call\n" + +#: ../src/help.c:234 +msgid "Hangup active call\n" +msgstr "Hangup active call\n" + +#: ../src/help.c:236 +msgid "Change active device\n" +msgstr "Change active device\n" + +#: ../src/help.c:238 +msgid "Mute active device if in call\n" +msgstr "Mute active device if in call\n" + +#: ../src/help.c:240 +msgid "VAD sensitivity threshold\n" +msgstr "VAD sensitivity threshold\n" + +#: ../src/help.c:256 +msgid "Key bindings:\n" +msgstr "Key bindings:\n" + +#: ../src/help.c:260 +msgid "Navigate through the tabs\n" +msgstr "Navigate through the tabs\n" + +#: ../src/help.c:262 +msgid "Scroll window history one line\n" +msgstr "Scroll window history one line\n" + +#: ../src/help.c:264 +msgid "Scroll window history half a page\n" +msgstr "Scroll window history half a page\n" + +#: ../src/help.c:266 +msgid "Move to the bottom of window history\n" +msgstr "Move to the bottom of window history\n" + +#: ../src/help.c:268 +msgid "Scroll peer list in groupchats\n" +msgstr "Scroll peer list in groupchats\n" + +#: ../src/help.c:270 +msgid "" +"Toggle the groupchat peerlist\n" +"\n" +msgstr "" +"Toggle the groupchat peerlist\n" +"\n" + +#: ../src/help.c:271 +msgid "" +" (Note: Custom keybindings override these defaults.)\n" +"\n" +msgstr "" +" (Note: Custom keybindings override these defaults.)\n" +"\n" + +#: ../src/help.c:286 +msgid "Group commands:\n" +msgstr "Group commands:\n" + +#: ../src/help.c:290 +msgid "" +"Set group title (show current title if no msg)\n" +"\n" +msgstr "" +"Set group title (show current title if no msg)\n" +"\n" + +#: ../src/help.c:305 +msgid "Friendlist controls:\n" +msgstr "Friendlist controls:\n" + +#: ../src/help.c:308 +msgid " Up and Down arrows : Scroll through list\n" +msgstr " Up and Down arrows : Scroll through list\n" + +#: ../src/help.c:309 +msgid "" +" Right and Left arrows : Switch between friendlist and blocked " +"list\n" +msgstr "" +" Right and Left arrows : Switch between friendlist and blocked " +"list\n" + +#: ../src/help.c:310 +msgid "" +" Enter : Open a chat window with selected contact\n" +msgstr "" +" Enter : Open a chat window with selected contact\n" + +#: ../src/help.c:311 +msgid " Delete : Permanently delete a contact\n" +msgstr " Delete : Permanently delete a contact\n" + +#: ../src/help.c:313 +msgid "Block or unblock a contact\n" +msgstr "Block or unblock a contact\n" + +#: ../src/line_info.c:50 +msgid "failed in line_info_init" +msgstr "failed in line_info_init" + +#: ../src/line_info.c:150 +msgid "failed in line_info_add" +msgstr "failed in line_info_add" + +#: ../src/log.c:189 +msgid "failed in load_chat_history" +msgstr "failed in load_chat_history" + +#: ../src/log.c:193 ../src/log.c:199 +msgid " * Failed to read log file" +msgstr " * Failed to read log file" + +#: ../src/message_queue.c:56 +msgid "failed in cqueue_message" +msgstr "failed in cqueue_message" + +#: ../src/misc_tools.c:240 ../src/misc_tools.c:248 +msgid "failed in get_file_name" +msgstr "failed in get_file_name" + +#: ../src/prompt.c:139 +#, c-format +msgid "Failed to set note (error %d)\n" +msgstr "Failed to set note (error %d)\n" + +#: ../src/prompt.c:271 +msgid "ERROR" +msgstr "ERROR" + +#: ../src/prompt.c:275 +msgid "Online" +msgstr "Online" + +#: ../src/prompt.c:279 +msgid "Away" +msgstr "Away" + +#: ../src/prompt.c:283 +msgid "Busy" +msgstr "Busy" + +#: ../src/prompt.c:296 +msgid " [Offline]" +msgstr " [Offline]" + +#: ../src/prompt.c:366 ../src/prompt.c:369 +#, c-format +msgid "%s has come online" +msgstr "%s has come online" + +#: ../src/prompt.c:378 ../src/prompt.c:381 +#, c-format +msgid "%s has gone offline" +msgstr "%s has gone offline" + +#: ../src/prompt.c:392 ../src/prompt.c:393 +#, c-format +msgid "Friend request with the message '%s'" +msgstr "Friend request with the message '%s'" + +#: ../src/prompt.c:398 +msgid "Friend request queue is full. Discarding request." +msgstr "Friend request queue is full. Discarding request." + +#: ../src/prompt.c:403 +#, c-format +msgid "Type \"%s %d\" or \"%s %d\"" +msgstr "Type \"%s %d\" or \"%s %d\"" + +#: ../src/prompt.c:432 ../src/prompt.c:433 +#, c-format +msgid "Toxing on Toxic" +msgstr "Toxing on Toxic" + +#: ../src/prompt.c:455 +msgid "" +"Welcome to Toxic, a free, open source Tox-based instant messenging client." +msgstr "" +"Welcome to Toxic, a free, open source Tox-based instant messenging client." + +#: ../src/prompt.c:457 +#, c-format +msgid "Type \"%s\" for assistance. Further help may be found via the man page." +msgstr "" +"Type \"%s\" for assistance. Further help may be found via the man page." + +#: ../src/prompt.c:476 +msgid "failed in prompt_onInit" +msgstr "failed in prompt_onInit" + +#: ../src/prompt.c:514 +msgid "failed in new_prompt" +msgstr "failed in new_prompt" + +#: ../src/toxic.c:112 +#, c-format +msgid "Caught SIGSEGV: Aborting toxic session.\n" +msgstr "Caught SIGSEGV: Aborting toxic session.\n" + +#: ../src/toxic.c:161 +#, c-format +msgid "Toxic session aborted with error code %d (%s)\n" +msgstr "Toxic session aborted with error code %d (%s)\n" + +#: ../src/toxic.c:171 +msgid "" +"Could not set your locale, please check your locale settings or disable " +"unicode support with the -d flag." +msgstr "" +"Could not set your locale, please check your locale settings or disable " +"unicode support with the -d flag." + +#: ../src/toxic.c:231 ../src/toxic.c:236 +msgid "Failed in queue_init_message" +msgstr "Failed in queue_init_message" + +#: ../src/toxic.c:328 +#, c-format +msgid "Failed to bootstrap %s:%d\n" +msgstr "Failed to bootstrap %s:%d\n" + +#: ../src/toxic.c:335 +#, c-format +msgid "Failed to add TCP relay %s:%d\n" +msgstr "Failed to add TCP relay %s:%d\n" + +#: ../src/toxic.c:466 +#, c-format +msgid "Enter a new password (must be at least %d characters) " +msgstr "Enter a new password (must be at least %d characters) " + +#: ../src/toxic.c:476 +#, c-format +msgid "Password must be between %d and %d characters long. " +msgstr "Password must be between %d and %d characters long. " + +#: ../src/toxic.c:481 +#, c-format +msgid "Enter password again " +msgstr "Enter password again " + +#: ../src/toxic.c:489 +#, c-format +msgid "Passwords don't match. Try again. " +msgstr "Passwords don't match. Try again. " + +#: ../src/toxic.c:496 +#, c-format +msgid "Data file '%s' is encrypted" +msgstr "Data file '%s' is encrypted" + +#: ../src/toxic.c:533 +#, c-format +msgid "tox_pass_encrypt() failed with error %d\n" +msgstr "tox_pass_encrypt() failed with error %d\n" + +#: ../src/toxic.c:584 +msgid "Forcing IPv4 connection" +msgstr "Forcing IPv4 connection" + +#: ../src/toxic.c:592 +#, c-format +msgid "Using %s proxy %s : %d" +msgstr "Using %s proxy %s : %d" + +#: ../src/toxic.c:597 +msgid "UDP disabled" +msgstr "UDP disabled" + +#: ../src/toxic.c:599 +msgid "" +"WARNING: Using a proxy without disabling UDP may leak your real IP address." +msgstr "" +"WARNING: Using a proxy without disabling UDP may leak your real IP address." + +#: ../src/toxic.c:601 +msgid "Use the -t option to disable UDP." +msgstr "Use the -t option to disable UDP." + +#: ../src/toxic.c:620 ../src/toxic.c:627 ../src/toxic.c:635 ../src/toxic.c:712 +#: ../src/toxic.c:722 +msgid "failed in load_toxic" +msgstr "failed in load_toxic" + +#: ../src/toxic.c:639 +#, c-format +msgid "Data file '%s' has been unencrypted" +msgstr "Data file '%s' has been unencrypted" + +#: ../src/toxic.c:641 +#, c-format +msgid "Warning: passed --unencrypt-data option with unencrypted data file '%s'" +msgstr "" +"Warning: passed --unencrypt-data option with unencrypted data file '%s'" + +#: ../src/toxic.c:649 +#, c-format +msgid "Enter password (\"%s\" to quit) " +msgstr "Enter password (\"%s\" to quit) " + +#: ../src/toxic.c:666 ../src/toxic.c:690 +#, c-format +msgid "Invalid password. Try again. " +msgstr "Invalid password. Try again. " + +#: ../src/toxic.c:693 +msgid "tox_pass_decrypt() failed" +msgstr "tox_pass_decrypt() failed" + +#: ../src/toxic.c:737 +msgid "Falling back to ipv4" +msgstr "Falling back to ipv4" + +#: ../src/toxic.c:743 +msgid "tox_new returned fatal error" +msgstr "tox_new returned fatal error" + +#: ../src/toxic.c:746 +#, c-format +msgid "tox_new returned non-fatal error %d" +msgstr "tox_new returned non-fatal error %d" + +#: ../src/toxic.c:753 +msgid "Toxic User" +msgstr "Toxic User" + +#: ../src/toxic.c:779 +#, c-format +msgid "Auto-connect failed with error code %d" +msgstr "Auto-connect failed with error code %d" + +#: ../src/toxic.c:860 +#, c-format +msgid "usage: toxic [OPTION] [FILE ...]\n" +msgstr "usage: toxic [OPTION] [FILE ...]\n" + +#: ../src/toxic.c:862 +#, c-format +msgid "Force IPv4 connection\n" +msgstr "Force IPv4 connection\n" + +#: ../src/toxic.c:864 +#, c-format +msgid "Enable stderr for debugging\n" +msgstr "Enable stderr for debugging\n" + +#: ../src/toxic.c:866 +#, c-format +msgid "Use specified config file\n" +msgstr "Use specified config file\n" + +#: ../src/toxic.c:868 +#, c-format +msgid "Use default POSIX locale\n" +msgstr "Use default POSIX locale\n" + +#: ../src/toxic.c:870 +#, c-format +msgid "Encrypt an unencrypted data file\n" +msgstr "Encrypt an unencrypted data file\n" + +#: ../src/toxic.c:872 +#, c-format +msgid "Use specified data file\n" +msgstr "Use specified data file\n" + +#: ../src/toxic.c:874 +#, c-format +msgid "Show this message and exit\n" +msgstr "Show this message and exit\n" + +#: ../src/toxic.c:876 +#, c-format +msgid "Use specified DHTnodes file\n" +msgstr "Use specified DHTnodes file\n" + +#: ../src/toxic.c:878 +#, c-format +msgid "Do not connect to the DHT network\n" +msgstr "Do not connect to the DHT network\n" + +#: ../src/toxic.c:880 +#, c-format +msgid "Use SOCKS5 proxy: Requires [IP] [port]\n" +msgstr "Use SOCKS5 proxy: Requires [IP] [port]\n" + +#: ../src/toxic.c:882 +#, c-format +msgid "Use HTTP proxy: Requires [IP] [port]\n" +msgstr "Use HTTP proxy: Requires [IP] [port]\n" + +#: ../src/toxic.c:884 +#, c-format +msgid "Use specified DNSservers file\n" +msgstr "Use specified DNSservers file\n" + +#: ../src/toxic.c:886 +#, c-format +msgid "Force TCP connection (use this with proxies)\n" +msgstr "Force TCP connection (use this with proxies)\n" + +#: ../src/toxic.c:888 +#, c-format +msgid "Unencrypt an encrypted data file\n" +msgstr "Unencrypt an encrypted data file\n" + +#: ../src/toxic.c:932 +msgid "stderr enabled" +msgstr "stderr enabled" + +#: ../src/toxic.c:939 +msgid "Config file not found" +msgstr "Config file not found" + +#: ../src/toxic.c:945 +msgid "Using default POSIX locale" +msgstr "Using default POSIX locale" + +#: ../src/toxic.c:958 +msgid "failed in parse_args" +msgstr "failed in parse_args" + +#: ../src/toxic.c:963 +#, c-format +msgid "Using '%s' data file" +msgstr "Using '%s' data file" + +#: ../src/toxic.c:971 +msgid "DHTnodes file not found" +msgstr "DHTnodes file not found" + +#: ../src/toxic.c:977 +msgid "DHT disabled" +msgstr "DHT disabled" + +#: ../src/toxic.c:985 ../src/toxic.c:995 +msgid "Proxy error" +msgstr "Proxy error" + +#: ../src/toxic.c:1004 +msgid "DNSservers file not found" +msgstr "DNSservers file not found" + +#: ../src/toxic.c:1101 +#, c-format +msgid "Warning: Using \"%s\" and \"%s\" simultaneously has no effect" +msgstr "Warning: Using \"%s\" and \"%s\" simultaneously has no effect" + +#: ../src/toxic.c:1114 +msgid "Creating new data file. Would you like to encrypt it? Y/n (q to quit)" +msgstr "Creating new data file. Would you like to encrypt it? Y/n (q to quit)" + +#: ../src/toxic.c:1116 +msgid "Encrypt existing data file? Y/n (q to quit)" +msgstr "Encrypt existing data file? Y/n (q to quit)" + +#: ../src/toxic.c:1123 ../src/toxic.c:1146 ../src/toxic.c:1149 +#: ../src/toxic.c:1153 ../src/toxic.c:1161 +msgid "failed in main" +msgstr "failed in main" + +#: ../src/toxic.c:1130 +msgid "X failed to initialize" +msgstr "X failed to initialize" + +#: ../src/toxic.c:1168 +msgid "Failed to init audio devices" +msgstr "Failed to init audio devices" + +#: ../src/toxic.c:1177 +msgid "" +"Unable to determine configuration directory. Defaulting to 'data' for data " +"file..." +msgstr "" +"Unable to determine configuration directory. Defaulting to 'data' for data " +"file..." + +#: ../src/toxic.c:1182 +msgid "Failed to load user settings" +msgstr "Failed to load user settings" + +#: ../src/toxic.c:1186 +msgid "Failed to init mplex auto-away." +msgstr "Failed to init mplex auto-away." + +#: ../src/toxic.c:1209 +msgid "WARNING: Failed to save to data file" +msgstr "WARNING: Failed to save to data file" + +#: ../src/toxic.h:43 +msgid "Anonymous" +msgstr "Anonymous" + +#: ../src/toxic.h:44 +msgid "Tox User" +msgstr "Tox User" + +#: ../src/windows.c:368 +msgid "failed in set_next_window" +msgstr "failed in set_next_window" + +#: ../src/windows.c:390 +msgid "failed in init_windows" +msgstr "failed in init_windows" diff --git a/translations/it.mo b/translations/it.mo new file mode 100644 index 0000000000000000000000000000000000000000..a7aaff16b0085e79ff2c15ad3b6dfc55088ae8ba GIT binary patch literal 30657 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 OOaNQsrhNZ " +msgstr "Richiede: " + +#: ../src/global_commands.c:261 +msgid "Invalid port." +msgstr "Porta non valida." + +#: ../src/global_commands.c:274 +msgid "Bootstrap failed: Invalid IP." +msgstr "Bootstrap fallito: IP non valido." + +#: ../src/global_commands.c:278 +msgid "Bootstrap failed: Invalid port." +msgstr "Bootstrap fallito: porta non valida." + +#: ../src/global_commands.c:282 +msgid "Bootstrap failed." +msgstr "Bootstrap fallito." + +#: ../src/global_commands.c:329 +#, c-format +msgid "Please specify group type: %s" +msgstr "Specifica il tipo di chat di gruppo: %s" + +#: ../src/global_commands.c:340 +#, c-format +msgid "Valid group types are: %s" +msgstr "I tipi di chat di gruppo permessi sono: %s" + +#: ../src/global_commands.c:364 +#, c-format +msgid "Group chat [%d] created." +msgstr "Chat di gruppo [%d] creata." + +#: ../src/global_commands.c:374 +msgid "Logging for this window is ON. Type \"/log off\" to disable." +msgstr "" +"La cronologia chat per questa finestra è ON. Usa \"/log off\" per " +"disabilitarla." + +#: ../src/global_commands.c:376 +msgid "Logging for this window is OFF. Type \"/log on\" to enable." +msgstr "" +"La cronologia chat per questa finestra è OFF. Usa \"/log on\" per abilitarla." + +#: ../src/global_commands.c:397 +msgid "Logging enabled" +msgstr "Cronologia chat abilitata" + +#: ../src/global_commands.c:406 +msgid "Logging disabled" +msgstr "Cronologia chat disabilitata" + +#: ../src/global_commands.c:411 +#, c-format +msgid "Invalid option. Use \"%s\" to toggle logging." +msgstr "Opzione non valida. Usa \"%s\" per impostare la cronologia chat." + +#: ../src/global_commands.c:435 ../src/global_commands.c:468 +msgid "Input required." +msgstr "Input richiesto." + +#: ../src/global_commands.c:452 +msgid "Invalid name." +msgstr "Nome non valido." + +#: ../src/global_commands.c:473 ../src/global_commands.c:561 +msgid "Note must be enclosed in quotes." +msgstr "Il messaggio di stato deve essere tra virgolette." + +#: ../src/global_commands.c:499 +msgid "No pending friend requests." +msgstr "Nessuna richiesta d'amicizia in sospeso." + +#: ../src/global_commands.c:536 +#, c-format +msgid "Require a status. Statuses are: %s." +msgstr "Richiede uno stato. Gli stati sono: %s." + +#: ../src/global_commands.c:551 +#, c-format +msgid "Invalid status. Valid statuses are: %s." +msgstr "Stato non valido. Gli stati disponibilit sono: %s." + +#: ../src/group_commands.c:46 +#, c-format +msgid "Title is set to: %s" +msgstr "Titolo impostato a: \"%s\"" + +#: ../src/group_commands.c:48 +msgid "Title is not set" +msgstr "Titolo non impostato" + +#: ../src/group_commands.c:55 +msgid "Title must be enclosed in quotes." +msgstr "Il titolo deve essere tra virgolette." + +#: ../src/group_commands.c:65 +msgid "Failed to set title." +msgstr "Errore nell'impostare il titolo." + +#: ../src/group_commands.c:80 ../src/groupchat.c:337 +#, c-format +msgid " set the group title to: %s" +msgstr " ha impostato il titolo a: \"%s\"" + +#: ../src/group_commands.c:83 ../src/groupchat.c:340 +#, c-format +msgid "set title to %s" +msgstr "ha impostato il titolo a \"%s\"" + +#: ../src/groupchat.c:143 +msgid "failed in init_groupchat_win" +msgstr "errore in \"init_groupchat_win\"" + +#: ../src/groupchat.c:151 +#, c-format +msgid "Group Audio failed to init\n" +msgstr "Inizializzazione fallita delle chat di gruppo audio\n" + +#: ../src/groupchat.c:362 +msgid "failed in copy_peernames" +msgstr "errore in \"copy_peernames\"" + +#: ../src/groupchat.c:419 +msgid "has joined the room" +msgstr "è entrato nella chat" + +#: ../src/groupchat.c:517 +msgid "has left the room" +msgstr "ha lasciato la chat" + +#: ../src/groupchat.c:534 +msgid " is now known as " +msgstr " è ora conosciuto come " + +#: ../src/groupchat.c:538 +#, c-format +msgid "is now known as %s" +msgstr "è ora conosciuto come %s" + +#: ../src/groupchat.c:549 +msgid "Invalid syntax.\n" +msgstr "Sintassi non valida.\n" + +#: ../src/groupchat.c:554 +msgid " * Failed to send action." +msgstr " * Errore nell'inviare l'azione." + +#: ../src/groupchat.c:641 +msgid " * Failed to send message." +msgstr " * Errore nell'inviare il messaggio." + +#: ../src/groupchat.c:678 +#, c-format +msgid "Peers: %d\n" +msgstr "Utenti: %d\n" + +#: ../src/groupchat.c:728 +msgid "failed in groupchat_onInit" +msgstr "errore in \"groupchat_onInit\"" + +#: ../src/groupchat.c:813 +#, c-format +msgid "source: %d, queued: %d, processed: %d\n" +msgstr "sorgente: %d, coda: %d, processati: %d\n" + +#: ../src/groupchat.c:852 +#, c-format +msgid "dvhandle is null)\n" +msgstr "\"dvhandle\" è null)\n" + +#: ../src/groupchat.c:855 +#, c-format +msgid "ctx is null\n" +msgstr "\"ctx\" è null\n" + +#: ../src/groupchat.c:858 +#, c-format +msgid "write: %d\n" +msgstr "scritto: %d\n" + +#: ../src/groupchat.c:882 +#, c-format +msgid "Group %d" +msgstr "Chat di gruppo %d" + +#: ../src/groupchat.c:888 +msgid "failed in new_group_chat" +msgstr "errore in \"new_group_chat\"" + +#: ../src/help.c:148 +msgid "Global Commands:\n" +msgstr "Comandi Globali:\n" + +#: ../src/help.c:152 +msgid "Add contact with optional message\n" +msgstr "Aggiungi contatto con un messaggio opzionale\n" + +#: ../src/help.c:154 +msgid "Accept friend request\n" +msgstr "Accetta richiesta d'amicizia\n" + +#: ../src/help.c:156 +msgid "Set an avatar (leave path empty to unset)\n" +msgstr "Imposta un avatar (lascia vuoto per resettare)\n" + +#: ../src/help.c:158 +msgid "Decline friend request\n" +msgstr "Rifiuta richiesta d'amicizia\n" + +#: ../src/help.c:160 +msgid "List pending friend requests\n" +msgstr "Mostra le richieste d'amicizia in sospeso\n" + +#: ../src/help.c:162 +msgid "Manually connect to a DHT node\n" +msgstr "Connettiti manualmente ad un nodo DHT\n" + +#: ../src/help.c:164 +msgid "Set status with optional note\n" +msgstr "Imposta lo stato con un messaggio opzionale\n" + +#: ../src/help.c:166 +msgid "Set a personal note\n" +msgstr "Imposta il messaggio di stato\n" + +#: ../src/help.c:168 +msgid "Set your nickname\n" +msgstr "Imposta il nickname\n" + +#: ../src/help.c:170 +msgid "Enable/disable logging\n" +msgstr "Abilita/disabilita cronologia chat\n" + +#: ../src/help.c:172 +msgid "Create a group chat where type: text | audio\n" +msgstr "Crea una caht di gruppo di tipo: text|audio\n" + +#: ../src/help.c:174 +msgid "Print your Tox ID\n" +msgstr "Mostra il tuo Tox ID\n" + +#: ../src/help.c:176 +msgid "Clear window history\n" +msgstr "Pulisce la cronologia della finestra\n" + +#: ../src/help.c:178 +msgid "Close the current chat window\n" +msgstr "Chiude la fiestra di chat corrente\n" + +#: ../src/help.c:180 +msgid "Exit Toxic\n" +msgstr "Esce da Toxic\n" + +#: ../src/help.c:184 ../src/help.c:224 +msgid "" +"\n" +" Audio:\n" +msgstr "" +"\n" +" Audio:\n" + +#: ../src/help.c:188 +msgid "List devices where type:" +msgstr "Mostra i dispositivi di tipo:" + +#: ../src/help.c:191 +msgid "Set active device\n" +msgstr "Imposta il device attivo\n" + +#: ../src/help.c:207 +msgid "Chat Commands:\n" +msgstr "Comandi Chat:\n" + +#: ../src/help.c:211 +msgid "Invite contact to a group chat\n" +msgstr "Invita un contatto ad una chat di gruppo\n" + +#: ../src/help.c:213 +msgid "Join a pending group chat\n" +msgstr "Unisciti ad una chat di gruppo a cui sei stato invitato\n" + +#: ../src/help.c:215 +msgid "Send a file\n" +msgstr "Invia un file\n" + +#: ../src/help.c:217 +msgid "Receive a file\n" +msgstr "Accetta la ricezione di un file\n" + +#: ../src/help.c:219 +msgid "Cancel file transfer where type:" +msgstr "Annulla trasferimento file di tipo:" + +#: ../src/help.c:228 +msgid "Audio call\n" +msgstr "Chiamata audio\n" + +#: ../src/help.c:230 +msgid "Answer incoming call\n" +msgstr "Rispondi ad una chiamata\n" + +#: ../src/help.c:232 +msgid "Reject incoming call\n" +msgstr "Rifiuta una chiamata\n" + +#: ../src/help.c:234 +msgid "Hangup active call\n" +msgstr "Termina una chiamata attiva\n" + +#: ../src/help.c:236 +msgid "Change active device\n" +msgstr "Cambia il dispositivo attivo\n" + +#: ../src/help.c:238 +msgid "Mute active device if in call\n" +msgstr "Disabilita il dispositivo attivo mentre sei in una chiamata\n" + +#: ../src/help.c:240 +msgid "VAD sensitivity threshold\n" +msgstr "Sensibilità VAD\n" + +#: ../src/help.c:256 +msgid "Key bindings:\n" +msgstr "Mappatura tasti:\n" + +#: ../src/help.c:260 +msgid "Navigate through the tabs\n" +msgstr "Naviga tra le schede\n" + +#: ../src/help.c:262 +msgid "Scroll window history one line\n" +msgstr "Scorri la cronologia della finestra di una riga\n" + +#: ../src/help.c:264 +msgid "Scroll window history half a page\n" +msgstr "Scorri la cronologia della finestra di metà pagina\n" + +#: ../src/help.c:266 +msgid "Move to the bottom of window history\n" +msgstr "Vai in fondo alla finestra\n" + +#: ../src/help.c:268 +msgid "Scroll peer list in groupchats\n" +msgstr "Scorre la lista utenti nelle chat di gruppo\n" + +#: ../src/help.c:270 +msgid "" +"Toggle the groupchat peerlist\n" +"\n" +msgstr "" +"Mostra/nasconde la lista degli utenti nelle chat di gruppo\n" +"\n" + +#: ../src/help.c:271 +msgid "" +" (Note: Custom keybindings override these defaults.)\n" +"\n" +msgstr "" +" (Nota: mappature personalizzate sovrascrivono i defaults.)\n" +"\n" + +#: ../src/help.c:286 +msgid "Group commands:\n" +msgstr "Comandi chat di gruppo:\n" + +#: ../src/help.c:290 +msgid "" +"Set group title (show current title if no msg)\n" +"\n" +msgstr "" +"Imposta il titolo (mostra il titolo corrente se non è specificato niente)\n" +"\n" + +#: ../src/help.c:305 +msgid "Friendlist controls:\n" +msgstr "Controllo lista contatti:\n" + +#: ../src/help.c:308 +msgid " Up and Down arrows : Scroll through list\n" +msgstr " Frecce Su e Giù : Scorri la lista\n" + +#: ../src/help.c:309 +msgid "" +" Right and Left arrows : Switch between friendlist and blocked " +"list\n" +msgstr "" +" Frecce Destra e Sinistra : Cambia tra lista contatti e lista " +"bloccati\n" + +#: ../src/help.c:310 +msgid "" +" Enter : Open a chat window with selected contact\n" +msgstr "" +" Invio : Apre una finestra di chat con il contatto " +"selezionato\n" + +#: ../src/help.c:311 +msgid " Delete : Permanently delete a contact\n" +msgstr "" +" Canc : Elimina un contatto definitivamente\n" + +#: ../src/help.c:313 +msgid "Block or unblock a contact\n" +msgstr "Blocca o sblocca un contatto\n" + +#: ../src/line_info.c:50 +msgid "failed in line_info_init" +msgstr "errore in \"line_info_init\"" + +#: ../src/line_info.c:150 +msgid "failed in line_info_add" +msgstr "errore in \"line_info_add\"" + +#: ../src/log.c:189 +msgid "failed in load_chat_history" +msgstr "errore in \"load_chat_history\"" + +#: ../src/log.c:193 ../src/log.c:199 +msgid " * Failed to read log file" +msgstr " * Errore nel leggere il file della cronologia chat" + +#: ../src/message_queue.c:56 +msgid "failed in cqueue_message" +msgstr "errore in \"cqueue_message\"" + +#: ../src/misc_tools.c:240 ../src/misc_tools.c:248 +msgid "failed in get_file_name" +msgstr "errore in \"get_file_name\"" + +#: ../src/prompt.c:139 +#, c-format +msgid "Failed to set note (error %d)\n" +msgstr "Errore nell'impostare il messaggio di stato (errore %d)\n" + +#: ../src/prompt.c:271 +msgid "ERROR" +msgstr "ERRORE" + +#: ../src/prompt.c:275 +msgid "Online" +msgstr "Online" + +#: ../src/prompt.c:279 +msgid "Away" +msgstr "Assente" + +#: ../src/prompt.c:283 +msgid "Busy" +msgstr "Occupato" + +#: ../src/prompt.c:296 +msgid " [Offline]" +msgstr " [Offline]" + +#: ../src/prompt.c:366 ../src/prompt.c:369 +#, c-format +msgid "%s has come online" +msgstr "%s si è connesso" + +#: ../src/prompt.c:378 ../src/prompt.c:381 +#, c-format +msgid "%s has gone offline" +msgstr "%s si è disconnesso" + +#: ../src/prompt.c:392 ../src/prompt.c:393 +#, c-format +msgid "Friend request with the message '%s'" +msgstr "Richiesta d'amicizia con il messaggio '%s'" + +#: ../src/prompt.c:398 +msgid "Friend request queue is full. Discarding request." +msgstr "Coda delle richieste d'amicizia piena. Richiesta scartata." + +#: ../src/prompt.c:403 +#, c-format +msgid "Type \"%s %d\" or \"%s %d\"" +msgstr "Scrivi \"%s %d\" o \"%s %d\"" + +#: ../src/prompt.c:432 ../src/prompt.c:433 +#, c-format +msgid "Toxing on Toxic" +msgstr "Toxing on Toxic" + +#: ../src/prompt.c:455 +msgid "" +"Welcome to Toxic, a free, open source Tox-based instant messenging client." +msgstr "Benvenuto in Toxic, un client gratis e open source per la rete Tox." + +#: ../src/prompt.c:457 +#, c-format +msgid "Type \"%s\" for assistance. Further help may be found via the man page." +msgstr "" +"Usa \"%s\" per ricevere assistenza. Ulteriori aiuto può essere ottenuto " +"attraverso la pagina di manuale." + +#: ../src/prompt.c:476 +msgid "failed in prompt_onInit" +msgstr "errore in \"prompt_onInit\"" + +#: ../src/prompt.c:514 +msgid "failed in new_prompt" +msgstr "errore in \"new_prompt\"" + +#: ../src/toxic.c:112 +#, c-format +msgid "Caught SIGSEGV: Aborting toxic session.\n" +msgstr "Ricevuto segnale SIGSEGV: chiudo sessione.\n" + +#: ../src/toxic.c:161 +#, c-format +msgid "Toxic session aborted with error code %d (%s)\n" +msgstr "Sessio ciusa con errore %d (%s)\n" + +#: ../src/toxic.c:171 +msgid "" +"Could not set your locale, please check your locale settings or disable " +"unicode support with the -d flag." +msgstr "" +"Impossibile impostare la localizzazione, controlla le impostazione o " +"disabilita il supporto unicode con l'opzione \"-d\"." + +#: ../src/toxic.c:231 ../src/toxic.c:236 +msgid "Failed in queue_init_message" +msgstr "errore in \"queue_init_message\"" + +#: ../src/toxic.c:328 +#, c-format +msgid "Failed to bootstrap %s:%d\n" +msgstr "Bootstrap fallito %s:%d\n" + +#: ../src/toxic.c:335 +#, c-format +msgid "Failed to add TCP relay %s:%d\n" +msgstr "Errore aggiungendo relay TCP %s:%d\n" + +#: ../src/toxic.c:466 +#, c-format +msgid "Enter a new password (must be at least %d characters) " +msgstr "Inserisci una nuova password (deve contenere almeno %d caratteri) " + +#: ../src/toxic.c:476 +#, c-format +msgid "Password must be between %d and %d characters long. " +msgstr "La password deve essere lunga tra %d e %d caratteri. " + +#: ../src/toxic.c:481 +#, c-format +msgid "Enter password again " +msgstr "Reinserisci password " + +#: ../src/toxic.c:489 +#, c-format +msgid "Passwords don't match. Try again. " +msgstr "Le passwords non corrispondono. Riprova. " + +#: ../src/toxic.c:496 +#, c-format +msgid "Data file '%s' is encrypted" +msgstr "Il file dati '%s' è criptato" + +#: ../src/toxic.c:533 +#, c-format +msgid "tox_pass_encrypt() failed with error %d\n" +msgstr "\"tox_pass_encrypt()\" fallita con errore %d\n" + +#: ../src/toxic.c:584 +msgid "Forcing IPv4 connection" +msgstr "Forzata connessione IPv4" + +#: ../src/toxic.c:592 +#, c-format +msgid "Using %s proxy %s : %d" +msgstr "Uso %s proxy %s:%d" + +#: ../src/toxic.c:597 +msgid "UDP disabled" +msgstr "UDP disabilitato" + +#: ../src/toxic.c:599 +msgid "" +"WARNING: Using a proxy without disabling UDP may leak your real IP address." +msgstr "" +"ATTENZIONE: usare un proxy senza disabilitare UDP potrebbe portare alla " +"rivelazione del tuo vero IP." + +#: ../src/toxic.c:601 +msgid "Use the -t option to disable UDP." +msgstr "Usa l'optione \"-t\" per disabilitare UDP." + +#: ../src/toxic.c:620 ../src/toxic.c:627 ../src/toxic.c:635 ../src/toxic.c:712 +#: ../src/toxic.c:722 +msgid "failed in load_toxic" +msgstr "errore in \"load_toxic\"" + +#: ../src/toxic.c:639 +#, c-format +msgid "Data file '%s' has been unencrypted" +msgstr "Il file di dati '%s' è stato decriptato" + +#: ../src/toxic.c:641 +#, c-format +msgid "Warning: passed --unencrypt-data option with unencrypted data file '%s'" +msgstr "" +"Attenzione: opzione \"--unencrypt-data\" usata con un file di dati non " +"criptato (%s)" + +#: ../src/toxic.c:649 +#, c-format +msgid "Enter password (\"%s\" to quit) " +msgstr "Inserisci password (\"%s\" per uscire) " + +#: ../src/toxic.c:666 ../src/toxic.c:690 +#, c-format +msgid "Invalid password. Try again. " +msgstr "Password errata. Riprova. " + +#: ../src/toxic.c:693 +msgid "tox_pass_decrypt() failed" +msgstr "\"tox_pass_decrypt()\" fallita" + +#: ../src/toxic.c:737 +msgid "Falling back to ipv4" +msgstr "Ritorno a IPv4" + +#: ../src/toxic.c:743 +msgid "tox_new returned fatal error" +msgstr "\"tox_new\" ha ritornato un errore fatale" + +#: ../src/toxic.c:746 +#, c-format +msgid "tox_new returned non-fatal error %d" +msgstr "\"tox_new\" ha ritornato un errore non fatale %d" + +#: ../src/toxic.c:753 +msgid "Toxic User" +msgstr "Utente Toxic" + +#: ../src/toxic.c:779 +#, c-format +msgid "Auto-connect failed with error code %d" +msgstr "Connessione automatica fallita con errore %d" + +#: ../src/toxic.c:860 +#, c-format +msgid "usage: toxic [OPTION] [FILE ...]\n" +msgstr "uso: toxic [OPZIONE] [FILE...]\n" + +#: ../src/toxic.c:862 +#, c-format +msgid "Force IPv4 connection\n" +msgstr "Forza connessioni IPv4\n" + +#: ../src/toxic.c:864 +#, c-format +msgid "Enable stderr for debugging\n" +msgstr "Abilita stderr per il debugging\n" + +#: ../src/toxic.c:866 +#, c-format +msgid "Use specified config file\n" +msgstr "Usa il file di configurazione specificato\n" + +#: ../src/toxic.c:868 +#, c-format +msgid "Use default POSIX locale\n" +msgstr "Usa localizzazione POSIX di default\n" + +#: ../src/toxic.c:870 +#, c-format +msgid "Encrypt an unencrypted data file\n" +msgstr "Cripta un file di dati non criptato\n" + +#: ../src/toxic.c:872 +#, c-format +msgid "Use specified data file\n" +msgstr "Usa il file di dati specificato\n" + +#: ../src/toxic.c:874 +#, c-format +msgid "Show this message and exit\n" +msgstr "Mostra questo messaggio ed esce\n" + +#: ../src/toxic.c:876 +#, c-format +msgid "Use specified DHTnodes file\n" +msgstr "Usa il file DHTnodes specificato\n" + +#: ../src/toxic.c:878 +#, c-format +msgid "Do not connect to the DHT network\n" +msgstr "Non si connette alla rete DHT\n" + +#: ../src/toxic.c:880 +#, c-format +msgid "Use SOCKS5 proxy: Requires [IP] [port]\n" +msgstr "Usa proxy SOCKS5: richiede [IP] [porta]\n" + +#: ../src/toxic.c:882 +#, c-format +msgid "Use HTTP proxy: Requires [IP] [port]\n" +msgstr "Usa proxy HTTP: richiede [IP] [porta]\n" + +#: ../src/toxic.c:884 +#, c-format +msgid "Use specified DNSservers file\n" +msgstr "Usa il file DNSservers specificato\n" + +#: ../src/toxic.c:886 +#, c-format +msgid "Force TCP connection (use this with proxies)\n" +msgstr "Forza connessioni TCP (usa questa opzione per i proxies)\n" + +#: ../src/toxic.c:888 +#, c-format +msgid "Unencrypt an encrypted data file\n" +msgstr "Decripta un file di dati criptato\n" + +#: ../src/toxic.c:932 +msgid "stderr enabled" +msgstr "stderr abilitato" + +#: ../src/toxic.c:939 +msgid "Config file not found" +msgstr "File di configurazione non trovato" + +#: ../src/toxic.c:945 +msgid "Using default POSIX locale" +msgstr "Uso localizzazione POSIX di default" + +#: ../src/toxic.c:958 +msgid "failed in parse_args" +msgstr "erorre in \"parse_args\"" + +#: ../src/toxic.c:963 +#, c-format +msgid "Using '%s' data file" +msgstr "Uso il file di dati '%s'" + +#: ../src/toxic.c:971 +msgid "DHTnodes file not found" +msgstr "File DHTnodes non trovato" + +#: ../src/toxic.c:977 +msgid "DHT disabled" +msgstr "DHT disabilitato" + +#: ../src/toxic.c:985 ../src/toxic.c:995 +msgid "Proxy error" +msgstr "Errore proxy" + +#: ../src/toxic.c:1004 +msgid "DNSservers file not found" +msgstr "File DNSservers non trovato" + +#: ../src/toxic.c:1101 +#, c-format +msgid "Warning: Using \"%s\" and \"%s\" simultaneously has no effect" +msgstr "Attenzione: usando \"%s\" e \"%s\" simultaneamente non avrà effetto" + +#: ../src/toxic.c:1114 +msgid "Creating new data file. Would you like to encrypt it? Y/n (q to quit)" +msgstr "" +"Creazione di un nuovo file di dati. Vuoi criptarlo? Y/n (\"q\" per uscire)" + +#: ../src/toxic.c:1116 +msgid "Encrypt existing data file? Y/n (q to quit)" +msgstr "Criptare il file di dati esistente? Y/n (\"q\" per uscire)" + +#: ../src/toxic.c:1123 ../src/toxic.c:1146 ../src/toxic.c:1149 +#: ../src/toxic.c:1153 ../src/toxic.c:1161 +msgid "failed in main" +msgstr "errore in \"main\"" + +#: ../src/toxic.c:1130 +msgid "X failed to initialize" +msgstr "Errore inizializzazione X" + +#: ../src/toxic.c:1168 +msgid "Failed to init audio devices" +msgstr "Inizializzazione dispositivi audio fallita" + +#: ../src/toxic.c:1177 +msgid "" +"Unable to determine configuration directory. Defaulting to 'data' for data " +"file..." +msgstr "" +"Impossibile determinare la directory delle configurazioni. Uso 'data' come " +"file di dati..." + +#: ../src/toxic.c:1182 +msgid "Failed to load user settings" +msgstr "Errore nel caricamento delle impostazioni utente" + +#: ../src/toxic.c:1186 +msgid "Failed to init mplex auto-away." +msgstr "Errore nell'inizializzazione di mplex auto-away." + +#: ../src/toxic.c:1209 +msgid "WARNING: Failed to save to data file" +msgstr "ATTENZIONE: salvataggio file di dati fallito" + +#: ../src/toxic.h:43 +msgid "Anonymous" +msgstr "Anonimo" + +#: ../src/toxic.h:44 +msgid "Tox User" +msgstr "Utente Toxic" + +#: ../src/windows.c:368 +msgid "failed in set_next_window" +msgstr "errore in \"set_next_window\"" + +#: ../src/windows.c:390 +msgid "failed in init_windows" +msgstr "errore in \"init_windows\"" diff --git a/translations/tools/create_mo.sh b/translations/tools/create_mo.sh new file mode 100755 index 0000000..b0de40c --- /dev/null +++ b/translations/tools/create_mo.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +cd $(dirname $0) + +loc="$1" +while [ -z "$1" -a -z "$loc" ]; do + echo -n "Insert locale (for example \"en\"): " + read loc +done + +cd .. + +if [ ! -e "$loc.po" ]; then + echo "File \"$loc.po\" not found" + echo "The translation file must exist" + exit 1 +else + msgfmt -c -o $loc.mo $loc.po +fi diff --git a/translations/tools/create_po.sh b/translations/tools/create_po.sh new file mode 100755 index 0000000..6a884a6 --- /dev/null +++ b/translations/tools/create_po.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +cd $(dirname $0) + +loc="$1" +while [ -z "$1" -a -z "$loc" ]; do + echo -n "Insert locale to create (for example \"en\"): " + read loc +done + +cd .. + +if [ -e "$loc.po" ]; then + echo "File \"$loc.po\" found" + echo "The translation file must not exist" + exit 1 +else + v=$(grep TOXIC_VERSION ../cfg/global_vars.mk | head -1 | cut -d "=" -f 2 | tr -d " ") + echo "PACKAGE_NAME=Toxic" > configure + echo "PACKAGE_VERSION=$v" >> configure + msginit --no-translator -l $loc -o $loc.po -i toxic.pot + rm -f configure +fi diff --git a/translations/tools/update_po.sh b/translations/tools/update_po.sh new file mode 100755 index 0000000..ee352ff --- /dev/null +++ b/translations/tools/update_po.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +cd $(dirname $0) + +loc="$1" +while [ -z "$1" -a -z "$loc" ]; do + echo -n "Insert locale to update (for example \"en\"): " + read loc +done + +cd .. + +if [ ! -e "$loc.po" ]; then + echo "File \"$loc.po\" not found" + echo "The translation file must exist" + exit 1 +else + msgmerge -U --backup=none --previous $loc.po toxic.pot +fi diff --git a/translations/tools/update_pot.sh b/translations/tools/update_pot.sh new file mode 100755 index 0000000..e182ea9 --- /dev/null +++ b/translations/tools/update_pot.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +cd $(dirname $0)/.. +v=$(grep TOXIC_VERSION ../cfg/global_vars.mk | head -1 | cut -d "=" -f 2 | tr -d " ") +xgettext --default-domain="toxic" \ + --from-code="UTF-8" \ + --copyright-holder="Toxic Team" \ + --msgid-bugs-address="JFreegman@tox.im" \ + --package-name="Toxic" \ + --package-version="$v" \ + --output="toxic.pot" \ + ../src/* diff --git a/translations/toxic.pot b/translations/toxic.pot new file mode 100644 index 0000000..278d575 --- /dev/null +++ b/translations/toxic.pot @@ -0,0 +1,1574 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Toxic Team +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Toxic 0.6.0\n" +"Report-Msgid-Bugs-To: JFreegman@tox.im\n" +"POT-Creation-Date: 2015-05-30 11:30+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../src/audio_call.c:133 +msgid "Failed to init devices" +msgstr "" + +#: ../src/audio_call.c:195 ../src/audio_call.c:201 +msgid "Could not prepare transmission" +msgstr "" + +#: ../src/audio_call.c:217 +msgid "Failed to open input device!" +msgstr "" + +#: ../src/audio_call.c:222 +msgid "Failed to register input handler!" +msgstr "" + +#: ../src/audio_call.c:226 +msgid "Failed to open output device!" +msgstr "" + +#: ../src/audio_call.c:284 ../src/audio_call.c:303 +msgid "Error starting transmission!" +msgstr "" + +#: ../src/audio_call.c:357 ../src/audio_call.c:392 ../src/audio_call.c:423 +#: ../src/audio_call.c:454 +msgid "Unknown arguments." +msgstr "" + +#: ../src/audio_call.c:362 ../src/audio_call.c:397 ../src/audio_call.c:428 +#: ../src/audio_call.c:459 +msgid "Audio not supported!" +msgstr "" + +#: ../src/audio_call.c:367 +msgid "Friend is offline." +msgstr "" + +#: ../src/audio_call.c:374 +msgid "Already in a call!" +msgstr "" + +#: ../src/audio_call.c:375 ../src/audio_call.c:406 ../src/audio_call.c:437 +#: ../src/audio_call.c:479 +msgid "Internal error!" +msgstr "" + +#: ../src/audio_call.c:380 +#, c-format +msgid "Calling... idx: %d" +msgstr "" + +#: ../src/audio_call.c:404 +msgid "Cannot answer in invalid state!" +msgstr "" + +#: ../src/audio_call.c:405 ../src/audio_call.c:436 +msgid "No incoming call!" +msgstr "" + +#: ../src/audio_call.c:432 +msgid "Why not?" +msgstr "" + +#: ../src/audio_call.c:435 +msgid "Cannot reject in invalid state!" +msgstr "" + +#: ../src/audio_call.c:467 +msgid "Only those who appreciate small things know the beauty that is life" +msgstr "" + +#: ../src/audio_call.c:471 ../src/chat.c:653 +msgid "Call canceled!" +msgstr "" + +#: ../src/audio_call.c:477 +msgid "Cannot hangup in invalid state!" +msgstr "" + +#: ../src/audio_call.c:478 +msgid "No call!" +msgstr "" + +#: ../src/audio_call.c:494 ../src/audio_call.c:526 ../src/audio_call.c:570 +#: ../src/audio_call.c:643 +msgid "Type must be specified!" +msgstr "" + +#: ../src/audio_call.c:495 +msgid "Only one argument allowed!" +msgstr "" + +#: ../src/audio_call.c:509 ../src/audio_call.c:542 ../src/audio_call.c:586 +#: ../src/audio_call.c:658 +#, c-format +msgid "Invalid type: %s" +msgstr "" + +#: ../src/audio_call.c:527 ../src/audio_call.c:571 +msgid "Must have id!" +msgstr "" + +#: ../src/audio_call.c:528 ../src/audio_call.c:572 ../src/audio_call.c:644 +#: ../src/audio_call.c:690 +msgid "Only two arguments allowed!" +msgstr "" + +#: ../src/audio_call.c:551 ../src/audio_call.c:595 ../src/audio_call.c:699 +msgid "Invalid input" +msgstr "" + +#: ../src/audio_call.c:556 ../src/audio_call.c:600 +msgid "Invalid selection!" +msgstr "" + +#: ../src/audio_call.c:689 +msgid "Must have value!" +msgstr "" + +#: ../src/audio_call.c:728 +msgid "Not interested anymore" +msgstr "" + +#: ../src/audio_call.c:731 +msgid "Not interested" +msgstr "" + +#: ../src/autocomplete.c:126 +msgid "failed in complete_line" +msgstr "" + +#: ../src/avatars.c:68 +#, c-format +msgid "tox_file_send failed for friendnumber %d (error %d)\n" +msgstr "" + +#: ../src/avatars.c:212 +#, c-format +msgid "tox_file_send_chunk failed in avatar callback (error %d)\n" +msgstr "" + +#: ../src/chat.c:56 +msgid "yes" +msgstr "" + +#: ../src/chat.c:57 +msgid "no" +msgstr "" + +#: ../src/chat.c:223 ../src/prompt.c:360 +msgid "has come online" +msgstr "" + +#: ../src/chat.c:234 ../src/prompt.c:372 +msgid "has gone offline" +msgstr "" + +#: ../src/chat.c:319 +#, c-format +msgid "File '%s' successfully sent." +msgstr "" + +#: ../src/chat.c:326 +#, c-format +msgid "File transfer for '%s' failed: Null file pointer." +msgstr "" + +#: ../src/chat.c:333 +#, c-format +msgid "File transfer for '%s' failed: Seek fail." +msgstr "" + +#: ../src/chat.c:345 +#, c-format +msgid "File transfer for '%s' failed: Read fail." +msgstr "" + +#: ../src/chat.c:354 +#, c-format +msgid "tox_file_send_chunk failed in chat callback (error %d)\n" +msgstr "" + +#: ../src/chat.c:377 +#, c-format +msgid "File '%s' successfully received." +msgstr "" + +#: ../src/chat.c:384 +#, c-format +msgid "File transfer for '%s' failed: Invalid file pointer." +msgstr "" + +#: ../src/chat.c:390 +#, c-format +msgid "File transfer for '%s' failed: Write fail." +msgstr "" + +#: ../src/chat.c:416 +#, c-format +msgid "File transfer [%d] for '%s' accepted." +msgstr "" + +#: ../src/chat.c:434 +#, c-format +msgid "File transfer for '%s' was aborted." +msgstr "" + +#: ../src/chat.c:450 ../src/chat_commands.c:309 +msgid "File transfer failed: Too many concurrent file transfers." +msgstr "" + +#: ../src/chat.c:456 +#, c-format +msgid "File transfer request for '%s' (%s)" +msgstr "" + +#: ../src/chat.c:471 +msgid "File transfer faield: File path too long." +msgstr "" + +#: ../src/chat.c:497 +msgid "File transfer failed: invalid file path." +msgstr "" + +#: ../src/chat.c:502 +#, c-format +msgid "Type '%s %d' to accept the file transfer." +msgstr "" + +#: ../src/chat.c:515 ../src/chat.c:518 +#, c-format +msgid "Incoming file: %s" +msgstr "" + +#: ../src/chat.c:533 +msgid "Failed in chat_onGroupInvite" +msgstr "" + +#: ../src/chat.c:547 ../src/chat.c:549 +msgid "invites you to join group chat" +msgstr "" + +#: ../src/chat.c:551 +#, c-format +msgid "%s has invited you to a group chat." +msgstr "" + +#: ../src/chat.c:552 +#, c-format +msgid "Type \"%s\" to join the chat." +msgstr "" + +#: ../src/chat.c:566 +#, c-format +msgid "Incoming audio call! Type: \"%s\" or \"%s\"" +msgstr "" + +#: ../src/chat.c:573 ../src/chat.c:575 +msgid "Incoming audio call!" +msgstr "" + +#: ../src/chat.c:583 +#, c-format +msgid "Ringing...type \"%s\" to cancel it." +msgstr "" + +#: ../src/chat.c:598 ../src/chat.c:639 +#, c-format +msgid "Call started! Type: \"%s\" to end it." +msgstr "" + +#: ../src/chat.c:612 ../src/chat.c:680 +msgid "Call ended!" +msgstr "" + +#: ../src/chat.c:625 +msgid "Error!" +msgstr "" + +#: ../src/chat.c:666 +msgid "Rejected!" +msgstr "" + +#: ../src/chat.c:693 +msgid "No answer!" +msgstr "" + +#: ../src/chat.c:707 +msgid "Peer disconnected; call ended!" +msgstr "" + +#: ../src/chat.c:769 +msgid " Call Active\n" +msgstr "" + +#: ../src/chat.c:773 +msgid " Duration: " +msgstr "" + +#: ../src/chat.c:778 +msgid " In muted: " +msgstr "" + +#: ../src/chat.c:783 +msgid " Out muted: " +msgstr "" + +#: ../src/chat.c:788 +msgid " VAD level: " +msgstr "" + +#: ../src/chat.c:1080 +msgid "failed in chat_onInit" +msgstr "" + +#: ../src/chat.c:1152 +msgid "failed in new_chat" +msgstr "" + +#: ../src/chat_commands.c:48 +#, c-format +msgid "Requires type %s and the file ID." +msgstr "" + +#: ../src/chat_commands.c:57 ../src/chat_commands.c:74 +#: ../src/chat_commands.c:79 +msgid "Invalid file ID." +msgstr "" + +#: ../src/chat_commands.c:69 +#, c-format +msgid "Type must be '%s' or '%s'." +msgstr "" + +#: ../src/chat_commands.c:83 +#, c-format +msgid "File transfer for '%s' aborted." +msgstr "" + +#: ../src/chat_commands.c:90 +msgid "Group number required." +msgstr "" + +#: ../src/chat_commands.c:97 +msgid "Invalid group number." +msgstr "" + +#: ../src/chat_commands.c:102 +msgid "Failed to invite contact to group." +msgstr "" + +#: ../src/chat_commands.c:106 +#, c-format +msgid "Invited contact to Group %d." +msgstr "" + +#: ../src/chat_commands.c:112 ../src/global_commands.c:324 +msgid " * Warning: Too many windows are open." +msgstr "" + +#: ../src/chat_commands.c:121 +msgid "No pending group chat invite." +msgstr "" + +#: ../src/chat_commands.c:136 ../src/global_commands.c:354 +msgid "Group chat instance failed to initialize." +msgstr "" + +#: ../src/chat_commands.c:141 ../src/global_commands.c:359 +msgid "Group chat window failed to initialize." +msgstr "" + +#: ../src/chat_commands.c:151 +msgid "File ID required." +msgstr "" + +#: ../src/chat_commands.c:158 ../src/chat_commands.c:165 +#: ../src/chat_commands.c:170 +msgid "No pending file transfers with that ID." +msgstr "" + +#: ../src/chat_commands.c:175 +msgid "File transfer failed: Invalid file path." +msgstr "" + +#: ../src/chat_commands.c:186 +#, c-format +msgid "Saving file [%d] as: '%s'" +msgstr "" + +#: ../src/chat_commands.c:201 +msgid "File transfer failed: Friend not found." +msgstr "" + +#: ../src/chat_commands.c:205 +msgid "File transfer failed: Friend is not online." +msgstr "" + +#: ../src/chat_commands.c:209 +msgid "File transfer failed: Invalid filenumber." +msgstr "" + +#: ../src/chat_commands.c:213 +msgid "File transfer failed: Connection error." +msgstr "" + +#: ../src/chat_commands.c:217 +#, c-format +msgid "File transfer failed (error %d)\n" +msgstr "" + +#: ../src/chat_commands.c:227 +msgid "File path required." +msgstr "" + +#: ../src/chat_commands.c:232 +msgid "File path must be enclosed in quotes." +msgstr "" + +#: ../src/chat_commands.c:243 +msgid "File path exceeds character limit." +msgstr "" + +#: ../src/chat_commands.c:250 +msgid "File not found." +msgstr "" + +#: ../src/chat_commands.c:257 +msgid "Invalid file." +msgstr "" + +#: ../src/chat_commands.c:290 +#, c-format +msgid "Sending file [%d]: '%s' (%s)" +msgstr "" + +#: ../src/chat_commands.c:297 +msgid "File transfer failed: Invalid friend." +msgstr "" + +#: ../src/chat_commands.c:301 +msgid "File transfer failed: Friend is offline." +msgstr "" + +#: ../src/chat_commands.c:305 +msgid "File transfer failed: Filename is too long." +msgstr "" + +#: ../src/chat_commands.c:313 +msgid "File transfer failed." +msgstr "" + +#: ../src/configdir.c:125 ../src/toxic.c:1039 ../src/toxic.c:1045 +msgid "failed in load_data_structures" +msgstr "" + +#: ../src/dns.c:155 +#, c-format +msgid "User lookup failed: %s" +msgstr "" + +#: ../src/dns.c:181 +msgid "dn_expand failed." +msgstr "" + +#: ../src/dns.c:186 ../src/dns.c:209 +msgid "DNS reply was too short." +msgstr "" + +#: ../src/dns.c:192 +msgid "Broken DNS reply." +msgstr "" + +#: ../src/dns.c:204 +msgid "Second dn_expand failed." +msgstr "" + +#: ../src/dns.c:217 +msgid "RR overflow." +msgstr "" + +#: ../src/dns.c:222 +msgid "DNS response failed." +msgstr "" + +#: ../src/dns.c:227 +msgid "No record found." +msgstr "" + +#: ../src/dns.c:230 +msgid "Invalid DNS response." +msgstr "" + +#: ../src/dns.c:307 +msgid "Must be a Tox ID or an address in the form username@domain" +msgstr "" + +#: ../src/dns.c:317 +msgid "Domain not found." +msgstr "" + +#: ../src/dns.c:324 +msgid "Core failed to create DNS object." +msgstr "" + +#: ../src/dns.c:335 +msgid "Core failed to generate DNS3 string." +msgstr "" + +#: ../src/dns.c:349 +msgid "DNS query failed." +msgstr "" + +#: ../src/dns.c:364 +msgid "Bad DNS3 TXT response." +msgstr "" + +#: ../src/dns.c:372 +msgid "Core failed to decrypt DNS response." +msgstr "" + +#: ../src/dns.c:388 +msgid "DNS lookups are disabled." +msgstr "" + +#: ../src/dns.c:393 +msgid "Please wait for previous user lookup to finish." +msgstr "" + +#: ../src/dns.c:403 +#, c-format +msgid "" +"DNS server list failed to load with error code %d. Falling back to hard-" +"coded list." +msgstr "" + +#: ../src/dns.c:416 +msgid "Error: DNS thread attr failed to init" +msgstr "" + +#: ../src/dns.c:422 +msgid "Error: DNS thread attr failed to set" +msgstr "" + +#: ../src/dns.c:429 +msgid "Error: DNS thread failed to init" +msgstr "" + +#: ../src/execute.c:107 +msgid "failed in parse_command" +msgstr "" + +#: ../src/execute.c:121 +msgid "Invalid argument. Did you forget a closing \"?" +msgstr "" + +#: ../src/execute.c:192 +msgid "Invalid command." +msgstr "" + +#: ../src/friendlist.c:93 +msgid "failed in realloc_friends" +msgstr "" + +#: ../src/friendlist.c:113 +msgid "failed in realloc_blocklist" +msgstr "" + +#: ../src/friendlist.c:141 +msgid "Failed in save_blocklist" +msgstr "" + +#: ../src/friendlist.c:208 +msgid "Failed in load_blocklist" +msgstr "" + +#: ../src/friendlist.c:331 ../src/friendlist.c:766 ../src/friendlist.c:1076 +msgid "* Warning: Too many windows are open." +msgstr "" + +#: ../src/friendlist.c:346 +#, c-format +msgid "avatar_send failed for friend %d\n" +msgstr "" + +#: ../src/friendlist.c:421 +#, c-format +msgid "tox_friend_get_public_key failed (error %d)\n" +msgstr "" + +#: ../src/friendlist.c:500 +#, c-format +msgid "* File transfer from %s failed: too many windows are open." +msgstr "" + +#: ../src/friendlist.c:523 +#, c-format +msgid "* Group chat invite from %s failed: too many windows are open." +msgstr "" + +#: ../src/friendlist.c:546 +#, c-format +msgid "tox_friend_delete failed with error %d\n" +msgstr "" + +#: ../src/friendlist.c:626 +msgid "Delete contact " +msgstr "" + +#: ../src/friendlist.c:707 +#, c-format +msgid "Failed to unblock friend (error %d)\n" +msgstr "" + +#: ../src/friendlist.c:803 +msgid " Blocked: " +msgstr "" + +#: ../src/friendlist.c:855 ../src/friendlist.c:1035 +msgid "Key: " +msgstr "" + +#: ../src/friendlist.c:881 +msgid " Press the" +msgstr "" + +#: ../src/friendlist.c:885 +msgid "" +"key for help\n" +"\n" +msgstr "" + +#: ../src/friendlist.c:897 +msgid " Online: " +msgstr "" + +#: ../src/friendlist.c:1011 +#, c-format +msgid " Last seen: Today %s\n" +msgstr "" + +#: ../src/friendlist.c:1015 +#, c-format +msgid " Last seen: Yesterday %s\n" +msgstr "" + +#: ../src/friendlist.c:1019 +#, c-format +msgid " Last seen: %d days ago\n" +msgstr "" + +#: ../src/friendlist.c:1023 +msgid " Last seen: Never\n" +msgstr "" + +#: ../src/friendlist.c:1074 +#, c-format +msgid "Audio action from: %s!" +msgstr "" + +#: ../src/friendlist.c:1126 +msgid "failed in new_friendlist" +msgstr "" + +#: ../src/friendlist.c:1129 +msgid "contacts" +msgstr "" + +#: ../src/global_commands.c:55 ../src/global_commands.c:292 +msgid "Request ID required." +msgstr "" + +#: ../src/global_commands.c:62 ../src/global_commands.c:67 +#: ../src/global_commands.c:299 ../src/global_commands.c:304 +msgid "No pending friend request with that ID." +msgstr "" + +#: ../src/global_commands.c:75 +#, c-format +msgid "Failed to add friend (error %d)\n" +msgstr "" + +#: ../src/global_commands.c:78 +msgid "Friend request accepted." +msgstr "" + +#: ../src/global_commands.c:105 +msgid "Message is too long." +msgstr "" + +#: ../src/global_commands.c:109 +msgid "Please add a message to your request." +msgstr "" + +#: ../src/global_commands.c:113 +msgid "That appears to be your own ID." +msgstr "" + +#: ../src/global_commands.c:117 +msgid "Friend request has already been sent." +msgstr "" + +#: ../src/global_commands.c:121 +msgid "Bad checksum in address." +msgstr "" + +#: ../src/global_commands.c:125 +msgid "Nospam was different." +msgstr "" + +#: ../src/global_commands.c:129 +msgid "Core memory allocation failed." +msgstr "" + +#: ../src/global_commands.c:133 +msgid "Friend request sent." +msgstr "" + +#: ../src/global_commands.c:140 +msgid "Failed to add friend: Unknown error." +msgstr "" + +#: ../src/global_commands.c:150 +msgid "Tox ID or address required." +msgstr "" + +#: ../src/global_commands.c:159 +msgid "Message must be enclosed in quotes." +msgstr "" + +#: ../src/global_commands.c:175 +#, c-format +msgid "Hello, my name is %s. Care to Tox?" +msgstr "" + +#: ../src/global_commands.c:193 +msgid "Invalid Tox ID." +msgstr "" + +#: ../src/global_commands.c:210 +msgid "Avatar is not set." +msgstr "" + +#: ../src/global_commands.c:215 +msgid "Path must be enclosed in quotes." +msgstr "" + +#: ../src/global_commands.c:225 +msgid "Invalid path." +msgstr "" + +#: ../src/global_commands.c:235 +#, c-format +msgid "" +"Failed to set avatar. Avatars must be in PNG format and may not exceed %d " +"bytes." +msgstr "" + +#: ../src/global_commands.c:240 +#, c-format +msgid "Avatar set to '%s'" +msgstr "" + +#: ../src/global_commands.c:252 +msgid "Require: " +msgstr "" + +#: ../src/global_commands.c:261 +msgid "Invalid port." +msgstr "" + +#: ../src/global_commands.c:274 +msgid "Bootstrap failed: Invalid IP." +msgstr "" + +#: ../src/global_commands.c:278 +msgid "Bootstrap failed: Invalid port." +msgstr "" + +#: ../src/global_commands.c:282 +msgid "Bootstrap failed." +msgstr "" + +#: ../src/global_commands.c:329 +#, c-format +msgid "Please specify group type: %s" +msgstr "" + +#: ../src/global_commands.c:340 +#, c-format +msgid "Valid group types are: %s" +msgstr "" + +#: ../src/global_commands.c:364 +#, c-format +msgid "Group chat [%d] created." +msgstr "" + +#: ../src/global_commands.c:374 +msgid "Logging for this window is ON. Type \"/log off\" to disable." +msgstr "" + +#: ../src/global_commands.c:376 +msgid "Logging for this window is OFF. Type \"/log on\" to enable." +msgstr "" + +#: ../src/global_commands.c:397 +msgid "Logging enabled" +msgstr "" + +#: ../src/global_commands.c:406 +msgid "Logging disabled" +msgstr "" + +#: ../src/global_commands.c:411 +#, c-format +msgid "Invalid option. Use \"%s\" to toggle logging." +msgstr "" + +#: ../src/global_commands.c:435 ../src/global_commands.c:468 +msgid "Input required." +msgstr "" + +#: ../src/global_commands.c:452 +msgid "Invalid name." +msgstr "" + +#: ../src/global_commands.c:473 ../src/global_commands.c:561 +msgid "Note must be enclosed in quotes." +msgstr "" + +#: ../src/global_commands.c:499 +msgid "No pending friend requests." +msgstr "" + +#: ../src/global_commands.c:536 +#, c-format +msgid "Require a status. Statuses are: %s." +msgstr "" + +#: ../src/global_commands.c:551 +#, c-format +msgid "Invalid status. Valid statuses are: %s." +msgstr "" + +#: ../src/group_commands.c:46 +#, c-format +msgid "Title is set to: %s" +msgstr "" + +#: ../src/group_commands.c:48 +msgid "Title is not set" +msgstr "" + +#: ../src/group_commands.c:55 +msgid "Title must be enclosed in quotes." +msgstr "" + +#: ../src/group_commands.c:65 +msgid "Failed to set title." +msgstr "" + +#: ../src/group_commands.c:80 ../src/groupchat.c:337 +#, c-format +msgid " set the group title to: %s" +msgstr "" + +#: ../src/group_commands.c:83 ../src/groupchat.c:340 +#, c-format +msgid "set title to %s" +msgstr "" + +#: ../src/groupchat.c:143 +msgid "failed in init_groupchat_win" +msgstr "" + +#: ../src/groupchat.c:151 +#, c-format +msgid "Group Audio failed to init\n" +msgstr "" + +#: ../src/groupchat.c:362 +msgid "failed in copy_peernames" +msgstr "" + +#: ../src/groupchat.c:419 +msgid "has joined the room" +msgstr "" + +#: ../src/groupchat.c:517 +msgid "has left the room" +msgstr "" + +#: ../src/groupchat.c:534 +msgid " is now known as " +msgstr "" + +#: ../src/groupchat.c:538 +#, c-format +msgid "is now known as %s" +msgstr "" + +#: ../src/groupchat.c:549 +msgid "Invalid syntax.\n" +msgstr "" + +#: ../src/groupchat.c:554 +msgid " * Failed to send action." +msgstr "" + +#: ../src/groupchat.c:641 +msgid " * Failed to send message." +msgstr "" + +#: ../src/groupchat.c:678 +#, c-format +msgid "Peers: %d\n" +msgstr "" + +#: ../src/groupchat.c:728 +msgid "failed in groupchat_onInit" +msgstr "" + +#: ../src/groupchat.c:813 +#, c-format +msgid "source: %d, queued: %d, processed: %d\n" +msgstr "" + +#: ../src/groupchat.c:852 +#, c-format +msgid "dvhandle is null)\n" +msgstr "" + +#: ../src/groupchat.c:855 +#, c-format +msgid "ctx is null\n" +msgstr "" + +#: ../src/groupchat.c:858 +#, c-format +msgid "write: %d\n" +msgstr "" + +#: ../src/groupchat.c:882 +#, c-format +msgid "Group %d" +msgstr "" + +#: ../src/groupchat.c:888 +msgid "failed in new_group_chat" +msgstr "" + +#: ../src/help.c:148 +msgid "Global Commands:\n" +msgstr "" + +#: ../src/help.c:152 +msgid "Add contact with optional message\n" +msgstr "" + +#: ../src/help.c:154 +msgid "Accept friend request\n" +msgstr "" + +#: ../src/help.c:156 +msgid "Set an avatar (leave path empty to unset)\n" +msgstr "" + +#: ../src/help.c:158 +msgid "Decline friend request\n" +msgstr "" + +#: ../src/help.c:160 +msgid "List pending friend requests\n" +msgstr "" + +#: ../src/help.c:162 +msgid "Manually connect to a DHT node\n" +msgstr "" + +#: ../src/help.c:164 +msgid "Set status with optional note\n" +msgstr "" + +#: ../src/help.c:166 +msgid "Set a personal note\n" +msgstr "" + +#: ../src/help.c:168 +msgid "Set your nickname\n" +msgstr "" + +#: ../src/help.c:170 +msgid "Enable/disable logging\n" +msgstr "" + +#: ../src/help.c:172 +msgid "Create a group chat where type: text | audio\n" +msgstr "" + +#: ../src/help.c:174 +msgid "Print your Tox ID\n" +msgstr "" + +#: ../src/help.c:176 +msgid "Clear window history\n" +msgstr "" + +#: ../src/help.c:178 +msgid "Close the current chat window\n" +msgstr "" + +#: ../src/help.c:180 +msgid "Exit Toxic\n" +msgstr "" + +#: ../src/help.c:184 ../src/help.c:224 +msgid "" +"\n" +" Audio:\n" +msgstr "" + +#: ../src/help.c:188 +msgid "List devices where type:" +msgstr "" + +#: ../src/help.c:191 +msgid "Set active device\n" +msgstr "" + +#: ../src/help.c:207 +msgid "Chat Commands:\n" +msgstr "" + +#: ../src/help.c:211 +msgid "Invite contact to a group chat\n" +msgstr "" + +#: ../src/help.c:213 +msgid "Join a pending group chat\n" +msgstr "" + +#: ../src/help.c:215 +msgid "Send a file\n" +msgstr "" + +#: ../src/help.c:217 +msgid "Receive a file\n" +msgstr "" + +#: ../src/help.c:219 +msgid "Cancel file transfer where type:" +msgstr "" + +#: ../src/help.c:228 +msgid "Audio call\n" +msgstr "" + +#: ../src/help.c:230 +msgid "Answer incoming call\n" +msgstr "" + +#: ../src/help.c:232 +msgid "Reject incoming call\n" +msgstr "" + +#: ../src/help.c:234 +msgid "Hangup active call\n" +msgstr "" + +#: ../src/help.c:236 +msgid "Change active device\n" +msgstr "" + +#: ../src/help.c:238 +msgid "Mute active device if in call\n" +msgstr "" + +#: ../src/help.c:240 +msgid "VAD sensitivity threshold\n" +msgstr "" + +#: ../src/help.c:256 +msgid "Key bindings:\n" +msgstr "" + +#: ../src/help.c:260 +msgid "Navigate through the tabs\n" +msgstr "" + +#: ../src/help.c:262 +msgid "Scroll window history one line\n" +msgstr "" + +#: ../src/help.c:264 +msgid "Scroll window history half a page\n" +msgstr "" + +#: ../src/help.c:266 +msgid "Move to the bottom of window history\n" +msgstr "" + +#: ../src/help.c:268 +msgid "Scroll peer list in groupchats\n" +msgstr "" + +#: ../src/help.c:270 +msgid "" +"Toggle the groupchat peerlist\n" +"\n" +msgstr "" + +#: ../src/help.c:271 +msgid "" +" (Note: Custom keybindings override these defaults.)\n" +"\n" +msgstr "" + +#: ../src/help.c:286 +msgid "Group commands:\n" +msgstr "" + +#: ../src/help.c:290 +msgid "" +"Set group title (show current title if no msg)\n" +"\n" +msgstr "" + +#: ../src/help.c:305 +msgid "Friendlist controls:\n" +msgstr "" + +#: ../src/help.c:308 +msgid " Up and Down arrows : Scroll through list\n" +msgstr "" + +#: ../src/help.c:309 +msgid "" +" Right and Left arrows : Switch between friendlist and blocked " +"list\n" +msgstr "" + +#: ../src/help.c:310 +msgid "" +" Enter : Open a chat window with selected contact\n" +msgstr "" + +#: ../src/help.c:311 +msgid " Delete : Permanently delete a contact\n" +msgstr "" + +#: ../src/help.c:313 +msgid "Block or unblock a contact\n" +msgstr "" + +#: ../src/line_info.c:50 +msgid "failed in line_info_init" +msgstr "" + +#: ../src/line_info.c:150 +msgid "failed in line_info_add" +msgstr "" + +#: ../src/log.c:189 +msgid "failed in load_chat_history" +msgstr "" + +#: ../src/log.c:193 ../src/log.c:199 +msgid " * Failed to read log file" +msgstr "" + +#: ../src/message_queue.c:56 +msgid "failed in cqueue_message" +msgstr "" + +#: ../src/misc_tools.c:240 ../src/misc_tools.c:248 +msgid "failed in get_file_name" +msgstr "" + +#: ../src/prompt.c:139 +#, c-format +msgid "Failed to set note (error %d)\n" +msgstr "" + +#: ../src/prompt.c:271 +msgid "ERROR" +msgstr "" + +#: ../src/prompt.c:275 +msgid "Online" +msgstr "" + +#: ../src/prompt.c:279 +msgid "Away" +msgstr "" + +#: ../src/prompt.c:283 +msgid "Busy" +msgstr "" + +#: ../src/prompt.c:296 +msgid " [Offline]" +msgstr "" + +#: ../src/prompt.c:366 ../src/prompt.c:369 +#, c-format +msgid "%s has come online" +msgstr "" + +#: ../src/prompt.c:378 ../src/prompt.c:381 +#, c-format +msgid "%s has gone offline" +msgstr "" + +#: ../src/prompt.c:392 ../src/prompt.c:393 +#, c-format +msgid "Friend request with the message '%s'" +msgstr "" + +#: ../src/prompt.c:398 +msgid "Friend request queue is full. Discarding request." +msgstr "" + +#: ../src/prompt.c:403 +#, c-format +msgid "Type \"%s %d\" or \"%s %d\"" +msgstr "" + +#: ../src/prompt.c:432 ../src/prompt.c:433 +#, c-format +msgid "Toxing on Toxic" +msgstr "" + +#: ../src/prompt.c:455 +msgid "" +"Welcome to Toxic, a free, open source Tox-based instant messenging client." +msgstr "" + +#: ../src/prompt.c:457 +#, c-format +msgid "Type \"%s\" for assistance. Further help may be found via the man page." +msgstr "" + +#: ../src/prompt.c:476 +msgid "failed in prompt_onInit" +msgstr "" + +#: ../src/prompt.c:514 +msgid "failed in new_prompt" +msgstr "" + +#: ../src/toxic.c:112 +#, c-format +msgid "Caught SIGSEGV: Aborting toxic session.\n" +msgstr "" + +#: ../src/toxic.c:161 +#, c-format +msgid "Toxic session aborted with error code %d (%s)\n" +msgstr "" + +#: ../src/toxic.c:171 +msgid "" +"Could not set your locale, please check your locale settings or disable " +"unicode support with the -d flag." +msgstr "" + +#: ../src/toxic.c:231 ../src/toxic.c:236 +msgid "Failed in queue_init_message" +msgstr "" + +#: ../src/toxic.c:328 +#, c-format +msgid "Failed to bootstrap %s:%d\n" +msgstr "" + +#: ../src/toxic.c:335 +#, c-format +msgid "Failed to add TCP relay %s:%d\n" +msgstr "" + +#: ../src/toxic.c:466 +#, c-format +msgid "Enter a new password (must be at least %d characters) " +msgstr "" + +#: ../src/toxic.c:476 +#, c-format +msgid "Password must be between %d and %d characters long. " +msgstr "" + +#: ../src/toxic.c:481 +#, c-format +msgid "Enter password again " +msgstr "" + +#: ../src/toxic.c:489 +#, c-format +msgid "Passwords don't match. Try again. " +msgstr "" + +#: ../src/toxic.c:496 +#, c-format +msgid "Data file '%s' is encrypted" +msgstr "" + +#: ../src/toxic.c:533 +#, c-format +msgid "tox_pass_encrypt() failed with error %d\n" +msgstr "" + +#: ../src/toxic.c:584 +msgid "Forcing IPv4 connection" +msgstr "" + +#: ../src/toxic.c:592 +#, c-format +msgid "Using %s proxy %s : %d" +msgstr "" + +#: ../src/toxic.c:597 +msgid "UDP disabled" +msgstr "" + +#: ../src/toxic.c:599 +msgid "" +"WARNING: Using a proxy without disabling UDP may leak your real IP address." +msgstr "" + +#: ../src/toxic.c:601 +msgid "Use the -t option to disable UDP." +msgstr "" + +#: ../src/toxic.c:620 ../src/toxic.c:627 ../src/toxic.c:635 ../src/toxic.c:712 +#: ../src/toxic.c:722 +msgid "failed in load_toxic" +msgstr "" + +#: ../src/toxic.c:639 +#, c-format +msgid "Data file '%s' has been unencrypted" +msgstr "" + +#: ../src/toxic.c:641 +#, c-format +msgid "Warning: passed --unencrypt-data option with unencrypted data file '%s'" +msgstr "" + +#: ../src/toxic.c:649 +#, c-format +msgid "Enter password (\"%s\" to quit) " +msgstr "" + +#: ../src/toxic.c:666 ../src/toxic.c:690 +#, c-format +msgid "Invalid password. Try again. " +msgstr "" + +#: ../src/toxic.c:693 +msgid "tox_pass_decrypt() failed" +msgstr "" + +#: ../src/toxic.c:737 +msgid "Falling back to ipv4" +msgstr "" + +#: ../src/toxic.c:743 +msgid "tox_new returned fatal error" +msgstr "" + +#: ../src/toxic.c:746 +#, c-format +msgid "tox_new returned non-fatal error %d" +msgstr "" + +#: ../src/toxic.c:753 +msgid "Toxic User" +msgstr "" + +#: ../src/toxic.c:779 +#, c-format +msgid "Auto-connect failed with error code %d" +msgstr "" + +#: ../src/toxic.c:860 +#, c-format +msgid "usage: toxic [OPTION] [FILE ...]\n" +msgstr "" + +#: ../src/toxic.c:862 +#, c-format +msgid "Force IPv4 connection\n" +msgstr "" + +#: ../src/toxic.c:864 +#, c-format +msgid "Enable stderr for debugging\n" +msgstr "" + +#: ../src/toxic.c:866 +#, c-format +msgid "Use specified config file\n" +msgstr "" + +#: ../src/toxic.c:868 +#, c-format +msgid "Use default POSIX locale\n" +msgstr "" + +#: ../src/toxic.c:870 +#, c-format +msgid "Encrypt an unencrypted data file\n" +msgstr "" + +#: ../src/toxic.c:872 +#, c-format +msgid "Use specified data file\n" +msgstr "" + +#: ../src/toxic.c:874 +#, c-format +msgid "Show this message and exit\n" +msgstr "" + +#: ../src/toxic.c:876 +#, c-format +msgid "Use specified DHTnodes file\n" +msgstr "" + +#: ../src/toxic.c:878 +#, c-format +msgid "Do not connect to the DHT network\n" +msgstr "" + +#: ../src/toxic.c:880 +#, c-format +msgid "Use SOCKS5 proxy: Requires [IP] [port]\n" +msgstr "" + +#: ../src/toxic.c:882 +#, c-format +msgid "Use HTTP proxy: Requires [IP] [port]\n" +msgstr "" + +#: ../src/toxic.c:884 +#, c-format +msgid "Use specified DNSservers file\n" +msgstr "" + +#: ../src/toxic.c:886 +#, c-format +msgid "Force TCP connection (use this with proxies)\n" +msgstr "" + +#: ../src/toxic.c:888 +#, c-format +msgid "Unencrypt an encrypted data file\n" +msgstr "" + +#: ../src/toxic.c:932 +msgid "stderr enabled" +msgstr "" + +#: ../src/toxic.c:939 +msgid "Config file not found" +msgstr "" + +#: ../src/toxic.c:945 +msgid "Using default POSIX locale" +msgstr "" + +#: ../src/toxic.c:958 +msgid "failed in parse_args" +msgstr "" + +#: ../src/toxic.c:963 +#, c-format +msgid "Using '%s' data file" +msgstr "" + +#: ../src/toxic.c:971 +msgid "DHTnodes file not found" +msgstr "" + +#: ../src/toxic.c:977 +msgid "DHT disabled" +msgstr "" + +#: ../src/toxic.c:985 ../src/toxic.c:995 +msgid "Proxy error" +msgstr "" + +#: ../src/toxic.c:1004 +msgid "DNSservers file not found" +msgstr "" + +#: ../src/toxic.c:1101 +#, c-format +msgid "Warning: Using \"%s\" and \"%s\" simultaneously has no effect" +msgstr "" + +#: ../src/toxic.c:1114 +msgid "Creating new data file. Would you like to encrypt it? Y/n (q to quit)" +msgstr "" + +#: ../src/toxic.c:1116 +msgid "Encrypt existing data file? Y/n (q to quit)" +msgstr "" + +#: ../src/toxic.c:1123 ../src/toxic.c:1146 ../src/toxic.c:1149 +#: ../src/toxic.c:1153 ../src/toxic.c:1161 +msgid "failed in main" +msgstr "" + +#: ../src/toxic.c:1130 +msgid "X failed to initialize" +msgstr "" + +#: ../src/toxic.c:1168 +msgid "Failed to init audio devices" +msgstr "" + +#: ../src/toxic.c:1177 +msgid "" +"Unable to determine configuration directory. Defaulting to 'data' for data " +"file..." +msgstr "" + +#: ../src/toxic.c:1182 +msgid "Failed to load user settings" +msgstr "" + +#: ../src/toxic.c:1186 +msgid "Failed to init mplex auto-away." +msgstr "" + +#: ../src/toxic.c:1209 +msgid "WARNING: Failed to save to data file" +msgstr "" + +#: ../src/toxic.h:43 +msgid "Anonymous" +msgstr "" + +#: ../src/toxic.h:44 +msgid "Tox User" +msgstr "" + +#: ../src/windows.c:368 +msgid "failed in set_next_window" +msgstr "" + +#: ../src/windows.c:390 +msgid "failed in init_windows" +msgstr ""