summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.reuse/dep54
-rw-r--r--NEWS3
-rw-r--r--meson.build16
-rw-r--r--meson/suppressions/meson.build1
-rw-r--r--po/LINGUAS2
-rw-r--r--po/POTFILES60
-rw-r--r--po/meson.build27
-rw-r--r--po/patchage.pot155
-rw-r--r--src/CanvasModule.cpp6
-rw-r--r--src/CanvasPort.hpp3
-rw-r--r--src/Legend.cpp3
-rw-r--r--src/Patchage.cpp37
-rw-r--r--src/i18n.hpp15
-rw-r--r--src/main.cpp11
-rw-r--r--src/patchage.ui.in6
-rw-r--r--src/patchage_config.h19
16 files changed, 344 insertions, 24 deletions
diff --git a/.reuse/dep5 b/.reuse/dep5
index 7749513..5bfac99 100644
--- a/.reuse/dep5
+++ b/.reuse/dep5
@@ -30,3 +30,7 @@ License: CC-BY-SA-4.0 OR GPL-3.0-or-later
Files: icons/*.png icons/*.svg
Copyright: 2007-2011 David Robillard <d@drobilla.net>
License: CC-BY-SA-4.0 OR GPL-3.0-or-later
+
+Files: po/patchage.pot
+Copyright: 2022 David Robillard <d@drobilla.net>
+License: GPL-3.0-or-later
diff --git a/NEWS b/NEWS
index 7cb305f..208dbec 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,10 @@
patchage (1.0.9) unstable; urgency=medium
+ * Add i18n support
* Replace boost with standard C++17 facilities
* Upgrade to fmt 9.0.0
- -- David Robillard <d@drobilla.net> Mon, 22 Aug 2022 17:07:17 +0000
+ -- David Robillard <d@drobilla.net> Tue, 23 Aug 2022 02:49:17 +0000
patchage (1.0.8) stable; urgency=medium
diff --git a/meson.build b/meson.build
index b49a56b..e5a5969 100644
--- a/meson.build
+++ b/meson.build
@@ -37,10 +37,12 @@ add_project_arguments(['-DFMT_HEADER_ONLY'], language: ['cpp'])
##########################
patchage_datadir = get_option('prefix') / get_option('datadir') / 'patchage'
+patchage_localedir = get_option('prefix') / get_option('localedir')
platform_defines = [
'-DPATCHAGE_VERSION="@0@"'.format(meson.project_version()),
'-DPATCHAGE_DATA_DIR="@0@"'.format(patchage_datadir),
+ '-DPATCHAGE_LOCALE_DIR="@0@"'.format(patchage_localedir),
]
if host_machine.system() in ['gnu', 'linux']
@@ -53,6 +55,9 @@ if get_option('checks')
dladdr_code = '''#include <dlfcn.h>
int main(void) { Dl_info info; return dladdr(&info, &info); }'''
+ gettext_code = '''#include <libintl.h>
+int main(void) { return !!gettext("hello"); }'''
+
jack_metadata_code = '''#include <jack/metadata.h>
int main(void) { return !!&jack_set_property; }'''
@@ -65,6 +70,11 @@ int main(void) { return !!&jack_set_property; }'''
platform_defines += ['-DHAVE_DLADDR=0']
endif
+ platform_defines += '-DHAVE_GETTEXT=@0@'.format(
+ cpp.compiles(gettext_code,
+ args: platform_defines,
+ name: 'gettext').to_int())
+
platform_defines += '-DHAVE_JACK_METADATA=@0@'.format(
cpp.compiles(jack_metadata_code,
args: platform_defines,
@@ -160,6 +170,12 @@ if jack_dep.found() and dbus_dep.found() and dbus_glib_dep.found()
message('Both libjack and D-Bus available, defaulting to libjack')
endif
+#######################
+# Translations (i18n) #
+#######################
+
+subdir('po')
+
###########
# Program #
###########
diff --git a/meson/suppressions/meson.build b/meson/suppressions/meson.build
index 8292d77..0875ccd 100644
--- a/meson/suppressions/meson.build
+++ b/meson/suppressions/meson.build
@@ -18,6 +18,7 @@ if is_variable('cpp')
if cpp.get_id() == 'clang'
cpp_suppressions += [
'-Wno-alloca',
+ '-Wno-c++20-compat',
'-Wno-cast-qual',
'-Wno-double-promotion',
'-Wno-float-conversion',
diff --git a/po/LINGUAS b/po/LINGUAS
new file mode 100644
index 0000000..ebf3dcb
--- /dev/null
+++ b/po/LINGUAS
@@ -0,0 +1,2 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later
diff --git a/po/POTFILES b/po/POTFILES
new file mode 100644
index 0000000..0f392b7
--- /dev/null
+++ b/po/POTFILES
@@ -0,0 +1,60 @@
+# Copyright 2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later
+
+src/Action.hpp
+src/ActionSink.hpp
+src/AlsaDriver.cpp
+src/AlsaStubDriver.cpp
+src/AudioDriver.hpp
+src/Canvas.cpp
+src/Canvas.hpp
+src/CanvasModule.cpp
+src/CanvasModule.hpp
+src/CanvasPort.hpp
+src/ClientID.hpp
+src/ClientInfo.hpp
+src/ClientType.hpp
+src/Configuration.cpp
+src/Configuration.hpp
+src/Coord.hpp
+src/Driver.hpp
+src/Drivers.cpp
+src/Drivers.hpp
+src/Event.hpp
+src/ILog.hpp
+src/JackDbusDriver.cpp
+src/JackLibDriver.cpp
+src/JackStubDriver.cpp
+src/Legend.cpp
+src/Legend.hpp
+src/Metadata.cpp
+src/Metadata.hpp
+src/Options.hpp
+src/Patchage.cpp
+src/Patchage.hpp
+src/PortID.hpp
+src/PortInfo.hpp
+src/PortNames.hpp
+src/PortType.hpp
+src/Reactor.cpp
+src/Reactor.hpp
+src/Setting.hpp
+src/SignalDirection.hpp
+src/TextViewLog.cpp
+src/TextViewLog.hpp
+src/UIFile.hpp
+src/Widget.hpp
+src/binary_location.h
+src/event_to_string.cpp
+src/event_to_string.hpp
+src/handle_event.cpp
+src/handle_event.hpp
+src/jackey.h
+src/main.cpp
+src/make_alsa_driver.hpp
+src/make_jack_driver.hpp
+# src/patchage.gladep
+# src/patchage.svg
+src/patchage.ui.in
+src/patchage_config.h
+src/warnings.hpp
diff --git a/po/meson.build b/po/meson.build
new file mode 100644
index 0000000..689ed1b
--- /dev/null
+++ b/po/meson.build
@@ -0,0 +1,27 @@
+# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later
+
+i18n = import('i18n')
+
+add_project_arguments(
+ ['-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name())],
+ language: 'cpp',
+)
+
+i18n.gettext(
+ meson.project_name(),
+ args: [
+ '--add-comments',
+ '--check=bullet-unicode',
+ '--check=ellipsis-unicode',
+ '--check=quote-unicode',
+ '--check=space-ellipsis',
+ '--copyright-holder=FULL NAME <EMAIL@ADDRESS>',
+ '--from-code=UTF-8',
+ '--msgid-bugs-address=https://gitlab.com/drobilla/patchage/issues/new',
+ '--package-version=@0@'.format(meson.project_version()),
+ '--sentence-end=double-space',
+ '--sort-by-file',
+ '--width=80',
+ ],
+)
diff --git a/po/patchage.pot b/po/patchage.pot
new file mode 100644
index 0000000..e12cf8f
--- /dev/null
+++ b/po/patchage.pot
@@ -0,0 +1,155 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR FULL NAME <EMAIL@ADDRESS>
+# This file is distributed under the same license as the patchage package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: patchage 1.0.9\n"
+"Report-Msgid-Bugs-To: https://gitlab.com/drobilla/patchage/issues/new\n"
+"POT-Creation-Date: 2022-08-23 00:52-0400\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: src/CanvasModule.cpp:93
+msgid "_Split"
+msgstr ""
+
+#: src/CanvasModule.cpp:97
+msgid "_Join"
+msgstr ""
+
+#: src/CanvasModule.cpp:101
+msgid "_Disconnect"
+msgstr ""
+
+#: src/CanvasPort.hpp:86
+msgid "Disconnect"
+msgstr ""
+
+#: src/Legend.cpp:27
+msgid "Audio"
+msgstr ""
+
+#: src/Patchage.cpp:453
+msgid "frames at {} kHz ({:0.2f} ms)"
+msgstr ""
+
+#: src/Patchage.cpp:475 src/Patchage.cpp:510 src/patchage.ui.in:391
+msgid "Dropouts: {}"
+msgstr ""
+
+#: src/Patchage.cpp:838
+msgid "Export Image"
+msgstr ""
+
+#: src/Patchage.cpp:860
+msgid "Draw _Background"
+msgstr ""
+
+#: src/Patchage.cpp:871
+msgid "File exists! Overwrite {}?"
+msgstr ""
+
+#: src/patchage.ui.in:21
+msgid "_File"
+msgstr ""
+
+#: src/patchage.ui.in:30
+msgid "_Export Image…"
+msgstr ""
+
+#: src/patchage.ui.in:60
+msgid "_System"
+msgstr ""
+
+#: src/patchage.ui.in:67
+msgid "Connect to _JACK"
+msgstr ""
+
+#: src/patchage.ui.in:78
+msgid "Disconnect from JACK"
+msgstr ""
+
+#: src/patchage.ui.in:95
+msgid "Connect to _ALSA"
+msgstr ""
+
+#: src/patchage.ui.in:106
+msgid "Disconnect from ALSA"
+msgstr ""
+
+#: src/patchage.ui.in:123
+msgid "_View"
+msgstr ""
+
+#: src/patchage.ui.in:132
+msgid "_Messages"
+msgstr ""
+
+#: src/patchage.ui.in:141
+msgid "Tool_bar"
+msgstr ""
+
+#: src/patchage.ui.in:157
+msgid "_Human Names"
+msgstr ""
+
+#: src/patchage.ui.in:167
+msgid "_Sort Ports by Name"
+msgstr ""
+
+#: src/patchage.ui.in:230
+msgid "_Increase Font Size"
+msgstr ""
+
+#: src/patchage.ui.in:239
+msgid "_Decrease Font Size"
+msgstr ""
+
+#: src/patchage.ui.in:248
+msgid "_Normal Font Size"
+msgstr ""
+
+#: src/patchage.ui.in:272
+msgid "_Arrange"
+msgstr ""
+
+#: src/patchage.ui.in:285
+msgid "Sprung Layou_t"
+msgstr ""
+
+#: src/patchage.ui.in:298
+msgid "_Help"
+msgstr ""
+
+#: src/patchage.ui.in:341
+msgid "JACK buffer size and sample rate."
+msgstr ""
+
+#: src/patchage.ui.in:353
+msgid "JACK buffer length in frames."
+msgstr ""
+
+#: src/patchage.ui.in:365
+msgid "frames at ? kHz (? ms)"
+msgstr ""
+
+#: src/patchage.ui.in:405
+msgid "Clear dropout indicator."
+msgstr ""
+
+#: src/patchage.ui.in:505
+msgid "A modular patchbay for JACK and ALSA applications."
+msgstr ""
+
+#. TRANSLATORS: Replace this string with your names, one name per line.
+#: src/patchage.ui.in:1183
+msgid "translator-credits"
+msgstr ""
diff --git a/src/CanvasModule.cpp b/src/CanvasModule.cpp
index d3908df..e93cefe 100644
--- a/src/CanvasModule.cpp
+++ b/src/CanvasModule.cpp
@@ -90,15 +90,15 @@ CanvasModule::show_menu(GdkEventButton* ev)
if (_type == SignalDirection::duplex) {
items.push_back(Gtk::Menu_Helpers::MenuElem(
- "_Split", sigc::mem_fun(this, &CanvasModule::on_split)));
+ _("_Split"), sigc::mem_fun(this, &CanvasModule::on_split)));
update_menu();
} else {
items.push_back(Gtk::Menu_Helpers::MenuElem(
- "_Join", sigc::mem_fun(this, &CanvasModule::on_join)));
+ _("_Join"), sigc::mem_fun(this, &CanvasModule::on_join)));
}
items.push_back(Gtk::Menu_Helpers::MenuElem(
- "_Disconnect", sigc::mem_fun(this, &CanvasModule::on_disconnect)));
+ _("_Disconnect"), sigc::mem_fun(this, &CanvasModule::on_disconnect)));
_menu->popup(ev->button, ev->time);
return true;
diff --git a/src/CanvasPort.hpp b/src/CanvasPort.hpp
index 548c9e5..c3195a9 100644
--- a/src/CanvasPort.hpp
+++ b/src/CanvasPort.hpp
@@ -6,6 +6,7 @@
#include "PortID.hpp"
#include "PortType.hpp"
+#include "i18n.hpp"
#include "warnings.hpp"
PATCHAGE_DISABLE_GANV_WARNINGS
@@ -82,7 +83,7 @@ public:
Gtk::Menu* menu = Gtk::manage(new Gtk::Menu());
menu->items().push_back(Gtk::Menu_Helpers::MenuElem(
- "Disconnect", sigc::mem_fun(this, &Port::disconnect)));
+ _("Disconnect"), sigc::mem_fun(this, &Port::disconnect)));
menu->popup(ev->button.button, ev->button.time);
return true;
diff --git a/src/Legend.cpp b/src/Legend.cpp
index bdf51bc..a4e8705 100644
--- a/src/Legend.cpp
+++ b/src/Legend.cpp
@@ -5,6 +5,7 @@
#include "Configuration.hpp"
#include "PortType.hpp"
+#include "i18n.hpp"
#include "patchage_config.h"
#include <gdkmm/color.h>
@@ -23,7 +24,7 @@ namespace patchage {
Legend::Legend(const Configuration& configuration)
{
add_button(PortType::jack_audio,
- "Audio",
+ _("Audio"),
configuration.get_port_color(PortType::jack_audio));
#if USE_JACK_METADATA
diff --git a/src/Patchage.cpp b/src/Patchage.cpp
index 1f3d706..c3166c2 100644
--- a/src/Patchage.cpp
+++ b/src/Patchage.cpp
@@ -23,6 +23,7 @@
#include "Widget.hpp"
#include "event_to_string.hpp"
#include "handle_event.hpp"
+#include "i18n.hpp"
#include "patchage_config.h" // IWYU pragma: keep
#include "warnings.hpp"
@@ -445,11 +446,14 @@ Patchage::update_toolbar()
const auto buffer_size = _drivers.jack()->buffer_size();
const auto sample_rate = _drivers.jack()->sample_rate();
if (sample_rate != 0) {
- const auto latency_ms =
- buffer_size * 1000 / static_cast<float>(sample_rate);
+ const auto sample_rate_khz = sample_rate / 1000.0;
+ const auto latency_ms = buffer_size / sample_rate_khz;
+
+ _latency_label->set_label(" " +
+ fmt::format(_("frames at {} kHz ({:0.2f} ms)"),
+ sample_rate_khz,
+ latency_ms));
- _latency_label->set_label(fmt::format(
- " frames @ {} kHz ({:0.2f} ms)", sample_rate / 1000, latency_ms));
_latency_label->set_visible(true);
_buf_size_combo->set_active(
static_cast<int>(log2f(_drivers.jack()->buffer_size()) - 5));
@@ -467,12 +471,13 @@ Patchage::update_load()
{
if (_drivers.jack() && _drivers.jack()->is_attached()) {
const auto xruns = _drivers.jack()->xruns();
+
+ _dropouts_label->set_text(" " + fmt::format(_("Dropouts: {}"), xruns));
+
if (xruns > 0u) {
- _dropouts_label->set_text(fmt::format(" Dropouts: {}", xruns));
_dropouts_label->show();
_clear_load_but->show();
} else {
- _dropouts_label->set_text(" Dropouts: 0");
_dropouts_label->hide();
_clear_load_but->hide();
}
@@ -502,7 +507,7 @@ Patchage::store_window_location()
void
Patchage::clear_load()
{
- _dropouts_label->set_text(" Dropouts: 0");
+ _dropouts_label->set_text(" " + fmt::format(_("Dropouts: {}"), 0U));
_dropouts_label->hide();
_clear_load_but->hide();
if (_drivers.jack()) {
@@ -830,7 +835,9 @@ Patchage::on_quit()
void
Patchage::on_export_image()
{
- Gtk::FileChooserDialog dialog("Export Image", Gtk::FILE_CHOOSER_ACTION_SAVE);
+ Gtk::FileChooserDialog dialog(_("Export Image"),
+ Gtk::FILE_CHOOSER_ACTION_SAVE);
+
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
dialog.set_default_response(Gtk::RESPONSE_OK);
@@ -850,7 +857,7 @@ Patchage::on_export_image()
dialog.add_filter(filt);
}
- auto* bg_but = new Gtk::CheckButton("Draw _Background", true);
+ auto* bg_but = new Gtk::CheckButton(_("Draw _Background"), true);
auto* extra = new Gtk::Alignment(1.0, 0.5, 0.0, 0.0);
bg_but->set_active(true);
extra->add(*Gtk::manage(bg_but));
@@ -860,12 +867,12 @@ Patchage::on_export_image()
if (dialog.run() == Gtk::RESPONSE_OK) {
const std::string filename = dialog.get_filename();
if (Glib::file_test(filename, Glib::FILE_TEST_EXISTS)) {
- Gtk::MessageDialog confirm(std::string("File exists! Overwrite ") +
- filename + "?",
- true,
- Gtk::MESSAGE_WARNING,
- Gtk::BUTTONS_YES_NO,
- true);
+ Gtk::MessageDialog confirm(
+ fmt::format(_("File exists! Overwrite {}?"), filename),
+ true,
+ Gtk::MESSAGE_WARNING,
+ Gtk::BUTTONS_YES_NO,
+ true);
confirm.set_transient_for(dialog);
if (confirm.run() != Gtk::RESPONSE_YES) {
return;
diff --git a/src/i18n.hpp b/src/i18n.hpp
new file mode 100644
index 0000000..4cf082d
--- /dev/null
+++ b/src/i18n.hpp
@@ -0,0 +1,15 @@
+// Copyright 2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef PATCHAGE_I18N_HPP
+#define PATCHAGE_I18N_HPP
+
+#include <libintl.h>
+
+/// Mark a string literal as translatable
+#define _(msgid) gettext(msgid)
+
+/// Mark a string literal as non-translatable
+// #define N_(msgid) (msgid)
+
+#endif // PATCHAGE_I18N_HPP
diff --git a/src/main.cpp b/src/main.cpp
index 4466e15..d76413f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -21,6 +21,10 @@
#include <glibmm/ustring.h>
#include <gtkmm/main.h>
+#if USE_GETTEXT
+# include <libintl.h>
+#endif
+
#include <cstring>
#include <exception>
#include <iostream>
@@ -94,6 +98,13 @@ main(int argc, char** argv)
set_bundle_environment();
#endif
+#if USE_GETTEXT
+ setlocale(LC_ALL, "");
+ bindtextdomain("patchage", PATCHAGE_LOCALE_DIR);
+ bind_textdomain_codeset("patchage", "UTF-8");
+ textdomain("patchage");
+#endif
+
try {
Glib::thread_init();
diff --git a/src/patchage.ui.in b/src/patchage.ui.in
index c63566a..89d749d 100644
--- a/src/patchage.ui.in
+++ b/src/patchage.ui.in
@@ -362,7 +362,7 @@
<child>
<object class="GtkLabel" id="latency_label">
<property name="can_focus">False</property>
- <property name="label" translatable="yes">frames @ ? kHz (? ms)</property>
+ <property name="label" translatable="yes">frames at ? kHz (? ms)</property>
</object>
<packing>
<property name="expand">False</property>
@@ -388,7 +388,7 @@
<object class="GtkLabel" id="dropouts_label">
<property name="can_focus">False</property>
<property name="visible">False</property>
- <property name="label" translatable="yes"> Dropouts: 0</property>
+ <property name="label" translatable="yes">Dropouts: {}</property>
</object>
</child>
</object>
@@ -502,7 +502,7 @@
<property name="version">@PATCHAGE_VERSION@</property>
<property name="copyright" translatable="no">© 2005-2022 David Robillard
© 2008 Nedko Arnaudov</property>
- <property name="comments" translatable="yes">A JACK and ALSA front-end.</property>
+ <property name="comments" translatable="yes">A modular patchbay for JACK and ALSA applications.</property>
<property name="website">http://drobilla.net/software/patchage</property>
<property name="license" translatable="no"> GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
diff --git a/src/patchage_config.h b/src/patchage_config.h
index e5f56df..6c3ad90 100644
--- a/src/patchage_config.h
+++ b/src/patchage_config.h
@@ -46,6 +46,19 @@
# endif
# endif
+// GNU gettext()
+# ifndef HAVE_GETTEXT
+# ifdef __has_include
+# if __has_include(<libintl.h>)
+# define HAVE_GETTEXT 1
+# else
+# define HAVE_GETTEXT 0
+# endif
+# else
+# define HAVE_GETTEXT 0
+# endif
+# endif
+
// JACK metadata API
# ifndef HAVE_JACK_METADATA
# ifdef __has_include
@@ -75,6 +88,12 @@
# define USE_DLADDR 0
#endif
+#if HAVE_GETTEXT
+# define USE_GETTEXT 1
+#else
+# define USE_GETTEXT 0
+#endif
+
#if HAVE_JACK_METADATA
# define USE_JACK_METADATA 1
#else