diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4517407..dbcc9fb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest container: alpine:edge steps: - - run: apk --no-cache add git gcc g++ binutils pkgconf meson ninja cmake musl-dev wayland-dev wayland-protocols libinput-dev libevdev-dev libxkbcommon-dev pixman-dev glm-dev libdrm-dev mesa-dev cairo-dev pango-dev eudev-dev libxml2-dev glibmm-dev libseat-dev libdisplay-info-dev hwdata-dev nlohmann-json gtk+3.0-dev gtkmm3-dev + - run: apk --no-cache add git gcc g++ binutils pkgconf meson ninja cmake musl-dev wayland-dev wayland-protocols libinput-dev libevdev-dev libxkbcommon-dev pixman-dev glm-dev libdrm-dev mesa-dev cairo-dev pango-dev eudev-dev libxml2-dev glibmm-dev libseat-dev libdisplay-info-dev hwdata-dev nlohmann-json gtk+3.0-dev gtkmm3-dev gettext-dev fmt-dev - name: Wayfire uses: actions/checkout@v2 with: diff --git a/locale/meson.build b/locale/meson.build new file mode 100644 index 0000000..eea7f1f --- /dev/null +++ b/locale/meson.build @@ -0,0 +1,27 @@ +share_dir = join_paths(get_option('prefix'), 'share') +wayfire_locale_dir = join_paths(share_dir, 'locale') + +fs = import('fs') + +mo_targets = [] + +po_files_raw = run_command('find', '.', '-name', '*.po', check : true).stdout().strip().split('\n') +po_files = files(po_files_raw) + +foreach po_file : po_files + language = fs.name(fs.parent(fs.parent(po_file))) + mo_file = fs.stem(po_file) + '.mo' + t = custom_target('mo-' + language, + input : po_file, + output : mo_file, + command : ['msgfmt', '@INPUT@', '-o', '@OUTPUT@'], + install : true, + install_dir : join_paths( + wayfire_locale_dir, + language, + 'LC_MESSAGES' + ) + ) + + mo_targets += t +endforeach diff --git a/locale/ro_RO/LC_MESSAGES/wcm.po b/locale/ro_RO/LC_MESSAGES/wcm.po new file mode 100644 index 0000000..c03b8ce --- /dev/null +++ b/locale/ro_RO/LC_MESSAGES/wcm.po @@ -0,0 +1,247 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-15 14:54+0300\n" +"PO-Revision-Date: 2025-09-15 15:00+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: ro_RO\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.7\n" + +#: src/metadata.cpp:382 +msgid "Uncategorized" +msgstr "Necategorizat" + +#: src/metadata.cpp:411 src/wcm.hpp:83 +msgid "General" +msgstr "Generale" + +#: src/wcm.cpp:26 +msgid "" +"Attempting to bind \"{key_str}\" without modifier. You will " +"be unable to use this key/button for anything else! Are you sure?" +msgstr "" +"Ați încercat să asociați «{key_str}» fără taste " +"modificatoare; nu veți putea folosi această tastă/buton pentru nimic " +"altceva. Sigur doriți să continuați?" + +#: src/wcm.cpp:66 +msgid "Waiting for Binding" +msgstr "Se așteaptă asocierea" + +#: src/wcm.cpp:67 +msgid "none" +msgstr "nimic" + +#: src/wcm.cpp:103 +msgid "(No modifiers pressed)" +msgstr "(Fără taste modificatoare apăsate)" + +#: src/wcm.cpp:200 +msgid "Edit binding" +msgstr "Editează asocierea" + +#: src/wcm.cpp:211 +msgid "Save binding" +msgstr "Salvează asocierea" + +#: src/wcm.cpp:222 src/wcm.cpp:576 src/wcm.cpp:698 +msgid "Cancel" +msgstr "Anulează" + +#: src/wcm.cpp:258 +msgid "Open context menu to choose layout" +msgstr "Deschideți meniul contextual pentru a alege aranjamentul" + +#: src/wcm.cpp:283 +msgid "Open context menu to choose model" +msgstr "Deschideți meniul contextual pentru a alege modelul" + +#: src/wcm.cpp:370 +msgid "Reset to default" +msgstr "Resetează la opțiunile implicite" + +#: src/wcm.cpp:577 src/wcm.cpp:699 +msgid "Open" +msgstr "Deschide" + +#: src/wcm.cpp:587 +msgid "Choose Directory" +msgstr "Alegeți directorul" + +#: src/wcm.cpp:591 +msgid "Select Folder" +msgstr "Alegeți director" + +#: src/wcm.cpp:601 +msgid "Choose File" +msgstr "Alegeți fișierul" + +#: src/wcm.cpp:605 +msgid "Select File" +msgstr "Alegeți fișier" + +#: src/wcm.cpp:694 src/wcm.cpp:697 +msgid "Choose Executable" +msgstr "Alegeți executabilul" + +#: src/wcm.cpp:706 +msgid "Run command" +msgstr "Execută comanda" + +#: src/wcm.cpp:712 +msgid "Remove from autostart list" +msgstr "Elimină din lista de pornire automată" + +#: src/wcm.cpp:774 +msgid "Regular" +msgstr "Obișnuită" + +#: src/wcm.cpp:775 +msgid "Repeat" +msgstr "Repetată" + +#: src/wcm.cpp:776 +msgid "Always" +msgstr "Mereu disponibilă" + +#: src/wcm.cpp:801 +msgid "Command {name}" +msgstr "Comanda {name}" + +#: src/wcm.cpp:804 +msgid "Command {name}: {command}" +msgstr "Comanda {name}: {command}" + +#: src/wcm.cpp:852 +msgid "Workspace Index" +msgstr "Indicele biroului" + +#: src/wcm.cpp:905 +msgid "Add new command" +msgstr "Adaugă o nouă comandă" + +#: src/wcm.cpp:979 +msgid "Go To Workspace" +msgstr "Treci la birou" + +#: src/wcm.cpp:982 +msgid "Go To Workspace With Window" +msgstr "Treci la birou cu fereastra" + +#: src/wcm.cpp:985 +msgid "Send Window To Workspace" +msgstr "Trimite fereastra pe birou" + +#: src/wcm.cpp:1011 src/wcm.cpp:1019 +msgid "{workspace_option_prefix} {workspace_index}" +msgstr "{workspace_option_prefix} {workspace_index}" + +#: src/wcm.cpp:1328 +msgid "Wayfire config file to use" +msgstr "fișierul de configurare Wayfire de folosit" + +#: src/wcm.cpp:1333 +msgid "wf-shell config file to use" +msgstr "fișierul de configurare wf-shell de folosit" + +#: src/wcm.cpp:1338 +msgid "plugin to open at launch, or none for default" +msgstr "" +"modul care să se deschidă la lansare, sau none pentru valoarea standard" + +#: src/wcm.cpp:1365 +msgid "Wayfire Config Manager" +msgstr "Administratorul configurărilor Wayfire" + +#: src/wcm.cpp:1438 +msgid "To use input binding capture, enable shortcuts-inhibit plugin." +msgstr "" +"Pentru a folosi captarea asocierilor de intrare, activați modulul shortcuts-" +"inhibit." + +#: src/wcm.cpp:1531 +msgid "Filter" +msgstr "Filtru" + +#: src/wcm.cpp:1565 +msgid "Cannot find program wdisplays" +msgstr "Nu se poate găsi programul wdisplays" + +#: src/wcm.hpp:84 +msgid "Accessibility" +msgstr "Accesibilitate" + +#: src/wcm.hpp:85 +msgid "Desktop" +msgstr "Birou" + +#: src/wcm.hpp:85 +msgid "Shell" +msgstr "Interfața biroului" + +#: src/wcm.hpp:86 +msgid "Effects" +msgstr "Efecte" + +#: src/wcm.hpp:87 +msgid "Window Management" +msgstr "Gestionarea ferestrelor" + +#: src/wcm.hpp:88 +msgid "Utility" +msgstr "Utilitare" + +#: src/wcm.hpp:88 +msgid "Other" +msgstr "Altele" + +#: src/wcm.hpp:94 +msgid "(none)" +msgstr "(nimic)" + +#: src/wcm.hpp:215 +msgid "Command:" +msgstr "Comandă:" + +#: src/wcm.hpp:221 +msgid "Type" +msgstr "Tip" + +#: src/wcm.hpp:222 +msgid "Binding" +msgstr "Asociere" + +#: src/wcm.hpp:223 +msgid "Command" +msgstr "Comandă" + +#: src/wcm.hpp:254 +msgid "Workspace" +msgstr "Birou" + +#: src/wcm.hpp:338 +msgid "Close" +msgstr "Închide" + +#: src/wcm.hpp:340 +msgid "Configure Outputs" +msgstr "Configurează ieșiri" + +#: src/wcm.hpp:347 +msgid "Use This Plugin" +msgstr "Folosește acest modul" + +#: src/wcm.hpp:348 +msgid "Back" +msgstr "Înapoi" diff --git a/meson.build b/meson.build index 0d33c4a..fbb7c31 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,7 @@ project('wcm', 'c', 'cpp', version : '0.11.0', default_options : 'cpp_std=c++17') +fs = import('fs') + add_global_arguments('-DWAYFIRE_CONFIG_FILE="' + get_option('wayfire_config_file_path') + '"', language : 'cpp') add_global_arguments('-DWF_SHELL_CONFIG_FILE="' + get_option('wf_shell_config_file_path') + '"', language : 'cpp') @@ -10,16 +12,18 @@ wayfire_metadata_dir = wayfire.get_variable(pkgconfig: 'metadatadir') wayfire_sysconf_dir = wayfire.get_variable(pkgconfig: 'sysconfdir') share_dir = join_paths(get_option('prefix'), 'share') +wayfire_locale_dir = join_paths(share_dir, 'locale') icon_dir = join_paths(share_dir, 'wcm', 'icons') add_global_arguments('-DWAYFIRE_METADATADIR="' + wayfire_metadata_dir + '"', language : 'cpp') +add_global_arguments('-DWAYFIRE_LOCALEDIR="' + wayfire_locale_dir + '"', language : 'cpp') add_global_arguments('-DWAYFIRE_SYSCONFDIR="' + wayfire_sysconf_dir + '"', language : 'cpp') if wf_shell.found() - wf_shell_metadata_dir = wf_shell.get_variable(pkgconfig: 'metadatadir') - wf_shell_sysconf_dir = wf_shell.get_variable(pkgconfig: 'sysconfdir') - add_project_arguments('-DHAVE_WFSHELL=1', language : 'cpp') - add_global_arguments('-DWFSHELL_METADATADIR="' + wf_shell_metadata_dir + '"', language : 'cpp') - add_global_arguments('-DWFSHELL_SYSCONFDIR="' + wf_shell_sysconf_dir + '"', language : 'cpp') + wf_shell_metadata_dir = wf_shell.get_variable(pkgconfig: 'metadatadir') + wf_shell_sysconf_dir = wf_shell.get_variable(pkgconfig: 'sysconfdir') + add_project_arguments('-DHAVE_WFSHELL=1', language : 'cpp') + add_global_arguments('-DWFSHELL_METADATADIR="' + wf_shell_metadata_dir + '"', language : 'cpp') + add_global_arguments('-DWFSHELL_SYSCONFDIR="' + wf_shell_sysconf_dir + '"', language : 'cpp') endif add_global_arguments('-DICONDIR="' + icon_dir + '"', language : 'cpp') @@ -31,5 +35,6 @@ add_project_arguments('-DICONDIR="' + icon_dir + '"', language : 'cpp') subdir('icons') subdir('proto') subdir('src') +subdir('locale') install_data('wcm.desktop', install_dir: join_paths(share_dir, 'applications')) diff --git a/src/main.cpp b/src/main.cpp index ba2ef10..b8007f2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,12 @@ +#include +#include #include int main(int argc, char **argv) { + setlocale(LC_ALL, ""); + bindtextdomain("wcm", WAYFIRE_LOCALEDIR); + textdomain("wcm"); auto app = Gtk::Application::create("org.gtk.wcm"); std::unique_ptr wcm = std::make_unique(app); return app->run(argc, argv); diff --git a/src/meson.build b/src/meson.build index b0c2453..9700a30 100644 --- a/src/meson.build +++ b/src/meson.build @@ -2,8 +2,10 @@ xml = dependency('libxml-2.0', required: true) gtkmm = dependency('gtkmm-3.0', required: true) wf_config = dependency('wf-config', version: '>=0.6.0', required: true) xkbregistry = dependency('xkbregistry', required: true) +libintl = dependency('intl', required: true) +libfmt = dependency('fmt', required: true) -dep_list = [xml, gtkmm, wf_config, wf_protos, evdev, xkbregistry] +dep_list = [xml, gtkmm, wf_config, wf_protos, evdev, xkbregistry, libintl, libfmt] sources = files('main.cpp', 'metadata.cpp', 'wcm.cpp', 'utils.cpp') diff --git a/src/metadata.cpp b/src/metadata.cpp index 269e0b9..65fac8a 100644 --- a/src/metadata.cpp +++ b/src/metadata.cpp @@ -25,8 +25,11 @@ */ #include "wcm.hpp" +#include +#include #include #include +#include Option::Option(xmlNode *cur_node, Plugin *plugin) { @@ -111,6 +114,7 @@ Option::Option(xmlNode *cur_node, Plugin *plugin) } free(prop); + std::string gettext_domain_name = "wf-plugin-" + plugin->name; for (node = cur_node->children; node; node = node->next) { if (node->type != XML_ELEMENT_NODE) @@ -121,10 +125,10 @@ Option::Option(xmlNode *cur_node, Plugin *plugin) std::string node_name = (char*)node->name; if (node_name == "_short") { - this->disp_name = (char*)node->children->content; + this->disp_name = dgettext(gettext_domain_name.c_str(), (char*)node->children->content); } else if (node_name == "_long") { - this->tooltip = (char*)node->children->content; + this->tooltip = dgettext(gettext_domain_name.c_str(), (char*)node->children->content); } else if (node_name == "default") { if (!node->children) @@ -284,7 +288,8 @@ Option::Option(xmlNode *cur_node, Plugin *plugin) if (is_name) { - li->name = strdup((char*)n->children->content); + li->name = + dgettext(gettext_domain_name.c_str(), strdup((char*)n->children->content)); } } else if (this->type == OPTION_TYPE_STRING) { @@ -307,7 +312,8 @@ Option::Option(xmlNode *cur_node, Plugin *plugin) if (is_name) { - ls->name = (char*)n->children->content; + ls->name = + dgettext(gettext_domain_name.c_str(), strdup((char*)n->children->content)); } } } @@ -374,11 +380,13 @@ Plugin*Plugin::get_plugin_data(xmlNode *cur_node, Option *main_group, Plugin *pl if (cur_node_name == "plugin") { plugin = new Plugin(); - plugin->category = "Uncategorized"; + plugin->category = _("Uncategorized"); prop = xmlGetProp(cur_node, (xmlChar*)"name"); if (prop) { plugin->name = (char*)prop; + // Initialise translations + bindtextdomain(("wf-plugin-" + plugin->name).c_str(), WAYFIRE_LOCALEDIR); } free(prop); @@ -401,7 +409,7 @@ Plugin*Plugin::get_plugin_data(xmlNode *cur_node, Option *main_group, Plugin *pl if (!main_group) { main_group = new Option(OPTION_TYPE_GROUP, plugin); - main_group->name = "General"; + main_group->name = _("General"); plugin->option_groups.push_back(main_group); } diff --git a/src/wcm.cpp b/src/wcm.cpp index 3db1d66..b51d199 100644 --- a/src/wcm.cpp +++ b/src/wcm.cpp @@ -2,12 +2,15 @@ #include "utils.hpp" #include +#include #include +#include #include #include #include #include #include +#include #define OUTPUT_CONFIG_PROGRAM "wdisplays" @@ -19,9 +22,10 @@ bool KeyEntry::check_and_confirm(const std::string & key_str) ((key_str.find("BTN") != std::string::npos) || (key_str.find("KEY") != std::string::npos))) { - auto dialog = Gtk::MessageDialog("Attempting to bind \"" + key_str + '"' + - " without modifier. You will be unable to use this key/button " - "for anything else! Are you sure?", + auto dialog = Gtk::MessageDialog( + fmt::format(_("Attempting to bind \"{key_str}\" without modifier." + " You will be unable to use this key/button for anything else!" + " Are you sure?"), fmt::arg("key_str", key_str)), true, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO); return dialog.run() == Gtk::RESPONSE_YES; } @@ -59,8 +63,8 @@ std::string KeyEntry::grab_key() { static const auto HW_OFFSET = 8; - auto grab_dialog = Gtk::Dialog("Waiting for Binding", true); - auto label = Gtk::Label("none"); + auto grab_dialog = Gtk::Dialog(_("Waiting for Binding"), true); + auto label = Gtk::Label(_("none")); grab_dialog.get_content_area()->pack_start(label); label.show(); @@ -96,7 +100,7 @@ std::string KeyEntry::grab_key() auto update_label = [=, &label] { const auto text = cur_state_string(); - label.set_text(text.empty() ? "(No modifiers pressed)" : text); + label.set_text(text.empty() ? _("(No modifiers pressed)") : text); }; update_label(); @@ -193,7 +197,7 @@ KeyEntry::KeyEntry() } }); edit_button.set_image_from_icon_name("gtk-edit"); - edit_button.set_tooltip_text("Edit binding"); + edit_button.set_tooltip_text(_("Edit binding")); edit_button.signal_clicked().connect([=] { entry.set_text(get_value()); @@ -204,7 +208,7 @@ KeyEntry::KeyEntry() edit_layout.pack_start(entry, true, true); ok_button.set_image_from_icon_name("gtk-ok"); - ok_button.set_tooltip_text("Save binding"); + ok_button.set_tooltip_text(_("Save binding")); ok_button.signal_clicked().connect([=] { const std::string value = entry.get_text(); @@ -215,7 +219,7 @@ KeyEntry::KeyEntry() } }); cancel_button.set_image_from_icon_name("gtk-cancel"); - cancel_button.set_tooltip_text("Cancel"); + cancel_button.set_tooltip_text(_("Cancel")); cancel_button.signal_clicked().connect([=] { set_visible_child(grab_layout); }); edit_layout.pack_start(cancel_button, false, false); edit_layout.pack_start(ok_button, false, false); @@ -251,7 +255,7 @@ LayoutsEntry::LayoutsEntry() }); } - set_tooltip_text("Open context menu to choose layout"); + set_tooltip_text(_("Open context menu to choose layout")); signal_populate_popup().connect([&] (Gtk::Menu *menu) { @@ -276,7 +280,7 @@ XkbModelEntry::XkbModelEntry() }); } - set_tooltip_text("Open context menu to choose model"); + set_tooltip_text(_("Open context menu to choose model")); signal_populate_popup().connect([&] (Gtk::Menu *menu) { @@ -363,7 +367,7 @@ OptionWidget::OptionWidget(Option *option) : Gtk::Box(Gtk::ORIENTATION_HORIZONTA name_label.set_alignment(Gtk::ALIGN_START); reset_button.set_image_from_icon_name("edit-clear"); - reset_button.set_tooltip_text("Reset to default"); + reset_button.set_tooltip_text(_("Reset to default")); pack_start(name_label, false, false); Gtk::Box::pack_end(reset_button, false, false); @@ -569,8 +573,8 @@ OptionWidget::OptionWidget(Option *option) : Gtk::Box(Gtk::ORIENTATION_HORIZONTA Gtk::FileChooserAction action) { auto dialog = Gtk::FileChooserDialog(label, action); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Open", Gtk::RESPONSE_ACCEPT); + dialog.add_button(_("Cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(_("Open"), Gtk::RESPONSE_ACCEPT); if (dialog.run() == Gtk::RESPONSE_ACCEPT) { widget->set_text(dialog.get_filename()); @@ -580,11 +584,11 @@ OptionWidget::OptionWidget(Option *option) : Gtk::Box(Gtk::ORIENTATION_HORIZONTA { auto dir_choose_button = std::make_unique(); dir_choose_button->set_image_from_icon_name("folder-open"); - dir_choose_button->set_tooltip_text("Choose Directory"); + dir_choose_button->set_tooltip_text(_("Choose Directory")); dir_choose_button->signal_clicked().connect( [=] { - run_dialog("Select Folder", + run_dialog(_("Select Folder"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); }); pack_end(std::move(dir_choose_button)); @@ -594,11 +598,11 @@ OptionWidget::OptionWidget(Option *option) : Gtk::Box(Gtk::ORIENTATION_HORIZONTA { auto file_choose_button = std::make_unique(); file_choose_button->set_image_from_icon_name("text-x-generic"); - file_choose_button->set_tooltip_text("Choose File"); + file_choose_button->set_tooltip_text(_("Choose File")); file_choose_button->signal_clicked().connect( [=] { - run_dialog("Select File", Gtk::FILE_CHOOSER_ACTION_OPEN); + run_dialog(_("Select File"), Gtk::FILE_CHOOSER_ACTION_OPEN); }); pack_end(std::move(file_choose_button)); } @@ -687,25 +691,25 @@ AutostartDynamicList::AutostartWidget::AutostartWidget(Option *option) : Gtk::Bo option->set_save(command_entry.get_text()); }); choose_button.set_image_from_icon_name("application-x-executable"); - choose_button.set_tooltip_text("Choose Executable"); + choose_button.set_tooltip_text(_("Choose Executable")); choose_button.signal_clicked().connect([&] { - auto dialog = Gtk::FileChooserDialog("Choose Executable"); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Open", Gtk::RESPONSE_ACCEPT); + auto dialog = Gtk::FileChooserDialog(_("Choose Executable")); + dialog.add_button(_("Cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(_("Open"), Gtk::RESPONSE_ACCEPT); if (dialog.run() == Gtk::RESPONSE_ACCEPT) { command_entry.set_text(dialog.get_filename()); } }); run_button.set_image_from_icon_name("media-playback-start"); - run_button.set_tooltip_text("Run command"); + run_button.set_tooltip_text(_("Run command")); run_button.signal_clicked().connect([=] { Glib::spawn_command_line_async(command_entry.get_text()); }); remove_button.set_image_from_icon_name("list-remove"); - remove_button.set_tooltip_text("Remove from autostart list"); + remove_button.set_tooltip_text(_("Remove from autostart list")); remove_button.signal_clicked().connect([=] { auto section = WCM::get_instance()->get_config_section(option->plugin); @@ -767,9 +771,9 @@ BindingsDynamicList::BindingWidget::BindingWidget(const std::string & cmd_name, type_label.set_size_request(OPTION_LABEL_SIZE); type_label.set_alignment(Gtk::ALIGN_START); type_box.pack_start(type_label, false, false); - type_combo_box.append("Regular"); - type_combo_box.append("Repeat"); - type_combo_box.append("Always"); + type_combo_box.append(_("Regular")); + type_combo_box.append(_("Repeat")); + type_combo_box.append(_("Always")); type_combo_box.set_active(always_opt ? 2 : repeatable_opt ? 1 : 0); type_combo_box.signal_changed().connect([=] { @@ -794,10 +798,12 @@ BindingsDynamicList::BindingWidget::BindingWidget(const std::string & cmd_name, command_label.set_size_request(OPTION_LABEL_SIZE); command_label.set_alignment(Gtk::ALIGN_START); command_box.pack_start(command_label, false, false); - expander.set_label("Command " + cmd_name); + expander.set_label(fmt::format(_("Command {name}"), fmt::arg("name", cmd_name))); command_entry.signal_changed().connect([=] { - expander.set_label("Command " + cmd_name + ": " + command_entry.get_text()); + expander.set_label(fmt::format(_("Command {name}: {command}"), + fmt::arg("name", cmd_name), + fmt::arg("command", command_entry.get_text().c_str()))); auto *label = (Gtk::Label*)expander.get_label_widget(); label->set_ellipsize(Pango::ELLIPSIZE_END); label->set_tooltip_text(command_entry.get_text()); @@ -843,7 +849,7 @@ VswitchBindingsDynamicList::BindingWidget::BindingWidget(std::shared_ptrsave_config(option->plugin); }); - workspace_spin_button.set_tooltip_text("Workspace Index"); + workspace_spin_button.set_tooltip_text(_("Workspace Index")); workspace_spin_button.set_value(workspace_index); workspace_spin_button.signal_value_changed().connect([=] { @@ -896,7 +902,7 @@ AutostartDynamicList::AutostartDynamicList(Option *option) pack_widget(std::make_unique(dyn_opt)); } - add_button.set_tooltip_text("Add new command"); + add_button.set_tooltip_text(_("Add new command")); add_button.signal_clicked().connect([=] { static const std::string prefix = "autostart"; @@ -970,13 +976,14 @@ const std::string VswitchBindingsDynamicList::O template<> const std::string VswitchBindingsDynamicList::OPTION_PREFIX = "send_win_"; template<> -const Glib::ustring VswitchBindingsWidget::LABEL_TEXT = "Go To Workspace"; +const Glib::ustring VswitchBindingsWidget::LABEL_TEXT = + _("Go To Workspace"); template<> const Glib::ustring VswitchBindingsWidget::LABEL_TEXT = - "Go To Workspace With Window"; + _("Go To Workspace With Window"); template<> const Glib::ustring VswitchBindingsWidget::LABEL_TEXT = - "Send Window To Workspace"; + _("Send Window To Workspace"); template VswitchBindingsDynamicList::VswitchBindingsDynamicList(Option *option) @@ -1009,8 +1016,8 @@ VswitchBindingsDynamicList::VswitchBindingsDynamicList(Option *option) Option *binding_option = option->create_child_option(OPTION_PREFIX + std::to_string(workspace_index), OPTION_TYPE_STRING); - section->register_new_option(std::make_shared>(binding_option->name, - "")); + section->register_new_option(std::make_shared>( + binding_option->name, "")); pack_widget(std::make_unique(section, binding_option, workspace_index)); show_all(); WCM::get_instance()->save_config(option->plugin); @@ -1020,7 +1027,7 @@ VswitchBindingsDynamicList::VswitchBindingsDynamicList(Option *option) template VswitchBindingsWidget::VswitchBindingsWidget(Option *option) : dynamic_list(option) { - set_label(LABEL_TEXT + " Bindings"); + set_label(fmt::format("{option_name} Bindings", fmt::arg("option_name", LABEL_TEXT.c_str()))); dynamic_list.property_margin().set_value(5); add(dynamic_list); } @@ -1096,6 +1103,7 @@ OptionGroupWidget::OptionGroupWidget(Option *group) PluginPage::PluginPage(Plugin *plugin) { + std::string gettext_domain_name = "wf-plugin-" + plugin->name; set_scrollable(); for (auto *group : plugin->option_groups) { @@ -1105,7 +1113,7 @@ PluginPage::PluginPage(Plugin *plugin) } groups.emplace_back(group); - append_page(groups.back(), group->name); + append_page(groups.back(), dgettext(gettext_domain_name.c_str(), group->name.c_str())); } } @@ -1138,11 +1146,12 @@ void Plugin::init_widget() } button_layout.pack_start(icon); - label.set_text(disp_name); + std::string gettext_domain_name = "wf-plugin-" + name; + label.set_text(dgettext(gettext_domain_name.c_str(), disp_name.c_str())); label.set_ellipsize(Pango::ELLIPSIZE_END); button_layout.pack_start(label); button_layout.set_halign(Gtk::ALIGN_START); - button.set_tooltip_markup(tooltip); + button.set_tooltip_markup(dgettext(gettext_domain_name.c_str(), tooltip.c_str())); button.set_relief(Gtk::RELIEF_NONE); button.add(button_layout); enabled_check.set_active(enabled); @@ -1180,7 +1189,7 @@ MainPage::MainPage(const std::vector & plugins) : plugins(plugins) std::find_if(categories.begin(), categories.end() - 1, [=] (const Category & cat) { - return cat.name == plugin->category; + return cat.name == Glib::ustring(_(plugin->category.c_str())); })->add_plugin(plugin); size_group->add_widget(plugin->widget); } @@ -1211,7 +1220,7 @@ void MainPage::set_filter(const Glib::ustring & filter) find_string(plug->tooltip, filter); // the parent of `plug->widget` is `Gtk::FlowBoxItem` plug->widget.get_parent()->set_visible(plug_visible); - category_visible[plug->category] |= plug_visible; + category_visible[_(plug->category.c_str())] |= plug_visible; } categories[0].vbox.set_visible(category_visible[categories[0].name]); @@ -1311,17 +1320,17 @@ WCM::WCM(Glib::RefPtr app) { wf_config_file = value; return true; - }, "config", 'c', "Wayfire config file to use", "file"); + }, "config", 'c', _("Wayfire config file to use"), "file"); app->add_main_option_entry([this] (const Glib::ustring &, const Glib::ustring & value, bool) { wf_shell_config_file = value; return true; - }, "shell-config", 's', "wf-shell config file to use", "file"); + }, "shell-config", 's', _("wf-shell config file to use"), "file"); app->add_main_option_entry([this] (const Glib::ustring &, const Glib::ustring & value, bool) { start_plugin = value; return true; - }, "plugin", 'p', "plugin to open at launch, or none for default", "name"); + }, "plugin", 'p', _("plugin to open at launch, or none for default"), "name"); app->signal_startup().connect([this, app] () { @@ -1348,7 +1357,7 @@ WCM::WCM(Glib::RefPtr app) window->set_icon(icon); window->set_size_request(750, 550); window->set_default_size(1000, 580); - window->set_title("Wayfire Config Manager"); + window->set_title(_("Wayfire Config Manager")); create_main_layout(); window->show_all(); }); @@ -1421,7 +1430,7 @@ bool WCM::lock_input(Gtk::Dialog *grab_dialog) auto error_dialog = Gtk::Dialog( "Compositor does not advertise zwp_keyboard_shortcuts_inhibit_manager_v1!", *window, Gtk::DIALOG_DESTROY_WITH_PARENT); - auto label = Gtk::Label("To use input binding capture, enable shortcuts-inhibit plugin."); + auto label = Gtk::Label(_("To use input binding capture, enable shortcuts-inhibit plugin.")); error_dialog.get_content_area()->pack_start(label, true, true, 50); error_dialog.add_button("Ok", 0); label.show(); @@ -1514,7 +1523,7 @@ void WCM::create_main_layout() main_page = std::make_unique(plugins); filter_label.property_margin().set_value(10); - filter_label.set_markup("Filter"); + filter_label.set_markup("" + std::string(_("Filter")) + ""); main_left_panel_layout.pack_start(filter_label, false, false); search_entry.property_margin().set_value(10); @@ -1548,7 +1557,7 @@ void WCM::create_main_layout() { output_config_button.set_sensitive(false); output_config_button.set_tooltip_markup( - "Cannot find program wdisplays"); + _("Cannot find program wdisplays")); } plugin_left_panel_layout.pack_start(plugin_name_label, false, false); @@ -1602,13 +1611,16 @@ void WCM::open_page(Plugin *plugin) { if (plugin) { + std::string gettext_domain_name = "wf-plugin-" + plugin->name; plugin_enabled_box.set_visible( !plugin->is_core_plugin() && plugin->type != PLUGIN_TYPE_WF_SHELL); plugin_enabled_check.set_active(plugin->enabled); plugin_name_label.set_markup( - "" + plugin->disp_name + ""); + "" + + std::string(dgettext(gettext_domain_name.c_str(), plugin->disp_name.c_str())) + ""); plugin_description_label.set_markup( - "" + plugin->tooltip + ""); + "" + + std::string(dgettext(gettext_domain_name.c_str(), plugin->tooltip.c_str())) + ""); plugin_page = std::make_unique(plugin); main_stack.add(*plugin_page); plugin_page->show_all(); diff --git a/src/wcm.hpp b/src/wcm.hpp index d75478b..4fc774a 100644 --- a/src/wcm.hpp +++ b/src/wcm.hpp @@ -31,11 +31,14 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #include "metadata.hpp" @@ -76,18 +79,18 @@ class MainPage : public Gtk::ScrolledWindow Gtk::SIZE_GROUP_BOTH); std::array separators; std::array categories = { - Category{"General", "preferences-system"}, - {"Accessibility", "preferences-desktop-accessibility"}, - {"Desktop", "preferences-desktop"}, {"Shell", "user-desktop"}, - {"Effects", "applications-graphics"}, - {"Window Management", "applications-accessories"}, - {"Utility", "applications-other"}, {"Other", "applications-other"}}; + Category{_("General"), "preferences-system"}, + {_("Accessibility"), "preferences-desktop-accessibility"}, + {_("Desktop"), "preferences-desktop"}, {_("Shell"), "user-desktop"}, + {_("Effects"), "applications-graphics"}, + {_("Window Management"), "applications-accessories"}, + {_("Utility"), "applications-other"}, {_("Other"), "applications-other"}}; }; class KeyEntry : public Gtk::Stack { Gtk::Box grab_layout = Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 10); - Gtk::Label grab_label = Gtk::Label("(none)"); + Gtk::Label grab_label = Gtk::Label(_("(none)")); Gtk::Button grab_button; Gtk::Button edit_button; @@ -208,15 +211,15 @@ class BindingsDynamicList : public DynamicListBase { struct BindingWidget : public Gtk::Frame { - Gtk::Expander expander = Gtk::Expander("Command:"); + Gtk::Expander expander = Gtk::Expander(_("Command:")); Gtk::Box vbox = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 10); Gtk::Box type_box = Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 10); Gtk::Box binding_box = Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 10); Gtk::Box command_box = Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 10); - Gtk::Label type_label = Gtk::Label("Type"); - Gtk::Label binding_label = Gtk::Label("Binding"); - Gtk::Label command_label = Gtk::Label("Command"); + Gtk::Label type_label = Gtk::Label(_("Type")); + Gtk::Label binding_label = Gtk::Label(_("Binding")); + Gtk::Label command_label = Gtk::Label(_("Command")); Gtk::ComboBoxText type_combo_box; std::unique_ptr key_entry; @@ -247,7 +250,7 @@ class VswitchBindingsDynamicList : public DynamicListBase struct BindingWidget : public Gtk::Box { - Gtk::Label label = Gtk::Label("Workspace"); + Gtk::Label label = Gtk::Label(_("Workspace")); Gtk::SpinButton workspace_spin_button = Gtk::SpinButton(Gtk::Adjustment::create(1, 1, 30)); KeyEntry key_entry; Gtk::Button remove_button; @@ -331,17 +334,17 @@ class WCM Gtk::Box main_left_panel_layout = Gtk::Box(Gtk::ORIENTATION_VERTICAL); Gtk::Label filter_label; Gtk::SearchEntry search_entry; - PrettyButton close_button = PrettyButton("Close", "window-close"); + PrettyButton close_button = PrettyButton(_("Close"), "window-close"); PrettyButton output_config_button = - PrettyButton("Configure Outputs", "computer"); + PrettyButton(_("Configure Outputs"), "computer"); Gtk::Box plugin_left_panel_layout = Gtk::Box(Gtk::ORIENTATION_VERTICAL); Gtk::Label plugin_name_label; Gtk::Label plugin_description_label; Gtk::Box plugin_enabled_box = Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 10); Gtk::CheckButton plugin_enabled_check; - Gtk::Label plugin_enabled_label = Gtk::Label("Use This Plugin"); - PrettyButton back_button = PrettyButton("Back", "go-previous"); + Gtk::Label plugin_enabled_label = Gtk::Label(_("Use This Plugin")); + PrettyButton back_button = PrettyButton(_("Back"), "go-previous"); cairo_surface_t *grab_window_surface = nullptr; zwp_keyboard_shortcuts_inhibitor_v1 *shortcuts_inhibitor = nullptr;